summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/mta_session.c
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2015-12-01 15:30:43 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2015-12-01 15:30:43 +0000
commit07cbd9360b513281162bcff563a61e9fe68684d2 (patch)
treef03a579376ec748c8fcddd292349c852864462c8 /usr.sbin/smtpd/mta_session.c
parentc4ed28f037019ca260a3072f1055dec3e602b153 (diff)
when peer outputs a multi-line response, concat response into a single log
ok sunil@, jung@
Diffstat (limited to 'usr.sbin/smtpd/mta_session.c')
-rw-r--r--usr.sbin/smtpd/mta_session.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/usr.sbin/smtpd/mta_session.c b/usr.sbin/smtpd/mta_session.c
index 93f06197dd5..feef15c5131 100644
--- a/usr.sbin/smtpd/mta_session.c
+++ b/usr.sbin/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.75 2015/11/30 12:49:35 gilles Exp $ */
+/* $OpenBSD: mta_session.c,v 1.76 2015/12/01 15:30:42 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -129,6 +129,8 @@ struct mta_session {
FILE *datafp;
size_t failures;
+
+ char replybuf[2048];
};
static void mta_session_init(void);
@@ -597,6 +599,8 @@ mta_enter_state(struct mta_session *s, int newstate)
s->state = newstate;
+ memset(s->replybuf, 0, sizeof s->replybuf);
+
/* don't try this at home! */
#define mta_enter_state(_s, _st) do { newstate = _st; goto again; } while (0)
@@ -1229,8 +1233,36 @@ mta_io(struct io *io, int evt)
s->ext |= MTA_EXT_DSN;
}
- if (cont)
+ /* continuation reply, we parse out the repeating statuses and ESC */
+ if (cont) {
+ if (s->replybuf[0] == '\0')
+ (void)strlcat(s->replybuf, line, sizeof s->replybuf);
+ else {
+ line = line + 4;
+ if (isdigit((int)*line) && *(line + 1) == '.' &&
+ isdigit((int)*line+2) && *(line + 3) == '.' &&
+ isdigit((int)*line+4) && isspace((int)*(line + 5)))
+ (void)strlcat(s->replybuf, line+5, sizeof s->replybuf);
+ else
+ (void)strlcat(s->replybuf, line, sizeof s->replybuf);
+ }
goto nextline;
+ }
+
+ /* last line of a reply, check if we're on a continuation to parse out status and ESC.
+ * if we overflow reply buffer or are not on continuation, log entire last line.
+ */
+ if (s->replybuf[0] != '\0') {
+ p = line + 4;
+ if (isdigit((int)*p) && *(p + 1) == '.' &&
+ isdigit((int)*p+2) && *(p + 3) == '.' &&
+ isdigit((int)*p+4) && isspace((int)*(p + 5)))
+ p += 5;
+ if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf)
+ (void)strlcpy(s->replybuf, line, sizeof s->replybuf);
+ }
+ else
+ (void)strlcpy(s->replybuf, line, sizeof s->replybuf);
if (s->state == MTA_QUIT) {
log_info("smtp-out: Closing session %016"PRIx64
@@ -1240,7 +1272,7 @@ mta_io(struct io *io, int evt)
return;
}
io_set_write(io);
- mta_response(s, line);
+ mta_response(s, s->replybuf);
if (s->flags & MTA_FREE) {
mta_free(s);
return;
@@ -1562,12 +1594,12 @@ mta_verify_certificate(struct mta_session *s)
X509_free(x);
if (cert_len[0] < 0) {
- log_warnx("warn: failed to encode certificate");
+ log_warnx("warn: failed to encode certificate");
goto end;
}
log_debug("debug: certificate 0: len=%d", cert_len[0]);
if (cert_len[0] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
+ log_warnx("warn: certificate too long");
goto end;
}
@@ -1586,12 +1618,12 @@ mta_verify_certificate(struct mta_session *s)
x = sk_X509_value(xchain, i);
cert_len[i+1] = i2d_X509(x, &cert_der[i+1]);
if (cert_len[i+1] < 0) {
- log_warnx("warn: failed to encode certificate");
+ log_warnx("warn: failed to encode certificate");
goto end;
}
log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]);
if (cert_len[i+1] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
+ log_warnx("warn: certificate too long");
goto end;
}
}