summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2015-10-13 11:32:47 +0000
committereric <eric@openbsd.org>2015-10-13 11:32:47 +0000
commit1b33e826a0432cd66f6def1d51493f1a50bddc93 (patch)
tree3075eb321656c0fb66f38143bcef966c89383676
parentpledge() queue process (diff)
downloadwireguard-openbsd-1b33e826a0432cd66f6def1d51493f1a50bddc93.tar.xz
wireguard-openbsd-1b33e826a0432cd66f6def1d51493f1a50bddc93.zip
Add a helper for writing the message to simplify the code.
It also fixes the reported message length by taking prepended headers into account and adds missing error checks there. ok millert@ gilles@
-rw-r--r--usr.sbin/smtpd/smtp_session.c140
1 files changed, 62 insertions, 78 deletions
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index d99be447943..9355e3675e2 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.235 2015/10/12 20:16:31 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.236 2015/10/13 11:32:47 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -179,6 +179,7 @@ static void smtp_rfc4954_auth_login(struct smtp_session *, char *);
static void smtp_message_write(struct smtp_session *, const char *);
static void smtp_message_end(struct smtp_session *);
static void smtp_message_reset(struct smtp_session *, int);
+static int smtp_message_printf(struct smtp_session *, const char *, ...);
static void smtp_free(struct smtp_session *, const char *);
static const char *smtp_strstate(int);
static int smtp_verify_certificate(struct smtp_session *);
@@ -231,39 +232,21 @@ header_default_callback(const struct rfc2822_header *hdr, void *arg)
{
struct smtp_session *s = arg;
struct rfc2822_line *l;
- size_t len;
- len = strlen(hdr->name) + 1;
- if (fprintf(s->ofile, "%s:", hdr->name) != (int)len) {
- s->msgflags |= MF_ERROR_IO;
+ if (smtp_message_printf(s, "%s:", hdr->name) == -1)
return;
- }
- s->datalen += len;
- TAILQ_FOREACH(l, &hdr->lines, next) {
- len = strlen(l->buffer) + 1;
- if (fprintf(s->ofile, "%s\n", l->buffer) != (int)len) {
- s->msgflags |= MF_ERROR_IO;
+ TAILQ_FOREACH(l, &hdr->lines, next)
+ if (smtp_message_printf(s, "%s\n", l->buffer) == -1)
return;
- }
- s->datalen += len;
- }
}
static void
dataline_callback(const char *line, void *arg)
{
struct smtp_session *s = arg;
- size_t len;
-
- len = strlen(line) + 1;
-
- if (fprintf(s->ofile, "%s\n", line) != (int)len) {
- s->msgflags |= MF_ERROR_IO;
- return;
- }
- s->datalen += len;
+ smtp_message_printf(s, "%s\n", line);
}
static void
@@ -360,13 +343,10 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
struct rfc2822_line *l;
size_t i, j;
int escape, quote, comment, skip;
- size_t len;
char buffer[APPEND_DOMAIN_BUFFER_SIZE];
- len = strlen(hdr->name) + 1;
- if (fprintf(s->ofile, "%s:", hdr->name) != (int)len)
- goto ioerror;
- s->datalen += len;
+ if (smtp_message_printf(s, "%s:", hdr->name) == -1)
+ return;
i = j = 0;
escape = quote = comment = skip = 0;
@@ -389,27 +369,24 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
if (l->buffer[i] == ',' && !escape && !quote && !comment) {
if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer)
header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
- len = strlen(buffer) + 1;
- if (fprintf(s->ofile, "%s,", buffer) != (int)len)
- goto ioerror;
- s->datalen += len;
+ if (smtp_message_printf(s, "%s,", buffer) == -1)
+ return;
j = 0;
skip = 0;
memset(buffer, 0, sizeof buffer);
}
else {
if (skip) {
- if (fprintf(s->ofile, "%c", l->buffer[i]) != (int)1)
- goto ioerror;
- s->datalen += 1;
+ if (smtp_message_printf(s, "%c",
+ l->buffer[i]) == -1)
+ return;
}
else {
buffer[j++] = l->buffer[i];
if (j == sizeof (buffer) - 1) {
- len = strlen(buffer);
- if (fprintf(s->ofile, "%s", buffer) != (int)len)
- goto ioerror;
- s->datalen += len;
+ if (smtp_message_printf(s, "%s",
+ buffer) != -1)
+ return;
skip = 1;
j = 0;
memset(buffer, 0, sizeof buffer);
@@ -418,17 +395,14 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
}
}
if (skip) {
- if (fprintf(s->ofile, "\n") != (int)1)
- goto ioerror;
- s->datalen += 1;
+ if (smtp_message_printf(s, "\n") == -1)
+ return;
}
else {
buffer[j++] = '\n';
if (j == sizeof (buffer) - 1) {
- len = strlen(buffer);
- if (fprintf(s->ofile, "%s", buffer) != (int)len)
- goto ioerror;
- s->datalen += len;
+ if (smtp_message_printf(s, "%s", buffer) == -1)
+ return;
skip = 1;
j = 0;
memset(buffer, 0, sizeof buffer);
@@ -440,42 +414,21 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
if (buffer[0]) {
if (j + strlen(s->listener->hostname) + 1 < sizeof buffer)
header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
- len = strlen(buffer);
- if (fprintf(s->ofile, "%s", buffer) != (int)len)
- goto ioerror;
- s->datalen += len;
+ smtp_message_printf(s, "%s", buffer);
}
- return;
-
-ioerror:
- s->msgflags |= MF_ERROR_IO;
- return;
}
static void
header_missing_callback(const char *header, void *arg)
{
struct smtp_session *s = arg;
- int len;
- if (strcasecmp(header, "message-id") == 0) {
- len = fprintf(s->ofile, "Message-Id: <%016"PRIx64"@%s>\n",
+ if (strcasecmp(header, "message-id") == 0)
+ smtp_message_printf(s, "Message-Id: <%016"PRIx64"@%s>\n",
generate_uid(), s->listener->hostname);
- if (len == -1) {
- s->msgflags |= MF_ERROR_IO;
- return;
- }
- s->datalen += len;
- }
- if (strcasecmp(header, "date") == 0) {
- len = fprintf(s->ofile, "Date: %s\n", time_to_text(time(NULL)));
- if (len == -1) {
- s->msgflags |= MF_ERROR_IO;
- return;
- }
- s->datalen += len;
- }
+ if (strcasecmp(header, "date") == 0)
+ smtp_message_printf(s, "Date: %s\n", time_to_text(time(NULL)));
}
static void
@@ -677,14 +630,14 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
return;
}
- fprintf(s->ofile, "Received: ");
+ smtp_message_printf(s, "Received: ");
if (! (s->listener->flags & F_MASK_SOURCE)) {
- fprintf(s->ofile, "from %s (%s [%s])",
+ smtp_message_printf(s, "from %s (%s [%s])",
s->evp.helo,
s->hostname,
ss_to_text(&s->ss));
}
- fprintf(s->ofile, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
+ smtp_message_printf(s, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
s->smtpname,
SMTPD_NAME,
s->flags & SF_EHLO ? "E" : "",
@@ -694,7 +647,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
if (s->flags & SF_SECURE) {
x = SSL_get_peer_certificate(s->io.ssl);
- fprintf(s->ofile,
+ smtp_message_printf(s,
"\n\tTLS version=%s cipher=%s bits=%d verify=%s",
SSL_get_cipher_version(s->io.ssl),
SSL_get_cipher_name(s->io.ssl),
@@ -705,12 +658,20 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
}
if (s->rcptcount == 1) {
- fprintf(s->ofile, "\n\tfor <%s@%s>",
+ smtp_message_printf(s, "\n\tfor <%s@%s>",
s->evp.rcpt.user,
s->evp.rcpt.domain);
}
- fprintf(s->ofile, ";\n\t%s\n", time_to_text(time(NULL)));
+ smtp_message_printf(s, ";\n\t%s\n", time_to_text(time(NULL)));
+
+ if (s->msgflags & MF_ERROR) {
+ smtp_reply(s, "421 %s: Temporary Error",
+ esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
+ smtp_enter_state(s, STATE_QUIT);
+ io_reload(&s->io);
+ return;
+ }
smtp_enter_state(s, STATE_BODY);
smtp_reply(s, "354 Enter mail, end with \".\""
@@ -1919,6 +1880,29 @@ smtp_message_reset(struct smtp_session *s, int prepare)
}
}
+static int
+smtp_message_printf(struct smtp_session *s, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ if (s->msgflags & MF_ERROR)
+ return -1;
+
+ va_start(ap, fmt);
+ len = vfprintf(s->ofile, fmt, ap);
+ va_end(ap);
+
+ if (len < 0) {
+ log_warn("smtp-in: session %016"PRIx64": vfprintf", s->id);
+ s->msgflags |= MF_ERROR_IO;
+ }
+ else
+ s->datalen += len;
+
+ return len;
+}
+
static void
smtp_reply(struct smtp_session *s, char *fmt, ...)
{