summaryrefslogtreecommitdiffstats
path: root/qmail-smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-smtpd.c')
-rw-r--r--qmail-smtpd.c99
1 files changed, 88 insertions, 11 deletions
diff --git a/qmail-smtpd.c b/qmail-smtpd.c
index 86c5bd9..4466168 100644
--- a/qmail-smtpd.c
+++ b/qmail-smtpd.c
@@ -26,6 +26,7 @@
26#include "wait.h" 26#include "wait.h"
27#include "qregex.h" 27#include "qregex.h"
28#include "strerr.h" 28#include "strerr.h"
29#include "cdb.h"
29 30
30#define BMCHECK_BMF 0 31#define BMCHECK_BMF 0
31#define BMCHECK_BMFNR 1 32#define BMCHECK_BMFNR 1
@@ -42,6 +43,12 @@ int timeout = 1200;
42 43
43const char *protocol = "SMTP"; 44const char *protocol = "SMTP";
44 45
46char *remoteip;
47char *remotehost;
48char *remoteinfo;
49char *local;
50char *relayclient;
51
45#ifdef TLS 52#ifdef TLS
46#include <sys/stat.h> 53#include <sys/stat.h>
47#include "tls.h" 54#include "tls.h"
@@ -69,19 +76,52 @@ int safewrite(fd,buf,len) int fd; char *buf; int len;
69char ssoutbuf[512]; 76char ssoutbuf[512];
70substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); 77substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf);
71 78
79/* write errors to stderr */
80char erroutbuf[512];
81substdio errout = SUBSTDIO_FDBUF(safewrite,2,erroutbuf,sizeof erroutbuf);
82
72void flush() { substdio_flush(&ssout); } 83void flush() { substdio_flush(&ssout); }
73void out(s) char *s; { substdio_puts(&ssout,s); } 84void out(s) char *s; { substdio_puts(&ssout,s); }
74 85
86void eflush() { substdio_flush(&errout); }
87void eout(s) char *s; { substdio_puts(&errout,s); }
88void enew() { substdio_puts(&errout,"qmail-smtpd: "); }
89
75void die_read() { _exit(1); } 90void die_read() { _exit(1); }
76void die_alarm() { out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1); } 91
77void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); } 92void die_alarm()
78void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); } 93{
79void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); } 94 enew(); eout("Connection to "); eout(remoteip); eout(" timed out.\n");
80void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } 95 out("451 timeout (#4.4.2)\r\n"); flush(); eflush(); _exit(1);
96}
97void die_nomem()
98{
99 enew(); eout("Out of memory while connected to "); eout(remoteip); eout("!\n");
100 out("421 out of memory (#4.3.0)\r\n"); flush(); eflush(); _exit(1);
101}
102void die_control()
103{
104 enew(); eout("Unable to read controls!\n");
105 out("421 unable to read controls (#4.3.0)\r\n"); flush(); eflush();
106 _exit(1);
107}
108void die_ipme()
109{
110 enew(); eout("Unable to figure out my IP addresses!\n");
111 out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush();
112 eflush(); _exit(1);
113}
114void straynewline()
115{
116 enew(); eout("Stray newline from "); eout(remoteip); eout(".\n");
117 out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush();
118 eflush(); _exit(1);
119}
81 120
82void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } 121void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); }
83void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); } 122void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); }
84void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); } 123void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); }
124void err_brt() { out("550 sorry, this message is not deliverable (#5.7.1)\r\n"); }
85void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); } 125void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); }
86#ifndef TLS 126#ifndef TLS
87void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } 127void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
@@ -129,12 +169,6 @@ void smtp_quit()
129 smtp_greet("221 "); out("\r\n"); flush(); _exit(0); 169 smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
130} 170}
131 171
132char *remoteip;
133char *remotehost;
134char *remoteinfo;
135char *local;
136char *relayclient;
137
138stralloc helohost = {0}; 172stralloc helohost = {0};
139char *fakehelo; /* pointer into helohost, or 0 */ 173char *fakehelo; /* pointer into helohost, or 0 */
140 174
@@ -159,6 +193,11 @@ stralloc bmt = {0};
159int bmtnrok = 0; 193int bmtnrok = 0;
160stralloc bmtnr = {0}; 194stralloc bmtnr = {0};
161 195
196int brtok = 0;
197stralloc brt = {0};
198struct constmap mapbrt;
199int fdmbrt;
200
162int bhelook = 0; 201int bhelook = 0;
163stralloc bhelo = {0}; 202stralloc bhelo = {0};
164 203
@@ -197,6 +236,17 @@ void setup()
197 236
198 if (env_get("LOGREGEX")) logregex = 1; 237 if (env_get("LOGREGEX")) logregex = 1;
199 238
239
240 brtok = control_readfile(&brt,"control/badrcptto",0);
241 if (brtok == -1) die_control();
242 if (brtok)
243 if (!constmap_init(&mapbrt,brt.s,brt.len,0)) die_nomem();
244
245 fdmbrt = open_read("control/morebadrcptto.cdb");
246 if (fdmbrt == -1) if (errno != error_noent) die_control();
247
248
249
200 if (control_readint(&databytes,"control/databytes") == -1) die_control(); 250 if (control_readint(&databytes,"control/databytes") == -1) die_control();
201 x = env_get("DATABYTES"); 251 x = env_get("DATABYTES");
202 if (x) { scan_ulong(x,&u); databytes = u; } 252 if (x) { scan_ulong(x,&u); databytes = u; }
@@ -282,6 +332,14 @@ char *arg;
282 return 1; 332 return 1;
283} 333}
284 334
335static void log_deny(m,f,t) char *m,*f,*t;
336{
337 enew(); eout(m); eout(" check failed ("); eout(f); eout(") -> (");
338 eout(t); eout(") ["); eout(remoteip); eout("] (HELO ");
339 eout(helohost.s); eout(")\n");
340 eflush();
341}
342
285int bmcheck(which) int which; 343int bmcheck(which) int which;
286{ 344{
287 int i = 0; 345 int i = 0;
@@ -335,6 +393,19 @@ int bmcheck(which) int which;
335 return 0; 393 return 0;
336} 394}
337 395
396int brtcheck()
397{
398 int j;
399 if (brtok) if (constmap(&mapbrt,addr.s,addr.len - 1)) return 1;
400 if (fdmbrt != -1) {
401 uint32 dlen;
402 j = cdb_seek(fdmbrt, addr.s, addr.len - 1, &dlen);
403 if (j == -1) die_control();
404 if (j) return j;
405 }
406 return 0;
407}
408
338int addrallowed() 409int addrallowed()
339{ 410{
340 int r; 411 int r;
@@ -364,6 +435,7 @@ int addrrelay()
364int seenmail = 0; 435int seenmail = 0;
365int flagbarfbmf; /* defined if seenmail */ 436int flagbarfbmf; /* defined if seenmail */
366int flagbarfbmt; 437int flagbarfbmt;
438int flagbrt; /* defined if any bad rcpts */
367int flagbarfbhelo; 439int flagbarfbhelo;
368int flagsize; 440int flagsize;
369stralloc mailfrom = {0}; 441stralloc mailfrom = {0};
@@ -523,6 +595,10 @@ void smtp_rcpt(arg) char *arg; {
523 } 595 }
524 else 596 else
525 if (!addrallowed()) { err_nogateway(); return; } 597 if (!addrallowed()) { err_nogateway(); return; }
598 if (!env_get("RELAYCLIENT") && brtcheck()) {
599 flagbrt = 1;
600 log_deny("BAD RCPT TO", mailfrom.s,addr.s);
601 }
526 if (!stralloc_cats(&rcptto,"T")) die_nomem(); 602 if (!stralloc_cats(&rcptto,"T")) die_nomem();
527 if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); 603 if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
528 if (!stralloc_0(&rcptto)) die_nomem(); 604 if (!stralloc_0(&rcptto)) die_nomem();
@@ -642,6 +718,7 @@ void smtp_data() {
642 718
643 if (!seenmail) { err_wantmail(); return; } 719 if (!seenmail) { err_wantmail(); return; }
644 if (!rcptto.len) { err_wantrcpt(); return; } 720 if (!rcptto.len) { err_wantrcpt(); return; }
721 if (flagbrt) { err_brt(); return; }
645 seenmail = 0; 722 seenmail = 0;
646 if (databytes) bytestooverflow = databytes + 1; 723 if (databytes) bytestooverflow = databytes + 1;
647 if (qmail_open(&qqt) == -1) { err_qqt(); return; } 724 if (qmail_open(&qqt) == -1) { err_qqt(); return; }