diff options
-rw-r--r-- | usr.sbin/sendmail/cf/m4/proto.m4 | 4 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/collect.c | 56 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/conf.c | 4 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/conf.h | 6 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/readcf.c | 23 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/sendmail.h | 2 |
7 files changed, 82 insertions, 17 deletions
diff --git a/usr.sbin/sendmail/cf/m4/proto.m4 b/usr.sbin/sendmail/cf/m4/proto.m4 index 8e79454bc04..cce5e3241d1 100644 --- a/usr.sbin/sendmail/cf/m4/proto.m4 +++ b/usr.sbin/sendmail/cf/m4/proto.m4 @@ -478,6 +478,10 @@ ifdef(`confMAX_MIME_HEADER_LENGTH', `# Maximum MIME header length to protect MUAs O MaxMimeHeaderLength=confMAX_MIME_HEADER_LENGTH ') +ifdef(`confMAX_HEADER_LINES', +`# Maximum number of header lines and header line length limit +O MaxHeaderLines=confMAX_HEADER_LINES +') ########################### # Message precedences # diff --git a/usr.sbin/sendmail/src/Makefile b/usr.sbin/sendmail/src/Makefile index f8f82ce170f..d15e90afe97 100644 --- a/usr.sbin/sendmail/src/Makefile +++ b/usr.sbin/sendmail/src/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.20 1999/01/01 20:33:35 millert Exp $ +# $OpenBSD: Makefile,v 1.21 1999/01/21 19:37:23 millert Exp $ # # OpenBSD Makefile # @@ -22,7 +22,7 @@ MAPDEF+=-DNIS .endif # environment definitions (e.g., -DNETISO) -ENVDEF= -DNETISO -D_FFR_MAX_MIME_HEADER_LENGTH=1 +ENVDEF= -DNETISO -D_FFR_MAX_MIME_HEADER_LENGTH=1 -D_FFR_MAX_HEADER_LINES=1 .if (${TCP_WRAPPERS} == "yes") ENVDEF+=-DTCPWRAPPERS diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c index 741336aaecf..9fa56b8d75a 100644 --- a/usr.sbin/sendmail/src/collect.c +++ b/usr.sbin/sendmail/src/collect.c @@ -57,8 +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 MAXHDRLINES 512 /* max number of lines in the mail headers */ +#define MS_DISCARD 3 /* discarding rest of message */ void collect(fp, smtpmode, hdrp, e) @@ -79,10 +78,11 @@ 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]; - int numheaders = 0; extern bool isheader __P((char *)); extern void tferror __P((FILE *volatile, ENVELOPE *)); @@ -201,6 +201,7 @@ collect(fp, smtpmode, hdrp, e) switch (istate) { case IS_BOL: + hdrlinelen = 0; if (c == '.') { istate = IS_DOT; @@ -265,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; } @@ -301,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; } @@ -334,16 +356,21 @@ nextstate: goto nextstate; } - /* check for unreasonable number of headers */ - if (numheaders++ > MAXHDRLINES) - { - sm_syslog(LOG_NOTICE, e->e_id, - "excessive headers from %s during message collect", - CurHostName ? CurHostName : "<local machine>"); - errno = 0; - usrerr("451 Excessive number of mail headers."); - goto readerr; - } + 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 @@ -364,6 +391,7 @@ nextstate: if (*--bp != '\n' || *--bp != '\r') bp++; *bp = '\0'; + if (bitset(H_EOH, chompheader(buf, FALSE, hdrp, e))) { mstate = MS_BODY; diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c index 443ae034de4..9672c53d460 100644 --- a/usr.sbin/sendmail/src/conf.c +++ b/usr.sbin/sendmail/src/conf.c @@ -284,6 +284,8 @@ setdefaults(e) ColonOkInAddr = TRUE; DontLockReadFiles = TRUE; DoubleBounceAddr = "postmaster"; + MaxHeaderLines = MAXHDRLINES; + MaxHeaderLineLength = MAXHDRLINELEN; snprintf(buf, sizeof buf, "%s%sdead.letter", _PATH_VARTMP, _PATH_VARTMP[sizeof _PATH_VARTMP - 2] == '/' ? "" : "/"); @@ -1946,7 +1948,7 @@ getla() /* Non Apollo stuff removed by Don Lewis 11/15/93 */ #ifndef lint -static char rcsid[] = "@(#)$Id: conf.c,v 1.11 1999/01/01 20:33:39 millert Exp $"; +static char rcsid[] = "@(#)$Id: conf.c,v 1.12 1999/01/21 19:37:24 millert Exp $"; #endif /* !lint */ #ifdef apollo diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h index b9cdc6862ca..e45529a8604 100644 --- a/usr.sbin/sendmail/src/conf.h +++ b/usr.sbin/sendmail/src/conf.h @@ -69,6 +69,12 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ # else # define MAXMACNAMELEN 20 /* max macro name length */ # endif +# ifndef MAXHDRLINES +# define MAXHDRLINES 1000 /* max lines in a message header */ +# endif +# ifndef MAXHDRLINELEN +# define MAXHDRLINELEN SMTPLINELIM /* max length of a header line */ +# endif /********************************************************************** ** Compilation options. diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c index 56aa825981b..e507d79ca64 100644 --- a/usr.sbin/sendmail/src/readcf.c +++ b/usr.sbin/sendmail/src/readcf.c @@ -1527,6 +1527,10 @@ struct optioninfo #define O_CONTROLSOCKET 0xa9 { "ControlSocketName", O_CONTROLSOCKET, FALSE }, #endif +#if _FFR_MAX_HEADER_LINES +#define O_MAXHDRLINES 0xaa + { "MaxHeaderLines", O_MAXHDRLINES, FALSE }, +#endif { NULL, '\0', FALSE } }; @@ -2463,6 +2467,25 @@ setoption(opt, val, safe, sticky, e) if (ControlSocketName != NULL) free(ControlSocketName); ControlSocketName = newstr(val); + break; +#endif + +#if _FFR_MAX_HEADER_LINES + case O_MAXHDRLINES: + p = strchr(val, '/'); + if (p != NULL) + *p++ = '\0'; + MaxHeaderLines = atoi(val); + if (p != NULL && *p != '\0') + MaxHeaderLineLength = atoi(p); + + if (MaxHeaderLines > 0 && + MaxHeaderLines < 50) + printf("Warning: MaxHeaderLines: header line limit set lower than 50\n"); + + if (MaxHeaderLineLength > 0 && + MaxHeaderLineLength < MAXHDRLINELEN) + printf("Warning: MaxHeaderLines: header line length limit set lower than %d\n", MAXHDRLINELEN); break; #endif diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h index 023799d7e81..624ecf1d086 100644 --- a/usr.sbin/sendmail/src/sendmail.h +++ b/usr.sbin/sendmail/src/sendmail.h @@ -1258,6 +1258,8 @@ EXTERN gid_t RunAsGid; /* GID to become for bulk of run */ EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */ EXTERN bool DoQueueRun; /* non-interrupt time queue run needed */ EXTERN u_long ConnectOnlyTo; /* override connection address (for testing) */ +EXTERN int MaxHeaderLines; /* max lines of headers per message */ +EXTERN int MaxHeaderLineLength; /* max length of a header line */ #if _FFR_DSN_RRT_OPTION EXTERN bool RrtImpliesDsn; /* turn Return-Receipt-To: into DSN */ #endif |