1 diff -u --new-file qmail-1.03-orig/Makefile qmail-1.03/Makefile
2 --- qmail-1.03-orig/Makefile 2006-03-21 19:04:21.000000000 -0300
3 +++ qmail-1.03/Makefile 2006-03-21 19:07:54.000000000 -0300
4 @@ -1549,16 +1549,21 @@
6 ./compile qmail-showctl.c
9 +compile qmail-spp.c readwrite.h stralloc.h substdio.h control.h str.h \
10 +byte.h env.h exit.h wait.h fork.h fd.h fmt.h getln.h
11 + ./compile qmail-spp.c
14 load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
15 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
17 date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
18 open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \
19 -fs.a auto_qmail.o base64.o socket.lib
20 +fs.a auto_qmail.o base64.o qmail-spp.o socket.lib
21 ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
22 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
24 + ucspitls.o qmail-spp.o \
25 received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
26 datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
27 alloc.a substdio.a error.a str.a fs.a auto_qmail.o base64.o `cat \
29 substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
30 error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
31 substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
32 -exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h
33 +exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h qmail-spp.h
34 ./compile qmail-smtpd.c
37 Subdirectorios comunes: qmail-1.03-orig/qmail-rhinit y qmail-1.03/qmail-rhinit
38 diff -u --new-file qmail-1.03-orig/qmail-smtpd.c qmail-1.03/qmail-smtpd.c
39 --- qmail-1.03-orig/qmail-smtpd.c 2006-03-21 19:04:21.000000000 -0300
40 +++ qmail-1.03/qmail-smtpd.c 2006-03-21 19:13:22.000000000 -0300
45 +#include "qmail-spp.h"
52 if (timeout <= 0) timeout = 1;
54 if (rcpthosts_init() == -1) die_control();
55 + if (spp_init() == -1) die_control();
57 bmfok = control_readfile(&bmf,"control/badmailfrom",0);
58 if (bmfok == -1) die_control();
62 int flagbarf; /* defined if seenmail */
65 stralloc mailfrom = {0};
66 stralloc rcptto = {0};
69 void smtp_helo(arg) char *arg;
71 + if(!spp_helo(arg)) return;
72 smtp_greet("250 "); out("\r\n");
73 seenmail = 0; dohelo(arg);
75 void smtp_ehlo(arg) char *arg;
78 + if(!spp_helo(arg)) return;
80 size[fmt_ulong(size,(unsigned int) databytes)] = 0;
88 out("250 flushed\r\n");
90 void smtp_mail(arg) char *arg;
92 if (!addrparse(arg)) { err_syntax(); return; }
93 + if (!(spp_val = spp_mail())) return;
97 if (flagsize) { err_size(); return; }
99 if (!seenmail) { err_wantmail(); return; }
100 if (!addrparse(arg)) { err_syntax(); return; }
101 if (flagbarf) { err_bmf(); return; }
102 + if (!relayclient) allowed = addrallowed();
103 + if (!(spp_val = spp_rcpt(addrallowed()))) return;
104 + if (spp_val == 1) {
107 if (!stralloc_cats(&addr,relayclient)) die_nomem();
108 if (!stralloc_0(&addr)) die_nomem();
111 - if (!addrallowed()) { err_nogateway(); return; }
112 + if (!allowed) { err_nogateway(); return; }
114 + spp_rcpt_accepted();
115 if (!stralloc_cats(&rcptto,"T")) die_nomem();
116 if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
117 if (!stralloc_0(&rcptto)) die_nomem();
120 if (!seenmail) { err_wantmail(); return; }
121 if (!rcptto.len) { err_wantrcpt(); return; }
122 + if (!spp_data()) return;
124 if (databytes) bytestooverflow = databytes + 1;
125 if (qmail_open(&qqt) == -1) { err_qqt(); return; }
127 out("354 go ahead\r\n");
129 received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
130 + qmail_put(&qqt,sppheaders.s,sppheaders.len); /* set in qmail-spp.c */
133 hops = (hops >= MAXHOPS);
134 if (hops) qmail_fail(&qqt);
137 switch (authcmds[i].fun(arg)) {
139 + if (!spp_auth(authcmds[i].text, user.s)) return;
144 if (chdir(auto_qmail) == -1) die_control();
146 if (ipme_init() != 1) die_ipme();
147 - tls_available = !!env_get("UCSPITLS");
148 - smtp_greet("220 ");
150 + if (spp_connect()) {
151 + tls_available = !!env_get("UCSPITLS");
152 + smtp_greet("220 ");
155 if (commands(&ssin,&smtpcommands) == 0) die_read();
158 diff -u --new-file qmail-1.03-orig/qmail-spp.c qmail-1.03/qmail-spp.c
159 --- qmail-1.03-orig/qmail-spp.c 1969-12-31 21:00:00.000000000 -0300
160 +++ qmail-1.03/qmail-spp.c 2006-03-21 19:13:48.000000000 -0300
163 + * Copyright (C) 2004-2005 Pawel Foremski <pjf@asn.pl>
165 + * This program is free software; you can redistribute it and/or
166 + * modify it under the terms of the GNU General Public License
167 + * as published by the Free Software Foundation; either
168 + * version 2 of the License, or (at your option) any later
171 + * This program is distributed in the hope that it will be useful,
172 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
173 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
174 + * GNU General Public License for more details.
176 + * You should have received a copy of the GNU General Public License
177 + * along with this program; if not, write to the Free Software Foundation,
178 + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
182 + * This is the core of qmail-spp patch for qmail
184 + * Why I made it a separate file? Because I wanted qmail-spp to apply more
185 + * cleanly on heavily patched qmail sources and to make it bit simpler to
186 + * maintain, so don't treat it as a library.
188 + * "..." comments marks places where code for other SMTP commands should be
189 + * added, if needed.
193 +#include "readwrite.h"
194 +#include "stralloc.h"
195 +#include "substdio.h"
196 +#include "control.h"
207 +/* stuff needed from qmail-smtpd */
208 +extern void flush();
210 +extern void die_nomem();
211 +extern stralloc addr;
214 +stralloc sppheaders = {0};
215 +static int spprun = 0;
216 +static int sppfok = 0;
218 +static stralloc sppf = {0};
219 +static stralloc plugins_dummy = {0}, plugins_connect = {0}, plugins_helo = {0}, plugins_mail = {0},
220 + plugins_rcpt = {0}, plugins_data = {0}, plugins_auth = {0}; /* ... */
221 +static stralloc error_mail = {0}, error_rcpt = {0}, error_data = {0}; /* ... */
222 +static stralloc sppmsg = {0};
223 +static char rcptcountstr[FMT_ULONG];
224 +static unsigned long rcptcount;
225 +static substdio ssdown;
226 +static char downbuf[128];
228 +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"); }
233 + stralloc *plugins_to;
234 + char *x, *conffile = "control/smtpplugins";
236 + if (!env_get("NOSPP")) {
238 + plugins_to = &plugins_dummy;
239 + x = env_get("SPPCONFFILE");
240 + if (x && *x) conffile = x;
241 + sppfok = control_readfile(&sppf, conffile, 0);
242 + if (sppfok != 1) return -1;
243 + for (i = 0; i < sppf.len; i += len) {
244 + len = str_len(sppf.s + i) + 1;
245 + if (sppf.s[i] == '[')
246 + switch (sppf.s[i + 1]) {
247 + case 'c': plugins_to = &plugins_connect; break;
248 + case 'h': plugins_to = &plugins_helo; break;
249 + case 'm': plugins_to = &plugins_mail; break;
250 + case 'r': plugins_to = &plugins_rcpt; break;
251 + case 'd': plugins_to = &plugins_data; break;
252 + case 'a': plugins_to = &plugins_auth; break;
254 + default: plugins_to = &plugins_dummy;
257 + if (!stralloc_catb(plugins_to, sppf.s + i, len)) die_nomem();
264 +void sppout() { if (sppmsg.len) out(sppmsg.s); out("\r\n"); }
266 +int spp(plugins, addrenv) stralloc *plugins; char *addrenv;
268 + static int pipes[2];
269 + static int i, pid, wstat, match, last;
270 + static stralloc data = {0};
271 + static char *(args[4]);
272 + static stralloc *errors_to;
274 + if (!spprun) return 1;
275 + if (addrenv) if (!env_put2(addrenv, addr.s)) die_nomem();
278 + for (i = 0; i < plugins->len; i += str_len(plugins->s + i) + 1) {
279 + if (plugins->s[i] == ':')
280 + { args[0] = "/bin/sh"; args[1] = "-c"; args[2] = plugins->s + i + 1; args[3] = 0; }
282 + { args[0] = plugins->s + i; args[1] = 0; }
284 + if (pipe(pipes) == -1)
285 + { err_spp(plugins->s + i, "can't pipe()"); return 0; }
287 + switch (pid = vfork()) {
289 + err_spp(plugins->s + i, "vfork() failed");
292 + close(0); close(pipes[0]); fd_move(1, pipes[1]);
293 + execv(*args, args);
298 + substdio_fdbuf(&ssdown, read, pipes[0], downbuf, sizeof(downbuf));
300 + if (getln(&ssdown, &data, &match, '\n') == -1) die_nomem();
301 + if (data.len > 1) {
302 + data.s[data.len - 1] = 0;
303 + switch (data.s[0]) {
305 + if (!stralloc_catb(&sppheaders, data.s + 1, data.len - 2)) die_nomem();
306 + if (!stralloc_append(&sppheaders, "\n")) die_nomem();
310 + if (!stralloc_copyb(&addr, data.s + 1, data.len - 1)) die_nomem();
311 + if (!env_put2(addrenv, addr.s)) die_nomem();
314 + case 'S': if (!env_put(data.s + 1)) die_nomem(); break;
315 + case 'U': if (!env_unset(data.s + 1)) die_nomem(); break;
316 + case 'A': spprun = 0;
319 + case 'D': last = 1; match = 0; break;
321 + case 'R': last = 1; match = 0;
322 + case 'P': out(data.s + 1); out("\r\n"); break;
324 + switch (data.s[1]) {
325 + case 'M': errors_to = &error_mail; break;
326 + case 'R': errors_to = &error_rcpt; break;
327 + case 'D': errors_to = &error_data; break;
329 + default: errors_to = 0;
332 + if (!stralloc_catb(errors_to, data.s + 2, data.len - 3)) die_nomem();
333 + if (!stralloc_catb(errors_to, "\r\n", 2)) die_nomem();
341 + if (wait_pid(&wstat,pid) == -1) { err_spp(plugins->s + i, "wait_pid() failed"); return 0; }
342 + if (wait_crashed(wstat)) { err_spp(plugins->s + i, "child crashed"); return 0; }
343 + if (wait_exitcode(wstat) == 120) { err_spp(plugins->s + i, "can't execute"); return 0; }
347 + case 'E': return 0;
349 + case 'N': return 1;
350 + case 'O': return 2;
352 + case 'D': flush(); _exit(0);
359 +int spp_errors(errors) stralloc *errors;
361 + if (!errors->len) return 1;
362 + if (!stralloc_0(errors)) die_nomem();
367 +int spp_connect() { return spp(&plugins_connect, 0); }
369 +int spp_helo(arg) char *arg;
371 + if (!env_put2("SMTPHELOHOST", arg)) die_nomem();
372 + return spp(&plugins_helo, 0);
377 + if (!stralloc_copys(&sppheaders, "")) die_nomem();
378 + if (!stralloc_copys(&error_mail, "")) die_nomem();
379 + if (!stralloc_copys(&error_rcpt, "")) die_nomem();
380 + if (!stralloc_copys(&error_data, "")) die_nomem();
387 + if (!spp_errors(&error_mail)) return 0;
389 + return spp(&plugins_mail, "SMTPMAILFROM");
392 +int spp_rcpt(allowed) int allowed;
394 + if (!spp_errors(&error_rcpt)) return 0;
395 + rcptcountstr[fmt_ulong(rcptcountstr, rcptcount)] = 0;
396 + if (!env_put2("SMTPRCPTCOUNT", rcptcountstr)) die_nomem();
397 + if (!env_put2("SMTPRCPTHOSTSOK", allowed ? "1" : "0")) die_nomem();
398 + sppret = spp(&plugins_rcpt, "SMTPRCPTTO");
402 +void spp_rcpt_accepted() { rcptcount++; }
406 + if (!spp_errors(&error_data)) return 0;
407 + return spp(&plugins_data, 0);
410 +int spp_auth(method, user) char *method, *user;
412 + if (!env_put2("SMTPAUTHMETHOD", method)) die_nomem();
413 + if (!env_put2("SMTPAUTHUSER", user)) die_nomem();
414 + return spp(&plugins_auth, 0);
418 diff -u --new-file qmail-1.03-orig/qmail-spp.h qmail-1.03/qmail-spp.h
419 --- qmail-1.03-orig/qmail-spp.h 1969-12-31 21:00:00.000000000 -0300
420 +++ qmail-1.03/qmail-spp.h 2006-03-21 19:14:06.000000000 -0300
425 +extern stralloc sppheaders;
426 +extern int spp_init();
427 +extern int spp_connect();
428 +extern int spp_helo();
429 +extern void spp_rset();
430 +extern int spp_mail();
431 +extern int spp_rcpt();
432 +extern int spp_data();
433 +extern int spp_auth();