commit 39910b637a9a53cc48b0c63766da691dec0af593 from: Omar Polo date: Wed Mar 20 12:06:53 2024 UTC got-notify-email: split dial() out of send_email() This allows to reduce the set of pledge(2) promises needed at runtime down to only "stdio" which will also help sandboxing -portable. ok stsp commit - 100d3e4bb875b64f537d67257b0876159b59b068 commit + 39910b637a9a53cc48b0c63766da691dec0af593 blob - df8ea0be82de096d29cc259924f9cc1e45c2a752 blob + ef9b199c10bfcb34951de0d9a6e4c0915a91e274 --- gotd/libexec/got-notify-email/got-notify-email.c +++ gotd/libexec/got-notify-email/got-notify-email.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,48 @@ usage(void) exit(1); } +static int +dial(const char *host, const char *port) +{ + struct addrinfo hints, *res, *res0; + const char *cause = NULL; + int s, error, save_errno; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(host, port, &hints, &res0); + if (error) + errx(1, "failed to resolve %s:%s: %s", host, port, + gai_strerror(error)); + + s = -1; + for (res = res0; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (s == -1) { + cause = "socket"; + continue; + } + + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { + cause = "connect"; + save_errno = errno; + close(s); + errno = save_errno; + s = -1; + continue; + } + + break; + } + + freeaddrinfo(res0); + if (s == -1) + err(1, "%s", cause); + return s; +} + static char * set_default_fromaddr(void) { @@ -156,38 +199,21 @@ get_datestr(time_t *time, char *datebuf) } static void -send_email(const char *myfromaddr, const char *fromaddr, +send_email(int s, const char *myfromaddr, const char *fromaddr, const char *recipient, const char *replytoaddr, - const char *subject, const char *hostname, const char *port) + const char *subject) { const struct got_error *error; char *line = NULL; size_t linesize = 0; ssize_t linelen; - struct addrinfo hints, *res = NULL; - int s = -1, ret; time_t now; char datebuf[26]; char *datestr; now = time(NULL); datestr = get_datestr(&now, datebuf); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - ret = getaddrinfo(hostname, port, &hints, &res); - if (ret) - errx(1, "getaddrinfo: %s", gai_strerror(ret)); - - s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s == -1) - err(1, "socket"); - if (connect(s, res->ai_addr, res->ai_addrlen) == -1) - err(1, "connect %s:%s", hostname, port); - if (read_smtp_code(s, "220")) errx(1, "unexpected SMTP greeting received"); if (skip_to_crlf(s)) @@ -266,8 +292,6 @@ send_email(const char *myfromaddr, const char *fromadd close(s); free(line); - if (res) - freeaddrinfo(res); } int @@ -280,7 +304,7 @@ main(int argc, char *argv[]) const char *port = "25"; const char *errstr; char *timeoutstr; - int ch; + int ch, s; while ((ch = getopt(argc, argv, "f:r:s:h:p:")) != -1) { switch (ch) { @@ -336,9 +360,16 @@ main(int argc, char *argv[]) if (fromaddr == NULL) fromaddr = default_fromaddr; - send_email(default_fromaddr, fromaddr, recipient, replytoaddr, - subject, hostname, port); + s = dial(hostname, port); +#ifndef PROFILE + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); +#endif + + send_email(s, default_fromaddr, fromaddr, recipient, replytoaddr, + subject); + free(default_fromaddr); return 0; }