diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/delivery_lmtp.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/usr.sbin/smtpd/delivery_lmtp.c b/usr.sbin/smtpd/delivery_lmtp.c index 9459b72163f..8df04f5dcb5 100644 --- a/usr.sbin/smtpd/delivery_lmtp.c +++ b/usr.sbin/smtpd/delivery_lmtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: delivery_lmtp.c,v 1.15 2015/12/14 10:22:11 jung Exp $ */ +/* $OpenBSD: delivery_lmtp.c,v 1.16 2016/06/05 11:48:56 gilles Exp $ */ /* * Copyright (c) 2013 Ashish SHUKLA <ashish.is@lostca.se> @@ -36,6 +36,9 @@ #include "smtpd.h" +/* should be more than enough for any LMTP server */ +#define MAX_CONTINUATIONS 100 + static int inet_socket(char *); static int lmtp_cmd(char **buf, size_t *, int, FILE *, const char *, ...) __attribute__((__format__ (printf, 5, 6))) @@ -175,6 +178,7 @@ lmtp_cmd(char **buf, size_t *sz, int code, FILE *fp, const char *fmt, ...) va_list ap; char *bufp; ssize_t len; + size_t counter; va_start(ap, fmt); if (vfprintf(fp, fmt, ap) < 0) @@ -187,14 +191,30 @@ lmtp_cmd(char **buf, size_t *sz, int code, FILE *fp, const char *fmt, ...) if (fflush(fp) != 0) err(1, "fflush"); - if ((len = getline(buf, sz, fp)) == -1) - err(1, "getline"); - - bufp = *buf; - if (len >= 2 && bufp[len - 2] == '\r') - bufp[len - 2] = '\0'; - else if (bufp[len - 1] == '\n') - bufp[len - 1] = '\0'; + counter = 0; + do { + if ((len = getline(buf, sz, fp)) == -1) + err(1, "getline"); + if (len < 4) + err(1, "line too short"); + + bufp = *buf; + if (len >= 2 && bufp[len - 2] == '\r') + bufp[len - 2] = '\0'; + else if (bufp[len - 1] == '\n') + bufp[len - 1] = '\0'; + + if (bufp[3] == '\0' || bufp[3] == ' ') + break; + else if (bufp[3] == '-') { + if (counter == MAX_CONTINUATIONS) + errx(1, "LMTP server is sending too many continuations"); + counter++; + continue; + } + else + errx(1, "invalid line"); + } while (1); return bufp[0] != code; } |