[Qmail-it] Convivenza patch (dnsbl+chkuser+smtpauth..)

Fabio Busatto fabio.busatto at sikurezza.org
Wed Apr 4 10:56:32 CEST 2007


Eccola qui, versione di test e non integrata ancora in niente.
Ma come ovviamente predico da anni, dovrebbe essere meno invasiva
possibile, seppure con un occhio alle performance, quindi non
dovreste avere problemi a integrarla a mano.
Penso che a breve rilascero` comunque una patch combo con tutte
quelle che uso, in attesa del progetto che purtroppo ora non ho
ancora il tempo di seguire.

Spiegata brevemente funziona cosi`: quando uno fa un RCPT viene
invocato un helper esterno, al quale viene passato come unico
argomento l'indirizzo email da controllare.
Se l'helper (che puo` essere un programma qualsiasi, viene in
ogni caso invocata una shell quindi vanno bene anche script)
ritorna un valore uguale a 0 allora l'indirizzo e` valido, in
caso contrario viene rifiutato.
L'helper va indicato in control/rcptcheck, e puo` venire letto
con qmail-showctl.

Un esempio di helper, che deve chiaramente girare con i permessi
corretti per leggere i database degli utenti, potrebbe essere:

#!/bin/sh
/home/vpopmail/bin/vuserinfo -n $1 >/dev/null 2>&1 && exit 0
/home/vpopmail/bin/valias $1 >/dev/null 2>&1 && exit 0
exit 1

Immagino che qualcuno possa storcere il naso al pensiero di
dover usare un helper, ma e` l'unico modo per permettere la massima
flessibilita` (non tutti usano vpopmail).
Ovviamente poi l'idea e` di creare un helper (magari in c e che supporti
i piu` comuni sistemi di autenticazione usati con qmail).

Fatemi sapere cosa ne pensate :)
Ciao
Fabio
-- 
Fabio Busatto <fabio.busatto at sikurezza.org>
-------------- next part --------------
diff -uNr netqmail-1.05-orig/qmail-showctl.c netqmail-1.05/qmail-showctl.c
--- netqmail-1.05-orig/qmail-showctl.c	1998-06-15 12:53:16.000000000 +0200
+++ netqmail-1.05/qmail-showctl.c	2007-04-03 11:59:12.000000000 +0200
@@ -234,6 +234,7 @@
   do_str("plusdomain",1,"plusdomain","Plus domain name is ");
   do_lst("qmqpservers","No QMQP servers.","QMQP server: ",".");
   do_int("queuelifetime","604800","Message lifetime in the queue is "," seconds");
+  do_str("rcptcheck",0,"disabled","Recipient check helper is ");
 
   if (do_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ","."))
     do_lst("morercpthosts","No effect.","SMTP clients may send messages to recipients at ",".");
@@ -289,6 +290,7 @@
     if (str_equal(d->d_name,"plusdomain")) continue;
     if (str_equal(d->d_name,"qmqpservers")) continue;
     if (str_equal(d->d_name,"queuelifetime")) continue;
+    if (str_equal(d->d_name,"rcptcheck")) continue;
     if (str_equal(d->d_name,"rcpthosts")) continue;
     if (str_equal(d->d_name,"smtpgreeting")) continue;
     if (str_equal(d->d_name,"smtproutes")) continue;
diff -uNr netqmail-1.05-orig/qmail-smtpd.c netqmail-1.05/qmail-smtpd.c
--- netqmail-1.05-orig/qmail-smtpd.c	2007-04-03 10:17:30.000000000 +0200
+++ netqmail-1.05/qmail-smtpd.c	2007-04-04 10:39:29.000000000 +0200
@@ -23,6 +23,7 @@
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
+#include "wait.h"
 
 #define MAXHOPS 100
 unsigned int databytes = 0;
@@ -58,6 +59,7 @@
 void err_noop(arg) char *arg; { out("250 ok\r\n"); }
 void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); }
 void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
+void err_rcptcheck() { out("553 sorry, no mailbox here by that name (#5.1.1)\r\n"); }
 
 
 stralloc greeting = {0};
@@ -95,6 +97,9 @@
 stralloc liphost = {0};
 int bmfok = 0;
 stralloc bmf = {0};
+int rcptcheckok = 0;
+stralloc rcptcheckhelper = {0};
+
 struct constmap mapbmf;
 
 void setup()
@@ -121,6 +126,9 @@
   x = env_get("DATABYTES");
   if (x) { scan_ulong(x,&u); databytes = u; }
   if (!(databytes + 1)) --databytes;
+
+  rcptcheckok = control_readline(&rcptcheckhelper,"control/rcptcheck");
+  if (rcptcheckok == -1) die_control();
  
   remoteip = env_get("TCPREMOTEIP");
   if (!remoteip) remoteip = "unknown";
@@ -216,6 +224,36 @@
   return r;
 }
 
+int rcptcheck()
+{
+ int child;
+ char *(args[4]);
+ int wstat;
+ stralloc rcptchecktmp = {0};
+
+ if (!addr.s[0]) return 1;
+ 
+ switch(child = fork())
+  {
+   case -1:
+     return 0;
+   case 0:
+     if (!stralloc_copys(&rcptchecktmp,"")) die_nomem();
+     if (!stralloc_copy(&rcptchecktmp, &rcptcheckhelper)) die_nomem();
+     if (!stralloc_cats(&rcptchecktmp, " ")) die_nomem();
+     if (!stralloc_cat(&rcptchecktmp, &addr)) die_nomem();
+     if (!stralloc_0(&rcptchecktmp)) die_nomem();
+     args[0] = "/bin/sh";
+     args[1] = "-c";
+     args[2] = rcptchecktmp.s;
+     args[3] = 0;
+     execv(*args,args);
+     _exit(1);
+  }
+
+  wait_pid(&wstat,child);
+  return wait_exitcode(wstat);
+}
 
 int seenmail = 0;
 int flagbarf; /* defined if seenmail */
@@ -256,8 +294,10 @@
     if (!stralloc_cats(&addr,relayclient)) die_nomem();
     if (!stralloc_0(&addr)) die_nomem();
   }
-  else
+  else {
     if (!addrallowed()) { err_nogateway(); return; }
+    if (rcptcheckok) if(rcptcheck()) { err_rcptcheck(); return; }
+  }
   if (!stralloc_cats(&rcptto,"T")) die_nomem();
   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
   if (!stralloc_0(&rcptto)) die_nomem();


More information about the Qmail-it mailing list