--- orig-qmail-smtpd.c 1998-06-15 03:53:16.000000000 -0700 +++ qmail-smtpd.c 2009-09-02 14:28:33.000000000 -0700 @@ -21,15 +21,21 @@ #include "exit.h" #include "rcpthosts.h" #include "timeoutread.h" #include "timeoutwrite.h" #include "commands.h" +#include +#include +#include +#include #define MAXHOPS 100 unsigned int databytes = 0; int timeout = 1200; +char *addrcheckprog = 0; + int safewrite(fd,buf,len) int fd; char *buf; int len; { int r; r = timeoutwrite(timeout,fd,buf,len); if (r <= 0) _exit(1); @@ -47,10 +53,11 @@ void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); } void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); } void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); } void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } +void err_badpair() { out("553 sorry, I don't accept mail from/to your specified addresses (#5.7.1)\r\n"); } void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#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"); } void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } @@ -220,10 +227,31 @@ int seenmail = 0; int flagbarf; /* defined if seenmail */ stralloc mailfrom = {0}; stralloc rcptto = {0}; +int addrchecker() +{ + pid_t p,r; + int status; + + if (!addrcheckprog) return 1; + p=fork(); + if(-1==p) return -1; + if(!p) { + if (!stralloc_0(&addr)) die_nomem(); + execl(addrcheckprog,addrcheckprog,mailfrom.s,addr.s,0); + exit(-1); + } + r=waitpid(p,&status,0); + if (p != r) return -1; + if (!WIFEXITED(status)) return -1; + if (0==WEXITSTATUS(status)) return 1; + if (100==WEXITSTATUS(status)) return 0; + return -1; +} + void smtp_helo(arg) char *arg; { smtp_greet("250 "); out("\r\n"); seenmail = 0; dohelo(arg); } @@ -254,12 +282,14 @@ if (relayclient) { --addr.len; if (!stralloc_cats(&addr,relayclient)) die_nomem(); if (!stralloc_0(&addr)) die_nomem(); } - else + else { if (!addrallowed()) { err_nogateway(); return; } + if (!addrchecker()) { err_badpair(); return; } + } if (!stralloc_cats(&rcptto,"T")) die_nomem(); if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); if (!stralloc_0(&rcptto)) die_nomem(); out("250 ok\r\n"); } @@ -406,12 +436,15 @@ , { "noop", err_noop, flush } , { "vrfy", err_vrfy, flush } , { 0, err_unimpl, flush } } ; -void main() +void main(argc,argv) +int argc; +char *argv[]; { + if(2==argc) addrcheckprog=argv[1]; sig_pipeignore(); if (chdir(auto_qmail) == -1) die_control(); setup(); if (ipme_init() != 1) die_ipme(); smtp_greet("220 ");