commit - 8b10295ec9ddde4f3bfef322b31d3601d6040c62
commit + 2880100ab9ccb2f797b41e2c8c615e947eb42f77
blob - 1210e46dd5c67d6073935d5542ac84dc5a6f6a15
blob + bc9167c11f07085a6c16b8b189afe0d91b2930f0
--- gotd/gotd.c
+++ gotd/gotd.c
}
kill_proc(gotd.listen_proc, 0);
+
+ free(gotd.default_sender);
log_info("terminating");
exit(0);
/* This pipe is dead. Remove its event handler */
event_del(&iev->ev);
event_loopexit(NULL);
+ }
+}
+
+static const struct got_error *
+send_notification_target_email(struct gotd_imsgev *iev, const char *repo_name,
+ struct gotd_notification_target *target)
+{
+ struct gotd_imsg_notitfication_target_email itarget;
+ struct ibuf *wbuf = NULL;
+
+ memset(&itarget, 0, sizeof(itarget));
+
+ if (target->conf.email.sender)
+ itarget.sender_len = strlen(target->conf.email.sender);
+ else
+ itarget.sender_len = strlen(gotd.default_sender);
+ if (target->conf.email.recipient)
+ itarget.recipient_len = strlen(target->conf.email.recipient);
+ if (target->conf.email.responder)
+ itarget.responder_len = strlen(target->conf.email.responder);
+ if (target->conf.email.hostname)
+ itarget.hostname_len = strlen(target->conf.email.hostname);
+ if (target->conf.email.port)
+ itarget.port_len = strlen(target->conf.email.port);
+ itarget.repo_name_len = strlen(repo_name);
+
+ wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_EMAIL,
+ 0, 0, sizeof(itarget) + itarget.sender_len + itarget.recipient_len +
+ itarget.responder_len + itarget.hostname_len + itarget.port_len +
+ itarget.repo_name_len);
+ if (wbuf == NULL) {
+ return got_error_from_errno("imsg_create "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+
+ if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ if (target->conf.email.sender) {
+ if (imsg_add(wbuf, target->conf.email.sender,
+ itarget.sender_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ } else {
+ if (imsg_add(wbuf, gotd.default_sender,
+ itarget.sender_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ }
+ if (target->conf.email.recipient) {
+ if (imsg_add(wbuf, target->conf.email.recipient,
+ itarget.recipient_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ }
+ if (target->conf.email.responder) {
+ if (imsg_add(wbuf, target->conf.email.responder,
+ itarget.responder_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ }
+ if (target->conf.email.hostname) {
+ if (imsg_add(wbuf, target->conf.email.hostname,
+ itarget.hostname_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ }
+ if (target->conf.email.port) {
+ if (imsg_add(wbuf, target->conf.email.port,
+ itarget.port_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+ }
+ if (imsg_add(wbuf, repo_name, itarget.repo_name_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_EMAIL");
+ }
+
+ imsg_close(&iev->ibuf, wbuf);
+ return gotd_imsg_flush(&iev->ibuf);
+}
+
+static const struct got_error *
+send_notification_target_http(struct gotd_imsgev *iev, const char *repo_name,
+ struct gotd_notification_target *target)
+{
+ struct gotd_imsg_notitfication_target_http itarget;
+ struct ibuf *wbuf = NULL;
+
+ memset(&itarget, 0, sizeof(itarget));
+
+ itarget.tls = target->conf.http.tls;
+ itarget.hostname_len = strlen(target->conf.http.hostname);
+ itarget.port_len = strlen(target->conf.http.port);
+ itarget.path_len = strlen(target->conf.http.path);
+ if (target->conf.http.auth)
+ itarget.auth_len = strlen(target->conf.http.auth);
+ if (target->conf.http.hmac)
+ itarget.hmac_len = strlen(target->conf.http.hmac);
+ itarget.repo_name_len = strlen(repo_name);
+
+ wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_HTTP,
+ 0, 0, sizeof(itarget) + itarget.hostname_len + itarget.port_len +
+ itarget.path_len + itarget.auth_len + itarget.hmac_len +
+ itarget.repo_name_len);
+ if (wbuf == NULL) {
+ return got_error_from_errno("imsg_create "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+
+ if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+ if (imsg_add(wbuf, target->conf.http.hostname,
+ itarget.hostname_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+ if (imsg_add(wbuf, target->conf.http.port,
+ itarget.port_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+ if (imsg_add(wbuf, target->conf.http.path,
+ itarget.path_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+
+ if (target->conf.http.auth) {
+ if (imsg_add(wbuf, target->conf.http.auth,
+ itarget.auth_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+ }
+ if (target->conf.http.hmac) {
+ if (imsg_add(wbuf, target->conf.http.hmac,
+ itarget.hmac_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+ }
+ if (imsg_add(wbuf, repo_name, itarget.repo_name_len) == -1) {
+ return got_error_from_errno("imsg_add "
+ "NOTIFICATION_TARGET_HTTP");
+ }
+
+ imsg_close(&iev->ibuf, wbuf);
+ return gotd_imsg_flush(&iev->ibuf);
+}
+
+static const struct got_error *
+send_notification_target(struct gotd_imsgev *iev, const char *repo_name,
+ struct gotd_notification_target *target)
+{
+ const struct got_error *err = NULL;
+
+ switch (target->type) {
+ case GOTD_NOTIFICATION_VIA_EMAIL:
+ err = send_notification_target_email(iev, repo_name, target);
+ break;
+ case GOTD_NOTIFICATION_VIA_HTTP:
+ err = send_notification_target_http(iev, repo_name, target);
+ break;
+ default:
+ log_warn("unsupported notification target type %d",
+ target->type);
+ break;
+ }
+
+ return err;
+}
+
+static const struct got_error *
+send_notification_targets(struct gotd_imsgev *iev, const char *repo_name,
+ struct gotd_notification_targets *targets)
+{
+ const struct got_error *err = NULL;
+ struct gotd_notification_target *target;
+
+ STAILQ_FOREACH(target, targets, entry) {
+ err = send_notification_target(iev, repo_name, target);
+ if (err)
+ return err;
}
+
+ return NULL;
}
static void
break;
switch (imsg.hdr.type) {
+ case GOTD_IMSG_NOTIFIER_READY: {
+ struct gotd_repo *repo;
+
+ TAILQ_FOREACH(repo, &gotd.repos, entry) {
+ err = send_notification_targets(iev,
+ repo->name, &repo->notification_targets);
+ if (err)
+ break;
+ }
+ break;
+ }
default:
log_debug("unexpected imsg %d", imsg.hdr.type);
break;
}
return NULL;
-}
-
-static const struct got_error *
-send_notification_target_email(struct gotd_imsgev *iev,
- struct gotd_notification_target *target)
-{
- struct gotd_imsg_notitfication_target_email itarget;
- struct ibuf *wbuf = NULL;
-
- memset(&itarget, 0, sizeof(itarget));
-
- if (target->conf.email.sender)
- itarget.sender_len = strlen(target->conf.email.sender);
- if (target->conf.email.recipient)
- itarget.recipient_len = strlen(target->conf.email.recipient);
- if (target->conf.email.responder)
- itarget.responder_len = strlen(target->conf.email.responder);
- if (target->conf.email.hostname)
- itarget.hostname_len = strlen(target->conf.email.hostname);
- if (target->conf.email.port)
- itarget.port_len = strlen(target->conf.email.port);
-
- wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_EMAIL,
- 0, 0, sizeof(itarget) + itarget.sender_len + itarget.recipient_len +
- itarget.responder_len + itarget.hostname_len + itarget.port_len);
- if (wbuf == NULL) {
- return got_error_from_errno("imsg_create "
- "NOTIFICATION_TARGET_EMAIL");
- }
-
- if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- if (target->conf.email.sender) {
- if (imsg_add(wbuf, target->conf.email.sender,
- itarget.sender_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- }
- if (target->conf.email.recipient) {
- if (imsg_add(wbuf, target->conf.email.recipient,
- itarget.recipient_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- }
- if (target->conf.email.responder) {
- if (imsg_add(wbuf, target->conf.email.responder,
- itarget.responder_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- }
- if (target->conf.email.hostname) {
- if (imsg_add(wbuf, target->conf.email.hostname,
- itarget.hostname_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- }
- if (target->conf.email.port) {
- if (imsg_add(wbuf, target->conf.email.port,
- itarget.port_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_EMAIL");
- }
- }
-
- imsg_close(&iev->ibuf, wbuf);
- return gotd_imsg_flush(&iev->ibuf);
}
static const struct got_error *
-send_notification_target_http(struct gotd_imsgev *iev,
- struct gotd_notification_target *target)
-{
- struct gotd_imsg_notitfication_target_http itarget;
- struct ibuf *wbuf = NULL;
-
- memset(&itarget, 0, sizeof(itarget));
-
- itarget.tls = target->conf.http.tls;
- itarget.hostname_len = strlen(target->conf.http.hostname);
- itarget.port_len = strlen(target->conf.http.port);
- itarget.path_len = strlen(target->conf.http.path);
- if (target->conf.http.auth)
- itarget.auth_len = strlen(target->conf.http.auth);
- if (target->conf.http.hmac)
- itarget.hmac_len = strlen(target->conf.http.hmac);
-
- wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFICATION_TARGET_HTTP,
- 0, 0, sizeof(itarget) + itarget.hostname_len + itarget.port_len +
- itarget.path_len + itarget.auth_len + itarget.hmac_len);
- if (wbuf == NULL) {
- return got_error_from_errno("imsg_create "
- "NOTIFICATION_TARGET_HTTP");
- }
-
- if (imsg_add(wbuf, &itarget, sizeof(itarget)) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
- if (imsg_add(wbuf, target->conf.http.hostname,
- itarget.hostname_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
- if (imsg_add(wbuf, target->conf.http.port,
- itarget.port_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
- if (imsg_add(wbuf, target->conf.http.path,
- itarget.path_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
-
- if (target->conf.http.auth) {
- if (imsg_add(wbuf, target->conf.http.auth,
- itarget.auth_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
- }
- if (target->conf.http.hmac) {
- if (imsg_add(wbuf, target->conf.http.hmac,
- itarget.hmac_len) == -1) {
- return got_error_from_errno("imsg_add "
- "NOTIFICATION_TARGET_HTTP");
- }
- }
-
- imsg_close(&iev->ibuf, wbuf);
- return gotd_imsg_flush(&iev->ibuf);
-}
-
-static const struct got_error *
-send_notification_target(struct gotd_imsgev *iev,
- struct gotd_notification_target *target)
-{
- const struct got_error *err = NULL;
-
- switch (target->type) {
- case GOTD_NOTIFICATION_VIA_EMAIL:
- err = send_notification_target_email(iev, target);
- break;
- case GOTD_NOTIFICATION_VIA_HTTP:
- err = send_notification_target_http(iev, target);
- break;
- default:
- log_warn("unsupported notification target type %d",
- target->type);
- break;
- }
-
- return err;
-}
-
-static const struct got_error *
send_notification_config(struct gotd_imsgev *iev, char *repo_name)
{
const struct got_error *err = NULL;
struct gotd_repo *repo;
struct got_pathlist_entry *pe;
struct gotd_imsg_pathlist ilist;
- struct gotd_notification_target *target;
memset(&ilist, 0, sizeof(ilist));
}
}
- STAILQ_FOREACH(target, &repo->notification_targets, entry) {
- err = send_notification_target(iev, target);
- if (err)
- return err;
- }
-
- return NULL;
+ return send_notification_targets(iev, repo->name,
+ &repo->notification_targets);
}
static void
proc->iev.handler_arg = NULL;
event_set(&proc->iev.ev, proc->iev.ibuf.fd, EV_READ,
gotd_dispatch_notifier, &proc->iev);
+ gotd_imsg_event_add(&proc->iev);
gotd.notify_proc = proc;
}
struct event evsigint, evsigterm, evsighup, evsigusr1, evsigchld;
int *pack_fds = NULL, *temp_fds = NULL;
struct gotd_repo *repo = NULL;
- char *default_sender = NULL;
char hostname[_POSIX_HOST_NAME_MAX + 1];
FILE *fp;
FILE *diff_f1 = NULL, *diff_f2 = NULL, *tmp_f1 = NULL, *tmp_f2 = NULL;
if (proc_id != GOTD_PROC_LISTEN && proc_id != GOTD_PROC_AUTH &&
proc_id != GOTD_PROC_REPO_WRITE &&
- proc_id != GOTD_PROC_SESSION_WRITE) {
+ proc_id != GOTD_PROC_SESSION_WRITE && proc_id != GOTD_PROC_NOTIFY) {
if (gotd_parse_config(confpath, proc_id, secrets, &gotd) != 0)
return 1;
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname");
- if (asprintf(&default_sender, "%s@%s", pw->pw_name,
+ if (asprintf(&gotd.default_sender, "%s@%s", pw->pw_name,
hostname) == -1)
fatal("asprintf");
}
*/
unveil_notification_helpers();
- drop_privs(pw);
-
- notify_main(title, &gotd.repos, default_sender);
+ notify_main(title);
/* NOTREACHED */
exit(0);
default:
free(repo_path);
free(secretspath);
- free(default_sender);
gotd_shutdown();
return 0;
blob - 95ebcef04adc3f9d2afc5df131874ee0f9170ed7
blob + f04ba7601ab2f6ff8ec1e20c104c69749cacf93a
--- gotd/gotd.h
+++ gotd/gotd.h
struct gotd_uid_connection_limit *connection_limits;
size_t nconnection_limits;
struct gotd_secrets *secrets;
+ char *default_sender;
char *argv0;
const char *confpath;
GOTD_IMSG_PROTECTED_BRANCHES_ELEM,
/* Notify child process. */
+ GOTD_IMSG_NOTIFIER_READY,
GOTD_IMSG_NOTIFICATION_REFS,
GOTD_IMSG_NOTIFICATION_REFS_ELEM,
GOTD_IMSG_NOTIFICATION_REF_NAMESPACES,
size_t responder_len;
size_t hostname_len;
size_t port_len;
+ size_t repo_name_len;
/*
* Followed by sender_len + responder_len + responder_len +
- * hostname_len + port_len bytes.
+ * hostname_len + port_len + repo_name_len bytes.
*/
};
size_t path_len;
size_t auth_len;
size_t hmac_len;;
+ size_t repo_name_len;
/*
* Followed by hostname_len + port_len + path_len + auth_len +
- * hmac_len bytes.
+ * hmac_len + repo_name_len bytes.
*/
};
int gotd_parseuid(const char *s, uid_t *uid);
const struct got_error *gotd_parse_url(char **, char **, char **,
char **, const char *);
+const struct got_error *gotd_conf_new_repo(struct gotd_repo **, const char *);
/* imsg.c */
const struct got_error *gotd_imsg_flush(struct imsgbuf *);
const struct got_error *gotd_imsg_recv_pathlist(size_t *, struct imsg *);
const struct got_error *gotd_imsg_recv_pathlist_elem(struct imsg *,
struct got_pathlist_head *);
+void gotd_free_notification_target(struct gotd_notification_target *);
+const struct got_error *gotd_imsg_recv_notification_target_email(char **,
+ struct gotd_notification_target **, struct imsg *);
+const struct got_error *gotd_imsg_recv_notification_target_http(char **,
+ struct gotd_notification_target **, struct imsg *);
blob - e0c130803906829b51d5f392e75336ea4f953991
blob + ee2ae7e5319116d7f867753f8682273729ff9f20
--- gotd/imsg.c
+++ gotd/imsg.c
if (err || pe == NULL)
free(path);
return err;
+}
+
+void
+gotd_free_notification_target(struct gotd_notification_target *target)
+{
+ if (target == NULL)
+ return;
+
+ switch (target->type) {
+ case GOTD_NOTIFICATION_VIA_EMAIL:
+ free(target->conf.email.sender);
+ free(target->conf.email.recipient);
+ free(target->conf.email.responder);
+ free(target->conf.email.hostname);
+ free(target->conf.email.port);
+ break;
+ case GOTD_NOTIFICATION_VIA_HTTP:
+ free(target->conf.http.hostname);
+ free(target->conf.http.port);
+ free(target->conf.http.path);
+ free(target->conf.http.auth);
+ free(target->conf.http.hmac);
+ break;
+ default:
+ break;
+ }
+
+ free(target);
}
+const struct got_error *
+gotd_imsg_recv_notification_target_email(char **repo_name,
+ struct gotd_notification_target **new_target, struct imsg *imsg)
+{
+ const struct got_error *err = NULL;
+ struct gotd_imsg_notitfication_target_email itarget;
+ struct gotd_notification_target *target;
+ size_t datalen;
+
+ if (repo_name)
+ *repo_name = NULL;
+ *new_target = NULL;
+
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+ if (datalen < sizeof(itarget))
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+ memcpy(&itarget, imsg->data, sizeof(itarget));
+
+ if (datalen != sizeof(itarget) + itarget.sender_len +
+ itarget.recipient_len + itarget.responder_len +
+ itarget.hostname_len + itarget.port_len + itarget.repo_name_len)
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+ if (itarget.sender_len == 0 || itarget.recipient_len == 0 ||
+ itarget.repo_name_len == 0)
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+
+ target = calloc(1, sizeof(*target));
+ if (target == NULL)
+ return got_error_from_errno("calloc");
+
+ target->type = GOTD_NOTIFICATION_VIA_EMAIL;
+
+ if (itarget.sender_len) {
+ target->conf.email.sender = strndup(imsg->data +
+ sizeof(itarget), itarget.sender_len);
+ if (target->conf.email.sender == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.email.sender) != itarget.sender_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ target->conf.email.recipient = strndup(imsg->data + sizeof(itarget) +
+ itarget.sender_len, itarget.recipient_len);
+ if (target->conf.email.recipient == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.email.recipient) != itarget.recipient_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ if (itarget.responder_len) {
+ target->conf.email.responder = strndup(imsg->data +
+ sizeof(itarget) + itarget.sender_len + itarget.recipient_len,
+ itarget.responder_len);
+ if (target->conf.email.responder == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.email.responder) !=
+ itarget.responder_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ if (itarget.hostname_len) {
+ target->conf.email.hostname = strndup(imsg->data +
+ sizeof(itarget) + itarget.sender_len +
+ itarget.recipient_len + itarget.responder_len,
+ itarget.hostname_len);
+ if (target->conf.email.hostname == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.email.hostname) !=
+ itarget.hostname_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ if (itarget.port_len) {
+ target->conf.email.port = strndup(imsg->data +
+ sizeof(itarget) + itarget.sender_len +
+ itarget.recipient_len + itarget.responder_len +
+ itarget.hostname_len, itarget.port_len);
+ if (target->conf.email.port == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.email.port) != itarget.port_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ if (repo_name) {
+ *repo_name = strndup(imsg->data +
+ sizeof(itarget) + itarget.sender_len +
+ itarget.recipient_len + itarget.responder_len +
+ itarget.hostname_len + itarget.port_len,
+ itarget.repo_name_len);
+ if (*repo_name == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(*repo_name) != itarget.repo_name_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ free(*repo_name);
+ *repo_name = NULL;
+ goto done;
+ }
+ }
+
+ *new_target = target;
+done:
+ if (err)
+ gotd_free_notification_target(target);
+ return err;
+}
+
+const struct got_error *
+gotd_imsg_recv_notification_target_http(char **repo_name,
+ struct gotd_notification_target **new_target, struct imsg *imsg)
+{
+ const struct got_error *err = NULL;
+ struct gotd_imsg_notitfication_target_http itarget;
+ struct gotd_notification_target *target;
+ size_t datalen;
+
+ if (repo_name)
+ *repo_name = NULL;
+
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+ if (datalen < sizeof(itarget))
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+ memcpy(&itarget, imsg->data, sizeof(itarget));
+
+ if (datalen != sizeof(itarget) + itarget.hostname_len +
+ itarget.port_len + itarget.path_len + itarget.auth_len +
+ itarget.hmac_len + itarget.repo_name_len)
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+
+ if (itarget.hostname_len == 0 || itarget.port_len == 0 ||
+ itarget.path_len == 0 || itarget.repo_name_len == 0)
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+
+ target = calloc(1, sizeof(*target));
+ if (target == NULL)
+ return got_error_from_errno("calloc");
+
+ target->type = GOTD_NOTIFICATION_VIA_HTTP;
+
+ target->conf.http.tls = itarget.tls;
+
+ target->conf.http.hostname = strndup(imsg->data +
+ sizeof(itarget), itarget.hostname_len);
+ if (target->conf.http.hostname == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.http.hostname) != itarget.hostname_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ target->conf.http.port = strndup(imsg->data + sizeof(itarget) +
+ itarget.hostname_len, itarget.port_len);
+ if (target->conf.http.port == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.http.port) != itarget.port_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ target->conf.http.path = strndup(imsg->data +
+ sizeof(itarget) + itarget.hostname_len + itarget.port_len,
+ itarget.path_len);
+ if (target->conf.http.path == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.http.path) != itarget.path_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ if (itarget.auth_len) {
+ target->conf.http.auth = strndup(imsg->data +
+ sizeof(itarget) + itarget.hostname_len +
+ itarget.port_len + itarget.path_len,
+ itarget.auth_len);
+ if (target->conf.http.auth == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.http.auth) != itarget.auth_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ if (itarget.hmac_len) {
+ target->conf.http.hmac = strndup(imsg->data +
+ sizeof(itarget) + itarget.hostname_len +
+ itarget.port_len + itarget.path_len +
+ itarget.auth_len, itarget.hmac_len);
+ if (target->conf.http.hmac == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(target->conf.http.hmac) != itarget.hmac_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+ }
+
+ if (repo_name) {
+ *repo_name = strndup(imsg->data +
+ sizeof(itarget) + itarget.hostname_len +
+ itarget.port_len + itarget.path_len +
+ itarget.auth_len + itarget.hmac_len,
+ itarget.repo_name_len);
+ if (*repo_name == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (strlen(*repo_name) != itarget.repo_name_len) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ free(*repo_name);
+ *repo_name = NULL;
+ goto done;
+ }
+ }
+
+ *new_target = target;
+done:
+ if (err)
+ gotd_free_notification_target(target);
+ return err;
+}
+
+
blob - 78a75d6ba9a3cacdcae284eeba502b2011158558
blob + 2713d529309f6d5bc43ac78227353480490cb126
--- gotd/notify.c
+++ gotd/notify.c
pid_t pid;
const char *title;
struct gotd_imsgev parent_iev;
- struct gotd_repolist *repos;
- const char *default_sender;
+ struct gotd_repolist repos;
} gotd_notify;
struct gotd_notify_session {
argv[i++] = GOTD_PATH_PROG_NOTIFY_EMAIL;
argv[i++] = "-f";
- if (target->conf.email.sender)
- argv[i++] = target->conf.email.sender;
- else
- argv[i++] = gotd_notify.default_sender;
+ argv[i++] = target->conf.email.sender;
if (target->conf.email.responder) {
argv[i++] = "-r";
if (datalen != sizeof(inotify) + inotify.username_len)
return got_error(GOT_ERR_PRIVSEP_LEN);
- repo = gotd_find_repo_by_name(inotify.repo_name, gotd_notify.repos);
+ repo = gotd_find_repo_by_name(inotify.repo_name, &gotd_notify.repos);
if (repo == NULL)
return got_error(GOT_ERR_PRIVSEP_MSG);
return NULL;
}
+static const struct got_error *
+add_notification_target(const char *repo_name,
+ struct gotd_notification_target *target)
+{
+ const struct got_error *err = NULL;
+ struct gotd_repo *repo;
+
+ repo = gotd_find_repo_by_name(repo_name, &gotd_notify.repos);
+ if (repo == NULL) {
+ err = gotd_conf_new_repo(&repo, repo_name);
+ if (err)
+ return err;
+ TAILQ_INSERT_TAIL(&gotd_notify.repos, repo, entry);
+ }
+
+ STAILQ_INSERT_TAIL(&repo->notification_targets, target, entry);
+ return NULL;
+}
static void
notify_dispatch(int fd, short event, void *arg)
{
break;
switch (imsg.hdr.type) {
+ case GOTD_IMSG_NOTIFICATION_TARGET_EMAIL: {
+ struct gotd_notification_target *target;
+ char *repo_name;
+
+ err = gotd_imsg_recv_notification_target_email(
+ &repo_name, &target, &imsg);
+ if (err)
+ break;
+ err = add_notification_target(repo_name, target);
+ if (err)
+ gotd_free_notification_target(target);
+ break;
+ }
+ case GOTD_IMSG_NOTIFICATION_TARGET_HTTP: {
+ struct gotd_notification_target *target;
+ char *repo_name;
+
+ err = gotd_imsg_recv_notification_target_http(
+ &repo_name, &target, &imsg);
+ if (err)
+ break;
+ err = add_notification_target(repo_name, target);
+ if (err)
+ gotd_free_notification_target(target);
+ break;
+ }
case GOTD_IMSG_CONNECT_SESSION:
err = recv_session(&imsg);
break;
}
void
-notify_main(const char *title, struct gotd_repolist *repos,
- const char *default_sender)
+notify_main(const char *title)
{
const struct got_error *err = NULL;
struct event evsigint, evsigterm, evsighup, evsigusr1;
arc4random_buf(&sessions_hash_key, sizeof(sessions_hash_key));
gotd_notify.title = title;
- gotd_notify.repos = repos;
- gotd_notify.default_sender = default_sender;
gotd_notify.pid = getpid();
+ TAILQ_INIT(&gotd_notify.repos);
signal_set(&evsigint, SIGINT, gotd_notify_sighdlr, NULL);
signal_set(&evsigterm, SIGTERM, gotd_notify_sighdlr, NULL);
gotd_notify.parent_iev.handler_arg = NULL;
event_set(&gotd_notify.parent_iev.ev, gotd_notify.parent_iev.ibuf.fd,
EV_READ, notify_dispatch, &gotd_notify.parent_iev);
- gotd_imsg_event_add(&gotd_notify.parent_iev);
+ if (gotd_imsg_compose_event(&gotd_notify.parent_iev,
+ GOTD_IMSG_NOTIFIER_READY, GOTD_PROC_NOTIFY, -1, NULL, 0) == -1)
+ fatal("imsg compose NOTIFIER_READY");
event_dispatch();
blob - 8173549e2a96f7a2443ff8bd53806411e4312d57
blob + 8f9d9538652602ced40b216c70debce37cbda0db
--- gotd/notify.h
+++ gotd/notify.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-void notify_main(const char *, struct gotd_repolist *, const char *);
+void notify_main(const char *);
blob - daaf2c2aa310ab499970f60fa62149dff6b06347
blob + df4c6ae0933e6455023be61dfd1d6524ea69cbb3
--- gotd/parse.y
+++ gotd/parse.y
;
notifyflags : BRANCH STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_branch(new_repo, $2)) {
free($2);
YYERROR;
free($2);
}
| REFERENCE NAMESPACE STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_ref_namespace(new_repo, $3)) {
free($3);
YYERROR;
free($3);
}
| EMAIL TO STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
NULL, NULL, NULL)) {
free($3);
free($3);
}
| EMAIL FROM STRING TO STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
NULL, NULL, NULL)) {
free($3);
free($5);
}
| EMAIL TO STRING REPLY TO STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
$6, NULL, NULL)) {
free($3);
free($6);
}
| EMAIL FROM STRING TO STRING REPLY TO STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
$8, NULL, NULL)) {
free($3);
free($8);
}
| EMAIL TO STRING RELAY STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
NULL, $5, NULL)) {
free($3);
free($5);
}
| EMAIL FROM STRING TO STRING RELAY STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
NULL, $7, NULL)) {
free($3);
free($7);
}
| EMAIL TO STRING REPLY TO STRING RELAY STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
$6, $8, NULL)) {
free($3);
free($8);
}
| EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
$8, $10, NULL)) {
free($3);
free($10);
}
| EMAIL TO STRING RELAY STRING PORT STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
NULL, $5, $7)) {
free($3);
free($7);
}
| EMAIL FROM STRING TO STRING RELAY STRING PORT STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
NULL, $7, $9)) {
free($3);
free($9);
}
| EMAIL TO STRING REPLY TO STRING RELAY STRING PORT STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
$6, $8, $10)) {
free($3);
free($10);
}
| EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING PORT STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
$8, $10, $12)) {
free($3);
free($12);
}
| EMAIL TO STRING RELAY STRING PORT NUMBER {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
NULL, $5, port_sprintf($7))) {
free($3);
free($5);
}
| EMAIL FROM STRING TO STRING RELAY STRING PORT NUMBER {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
NULL, $7, port_sprintf($9))) {
free($3);
free($7);
}
| EMAIL TO STRING REPLY TO STRING RELAY STRING PORT NUMBER {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, NULL, $3,
$6, $8, port_sprintf($10))) {
free($3);
free($8);
}
| EMAIL FROM STRING TO STRING REPLY TO STRING RELAY STRING PORT NUMBER {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_email(new_repo, $3, $5,
$8, $10, port_sprintf($12))) {
free($3);
free($10);
}
| URL STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, NULL,
NULL, 0)) {
free($2);
free($2);
}
| URL STRING AUTH STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, $4, NULL,
0)) {
free($2);
free($4);
}
| URL STRING AUTH STRING INSECURE {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, $4, NULL,
1)) {
free($2);
free($4);
}
| URL STRING HMAC STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, NULL, $4,
0)) {
free($2);
free($4);
}
| URL STRING AUTH STRING HMAC STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, $4, $6,
0)) {
free($2);
free($6);
}
| URL STRING AUTH STRING INSECURE HMAC STRING {
- if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ if (gotd_proc_id == GOTD_PROC_GOTD) {
if (conf_notify_http(new_repo, $2, $4, $7,
1)) {
free($2);
}
if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_GITWRAPPER |
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ gotd_proc_id == GOTD_PROC_GITWRAPPER) {
new_repo = conf_new_repo($2);
}
free($2);
repoopts1 : PATH STRING {
if (gotd_proc_id == GOTD_PROC_GOTD ||
- gotd_proc_id == GOTD_PROC_GITWRAPPER ||
- gotd_proc_id == GOTD_PROC_NOTIFY) {
+ gotd_proc_id == GOTD_PROC_GITWRAPPER) {
if (!got_path_is_absolute($2)) {
yyerror("%s: path %s is not absolute",
__func__, $2);
return 0;
}
-static struct gotd_repo *
-conf_new_repo(const char *name)
+const struct got_error *
+gotd_conf_new_repo(struct gotd_repo **new_repo, const char *name)
{
struct gotd_repo *repo;
-
- if (name[0] == '\0') {
- fatalx("syntax error: empty repository name found in %s",
- file->name);
- }
- if (strchr(name, '\n') != NULL)
- fatalx("repository names must not contain linefeeds: %s", name);
-
repo = calloc(1, sizeof(*repo));
if (repo == NULL)
- fatalx("%s: calloc", __func__);
+ return got_error_from_errno("calloc");
STAILQ_INIT(&repo->rules);
RB_INIT(&repo->protected_tag_namespaces);
STAILQ_INIT(&repo->notification_targets);
if (strlcpy(repo->name, name, sizeof(repo->name)) >=
- sizeof(repo->name))
- fatalx("%s: strlcpy", __func__);
+ sizeof(repo->name)) {
+ free(repo);
+ return got_error_msg(GOT_ERR_NO_SPACE,
+ "repository name too long");
+ }
+ *new_repo = repo;
+ return NULL;
+}
+
+static struct gotd_repo *
+conf_new_repo(const char *name)
+{
+ const struct got_error *err;
+ struct gotd_repo *repo;
+
+ if (name[0] == '\0') {
+ fatalx("syntax error: empty repository name found in %s",
+ file->name);
+ }
+
+ if (strchr(name, '\n') != NULL)
+ fatalx("repository names must not contain linefeeds: %s", name);
+
+ err = gotd_conf_new_repo(&repo, name);
+ if (err)
+ fatalx("%s", err->msg);
+
TAILQ_INSERT_TAIL(&gotd->repos, repo, entry);
gotd->nrepos++;
blob - d139091dacf9e073b2a167c8dca8537a36c7c461
blob + 8ab93f57b38a1436a2f09373f54f92d6d3f6aa96
--- gotd/session_write.c
+++ gotd/session_write.c
fatal("pledge");
return NULL;
-}
-
-static void
-free_notification_target(struct gotd_notification_target *target)
-{
- if (target == NULL)
- return;
-
- switch (target->type) {
- case GOTD_NOTIFICATION_VIA_EMAIL:
- free(target->conf.email.sender);
- free(target->conf.email.recipient);
- free(target->conf.email.responder);
- free(target->conf.email.hostname);
- free(target->conf.email.port);
- break;
- case GOTD_NOTIFICATION_VIA_HTTP:
- free(target->conf.http.hostname);
- free(target->conf.http.port);
- free(target->conf.http.path);
- free(target->conf.http.auth);
- free(target->conf.http.hmac);
- break;
- default:
- break;
- }
-
- free(target);
-}
-
-static const struct got_error *
-recv_notification_target_email(struct imsg *imsg)
-{
- const struct got_error *err = NULL;
- struct gotd_imsg_notitfication_target_email itarget;
- struct gotd_notification_target *target;
- size_t datalen;
-
- datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
- if (datalen < sizeof(itarget))
- return got_error(GOT_ERR_PRIVSEP_LEN);
- memcpy(&itarget, imsg->data, sizeof(itarget));
-
- if (datalen != sizeof(itarget) + itarget.sender_len +
- itarget.recipient_len + itarget.responder_len +
- itarget.hostname_len + itarget.port_len)
- return got_error(GOT_ERR_PRIVSEP_LEN);
- if (itarget.recipient_len == 0)
- return got_error(GOT_ERR_PRIVSEP_LEN);
-
- target = calloc(1, sizeof(*target));
- if (target == NULL)
- return got_error_from_errno("calloc");
-
- target->type = GOTD_NOTIFICATION_VIA_EMAIL;
-
- if (itarget.sender_len) {
- target->conf.email.sender = strndup(imsg->data +
- sizeof(itarget), itarget.sender_len);
- if (target->conf.email.sender == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.email.sender) != itarget.sender_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- target->conf.email.recipient = strndup(imsg->data + sizeof(itarget) +
- itarget.sender_len, itarget.recipient_len);
- if (target->conf.email.recipient == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.email.recipient) != itarget.recipient_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
-
- if (itarget.responder_len) {
- target->conf.email.responder = strndup(imsg->data +
- sizeof(itarget) + itarget.sender_len + itarget.recipient_len,
- itarget.responder_len);
- if (target->conf.email.responder == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.email.responder) !=
- itarget.responder_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- if (itarget.hostname_len) {
- target->conf.email.hostname = strndup(imsg->data +
- sizeof(itarget) + itarget.sender_len +
- itarget.recipient_len + itarget.responder_len,
- itarget.hostname_len);
- if (target->conf.email.hostname == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.email.hostname) !=
- itarget.hostname_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- if (itarget.port_len) {
- target->conf.email.port = strndup(imsg->data +
- sizeof(itarget) + itarget.sender_len +
- itarget.recipient_len + itarget.responder_len +
- itarget.hostname_len, itarget.port_len);
- if (target->conf.email.port == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.email.port) != itarget.port_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- STAILQ_INSERT_TAIL(&gotd_session.notification_targets, target, entry);
- target = NULL;
-done:
- if (err)
- free_notification_target(target);
- return err;
-}
-
-static const struct got_error *
-recv_notification_target_http(struct imsg *imsg)
-{
- const struct got_error *err = NULL;
- struct gotd_imsg_notitfication_target_http itarget;
- struct gotd_notification_target *target;
- size_t datalen;
-
- datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
- if (datalen < sizeof(itarget))
- return got_error(GOT_ERR_PRIVSEP_LEN);
- memcpy(&itarget, imsg->data, sizeof(itarget));
-
- if (datalen != sizeof(itarget) + itarget.hostname_len +
- itarget.port_len + itarget.path_len + itarget.auth_len +
- itarget.hmac_len)
- return got_error(GOT_ERR_PRIVSEP_LEN);
-
- if (itarget.hostname_len == 0 || itarget.port_len == 0 ||
- itarget.path_len == 0)
- return got_error(GOT_ERR_PRIVSEP_LEN);
-
- target = calloc(1, sizeof(*target));
- if (target == NULL)
- return got_error_from_errno("calloc");
-
- target->type = GOTD_NOTIFICATION_VIA_HTTP;
-
- target->conf.http.tls = itarget.tls;
-
- target->conf.http.hostname = strndup(imsg->data +
- sizeof(itarget), itarget.hostname_len);
- if (target->conf.http.hostname == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.http.hostname) != itarget.hostname_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
-
- target->conf.http.port = strndup(imsg->data + sizeof(itarget) +
- itarget.hostname_len, itarget.port_len);
- if (target->conf.http.port == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.http.port) != itarget.port_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
-
- target->conf.http.path = strndup(imsg->data +
- sizeof(itarget) + itarget.hostname_len + itarget.port_len,
- itarget.path_len);
- if (target->conf.http.path == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.http.path) != itarget.path_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
-
- if (itarget.auth_len) {
- target->conf.http.auth = strndup(imsg->data +
- sizeof(itarget) + itarget.hostname_len +
- itarget.port_len + itarget.path_len,
- itarget.auth_len);
- if (target->conf.http.auth == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.http.auth) != itarget.auth_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- if (itarget.hmac_len) {
- target->conf.http.hmac = strndup(imsg->data +
- sizeof(itarget) + itarget.hostname_len +
- itarget.port_len + itarget.path_len +
- itarget.auth_len, itarget.hmac_len);
- if (target->conf.http.hmac == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- if (strlen(target->conf.http.hmac) != itarget.hmac_len) {
- err = got_error(GOT_ERR_PRIVSEP_LEN);
- goto done;
- }
- }
-
- STAILQ_INSERT_TAIL(&gotd_session.notification_targets, target, entry);
- target = NULL;
-done:
- if (err)
- free_notification_target(target);
- return err;
}
static void
gotd_session.num_notification_refs_needed = 0;
}
break;
- case GOTD_IMSG_NOTIFICATION_TARGET_EMAIL:
- err = recv_notification_target_email(&imsg);
- break;
- case GOTD_IMSG_NOTIFICATION_TARGET_HTTP:
- err = recv_notification_target_http(&imsg);
+ case GOTD_IMSG_NOTIFICATION_TARGET_EMAIL: {
+ struct gotd_notification_target *target;
+
+ err = gotd_imsg_recv_notification_target_email(NULL,
+ &target, &imsg);
+ if (err)
+ break;
+ STAILQ_INSERT_TAIL(&gotd_session.notification_targets,
+ target, entry);
break;
+ }
+ case GOTD_IMSG_NOTIFICATION_TARGET_HTTP: {
+ struct gotd_notification_target *target;
+
+ err = gotd_imsg_recv_notification_target_http(NULL,
+ &target, &imsg);
+ if (err)
+ break;
+ STAILQ_INSERT_TAIL(&gotd_session.notification_targets,
+ target, entry);
+ break;
+ }
case GOTD_IMSG_CONNECT_NOTIFIER:
err = recv_notifier(&imsg);
break;