aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2019-07-04 20:10:14 +0200
committerGilles Chehade <gilles@poolp.org>2019-07-04 20:10:14 +0200
commitf43b708cf1d57842a15565d88b9dc06140568f05 (patch)
tree0018bdcac2ff2cc8c0292a2a742624e61f273193
parentMerge branch 'master' into portable (diff)
parentsync (diff)
downloadOpenSMTPD-f43b708cf1d57842a15565d88b9dc06140568f05.tar.xz
OpenSMTPD-f43b708cf1d57842a15565d88b9dc06140568f05.zip
Merge branch 'master' into portable
-rw-r--r--smtpd/crypto.c6
-rw-r--r--smtpd/enqueue.c17
-rw-r--r--smtpd/envelope.c6
-rw-r--r--smtpd/lka.c14
-rw-r--r--smtpd/lka_filter.c49
-rw-r--r--smtpd/lka_proc.c32
-rw-r--r--smtpd/mail.maildir.c18
-rw-r--r--smtpd/mail.mboxfile.c4
-rw-r--r--smtpd/mda.c2
-rw-r--r--smtpd/mproc.c5
-rw-r--r--smtpd/mta_session.c6
-rw-r--r--smtpd/parse.y4
-rw-r--r--smtpd/queue_fs.c4
-rw-r--r--smtpd/smtp.c4
-rw-r--r--smtpd/smtp_session.c14
-rw-r--r--smtpd/smtpc.c13
-rw-r--r--smtpd/smtpctl.c18
-rw-r--r--smtpd/smtpd.c56
-rw-r--r--smtpd/smtpd.h5
-rw-r--r--smtpd/table_db.c6
-rw-r--r--smtpd/util.c8
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;