From: shields@crosslink.net (Michael Shields) To: qmail mailing list Subject: smtpmaxsize patch, take two Date: 19 Jun 1997 18:10:20 -0000 Here's a revision of the patch I posted a few weeks ago. Firstly it should be a clean patch against 1.01; apparently last time I didn't quite break out the smtpmaxsize portion from the other modifications I've made. This is the result of an emerge session so it should be ok. Apart from the patch format, there are three changes, all suggested by Jeff Hayward : 1. Stops writing to disk immediately after maxsize is reached. 2. Supports a MAXSIZE environment variable which overrides the control/smtpmaxsize file. You can set this from tcpcontrol to allow different maximum sizes for different groups of machines. 3. Manpage updated to explain that it counts "network bytes", with a CRLF, not "spool bytes", with a \n. ESMTP SIZE is still not supported, but it is on my todo list (not near the top, though). I haven't done any extensive testing but it's simple enough and has run on my workstation for the afternoon. I believe it's stable. diff -U3 -r qmail-1.01/qmail-control.9 qmail-1.01.smtpmaxsize/qmail-control.9 --- qmail-1.01/qmail-control.9 Tue Apr 15 05:05:23 1997 +++ qmail-1.01.smtpmaxsize/qmail-control.9 Thu Jun 19 17:47:14 1997 @@ -59,6 +59,7 @@ .I rcpthosts \fR(none) \fRqmail-smtpd .I recipientmap \fR(none) \fRqmail-send .I smtpgreeting \fIme \fRqmail-smtpd +.I smtpmaxsize \fR(none) \fRqmail-smtpd .I smtproutes \fR(none) \fRqmail-remote .I timeoutconnect \fR60 \fRqmail-remote .I timeoutremote \fR1200 \fRqmail-remote diff -U3 -r qmail-1.01/qmail-showctl.c qmail-1.01.smtpmaxsize/qmail-showctl.c --- qmail-1.01/qmail-showctl.c Tue Apr 15 05:05:23 1997 +++ qmail-1.01.smtpmaxsize/qmail-showctl.c Thu Jun 19 17:56:52 1997 @@ -186,6 +186,7 @@ do_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ","."); do_lst("recipientmap","No redirections.","Redirection: ",""); do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 "); + do_int("smtpmaxsize","unlimited","Maximum size accepted via SMTP is ",""); do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ",""); do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds"); do_int("timeoutremote","1200","SMTP client data timeout is "," seconds"); @@ -218,6 +219,7 @@ if (str_equal(d->d_name,"rcpthosts")) continue; if (str_equal(d->d_name,"recipientmap")) continue; if (str_equal(d->d_name,"smtpgreeting")) continue; + if (str_equal(d->d_name,"smtpmaxsize")) continue; if (str_equal(d->d_name,"smtproutes")) continue; if (str_equal(d->d_name,"timeoutconnect")) continue; if (str_equal(d->d_name,"timeoutremote")) continue; diff -U3 -r qmail-1.01/qmail-smtpd.8 qmail-1.01.smtpmaxsize/qmail-smtpd.8 --- qmail-1.01/qmail-smtpd.8 Tue Apr 15 05:05:23 1997 +++ qmail-1.01.smtpmaxsize/qmail-smtpd.8 Thu Jun 19 17:45:33 1997 @@ -111,6 +111,13 @@ .I smtpgreeting should be the current host's name. .TP 5 +.I smtpmaxsize +Maximum number of on-the-wire bytes in an incoming SMTP message. +This may be overridden with the +.B MAXSIZE +environment variable. +Default: unlimited. +.TP 5 .I timeoutsmtpd Number of seconds .B qmail-smtpd diff -U3 -r qmail-1.01/qmail-smtpd.c qmail-1.01.smtpmaxsize/qmail-smtpd.c --- qmail-1.01/qmail-smtpd.c Tue Apr 15 05:05:23 1997 +++ qmail-1.01.smtpmaxsize/qmail-smtpd.c Thu Jun 19 17:44:01 1997 @@ -22,6 +22,7 @@ #define MAXHOPS 100 int timeout = 1200; +unsigned long maxsize = (unsigned long) -1; char ssoutbuf[512]; substdio ssout = SUBSTDIO_FDBUF(write,1,ssoutbuf,sizeof(ssoutbuf)); @@ -80,6 +81,7 @@ void getenvs() { + char *maxsize_env; remoteip = env_get("TCPREMOTEIP"); if (!remoteip) remoteip = "unknown"; local = env_get("TCPLOCALHOST"); @@ -89,6 +91,8 @@ if (!remotehost) remotehost = "unknown"; remoteinfo = env_get("TCPREMOTEINFO"); relayclient = env_get("RELAYCLIENT"); + remoteislocal = env_get("TCPREMOTEISLOCAL"); + if (maxsize_env = env_get("MAXSIZE")) scan_ulong(maxsize_env,&maxsize); dohelo(remotehost); } @@ -103,9 +107,10 @@ die(); } -void blast(ssfrom,hops) +void blast(ssfrom,hops,maxsize) substdio *ssfrom; int *hops; +int *maxsize; { char ch; int state; @@ -164,7 +169,16 @@ if (ch == '\n') { state = 1; break; } if (ch != '\r') { qmail_put(&qqt,"\r",1); state = 0; } } - qmail_put(&qqt,&ch,1); + switch (*maxsize) + { + case 0: /* already full */ + break; + default: + (*maxsize)--; + /* fall through */ + case (unsigned long) -1: /* no limit */ + qmail_put(&qqt,&ch,1); + } } } @@ -318,7 +332,7 @@ } void smtp_data() { - int hops; int r; unsigned long qp; + int hops; int r; unsigned long qp; unsigned long maxsize2 = maxsize; if (!seenmail) { err_wantmail(); return; } if (!rcptto.len) { err_wantrcpt(); return; } seenmail = 0; @@ -327,15 +341,16 @@ out("354 go ahead\r\n"); received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,case_diffs(remotehost,helohost.s) ? helohost.s : 0); - blast(&ssin,&hops); + blast(&ssin,&hops,&maxsize2); hops = (hops >= MAXHOPS); - if (hops) qmail_fail(&qqt); + if (hops || !maxsize2) qmail_fail(&qqt); qmail_from(&qqt,mailfrom.s); qmail_put(&qqt,rcptto.s,rcptto.len); r = qmail_close(&qqt); if (!r) { acceptmessage(qp); return; } if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; } + if (!maxsize2) { out("552 message exceeds maximum size (#5.3.4)\r\n"); return; } switch(r) { case QMAIL_TOOLONG: out("554 address too long (#5.1.3)\r\n"); return; -- Shields, CrossLink.