summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2016-06-05 12:10:29 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2016-06-05 12:10:29 +0000
commit797dae7efbd22c14b5a0bd7b37484fc836ee0dfc (patch)
tree605505b03f9931a5ce40f599936e0b18de3e7e55
parent6badea9c3e26e2cd190813ca20b7ca5af93f5c54 (diff)
LMTP banner is handled by a getline() call so it cannot handle multiline
banners, introduce lmtp_banner() which takes care of this. ok sunil@
-rw-r--r--usr.sbin/smtpd/delivery_lmtp.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/usr.sbin/smtpd/delivery_lmtp.c b/usr.sbin/smtpd/delivery_lmtp.c
index 8df04f5dcb5..f6e7952ffdc 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.16 2016/06/05 11:48:56 gilles Exp $ */
+/* $OpenBSD: delivery_lmtp.c,v 1.17 2016/06/05 12:10:28 gilles Exp $ */
/*
* Copyright (c) 2013 Ashish SHUKLA <ashish.is@lostca.se>
@@ -40,6 +40,7 @@
#define MAX_CONTINUATIONS 100
static int inet_socket(char *);
+static int lmtp_banner(char **buf, size_t *, int, FILE *);
static int lmtp_cmd(char **buf, size_t *, int, FILE *, const char *, ...)
__attribute__((__format__ (printf, 5, 6)))
__attribute__((__nonnull__ (5)));
@@ -133,11 +134,8 @@ lmtp_open(struct deliver *deliver)
if ((fp = fdopen(s, "r+")) == NULL)
err(1, "fdopen");
- if (getline(&buf, &sz, fp) == -1)
- err(1, "getline");
-
- if (buf[0] != '2')
- errx(1, "Invalid LMTP greeting: %s", buf);
+ if (lmtp_banner(&buf, &sz, '2', fp) != 0)
+ errx(1, "Invalid LHLO reply: %s", buf);
if (gethostname(hn, sizeof hn) == -1)
err(1, "gethostname");
@@ -173,6 +171,41 @@ lmtp_open(struct deliver *deliver)
}
static int
+lmtp_banner(char **buf, size_t *sz, int code, FILE *fp)
+{
+ char *bufp;
+ ssize_t len;
+ size_t counter;
+
+ 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;
+}
+
+static int
lmtp_cmd(char **buf, size_t *sz, int code, FILE *fp, const char *fmt, ...)
{
va_list ap;