Download | Plain Text | No Line Numbers
- diff -ruN netqmail-1.05-tls-new/Makefile netqmail-1.05/Makefile
- --- Makefile 2006-04-02 17:02:34.000000000 -0400
- +++ Makefile 2006-04-02 17:09:20.000000000 -0400
- @@ -1536,19 +1536,24 @@
- auto_split.h spf.h
- ./compile qmail-showctl.c
-
- +qmail-spp.o: \
- +compile qmail-spp.c readwrite.h stralloc.h substdio.h control.h str.h \
- +byte.h env.h exit.h wait.h fork.h fd.h fmt.h getln.h
- + ./compile qmail-spp.c
- +
- qmail-smtpd: \
- load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
- timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o constmap.o \
- received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a fd.a wait.a \
- datetime.a getln.a open.a sig.a case.a env.a stralloc.a alloc.a substdio.a \
- -error.a str.a fs.a auto_qmail.o base64.o socket.lib dns.lib
- +error.a str.a fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.lib
- ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
- timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o \
- tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \
- constmap.o received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a \
- - fd.a wait.a datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
- + fd.a wait.a datetime.a getln.a open.a sig.a case.a qmail-spp.o env.a stralloc.a \
- alloc.a substdio.a error.a fs.a auto_qmail.o base64.o \
- str.a `cat socket.lib` `cat dns.lib`
-
- qmail-smtpd.0: \
- qmail-smtpd.8
- @@ -1557,7 +1562,7 @@
- qmail-smtpd.o: \
- compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
- substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
- -error.h ipme.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ip.h qmail.h \
- +error.h ipme.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ip.h qmail.h qmail-spp.h \
- substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
- exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h spf.h
- ./compile qmail-smtpd.c
- diff -ruN netqmail-1.05-tls-new/qmail-smtpd.c netqmail-1.05/qmail-smtpd.c
- --- qmail-smtpd.c 2006-04-02 17:02:34.000000000 -0400
- +++ qmail-smtpd.c 2006-04-02 17:19:33.000000000 -0400
- @@ -24,6 +24,9 @@
- #include "commands.h"
- #include "wait.h"
- #include "spf.h"
- +#include "qmail-spp.h"
- +
- +int spp_val;
-
- #define CRAM_MD5
- #define AUTHSLEEP 5
- @@ -151,6 +154,7 @@
- if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
- if (timeout <= 0) timeout = 1;
- if (rcpthosts_init() == -1) die_control();
- + if (spp_init() == -1) die_control();
-
- bmfok = control_readfile(&bmf,"control/badmailfrom",0);
- if (bmfok == -1) die_control();
- @@ -268,6 +272,7 @@
- int seenmail = 0;
- int flagbarf; /* defined if seenmail */
- int flagbarfspf;
- +int allowed;
- int flagsize;
- stralloc spfbarfmsg = {0};
- stralloc mailfrom = {0};
- @@ -335,6 +340,7 @@
-
- void smtp_helo(arg) char *arg;
- {
- + if(!spp_helo(arg)) return;
- smtp_greet("250 "); out("\r\n");
- seenmail = 0; dohelo(arg);
- }
- @@ -345,6 +351,7 @@
- #endif
- char size[FMT_ULONG];
- size[fmt_ulong(size,(unsigned int) databytes)] = 0;
- + if(!spp_helo(arg)) return;
- smtp_greet("250-");
- #ifdef TLS
- if (!ssl && (stat("control/servercert.pem",&st) == 0))
- @@ -362,6 +369,7 @@
- }
- void smtp_rset()
- {
- + spp_rset();
- seenmail = 0;
- out("250 flushed\r\n");
- }
- @@ -371,8 +379,10 @@
- flagsize = 0;
- mailfrom_parms(arg);
- if (flagsize) { err_size(); return; }
- + if (!(spp_val = spp_mail())) return;
- + flagbarfspf = 0;
- + if (spp_val == 1) {
- flagbarf = bmfcheck();
- - flagbarfspf = 0;
- if (spfbehavior && !relayclient)
- {
- switch(r = spfcheck()) {
- @@ -375,6 +384,7 @@
- }
- else
- env_unset("SPFRESULT");
- + }
- seenmail = 1;
- if (!stralloc_copys(&rcptto,"")) die_nomem();
- if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
- @@ -382,13 +392,18 @@
- if (!addrparse(arg)) { err_syntax(); return; }
- if (flagbarf) { err_bmf(); return; }
- if (flagbarfspf) { err_spf(); return; }
- + if (!relayclient) allowed = addrallowed();
- + else allowed = 1;
- + if (!(spp_val = spp_rcpt(allowed))) return;
- if (relayclient) {
- --addr.len;
- if (!stralloc_cats(&addr,relayclient)) die_nomem();
- if (!stralloc_0(&addr)) die_nomem();
- }
- - else
- - if (!addrallowed()) { err_nogateway(); return; }
- + else if (spp_val == 1) {
- + if (!allowed) { err_nogateway(); return; }
- + }
- + spp_rcpt_accepted();
- if (!stralloc_cats(&rcptto,"T")) die_nomem();
- if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
- if (!stralloc_0(&rcptto)) die_nomem();
- @@ -508,6 +523,7 @@
-
- if (!seenmail) { err_wantmail(); return; }
- if (!rcptto.len) { err_wantrcpt(); return; }
- + if (!spp_data()) return;
- seenmail = 0;
- if (databytes) bytestooverflow = databytes + 1;
- if (qmail_open(&qqt) == -1) { err_qqt(); return; }
- @@ -515,6 +531,8 @@
-
- received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
- spfreceived();
- + qmail_put(&qqt,sppheaders.s,sppheaders.len); /* set in qmail-spp.c */
- + spp_rset();
- blast(&hops);
- hops = (hops >= MAXHOPS);
- if (hops) qmail_fail(&qqt);
- @@ -738,6 +756,7 @@
-
- switch (authcmds[i].fun(arg)) {
- case 0:
- + if (!spp_auth(authcmds[i].text, user.s)) return;
- flagauth = 1;
- protocol = "ESMTPA";
- relayclient = "";
- @@ -1016,8 +1035,10 @@
- if (chdir(auto_qmail) == -1) die_control();
- setup();
- if (ipme_init() != 1) die_ipme();
- + if (spp_connect()) {
- smtp_greet("220 ");
- out(" ESMTP\r\n");
- + }
- if (commands(&ssin,&smtpcommands) == 0) die_read();
- die_nomem();
- }
- diff -ruN netqmail-1.05-tls-new/qmail-spp.c netqmail-1.05/qmail-spp.c
- --- qmail-spp.c 1969-12-31 19:00:00.000000000 -0500
- +++ qmail-spp.c 2006-04-02 17:22:52.000000000 -0400
- @@ -0,0 +1,259 @@
- +/*
- + * Copyright (C) 2004-2005 Pawel Foremski <pjf@asn.pl>
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License
- + * as published by the Free Software Foundation; either
- + * version 2 of the License, or (at your option) any later
- + * version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software Foundation,
- + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- + *
- + *** Note
- + *
- + * This is the core of qmail-spp patch for qmail
- + *
- + * Why I made it a separate file? Because I wanted qmail-spp to apply more
- + * cleanly on heavily patched qmail sources and to make it bit simpler to
- + * maintain, so don't treat it as a library.
- + *
- + * "..." comments marks places where code for other SMTP commands should be
- + * added, if needed.
- + *
- + */
- +
- +#include "readwrite.h"
- +#include "stralloc.h"
- +#include "substdio.h"
- +#include "control.h"
- +#include "str.h"
- +#include "byte.h"
- +#include "env.h"
- +#include "exit.h"
- +#include "wait.h"
- +#include "fork.h"
- +#include "fd.h"
- +#include "fmt.h"
- +#include "getln.h"
- +
- +/* stuff needed from qmail-smtpd */
- +extern void flush();
- +extern void out();
- +extern void die_nomem();
- +extern stralloc addr;
- +/* *** */
- +
- +stralloc sppheaders = {0};
- +static int spprun = 0;
- +static int sppfok = 0;
- +static int sppret;
- +static stralloc sppf = {0};
- +static stralloc plugins_dummy = {0}, plugins_connect = {0}, plugins_helo = {0}, plugins_mail = {0},
- + plugins_rcpt = {0}, plugins_data = {0}, plugins_auth = {0}; /* ... */
- +static stralloc error_mail = {0}, error_rcpt = {0}, error_data = {0}; /* ... */
- +static stralloc sppmsg = {0};
- +static char rcptcountstr[FMT_ULONG];
- +static unsigned long rcptcount;
- +static unsigned long rcptcountall;
- +static substdio ssdown;
- +static char downbuf[128];
- +
- +static void err_spp(s1, s2) char *s1, *s2; { out("451 qmail-spp failure: "); out(s1); out(": "); out(s2); out(" (#4.3.0)\r\n"); }
- +
- +int spp_init()
- +{
- + int i, len = 0;
- + stralloc *plugins_to;
- + char *x, *conffile = "control/smtpplugins";
- +
- + if (!env_get("NOSPP")) {
- + spprun = 1;
- + plugins_to = &plugins_dummy;
- + x = env_get("SPPCONFFILE");
- + if (x && *x) conffile = x;
- + sppfok = control_readfile(&sppf, conffile, 0);
- + if (sppfok != 1) return -1;
- + for (i = 0; i < sppf.len; i += len) {
- + len = str_len(sppf.s + i) + 1;
- + if (sppf.s[i] == '[')
- + switch (sppf.s[i + 1]) {
- + case 'c': plugins_to = &plugins_connect; break;
- + case 'h': plugins_to = &plugins_helo; break;
- + case 'm': plugins_to = &plugins_mail; break;
- + case 'r': plugins_to = &plugins_rcpt; break;
- + case 'd': plugins_to = &plugins_data; break;
- + case 'a': plugins_to = &plugins_auth; break;
- + /* ... */
- + default: plugins_to = &plugins_dummy;
- + }
- + else
- + if (!stralloc_catb(plugins_to, sppf.s + i, len)) die_nomem();
- + }
- + }
- +
- + return 0;
- +}
- +
- +void sppout() { if (sppmsg.len) out(sppmsg.s); out("\r\n"); }
- +
- +int spp(plugins, addrenv) stralloc *plugins; char *addrenv;
- +{
- + static int pipes[2];
- + static int i, pid, wstat, match, last;
- + static stralloc data = {0};
- + static char *(args[4]);
- + static stralloc *errors_to;
- +
- + if (!spprun) return 1;
- + if (addrenv) if (!env_put2(addrenv, addr.s)) die_nomem();
- + last = 0;
- +
- + for (i = 0; i < plugins->len; i += str_len(plugins->s + i) + 1) {
- + if (plugins->s[i] == ':')
- + { args[0] = "/bin/sh"; args[1] = "-c"; args[2] = plugins->s + i + 1; args[3] = 0; }
- + else
- + { args[0] = plugins->s + i; args[1] = 0; }
- +
- + if (pipe(pipes) == -1)
- + { err_spp(plugins->s + i, "can't pipe()"); return 0; }
- +
- + switch (pid = vfork()) {
- + case -1:
- + err_spp(plugins->s + i, "vfork() failed");
- + return 0;
- + case 0:
- + close(0); close(pipes[0]); fd_move(1, pipes[1]);
- + execv(*args, args);
- + _exit(120);
- + }
- +
- + close(pipes[1]);
- + substdio_fdbuf(&ssdown, read, pipes[0], downbuf, sizeof(downbuf));
- + do {
- + if (getln(&ssdown, &data, &match, '\n') == -1) die_nomem();
- + if (data.len > 1) {
- + data.s[data.len - 1] = 0;
- + switch (data.s[0]) {
- + case 'H':
- + if (!stralloc_catb(&sppheaders, data.s + 1, data.len - 2)) die_nomem();
- + if (!stralloc_append(&sppheaders, "\n")) die_nomem();
- + break;
- + case 'C':
- + if (addrenv) {
- + if (!stralloc_copyb(&addr, data.s + 1, data.len - 1)) die_nomem();
- + if (!env_put2(addrenv, addr.s)) die_nomem();
- + }
- + break;
- + case 'S': if (!env_put(data.s + 1)) die_nomem(); break;
- + case 'U': if (!env_unset(data.s + 1)) die_nomem(); break;
- + case 'A': spprun = 0;
- + case 'O':
- + case 'N':
- + case 'D': last = 1; match = 0; break;
- + case 'E':
- + case 'R': last = 1; match = 0;
- + case 'P': out(data.s + 1); out("\r\n"); break;
- + case 'L':
- + switch (data.s[1]) {
- + case 'M': errors_to = &error_mail; break;
- + case 'R': errors_to = &error_rcpt; break;
- + case 'D': errors_to = &error_data; break;
- + /* ... */
- + default: errors_to = 0;
- + }
- + if (errors_to) {
- + if (!stralloc_catb(errors_to, data.s + 2, data.len - 3)) die_nomem();
- + if (!stralloc_catb(errors_to, "\r\n", 2)) die_nomem();
- + }
- + break;
- + }
- + }
- + } while (match);
- +
- + close(pipes[0]);
- + if (wait_pid(&wstat,pid) == -1) { err_spp(plugins->s + i, "wait_pid() failed"); return 0; }
- + if (wait_crashed(wstat)) { err_spp(plugins->s + i, "child crashed"); return 0; }
- + if (wait_exitcode(wstat) == 120) { err_spp(plugins->s + i, "can't execute"); return 0; }
- +
- + if (last)
- + switch (*data.s) {
- + case 'E': return 0;
- + case 'A':
- + case 'N': return 1;
- + case 'O': return 2;
- + case 'R':
- + case 'D': flush(); _exit(0);
- + }
- + }
- +
- + return 1;
- +}
- +
- +int spp_errors(errors) stralloc *errors;
- +{
- + if (!errors->len) return 1;
- + if (!stralloc_0(errors)) die_nomem();
- + out(errors->s);
- + return 0;
- +}
- +
- +int spp_connect() { return spp(&plugins_connect, 0); }
- +
- +int spp_helo(arg) char *arg;
- +{
- + if (!env_put2("SMTPHELOHOST", arg)) die_nomem();
- + return spp(&plugins_helo, 0);
- +}
- +
- +void spp_rset()
- +{
- + if (!stralloc_copys(&sppheaders, "")) die_nomem();
- + if (!stralloc_copys(&error_mail, "")) die_nomem();
- + if (!stralloc_copys(&error_rcpt, "")) die_nomem();
- + if (!stralloc_copys(&error_data, "")) die_nomem();
- + /* ... */
- + rcptcount = rcptcountall = 0;
- +}
- +
- +int spp_mail()
- +{
- + if (!spp_errors(&error_mail)) return 0;
- + rcptcount = rcptcountall = 0;
- + return spp(&plugins_mail, "SMTPMAILFROM");
- +}
- +
- +int spp_rcpt(allowed) int allowed;
- +{
- + if (!spp_errors(&error_rcpt)) return 0;
- + rcptcountstr[fmt_ulong(rcptcountstr, rcptcount)] = 0;
- + if (!env_put2("SMTPRCPTCOUNT", rcptcountstr)) die_nomem();
- + rcptcountstr[fmt_ulong(rcptcountstr, ++rcptcountall)] = 0;
- + if (!env_put2("SMTPRCPTCOUNTALL", rcptcountstr)) die_nomem();
- + if (!env_put2("SMTPRCPTHOSTSOK", allowed ? "1" : "0")) die_nomem();
- + sppret = spp(&plugins_rcpt, "SMTPRCPTTO");
- + return sppret;
- +}
- +
- +void spp_rcpt_accepted() { rcptcount++; }
- +
- +int spp_data()
- +{
- + if (!spp_errors(&error_data)) return 0;
- + return spp(&plugins_data, 0);
- +}
- +
- +int spp_auth(method, user) char *method, *user;
- +{
- + if (!env_put2("SMTPAUTHMETHOD", method)) die_nomem();
- + if (!env_put2("SMTPAUTHUSER", user)) die_nomem();
- + return spp(&plugins_auth, 0);
- +}
- +
- +/* ... */
- diff -ruN netqmail-1.05-tls-new/qmail-spp.h netqmail-1.05/qmail-spp.h
- --- qmail-spp.h 1969-12-31 19:00:00.000000000 -0500
- +++ qmail-spp.h 2006-04-02 17:23:10.000000000 -0400
- @@ -0,0 +1,14 @@
- +#ifndef QMAIL_SPP_H
- +#define QMAIL_SPP_H
- +
- +extern stralloc sppheaders;
- +extern int spp_init();
- +extern int spp_connect();
- +extern int spp_helo();
- +extern void spp_rset();
- +extern int spp_mail();
- +extern int spp_rcpt();
- +extern int spp_data();
- +extern int spp_auth();
- +
- +#endif
-