Merge branch 'mdw/relayhosts'
authorMark Wooding <mdw@distorted.org.uk>
Tue, 14 Feb 2006 02:52:33 +0000 (02:52 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 14 Feb 2006 02:52:33 +0000 (02:52 +0000)
* mdw/relayhosts:
  qmail-smtpd: Read list of hosts allowed to relay from control/relayhosts

Conflicts:

qmail-control.9
qmail-showctl.c
qmail-smtpd.c

1  2 
qmail-control.9
qmail-showctl.c
qmail-smtpd.8
qmail-smtpd.c

diff --cc qmail-control.9
@@@ -55,12 -53,12 +55,13 @@@ control    default used b
  .I idhost     \fIme   \fRqmail-inject
  .I localiphost        \fIme   \fRqmail-smtpd
  .I locals     \fIme   \fRqmail-send
 +.I morercpthosts      \fR(none)       \fRqmail-smtpd
  .I percenthack        \fR(none)       \fRqmail-send
  .I plusdomain \fIme   \fRqmail-inject
 +.I qmqpservers        \fR(none)       \fRqmail-qmqpc
  .I queuelifetime      \fR604800       \fRqmail-send
  .I rcpthosts  \fR(none)       \fRqmail-smtpd
 -.I recipientmap       \fR(none)       \fRqmail-send
+ .I relayhosts \fR(none)       \fRqmail-smtpd
  .I smtpgreeting       \fIme   \fRqmail-smtpd
  .I smtproutes \fR(none)       \fRqmail-remote
  .I timeoutconnect     \fR60   \fRqmail-remote
diff --cc qmail-showctl.c
@@@ -232,29 -182,10 +232,30 @@@ void main(
    do_str("me",0,"undefined! Uh-oh","My name is ");
    do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@",".");
    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_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ",".");
 -  do_lst("recipientmap","No redirections.","Redirection: ","");
 +
 +  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 ",".");
 +  else
 +    do_lst("morercpthosts","No rcpthosts; morercpthosts is irrelevant.","No rcpthosts; doesn't matter that morercpthosts has ",".");
 +  /* XXX: check morercpthosts.cdb contents */
 +  substdio_puts(subfdout,"\nmorercpthosts.cdb: ");
 +  if (stat("morercpthosts",&stmrh) == -1)
 +    if (stat("morercpthosts.cdb",&stmrhcdb) == -1)
 +      substdio_puts(subfdout,"(Default.) No effect.\n");
 +    else
 +      substdio_puts(subfdout,"Oops! morercpthosts.cdb exists but morercpthosts doesn't.\n");
 +  else
 +    if (stat("morercpthosts.cdb",&stmrhcdb) == -1)
 +      substdio_puts(subfdout,"Oops! morercpthosts exists but morercpthosts.cdb doesn't.\n");
 +    else
 +      if (stmrh.st_mtime > stmrhcdb.st_mtime)
 +        substdio_puts(subfdout,"Oops! morercpthosts.cdb is older than morercpthosts.\n");
 +      else
 +        substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
 +
+   do_lst("relayhosts","No relayhosts","Relay host: ","");
    do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
    do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
    do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
      if (str_equal(d->d_name,"localiphost")) continue;
      if (str_equal(d->d_name,"locals")) continue;
      if (str_equal(d->d_name,"me")) continue;
 +    if (str_equal(d->d_name,"morercpthosts")) continue;
 +    if (str_equal(d->d_name,"morercpthosts.cdb")) continue;
      if (str_equal(d->d_name,"percenthack")) continue;
      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,"rcpthosts")) continue;
 -    if (str_equal(d->d_name,"recipientmap")) continue;
+     if (str_equal(d->d_name,"relayhosts")) continue;
      if (str_equal(d->d_name,"smtpgreeting")) continue;
      if (str_equal(d->d_name,"smtproutes")) continue;
      if (str_equal(d->d_name,"timeoutconnect")) continue;
diff --cc qmail-smtpd.8
Simple merge
diff --cc qmail-smtpd.c
@@@ -82,61 -75,114 +82,86 @@@ char *remoteinfo
  char *local;
  char *relayclient;
  
 -void dohelo(arg) char *arg;
 -{
 - if (!stralloc_copys(&helohost,arg)) outofmem(); 
 - if (!stralloc_0(&helohost)) outofmem(); 
 -}
 +stralloc helohost = {0};
 +char *fakehelo; /* pointer into helohost, or 0 */
  
 -void getenvs()
 -{
 - remoteip = env_get("TCPREMOTEIP");
 - if (!remoteip) remoteip = "unknown";
 - local = env_get("TCPLOCALHOST");
 - if (!local) local = env_get("TCPLOCALIP");
 - if (!local) local = "unknown";
 - remotehost = env_get("TCPREMOTEHOST");
 - if (!remotehost) remotehost = "unknown";
 - remoteinfo = env_get("TCPREMOTEINFO");
 - relayclient = env_get("RELAYCLIENT");
 - if (!relayclient && relayhostsok) {
 -   int j;
 -   int l = str_len(remotehost);
 -   relayclient = constmap(&maprelayhosts, remotehost, l);
 -   if (!relayclient) for (j = 0; j < l; ++j) {
 -     if (remotehost[j] == '.' &&
 -       (relayclient = constmap(&maprelayhosts,
 -                               remotehost + j,
 -                               l - j)) != 0)
 -       break;
 -   }
 - }
 - dohelo(remotehost);
 +void dohelo(arg) char *arg; {
 +  if (!stralloc_copys(&helohost,arg)) die_nomem(); 
 +  if (!stralloc_0(&helohost)) die_nomem(); 
 +  fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0;
  }
  
 -void straynewline()
 -{
 - out("451 \
 -Put ,E=\\r\\n at the end of Mether, Mtcp, or Msmtp in sendmail.cf \
 -if you are using Solaris 2.5 (fixed in 2.5.1). \
 -I cannot accept messages with stray newlines. \
 -Many SMTP servers will time out waiting for \\r\\n.\\r\\n.\
 -\r\n");
 - die();
 -}
 +int liphostok = 0;
 +stralloc liphost = {0};
++int relayhostsok = 0;
++stralloc relayhosts = {0};
++struct constmap maprelayhosts;
 +int bmfok = 0;
 +stralloc bmf = {0};
 +struct constmap mapbmf;
  
 -void blast(ssfrom,hops)
 -substdio *ssfrom;
 -int *hops;
 +void setup()
  {
 - char ch;
 - int state;
 - int flaginheader;
 - int pos; /* number of bytes since most recent \n, if fih */
 - int flagmaybex; /* 1 if this line might match RECEIVED, if fih */
 - int flagmaybey; /* 1 if this line might match \r\n, if fih */
 - int flagmaybez; /* 1 if this line might match DELIVERED, if fih */
 -
 - state = 1;
 - *hops = 0;
 - flaginheader = 1;
 - pos = 0; flagmaybex = flagmaybey = flagmaybez = 1;
 - for (;;)
 -  {
 -   if (substdio_get(ssfrom,&ch,1) <= 0) die();
 -   if (flaginheader)
 -    {
 -     if (pos < 9)
 -      {
 -       if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
 -       if (flagmaybez) if (pos == 8) ++*hops;
 -       if (pos < 8)
 -         if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0;
 -       if (flagmaybex) if (pos == 7) ++*hops;
 -       if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
 -       if (flagmaybey) if (pos == 1) flaginheader = 0;
 -      }
 -     ++pos;
 -     if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
 -    }
 -   switch(state)
 -    {
 -     case 0:
 -       if (ch == '\n') straynewline();
 -       if (ch == '\r') { state = 4; continue; }
 -       break;
 -     case 1: /* \r\n */
 -       if (ch == '\n') straynewline();
 -       if (ch == '.') { state = 2; continue; }
 -       if (ch == '\r') { state = 4; continue; }
 -       state = 0;
 -       break;
 -     case 2: /* \r\n + . */
 -       if (ch == '\n') straynewline();
 -       if (ch == '\r') { state = 3; continue; }
 -       state = 0;
 -       break;
 -     case 3: /* \r\n + .\r */
 -       if (ch == '\n') return;
 -       qmail_put(&qqt,".\r",2);
 -       if (ch == '\r') { state = 4; continue; }
 -       state = 0;
 -       break;
 -     case 4: /* + \r */
 -       if (ch == '\n') { state = 1; break; }
 -       if (ch != '\r') { qmail_put(&qqt,"\r",1); state = 0; }
 +  char *x;
 +  unsigned long u;
 + 
 +  if (control_init() == -1) die_control();
 +  if (control_rldef(&greeting,"control/smtpgreeting",1,(char *) 0) != 1)
 +    die_control();
 +  liphostok = control_rldef(&liphost,"control/localiphost",1,(char *) 0);
 +  if (liphostok == -1) die_control();
 +  if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
 +  if (timeout <= 0) timeout = 1;
 +
 +  if (rcpthosts_init() == -1) die_control();
 +
 +  bmfok = control_readfile(&bmf,"control/badmailfrom",0);
 +  if (bmfok == -1) die_control();
 +  if (bmfok)
 +    if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
++
++  switch (control_readfile(&relayhosts, "control/relayhosts", 0)) {
++    case -1:
++      die_control();
++    case 1:
++      relayhostsok = 1;
++      if (!constmap_init(&maprelayhosts, relayhosts.s, relayhosts.len, 1))
++      die_nomem();
++  }
++
 + 
 +  if (control_readint(&databytes,"control/databytes") == -1) die_control();
 +  x = env_get("DATABYTES");
 +  if (x) { scan_ulong(x,&u); databytes = u; }
 +  if (!(databytes + 1)) --databytes;
 + 
 +  remoteip = env_get("TCPREMOTEIP");
 +  if (!remoteip) remoteip = "unknown";
 +  local = env_get("TCPLOCALHOST");
 +  if (!local) local = env_get("TCPLOCALIP");
 +  if (!local) local = "unknown";
 +  remotehost = env_get("TCPREMOTEHOST");
 +  if (!remotehost) remotehost = "unknown";
 +  remoteinfo = env_get("TCPREMOTEINFO");
 +  relayclient = env_get("RELAYCLIENT");
++  if (!relayclient && relayhostsok) {
++    int j;
++    int l = str_len(remotehost);
++    relayclient = constmap(&maprelayhosts, remotehost, l);
++    if (!relayclient) for (j = 0; j < l; ++j) {
++      if (remotehost[j] == '.' &&
++       (relayclient = constmap(&maprelayhosts,
++                               remotehost + j,
++                               l - j)) != 0)
++      break;
+     }
 -   qmail_put(&qqt,&ch,1);
+   }
 +  dohelo(remotehost);
  }
  
 +
 +stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */
 +
  int addrparse(arg)
  char *arg;
  {