diff -uNr qmail-1.03/Makefile qmail-1.03-noxa/Makefile --- qmail-1.03/Makefile 2004-07-27 17:38:20.065838464 +0200 +++ qmail-1.03-noxa/Makefile 2004-06-12 19:46:09.000000000 +0200 @@ -1598,13 +1598,14 @@ auto_split.h ./compile qmail-showctl.c +# XXX-noxa: added qsutil.o for logging qmail-smtpd: \ -load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \ +load qmail-smtpd.o rcpthosts.o qregex.o qsutil.o commands.o timeoutread.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \ open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \ fs.a auto_qmail.o base64.o socket.lib - ./load qmail-smtpd qregex.o rcpthosts.o commands.o timeoutread.o \ + ./load qmail-smtpd qregex.o rcpthosts.o qsutil.o commands.o timeoutread.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ datetime.a getln.a open.a sig.a case.a env.a stralloc.a \ diff -uNr qmail-1.03/qmail-send.c qmail-1.03-noxa/qmail-send.c --- qmail-1.03/qmail-send.c 2004-07-27 17:38:19.673898048 +0200 +++ qmail-1.03-noxa/qmail-send.c 2004-06-14 16:25:27.000000000 +0200 @@ -44,7 +44,8 @@ int lifetime = 604800; -int bouncemaxbytes = 50000; +/* XXX-noxa */ +int bouncemaxbytes = 5000; stralloc percenthack = {0}; struct constmap mappercenthack; @@ -706,6 +707,10 @@ qmail_puts(&qqt,"\nTo: "); while (!quote2("ed,bouncerecip)) nomem(); qmail_put(&qqt,quoted.s,quoted.len); + +#if 0 +/* XXX-noxa */ +/* qmail_puts(&qqt,"\n\ Subject: failure notice\n\ \n\ @@ -719,6 +724,22 @@ I tried to deliver a bounce message to this address, but the bounce bounced!\n\ \n\ "); +*/ +#endif + + /* XXX-noxa */ + qmail_puts(&qqt, "\n\ +Subject: failure notice\n\ +\n\ +Hi. This is the MTA at "); + qmail_put(&qqt,bouncehost.s,bouncehost.len); + qmail_puts(&qqt,*sender.s ? ".\n\ +The attached message couldn't be delivered to the following addresses.\n\ +\n\ +" : ".\n\ +I tried to deliver a bounce message to this address, but the bounce bounced.\n\ +\n\ +"); fd = open_read(fn2.s); if (fd == -1) @@ -953,7 +974,10 @@ log3("delivery ",strnum3,": failure: "); logsafe(dline[c].s + 3); log1("\n"); + /* XXX-noxa */ +#if 1 addbounce(jo[d[c][delnum].j].id,d[c][delnum].recip.s,dline[c].s + 3); +#endif markdone(c,jo[d[c][delnum].j].id,d[c][delnum].mpos); --jo[d[c][delnum].j].numtodo; break; diff -uNr qmail-1.03/qmail-smtpd.c qmail-1.03-noxa/qmail-smtpd.c --- qmail-1.03/qmail-smtpd.c 2004-07-27 17:38:19.050992744 +0200 +++ qmail-1.03-noxa/qmail-smtpd.c 2004-07-11 21:45:24.000000000 +0200 @@ -44,7 +44,8 @@ #define AUTHCRAM #define MAXHOPS 100 unsigned int databytes = 0; -int timeout = 1200; +/* XXX-noxa */ +int timeout = 600; char *remoteip; char *remotehost; @@ -123,7 +124,8 @@ void die_alarm() { enew(); eout("Connection to "); eout(remoteip); eout(" timed out.\n"); - out("451 timeout (#4.4.2)\r\n"); flush(); eflush(); _exit(1); + /* XXX-noxa */ + out("451 timeout: hey, don't fall asleep while talking to me!\r\n"); flush(); eflush(); _exit(1); } void die_nomem() { @@ -145,25 +147,32 @@ void straynewline() { enew(); eout("Stray newline from "); eout(remoteip); eout(".\n"); - out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); + /* XXX-noxa */ + out("451 Stray newline - please use \\r\\n. Have a look at http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); eflush(); _exit(1); } void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); } void err_brt() { out("550 sorry, this message is not deliverable (#5.7.1)\r\n"); } void err_bmt() { out("533 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); } -void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } + +/* XXX-noxa */ +void err_nogateway() { out("553 domain not local and relaying denied / Domain ist nicht lokal und Relaying nicht erlaubt / http://www.noxa.de/?faq#smtp\r\n"); } +void err_nouser() { out("550 no such account here / Account existiert nicht\r\n"); } +void err_toomany() { out("552 too many recipients / Zuviele Empfaenger\r\n"); } +void err_size() { out("552 message too big / Nachricht zu grosz\r\n"); } +void err_noop() { out("250 noopy!\r\n"); } +void err_wantmail() { out("503 no sender yet given\r\n"); } +void err_wantrcpt() { out("503 no recipient yet given\r\n"); } +void err_vrfy() { out("252 verify disabled\r\n"); } +/* End of XXX-noxa */ + #ifdef TLS void err_nogwcert() { out("553 no valid cert for gatewaying (#5.7.1)\r\n"); } #endif void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } -void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } void err_relay() { out("553 we don't relay (#5.7.1)\r\n"); } -void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } -void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } -void err_noop() { out("250 ok\r\n"); } -void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); } void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } int err_child() { out("454 oops, problem with child and I can't auth (#4.3.0)\r\n"); return -1; } @@ -185,7 +194,8 @@ } void smtp_help() { - out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); + /* XXX-noxa */ + out("214 RfC2822 is a good start\r\n"); } void smtp_quit() { @@ -288,6 +298,41 @@ stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */ + +/* ============================================================= */ +/* XXX-noxa */ +void say_toomany() +{ + enew(); eout("Too many recipients.\n"); eflush(); +} +void say_nolocaldomains() +{ + enew(); eout("Local domains file does not exist.\n"); eflush(); +} + +void say_foundlocaldomain() +{ + enew(); eout("Local domain found for <"); eout(addr.s); eout(">\n"); eflush(); +} + +void say_nolocalparts() +{ + enew(); eout("Local parts file does not exist.\n"); eflush(); +} + +void say_foundlocal() +{ + enew(); eout("Address <"); eout(addr.s); eout("> is valid.\n"); eflush(); +} + +void say_notfound() +{ + enew(); eout("Rejecting mail to <"); eout(addr.s); eout(">\n"); eflush(); +} +/* End of XXX-noxa */ +/* ============================================================= */ + + int addrparse(arg) char *arg; { @@ -438,11 +483,85 @@ return 0; } +int num_rcpts = 0; +/* ============================================================= */ +/* XXX-noxa */ +int cklocalpart(const char* s) +{ + FILE *f; + char buf[1024]; + char *p; + int i, found; + + num_rcpts++; + + if (num_rcpts > 20) { + say_toomany(); + return 2; + } + +/* VERIFY domain */ + if ((f = fopen("control/localpartsdomains", "r")) == NULL) { + say_nolocaldomains(); + return 1; + } + + p = s; + i = 0; + while (i++ < strlen(s) - 3 && *p != '@') + p++; + p++; + + found = 0; + i = 0; + while (found != 1 && fgets(buf, sizeof(buf), f) != NULL && i++ < 128) { + buf[sizeof(buf) - 1] = '\0'; + if(strlen(buf) > 1) + buf[strlen(buf) - 1] = '\0'; + if (strcasecmp(buf, p) == 0) + found = 1; + } + (void) fclose(f); + + if (found != 1) + return 1; + else + say_foundlocaldomain(); + +/* VERIFY localpart */ + if ((f = fopen("control/localparts", "r")) == NULL) { + say_nolocalparts(); + return 1; + } + + found = 0; + i = 0; + while (found != 1 && fgets(buf, sizeof(buf), f) != NULL && i++ < 8192) { + buf[sizeof(buf) - 1] = '\0'; + if(strlen(buf) > 1) + buf[strlen(buf) - 1] = '\0'; + if (strcasecmp(buf, s) == 0) + found = 1; + } + (void) fclose(f); + + if(found) + say_foundlocal(); + else + say_notfound(); + + return found; +} +/* Ende XXX-noxa */ +/* ============================================================= */ + int addrallowed() { int r; + r = rcpthosts(addr.s,str_len(addr.s)); if (r == -1) die_control(); + return r; } @@ -500,7 +619,8 @@ void smtp_rset() { seenmail = 0; - out("250 flushed\r\n"); + /* XXX-noxa */ + out("250 reset ok\r\n"); } void smtp_mail(arg) char *arg; { @@ -520,6 +640,9 @@ } #endif void smtp_rcpt(arg) char *arg; { + /* XXX-noxa */ + int noxar = 0; + if (!seenmail) { err_wantmail(); return; } if (!addrparse(arg)) { err_syntax(); return; } if (addrrelay()) { err_relay(); return; } @@ -534,6 +657,23 @@ err_bmt(); return; } + + /* XXX-noxa */ + /* RETURN LEVELS: + * 0 - no user + * 1 - ok + * 2 - too many recipients + */ + noxar = cklocalpart(addr.s); + if (noxar == 0) { + err_nouser(); + return; + } else if (noxar == 2) { + err_toomany(); + return; + } + /* End of XXX-noxa */ + if (relayclient) { --addr.len; if (!stralloc_cats(&addr,relayclient)) die_nomem(); @@ -718,7 +858,8 @@ if (databytes) bytestooverflow = databytes + 1; if (qmail_open(&qqt) == -1) { err_qqt(); return; } qp = qmail_qp(&qqt); - out("354 go ahead\r\n"); + /* XXX-noxa */ + out("354 tell me your message, when done, enter \".\" on a line by itself\r\n"); #ifdef TLS if(ssl){ if (!stralloc_copys(&protocolinfo, SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)))) die_nomem(); @@ -742,7 +883,8 @@ qqx = qmail_close(&qqt); if (!*qqx) { acceptmessage(qp); return; } if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; } - if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; } + /* XXX-noxa */ + if (databytes) if (!bytestooverflow) { err_size(); return; } if (*qqx == 'D') out("554 "); else out("451 "); out(qqx + 1); out("\r\n");