diff options
author | Gilles Chehade <gilles@poolp.org> | 2019-07-04 20:10:14 +0200 |
---|---|---|
committer | Gilles Chehade <gilles@poolp.org> | 2019-07-04 20:10:14 +0200 |
commit | f43b708cf1d57842a15565d88b9dc06140568f05 (patch) | |
tree | 0018bdcac2ff2cc8c0292a2a742624e61f273193 | |
parent | Merge branch 'master' into portable (diff) | |
parent | sync (diff) | |
download | OpenSMTPD-f43b708cf1d57842a15565d88b9dc06140568f05.tar.xz OpenSMTPD-f43b708cf1d57842a15565d88b9dc06140568f05.zip |
Merge branch 'master' into portable
-rw-r--r-- | smtpd/crypto.c | 6 | ||||
-rw-r--r-- | smtpd/enqueue.c | 17 | ||||
-rw-r--r-- | smtpd/envelope.c | 6 | ||||
-rw-r--r-- | smtpd/lka.c | 14 | ||||
-rw-r--r-- | smtpd/lka_filter.c | 49 | ||||
-rw-r--r-- | smtpd/lka_proc.c | 32 | ||||
-rw-r--r-- | smtpd/mail.maildir.c | 18 | ||||
-rw-r--r-- | smtpd/mail.mboxfile.c | 4 | ||||
-rw-r--r-- | smtpd/mda.c | 2 | ||||
-rw-r--r-- | smtpd/mproc.c | 5 | ||||
-rw-r--r-- | smtpd/mta_session.c | 6 | ||||
-rw-r--r-- | smtpd/parse.y | 4 | ||||
-rw-r--r-- | smtpd/queue_fs.c | 4 | ||||
-rw-r--r-- | smtpd/smtp.c | 4 | ||||
-rw-r--r-- | smtpd/smtp_session.c | 14 | ||||
-rw-r--r-- | smtpd/smtpc.c | 13 | ||||
-rw-r--r-- | smtpd/smtpctl.c | 18 | ||||
-rw-r--r-- | smtpd/smtpd.c | 56 | ||||
-rw-r--r-- | smtpd/smtpd.h | 5 | ||||
-rw-r--r-- | smtpd/table_db.c | 6 | ||||
-rw-r--r-- | smtpd/util.c | 8 |
21 files changed, 175 insertions, 116 deletions
diff --git a/smtpd/crypto.c b/smtpd/crypto.c index 2f718db9..20a422cd 100644 --- a/smtpd/crypto.c +++ b/smtpd/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.7 2019/05/24 18:01:52 gilles Exp $ */ +/* $OpenBSD: crypto.c,v 1.8 2019/06/28 13:32:50 deraadt Exp $ */ /* * Copyright (c) 2013 Gilles Chehade <gilles@openbsd.org> @@ -76,7 +76,7 @@ crypto_encrypt_file(FILE * in, FILE * out) struct stat sb; /* XXX - Do NOT encrypt files bigger than 64GB */ - if (fstat(fileno(in), &sb) < 0) + if (fstat(fileno(in), &sb) == -1) return 0; if (sb.st_size >= 0x1000000000LL) return 0; @@ -142,7 +142,7 @@ crypto_decrypt_file(FILE * in, FILE * out) struct stat sb; /* input file too small to be an encrypted file */ - if (fstat(fileno(in), &sb) < 0) + if (fstat(fileno(in), &sb) == -1) return 0; if (sb.st_size <= (off_t) (sizeof version + sizeof tag + sizeof iv)) return 0; diff --git a/smtpd/enqueue.c b/smtpd/enqueue.c index dcb40cd3..040a0d5b 100644 --- a/smtpd/enqueue.c +++ b/smtpd/enqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: enqueue.c,v 1.115 2018/05/31 21:06:12 gilles Exp $ */ +/* $OpenBSD: enqueue.c,v 1.116 2019/07/02 09:36:20 martijn Exp $ */ /* * Copyright (c) 2005 Henning Brauer <henning@bulabula.org> @@ -173,8 +173,6 @@ enqueue(int argc, char *argv[], FILE *ofp) FILE *fp = NULL, *fout; size_t sz = 0, envid_sz = 0; ssize_t len; - int fd; - char sfn[] = "/tmp/smtpd.XXXXXXXXXX"; char *line; int dotted; int inheaders = 1; @@ -271,16 +269,9 @@ enqueue(int argc, char *argv[], FILE *ofp) argc--; } - if ((fd = mkstemp(sfn)) == -1 || - (fp = fdopen(fd, "w+")) == NULL) { - int saved_errno = errno; - if (fd != -1) { - unlink(sfn); - close(fd); - } - errc(EX_UNAVAILABLE, saved_errno, "mkstemp"); - } - unlink(sfn); + if ((fp = tmpfile()) == NULL) + err(EX_UNAVAILABLE, "tmpfile"); + msg.noheader = parse_message(stdin, fake_from == NULL, tflag, fp); if (msg.rcpt_cnt == 0) diff --git a/smtpd/envelope.c b/smtpd/envelope.c index 596b701d..309c4985 100644 --- a/smtpd/envelope.c +++ b/smtpd/envelope.c @@ -1,4 +1,4 @@ -/* $OpenBSD: envelope.c,v 1.42 2018/12/30 23:09:58 guenther Exp $ */ +/* $OpenBSD: envelope.c,v 1.43 2019/07/03 03:24:03 deraadt Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -61,7 +61,7 @@ envelope_set_errormsg(struct envelope *e, char *fmt, ...) va_end(ap); /* this should not happen */ - if (ret == -1) + if (ret < 0) err(1, "vsnprintf"); if ((size_t)ret >= sizeof(e->errorline)) @@ -754,7 +754,7 @@ envelope_ascii_dump(const struct envelope *ep, char **dest, size_t *len, return; l = snprintf(*dest, *len, "%s: %s\n", field, buf); - if (l == -1 || (size_t) l >= *len) + if (l < 0 || (size_t) l >= *len) goto err; *dest += l; *len -= l; diff --git a/smtpd/lka.c b/smtpd/lka.c index 0d13720a..2a88fba2 100644 --- a/smtpd/lka.c +++ b/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.234 2019/06/13 11:45:34 eric Exp $ */ +/* $OpenBSD: lka.c,v 1.235 2019/06/27 05:14:49 martijn Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -364,9 +364,21 @@ lka_imsg(struct mproc *p, struct imsg *imsg) m_get_string(&m, &procname); m_end(&m); + m_create(p, IMSG_LKA_PROCESSOR_ERRFD, 0, 0, -1); + m_add_string(p, procname); + m_close(p); + lka_proc_forked(procname, imsg->fd); return; + case IMSG_LKA_PROCESSOR_ERRFD: + m_msg(&m, imsg); + m_get_string(&m, &procname); + m_end(&m); + + lka_proc_errfd(procname, imsg->fd); + shutdown(imsg->fd, SHUT_WR); + return; case IMSG_REPORT_SMTP_LINK_CONNECT: m_msg(&m, imsg); diff --git a/smtpd/lka_filter.c b/smtpd/lka_filter.c index 4bd3ac74..a3663913 100644 --- a/smtpd/lka_filter.c +++ b/smtpd/lka_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_filter.c,v 1.36 2019/05/02 11:39:45 martijn Exp $ */ +/* $OpenBSD: lka_filter.c,v 1.38 2019/07/01 07:40:43 martijn Exp $ */ /* * Copyright (c) 2018 Gilles Chehade <gilles@poolp.org> @@ -43,7 +43,7 @@ struct filter; struct filter_session; static void filter_protocol_internal(struct filter_session *, uint64_t *, uint64_t, enum filter_phase, const char *); static void filter_protocol(uint64_t, enum filter_phase, const char *); -static void filter_protocol_next(uint64_t, uint64_t, enum filter_phase, const char *); +static void filter_protocol_next(uint64_t, uint64_t, enum filter_phase); static void filter_protocol_query(struct filter *, uint64_t, uint64_t, const char *, const char *); static void filter_data_internal(struct filter_session *, uint64_t, uint64_t, const char *); @@ -70,6 +70,8 @@ struct filter_session { uint64_t id; struct io *io; + char *lastparam; + char *filter_name; struct sockaddr_storage ss_src; struct sockaddr_storage ss_dest; @@ -339,6 +341,9 @@ lka_filter_end(uint64_t reqid) fs = tree_xpop(&sessions, reqid); free(fs->rdns); + free(fs->helo); + free(fs->mail_from); + free(fs->lastparam); free(fs); log_trace(TRACE_FILTERS, "%016"PRIx64" filters session-end", reqid); } @@ -506,7 +511,7 @@ lka_filter_process_response(const char *name, const char *line) return 1; } - filter_protocol_next(token, reqid, 0, parameter); + filter_protocol_next(token, reqid, 0); return 1; } @@ -660,14 +665,11 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param) switch (phase) { case FILTER_HELO: case FILTER_EHLO: - if (fs->helo) - free(fs->helo); + free(fs->helo); fs->helo = xstrdup(param); break; case FILTER_MAIL_FROM: - if (fs->mail_from) - free(fs->mail_from); - + free(fs->mail_from); fs->mail_from = xstrdup(param + 1); *strchr(fs->mail_from, '>') = '\0'; param = fs->mail_from; @@ -685,13 +687,17 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param) default: break; } + + free(fs->lastparam); + fs->lastparam = xstrdup(param); + filter_protocol_internal(fs, &token, reqid, phase, param); if (nparam) free(nparam); } static void -filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase, const char *param) +filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase) { struct filter_session *fs; @@ -699,7 +705,7 @@ filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase, co if ((fs = tree_get(&sessions, reqid)) == NULL) return; - filter_protocol_internal(fs, &token, reqid, phase, param); + filter_protocol_internal(fs, &token, reqid, phase, fs->lastparam); } static void @@ -728,22 +734,23 @@ static void filter_protocol_query(struct filter *filter, uint64_t token, uint64_t reqid, const char *phase, const char *param) { int n; - time_t tm; struct filter_session *fs; + struct timeval tv; + gettimeofday(&tv, NULL); + fs = tree_xget(&sessions, reqid); - time(&tm); if (strcmp(phase, "connect") == 0) n = io_printf(lka_proc_get_io(filter->proc), - "filter|%d|%zd|smtp-in|%s|%016"PRIx64"|%016"PRIx64"|%s|%s\n", + "filter|%d|%lld.%06ld|smtp-in|%s|%016"PRIx64"|%016"PRIx64"|%s|%s\n", PROTOCOL_VERSION, - tm, + tv.tv_sec, tv.tv_usec, phase, reqid, token, fs->rdns, param); else n = io_printf(lka_proc_get_io(filter->proc), - "filter|%d|%zd|smtp-in|%s|%016"PRIx64"|%016"PRIx64"|%s\n", + "filter|%d|%lld.%06ld|smtp-in|%s|%016"PRIx64"|%016"PRIx64"|%s\n", PROTOCOL_VERSION, - tm, + tv.tv_sec, tv.tv_usec, phase, reqid, token, param); if (n == -1) fatalx("failed to write to processor"); @@ -753,14 +760,16 @@ static void filter_data_query(struct filter *filter, uint64_t token, uint64_t reqid, const char *line) { int n; - time_t tm; + struct timeval tv; + + gettimeofday(&tv, NULL); - time(&tm); n = io_printf(lka_proc_get_io(filter->proc), - "filter|%d|%zd|smtp-in|data-line|" + "filter|%d|%lld.%06ld|smtp-in|data-line|" "%016"PRIx64"|%016"PRIx64"|%s\n", PROTOCOL_VERSION, - tm, reqid, token, line); + tv.tv_sec, tv.tv_usec, + reqid, token, line); if (n == -1) fatalx("failed to write to processor"); } diff --git a/smtpd/lka_proc.c b/smtpd/lka_proc.c index eafebbec..7bd06cff 100644 --- a/smtpd/lka_proc.c +++ b/smtpd/lka_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_proc.c,v 1.6 2018/12/21 19:07:47 gilles Exp $ */ +/* $OpenBSD: lka_proc.c,v 1.7 2019/06/27 05:14:49 martijn Exp $ */ /* * Copyright (c) 2018 Gilles Chehade <gilles@poolp.org> @@ -43,10 +43,12 @@ static struct dict processors; struct processor_instance { char *name; struct io *io; + struct io *errfd; int ready; }; static void processor_io(struct io *, int, void *); +static void processor_errfd(struct io *, int, void *); int lka_filter_process_response(const char *, const char *); int @@ -83,6 +85,20 @@ lka_proc_forked(const char *name, int fd) dict_xset(&processors, name, processor); } +void +lka_proc_errfd(const char *name, int fd) +{ + struct processor_instance *processor; + + processor = dict_xget(&processors, name); + + io_set_nonblocking(fd); + + processor->errfd = io_new(); + io_set_fd(processor->errfd, fd); + io_set_callback(processor->errfd, processor_errfd, processor->name); +} + struct io * lka_proc_get_io(const char *name) { @@ -139,3 +155,17 @@ processor_io(struct io *io, int evt, void *arg) goto nextline; } } + +static void +processor_errfd(struct io *io, int evt, void *arg) +{ + const char *name = arg; + char *line = NULL; + ssize_t len; + + switch (evt) { + case IO_DATAIN: + while ((line = io_getline(io, &len)) != NULL) + log_warnx("%s: %s", name, line); + } +} diff --git a/smtpd/mail.maildir.c b/smtpd/mail.maildir.c index 637d3f72..05384c56 100644 --- a/smtpd/mail.maildir.c +++ b/smtpd/mail.maildir.c @@ -95,15 +95,15 @@ maildir_mkdirs(const char *dirname) char pathname[PATH_MAX]; char *subdirs[] = { "cur", "tmp", "new" }; - if (mkdirs(dirname, 0700) < 0 && errno != EEXIST) + if (mkdirs(dirname, 0700) == -1 && errno != EEXIST) err(1, NULL); for (i = 0; i < nitems(subdirs); ++i) { ret = snprintf(pathname, sizeof pathname, "%s/%s", dirname, subdirs[i]); - if (ret == -1 || (size_t)ret >= sizeof pathname) + if (ret < 0 || (size_t)ret >= sizeof pathname) errc(1, ENAMETOOLONG, "%s/%s", dirname, subdirs[i]); - if (mkdir(pathname, 0700) < 0 && errno != EEXIST) + if (mkdir(pathname, 0700) == -1 && errno != EEXIST) err(1, NULL); } } @@ -139,7 +139,7 @@ maildir_engine(const char *dirname, int junk) if ((home = getenv("HOME")) == NULL) err(1, NULL); ret = snprintf(rootpath, sizeof rootpath, "%s/Maildir", home); - if (ret == -1 || (size_t)ret >= sizeof rootpath) + if (ret < 0 || (size_t)ret >= sizeof rootpath) errc(1, ENAMETOOLONG, "%s/Maildir", home); dirname = rootpath; } @@ -148,7 +148,7 @@ maildir_engine(const char *dirname, int junk) if (junk) { /* create Junk subdirectory */ ret = snprintf(junkpath, sizeof junkpath, "%s/.Junk", dirname); - if (ret == -1 || (size_t)ret >= sizeof junkpath) + if (ret < 0 || (size_t)ret >= sizeof junkpath) errc(1, ENAMETOOLONG, "%s/.Junk", dirname); maildir_mkdirs(junkpath); } @@ -158,7 +158,7 @@ maildir_engine(const char *dirname, int junk) subdir[0]) { ret = snprintf(extpath, sizeof extpath, "%s/.%s", dirname, subdir); - if (ret == -1 || (size_t)ret >= sizeof extpath) + if (ret < 0 || (size_t)ret >= sizeof extpath) errc(1, ENAMETOOLONG, "%s/.%s", dirname, subdir); if (stat(extpath, &sb) != -1) { @@ -179,7 +179,7 @@ maildir_engine(const char *dirname, int junk) (void)snprintf(tmp, sizeof tmp, "%s/tmp/%s", dirname, filename); fd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0600); - if (fd < 0) + if (fd == -1) err(1, NULL); if ((fp = fdopen(fd, "w")) == NULL) err(1, NULL); @@ -200,14 +200,14 @@ maildir_engine(const char *dirname, int junk) if (fflush(fp) == EOF || ferror(fp) || - fsync(fd) < 0 || + fsync(fd) == -1 || fclose(fp) == EOF) err(1, NULL); (void)snprintf(new, sizeof new, "%s/new/%s", is_junk ? junkpath : dirname, filename); - if (rename(tmp, new) < 0) + if (rename(tmp, new) == -1) err(1, NULL); exit(0); diff --git a/smtpd/mail.mboxfile.c b/smtpd/mail.mboxfile.c index bf6951d8..437b1306 100644 --- a/smtpd/mail.mboxfile.c +++ b/smtpd/mail.mboxfile.c @@ -81,7 +81,7 @@ mboxfile_engine(const char *sender, const char *filename) #ifndef HAVE_O_EXLOCK /* XXX : do something! */ #endif - if (fd < 0) + if (fd == -1) err(1, NULL); if ((fp = fdopen(fd, "w")) == NULL) @@ -102,7 +102,7 @@ mboxfile_engine(const char *sender, const char *filename) if (fflush(fp) == EOF || ferror(fp) || - fsync(fd) < 0 || + fsync(fd) == -1 || fclose(fp) == EOF) err(1, NULL); } diff --git a/smtpd/mda.c b/smtpd/mda.c index 97b60631..dbfae945 100644 --- a/smtpd/mda.c +++ b/smtpd/mda.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mda.c,v 1.137 2019/01/05 10:20:21 gilles Exp $ */ +/* $OpenBSD: mda.c,v 1.138 2019/06/28 13:32:50 deraadt Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> diff --git a/smtpd/mproc.c b/smtpd/mproc.c index bb5e4a5f..ddd1ad84 100644 --- a/smtpd/mproc.c +++ b/smtpd/mproc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mproc.c,v 1.33 2019/05/24 14:31:30 gilles Exp $ */ +/* $OpenBSD: mproc.c,v 1.34 2019/06/28 13:32:50 deraadt Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@faurot.net> @@ -50,7 +50,7 @@ mproc_fork(struct mproc *p, const char *path, char *argv[]) { int sp[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) return (-1); io_set_nonblocking(sp[0]); @@ -63,7 +63,6 @@ mproc_fork(struct mproc *p, const char *path, char *argv[]) /* child process */ dup2(sp[0], STDIN_FILENO); closefrom(STDERR_FILENO + 1); - execv(path, argv); err(1, "execv: %s", path); } diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c index 01ca16fb..2cd232a9 100644 --- a/smtpd/mta_session.c +++ b/smtpd/mta_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta_session.c,v 1.118 2019/06/24 15:14:01 gilles Exp $ */ +/* $OpenBSD: mta_session.c,v 1.119 2019/06/28 13:32:50 deraadt Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -977,7 +977,7 @@ mta_response(struct mta_session *s, char *line) */ sa_len = sizeof(ss); sa = (struct sockaddr *)&ss; - if (getsockname(io_fileno(s->io), sa, &sa_len) < 0) + if (getsockname(io_fileno(s->io), sa, &sa_len) == -1) mta_delivery_log(e, NULL, buf, delivery, line); else mta_delivery_log(e, sa_to_text(sa), @@ -1375,7 +1375,7 @@ mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t co */ sa = (struct sockaddr *)&ss; sa_len = sizeof(ss); - if (getsockname(io_fileno(s->io), sa, &sa_len) < 0) + if (getsockname(io_fileno(s->io), sa, &sa_len) == -1) mta_delivery_log(e, NULL, relay, delivery, error); else mta_delivery_log(e, sa_to_text(sa), diff --git a/smtpd/parse.y b/smtpd/parse.y index b37c390d..f3ecfc5b 100644 --- a/smtpd/parse.y +++ b/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.252 2019/05/20 07:04:13 gilles Exp $ */ +/* $OpenBSD: parse.y,v 1.253 2019/06/28 13:32:50 deraadt Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -3182,7 +3182,7 @@ is_if_in_group(const char *ifname, const char *groupname) int s; int ret = 0; - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) err(1, "socket"); memset(&ifgr, 0, sizeof(ifgr)); diff --git a/smtpd/queue_fs.c b/smtpd/queue_fs.c index 88dde90b..b3ac4f95 100644 --- a/smtpd/queue_fs.c +++ b/smtpd/queue_fs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_fs.c,v 1.18 2018/12/30 23:09:58 guenther Exp $ */ +/* $OpenBSD: queue_fs.c,v 1.19 2019/06/28 13:32:51 deraadt Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org> @@ -424,7 +424,7 @@ fsqueue_check_space(void) uint64_t used; uint64_t total; - if (statfs(PATH_QUEUE, &buf) < 0) { + if (statfs(PATH_QUEUE, &buf) == -1) { log_warn("warn: queue-fs: statfs"); return 0; } diff --git a/smtpd/smtp.c b/smtpd/smtp.c index a0ab898b..45492a46 100644 --- a/smtpd/smtp.c +++ b/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.164 2018/12/23 16:37:53 eric Exp $ */ +/* $OpenBSD: smtp.c,v 1.165 2019/06/28 13:32:51 deraadt Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -144,7 +144,7 @@ smtp_setup_listeners(void) opt = 1; #ifdef SO_REUSEADDR if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR, &opt, - sizeof(opt)) < 0) + sizeof(opt)) == -1) fatal("smtpd: setsockopt"); #else if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEPORT, &opt, diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c index 9d3bef1f..0c3cf428 100644 --- a/smtpd/smtp_session.c +++ b/smtpd/smtp_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp_session.c,v 1.392 2019/06/26 08:46:08 gilles Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.395 2019/07/03 03:24:03 deraadt Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -1095,6 +1095,10 @@ smtp_io(struct io *io, int evt, void *arg) return; } + /* No complete line received */ + if (line == NULL) + return; + if (strchr(line, '\r')) { s->flags |= SF_BADINPUT; smtp_reply(s, "500 %s: <CR> is only allowed before <LF>", @@ -1104,10 +1108,6 @@ smtp_io(struct io *io, int evt, void *arg) return; } - /* No complete line received */ - if (line == NULL) - return; - /* Message body */ eom = 0; if (s->state == STATE_BODY) { @@ -2052,7 +2052,7 @@ smtp_reply(struct smtp_session *s, char *fmt, ...) va_start(ap, fmt); n = vsnprintf(buf, sizeof buf, fmt, ap); va_end(ap); - if (n == -1 || n >= LINE_MAX) + if (n < 0 || n >= LINE_MAX) fatalx("smtp_reply: line too long"); if (n < 4) fatalx("smtp_reply: response too short"); @@ -2918,7 +2918,7 @@ smtp_message_printf(struct smtp_tx *tx, const char *fmt, ...) len = vfprintf(tx->ofile, fmt, ap); va_end(ap); - if (len < 0) { + if (len == -1) { log_warn("smtp-in: session %016"PRIx64": vfprintf", tx->session->id); tx->error = TX_ERROR_IO; } diff --git a/smtpd/smtpc.c b/smtpd/smtpc.c index 2373aa76..fa468854 100644 --- a/smtpd/smtpc.c +++ b/smtpd/smtpc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpc.c,v 1.5 2019/05/15 05:02:43 eric Exp $ */ +/* $OpenBSD: smtpc.c,v 1.6 2019/07/02 09:36:20 martijn Exp $ */ /* * Copyright (c) 2018 Eric Faurot <eric@openbsd.org> @@ -263,19 +263,12 @@ parse_server(char *server) void parse_message(FILE *ifp) { - char sfn[] = "/tmp/smtp.XXXXXXXXXX"; char *line = NULL; size_t linesz = 0; ssize_t len; - int fd; - if ((fd = mkstemp(sfn)) == -1) - fatal("mkstemp"); - unlink(sfn); - - mail.fp = fdopen(fd, "w+"); - if ((mail.fp) == NULL) - fatal("fdopen"); + if ((mail.fp = tmpfile()) == NULL) + fatal("tmpfile"); for (;;) { if ((len = getline(&line, &linesz, ifp)) == -1) { diff --git a/smtpd/smtpctl.c b/smtpd/smtpctl.c index 42c018b9..9a16c549 100644 --- a/smtpd/smtpctl.c +++ b/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.163 2019/01/14 09:37:40 eric Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.164 2019/07/02 09:36:20 martijn Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -1320,20 +1320,10 @@ display(const char *s) if (is_encrypted_fp(fp)) { int i; - int fd; FILE *ofp = NULL; - char sfn[] = "/tmp/smtpd.XXXXXXXXXX"; - - if ((fd = mkstemp(sfn)) == -1 || - (ofp = fdopen(fd, "w+")) == NULL) { - int saved_errno = errno; - if (fd != -1) { - unlink(sfn); - close(fd); - } - errc(1, saved_errno, "mkstemp"); - } - unlink(sfn); + + if ((ofp = tmpfile()) == NULL) + err(1, "tmpfile"); for (i = 0; i < 3; i++) { key = getpass("key> "); diff --git a/smtpd/smtpd.c b/smtpd/smtpd.c index 879d141a..513b8266 100644 --- a/smtpd/smtpd.c +++ b/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.320 2019/06/13 11:45:35 eric Exp $ */ +/* $OpenBSD: smtpd.c,v 1.323 2019/06/28 13:32:51 deraadt Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -191,11 +191,12 @@ static void parent_imsg(struct mproc *p, struct imsg *imsg) { struct forward_req *fwreq; + struct processor *processor; struct deliver deliver; struct child *c; struct msg m; const void *data; - const char *username, *password, *cause; + const char *username, *password, *cause, *procname; uint64_t reqid; size_t sz; void *i; @@ -288,6 +289,17 @@ parent_imsg(struct mproc *p, struct imsg *imsg) m_end(&m); profiling = v; return; + + case IMSG_LKA_PROCESSOR_ERRFD: + m_msg(&m, imsg); + m_get_string(&m, &procname); + m_end(&m); + + processor = dict_xget(env->sc_processors_dict, procname); + m_create(p_lka, IMSG_LKA_PROCESSOR_ERRFD, 0, 0, processor->errfd); + m_add_string(p_lka, procname); + m_close(p_lka); + return; } errx(1, "parent_imsg: unexpected %s imsg from %s", @@ -1317,7 +1329,9 @@ static void fork_processor(const char *name, const char *command, const char *user, const char *group, const char *chroot_path) { pid_t pid; - int sp[2]; + struct processor *processor; + char buf; + int sp[2], errfd[2]; struct passwd *pw; struct group *gr; @@ -1337,14 +1351,19 @@ fork_processor(const char *name, const char *command, const char *user, const ch if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) err(1, "socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, errfd) == -1) + err(1, "socketpair"); - if ((pid = fork()) < 0) + if ((pid = fork()) == -1) err(1, "fork"); /* parent passes the child fd over to lka */ if (pid > 0) { + processor = dict_xget(env->sc_processors_dict, name); + processor->errfd = errfd[1]; child_add(pid, CHILD_PROCESSOR, name); close(sp[0]); + close(errfd[0]); m_create(p_lka, IMSG_LKA_PROCESSOR_FORK, 0, 0, sp[1]); m_add_string(p_lka, name); m_close(p_lka); @@ -1352,8 +1371,10 @@ fork_processor(const char *name, const char *command, const char *user, const ch } close(sp[1]); + close(errfd[1]); dup2(sp[0], STDIN_FILENO); dup2(sp[0], STDOUT_FILENO); + dup2(errfd[0], STDERR_FILENO); if (chroot_path) { if (chroot(chroot_path) != 0 || chdir("/") != 0) @@ -1376,6 +1397,16 @@ fork_processor(const char *name, const char *command, const char *user, const ch signal(SIGHUP, SIG_DFL) == SIG_ERR) err(1, "signal"); + /* + * Wait for lka to acknowledge that it received the fd. + * This prevents a race condition between the filter sending an error + * message, and exiting and lka not being able to log it because of + * SIGCHLD. + * (Ab)use read to determine if the fd is installed; since stderr is + * never going to be read from we can shutdown(2) the write-end in lka. + */ + if (read(STDERR_FILENO, &buf, 1) != 0) + errx(1, "lka didn't properly close write end of error socket"); if (system(command) == -1) err(1, NULL); @@ -1447,7 +1478,7 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver) return; } - if (pipe(pipefd) < 0) { + if (pipe(pipefd) == -1) { (void)snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno)); m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); m_add_id(p_pony, id); @@ -1461,7 +1492,7 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver) /* prepare file which captures stdout and stderr */ (void)strlcpy(sfn, "/tmp/smtpd.out.XXXXXXXXXXX", sizeof(sfn)); allout = mkstemp(sfn); - if (allout < 0) { + if (allout == -1) { (void)snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno)); m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); m_add_id(p_pony, id); @@ -1476,7 +1507,7 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver) unlink(sfn); pid = fork(); - if (pid < 0) { + if (pid == -1) { (void)snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno)); m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); m_add_id(p_pony, id); @@ -1501,15 +1532,15 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver) m_close(p); return; } - if (chdir(pw_dir) < 0 && chdir("/") < 0) + if (chdir(pw_dir) == -1 && chdir("/") == -1) err(1, "chdir"); if (setgroups(1, &pw_gid) || setresgid(pw_gid, pw_gid, pw_gid) || setresuid(pw_uid, pw_uid, pw_uid)) err(1, "forkmda: cannot drop privileges"); - if (dup2(pipefd[0], STDIN_FILENO) < 0 || - dup2(allout, STDOUT_FILENO) < 0 || - dup2(allout, STDERR_FILENO) < 0) + if (dup2(pipefd[0], STDIN_FILENO) == -1 || + dup2(allout, STDOUT_FILENO) == -1 || + dup2(allout, STDERR_FILENO) == -1) err(1, "forkmda: dup2"); closefrom(STDERR_FILENO + 1); if (setsid() < 0) @@ -1750,7 +1781,7 @@ parent_forward_open(char *username, char *directory, uid_t uid, gid_t gid) return -1; } - if (stat(directory, &sb) < 0) { + if (stat(directory, &sb) == -1) { log_warn("warn: smtpd: parent_forward_open: %s", directory); return -1; } @@ -2058,6 +2089,7 @@ imsg_to_str(int type) CASE(IMSG_SMTP_EVENT_DISCONNECT); CASE(IMSG_LKA_PROCESSOR_FORK); + CASE(IMSG_LKA_PROCESSOR_ERRFD); CASE(IMSG_REPORT_SMTP_LINK_CONNECT); CASE(IMSG_REPORT_SMTP_LINK_DISCONNECT); diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index 2a6190bf..4f646ca5 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.624 2019/06/14 19:55:25 eric Exp $ */ +/* $OpenBSD: smtpd.h,v 1.625 2019/06/27 05:14:49 martijn Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -332,6 +332,7 @@ enum imsg_type { IMSG_SMTP_EVENT_DISCONNECT, IMSG_LKA_PROCESSOR_FORK, + IMSG_LKA_PROCESSOR_ERRFD, IMSG_REPORT_SMTP_LINK_CONNECT, IMSG_REPORT_SMTP_LINK_DISCONNECT, @@ -1052,6 +1053,7 @@ struct processor { const char *user; const char *group; const char *chroot; + int errfd; }; enum filter_type { @@ -1344,6 +1346,7 @@ int lka(void); /* lka_proc.c */ int lka_proc_ready(void); void lka_proc_forked(const char *, int); +void lka_proc_errfd(const char *, int); struct io *lka_proc_get_io(const char *); diff --git a/smtpd/table_db.c b/smtpd/table_db.c index d4e39e08..f7d766dd 100644 --- a/smtpd/table_db.c +++ b/smtpd/table_db.c @@ -1,4 +1,4 @@ -/* $OpenBSD: table_db.c,v 1.20 2018/12/27 15:04:59 eric Exp $ */ +/* $OpenBSD: table_db.c,v 1.21 2019/06/28 13:32:51 deraadt Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org> @@ -143,7 +143,7 @@ table_db_open2(struct table *table) >= sizeof handle->pathname) goto error; - if (stat(handle->pathname, &sb) < 0) + if (stat(handle->pathname, &sb) == -1) goto error; handle->mtime = sb.st_mtime; @@ -180,7 +180,7 @@ table_db_lookup(struct table *table, enum table_service service, const char *key size_t i; struct stat sb; - if (stat(handle->pathname, &sb) < 0) + if (stat(handle->pathname, &sb) == -1) return -1; /* DB has changed, close and reopen */ diff --git a/smtpd/util.c b/smtpd/util.c index fd80b69a..b4f36a3a 100644 --- a/smtpd/util.c +++ b/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.140 2019/01/30 21:33:34 gilles Exp $ */ +/* $OpenBSD: util.c,v 1.142 2019/07/03 03:24:03 deraadt Exp $ */ /* * Copyright (c) 2000,2001 Markus Friedl. All rights reserved. @@ -178,7 +178,7 @@ bsnprintf(char *str, size_t size, const char *format, ...) va_start(ap, format); ret = vsnprintf(str, size, format, ap); va_end(ap); - if (ret == -1 || ret >= (int)size) + if (ret < 0 || ret >= (int)size) return 0; return 1; @@ -572,7 +572,7 @@ secure_file(int fd, char *path, char *userdir, uid_t uid, int mayread) homedir[0] = '\0'; /* Check the open file to avoid races. */ - if (fstat(fd, &st) < 0 || + if (fstat(fd, &st) == -1 || !S_ISREG(st.st_mode) || st.st_uid != uid || (st.st_mode & (mayread ? 022 : 066)) != 0) @@ -584,7 +584,7 @@ secure_file(int fd, char *path, char *userdir, uid_t uid, int mayread) return 0; (void)strlcpy(buf, cp, sizeof(buf)); - if (stat(buf, &st) < 0 || + if (stat(buf, &st) == -1 || (st.st_uid != 0 && st.st_uid != uid) || (st.st_mode & 022) != 0) return 0; |