diff options
author | peter <peter@FreeBSD.org> | 1999-01-24 07:40:56 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1999-01-24 07:40:56 +0000 |
commit | d7ac03c10c41129058bfcad4473d778394642703 (patch) | |
tree | 67c9250e87bf08c97b1bdc067576510ed21ad091 /contrib/sendmail/src/collect.c | |
parent | 2a7bd60222ce3c09208a265ad3a5f1490ccb6768 (diff) | |
download | FreeBSD-src-d7ac03c10c41129058bfcad4473d778394642703.zip FreeBSD-src-d7ac03c10c41129058bfcad4473d778394642703.tar.gz |
Check the patch obtained from sendmail.org for the header denial-of-service
attack into the vendor branch. It is a little unusual doing it this way
but it will eliminate (or minimize anyway) conflicts when 8.9.3 comes out.
Obtained from: sendmail.org (as posted on bugtraq, but without broken tabs)
Diffstat (limited to 'contrib/sendmail/src/collect.c')
-rw-r--r-- | contrib/sendmail/src/collect.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c index e334e96..7e68f40 100644 --- a/contrib/sendmail/src/collect.c +++ b/contrib/sendmail/src/collect.c @@ -57,6 +57,7 @@ static EVENT *CollectTimeout; #define MS_UFROM 0 /* reading Unix from line */ #define MS_HEADER 1 /* reading message header */ #define MS_BODY 2 /* reading message body */ +#define MS_DISCARD 3 /* discarding rest of message */ void collect(fp, smtpmode, hdrp, e) @@ -77,6 +78,8 @@ collect(fp, smtpmode, hdrp, e) volatile int istate; volatile int mstate; u_char *volatile pbp; + int nhdrlines = 0; + int hdrlinelen = 0; u_char peekbuf[8]; char dfname[MAXQFNAME]; char bufbuf[MAXLINE]; @@ -198,6 +201,7 @@ collect(fp, smtpmode, hdrp, e) switch (istate) { case IS_BOL: + hdrlinelen = 0; if (c == '.') { istate = IS_DOT; @@ -262,12 +266,17 @@ collect(fp, smtpmode, hdrp, e) bufferchar: if (!headeronly) e->e_msgsize++; - if (mstate == MS_BODY) + switch (mstate) { + case MS_BODY: /* just put the character out */ if (MaxMessageSize <= 0 || e->e_msgsize <= MaxMessageSize) putc(c, tf); + + /* fall through */ + + case MS_DISCARD: continue; } @@ -298,7 +307,23 @@ bufferchar: #endif } else if (c != '\0') + { *bp++ = c; + if (MaxHeaderLineLength > 0 && + ++hdrlinelen > MaxHeaderLineLength) + { + sm_syslog(LOG_NOTICE, e->e_id, + "header line too long (%d max) from %s during message collect", + MaxHeaderLineLength, + CurHostName != NULL ? CurHostName : "localhost"); + errno = 0; + e->e_flags |= EF_CLRQUEUE; + e->e_status = "5.6.0"; + usrerr("552 Header line too long (%d max)", + MaxHeaderLineLength); + mstate = MS_DISCARD; + } + } if (istate == IS_BOL) break; } @@ -331,6 +356,22 @@ nextstate: goto nextstate; } + if (MaxHeaderLines > 0 && + ++nhdrlines > MaxHeaderLines) + { + sm_syslog(LOG_NOTICE, e->e_id, + "too many header lines (%d max) from %s during message collect", + MaxHeaderLines, + CurHostName != NULL ? CurHostName : "localhost"); + errno = 0; + e->e_flags |= EF_CLRQUEUE; + e->e_status = "5.6.0"; + usrerr("552 Too many header lines (%d max)", + MaxHeaderLines); + mstate = MS_DISCARD; + break; + } + /* check for possible continuation line */ do { @@ -350,6 +391,7 @@ nextstate: if (*--bp != '\n' || *--bp != '\r') bp++; *bp = '\0'; + if (bitset(H_EOH, chompheader(buf, FALSE, hdrp, e))) { mstate = MS_BODY; |