updated on Wed Jan 25 16:08:47 UTC 2012
[aur-mirror.git] / qmail / qmail-1.03-spp.patch1
blob625e81cadf8f1c7ea1923146b69a09fd4e0de3d8
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 @@
5  auto_split.h
6         ./compile qmail-showctl.c
7  
8 +qmail-spp.o: \
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
13  qmail-smtpd: \
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 \
16  ucspitls.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 \
23 -       ucspitls.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 \
28 @@ -1573,7 +1578,7 @@
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
36  qmail-start: \
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
41 @@ -25,6 +25,9 @@
42  #include "commands.h"
43  #include "ucspitls.h"
44  #include "wait.h"
45 +#include "qmail-spp.h"
47 +int spp_val;
49  #define CRAM_MD5
50  #define AUTHSLEEP 5
51 @@ -131,6 +134,7 @@
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();
59 @@ -240,6 +244,7 @@
61  int seenmail = 0;
62  int flagbarf; /* defined if seenmail */
63 +int allowed;
64  int flagsize;
65  stralloc mailfrom = {0};
66  stralloc rcptto = {0};
67 @@ -307,12 +312,13 @@
69  void smtp_helo(arg) char *arg;
70  {
71 +  if(!spp_helo(arg)) return;
72    smtp_greet("250 "); out("\r\n");
73    seenmail = 0; dohelo(arg);
74  }
75  void smtp_ehlo(arg) char *arg;
76  {
78 +  if(!spp_helo(arg)) return;
79    char size[FMT_ULONG];
80    size[fmt_ulong(size,(unsigned int) databytes)] = 0;
81    smtp_greet("250-"); 
82 @@ -329,12 +335,15 @@
83  }
84  void smtp_rset()
85  {
86 +  spp_rset();
87    seenmail = 0;
88    out("250 flushed\r\n");
89  }
90  void smtp_mail(arg) char *arg;
91  {
92    if (!addrparse(arg)) { err_syntax(); return; }
93 +  if (!(spp_val = spp_mail())) return;
94 +  if (spp_val == 1)
95    flagsize = 0;
96    mailfrom_parms(arg);
97    if (flagsize) { err_size(); return; }
98 @@ -349,13 +358,18 @@
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) {
105    if (relayclient) {
106      --addr.len;
107      if (!stralloc_cats(&addr,relayclient)) die_nomem();
108      if (!stralloc_0(&addr)) die_nomem();
109    }
110    else
111 -    if (!addrallowed()) { err_nogateway(); return; }
112 +    if (!allowed) { err_nogateway(); return; }
113 +  }
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();
118 @@ -486,6 +500,7 @@
119   
120    if (!seenmail) { err_wantmail(); return; }
121    if (!rcptto.len) { err_wantrcpt(); return; }
122 +  if (!spp_data()) return;
123    seenmail = 0;
124    if (databytes) bytestooverflow = databytes + 1;
125    if (qmail_open(&qqt) == -1) { err_qqt(); return; }
126 @@ -493,6 +508,8 @@
127    out("354 go ahead\r\n");
128   
129    received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
130 +  qmail_put(&qqt,sppheaders.s,sppheaders.len); /* set in qmail-spp.c */
131 +  spp_rset();
132    blast(&hops);
133    hops = (hops >= MAXHOPS);
134    if (hops) qmail_fail(&qqt);
135 @@ -716,6 +733,7 @@
137    switch (authcmds[i].fun(arg)) {
138      case 0:
139 +      if (!spp_auth(authcmds[i].text, user.s)) return;
140        flagauth = 1;
141        protocol = "ESMTPA";
142        relayclient = "";
143 @@ -760,9 +778,11 @@
144    if (chdir(auto_qmail) == -1) die_control();
145    setup();
146    if (ipme_init() != 1) die_ipme();
147 -  tls_available = !!env_get("UCSPITLS");
148 -  smtp_greet("220 ");
149 -  out(" ESMTP\r\n");
150 +  if (spp_connect()) {
151 +    tls_available = !!env_get("UCSPITLS");
152 +    smtp_greet("220 ");
153 +    out(" ESMTP\r\n");
154 +  }
155    if (commands(&ssin,&smtpcommands) == 0) die_read();
156    die_nomem();
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
161 @@ -0,0 +1,256 @@
163 + * Copyright (C) 2004-2005 Pawel Foremski <pjf@asn.pl>
164 + *
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 
169 + * version.
170 + *
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.
175 + *
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.
179 + *
180 + *** Note
181 + *
182 + * This is the core of qmail-spp patch for qmail
183 + *
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.
187 + *
188 + * "..." comments marks places where code for other SMTP commands should be
189 + * added, if needed.
190 + *
191 + */
193 +#include "readwrite.h"
194 +#include "stralloc.h"
195 +#include "substdio.h"
196 +#include "control.h"
197 +#include "str.h"
198 +#include "byte.h"
199 +#include "env.h"
200 +#include "exit.h"
201 +#include "wait.h"
202 +#include "fork.h"
203 +#include "fd.h"
204 +#include "fmt.h"
205 +#include "getln.h"
207 +/* stuff needed from qmail-smtpd */
208 +extern void flush();
209 +extern void out();
210 +extern void die_nomem();
211 +extern stralloc addr;
212 +/* *** */
214 +stralloc sppheaders = {0};
215 +static int spprun = 0;
216 +static int sppfok = 0;
217 +static int sppret;
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"); }
230 +int spp_init()
232 +  int i, len = 0;
233 +  stralloc *plugins_to;
234 +  char *x, *conffile = "control/smtpplugins";
236 +  if (!env_get("NOSPP")) {
237 +    spprun = 1;
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;
253 +          /* ... */
254 +          default: plugins_to = &plugins_dummy;
255 +        }
256 +      else
257 +        if (!stralloc_catb(plugins_to, sppf.s + i, len)) die_nomem();
258 +    }
259 +  }
261 +  return 0;
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();
276 +  last = 0;
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; }
281 +    else
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()) {
288 +      case -1:
289 +        err_spp(plugins->s + i, "vfork() failed");
290 +        return 0;
291 +      case 0:
292 +        close(0); close(pipes[0]); fd_move(1, pipes[1]);
293 +        execv(*args, args);
294 +        _exit(120);
295 +    }
297 +    close(pipes[1]);
298 +    substdio_fdbuf(&ssdown, read, pipes[0], downbuf, sizeof(downbuf));
299 +    do {
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]) {
304 +          case 'H':
305 +            if (!stralloc_catb(&sppheaders, data.s + 1, data.len - 2)) die_nomem();
306 +            if (!stralloc_append(&sppheaders, "\n")) die_nomem();
307 +            break;
308 +          case 'C':
309 +            if (addrenv) {
310 +              if (!stralloc_copyb(&addr, data.s + 1, data.len - 1)) die_nomem();
311 +              if (!env_put2(addrenv, addr.s)) die_nomem();
312 +            }
313 +            break;
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;
317 +          case 'O':
318 +          case 'N':
319 +          case 'D': last = 1; match = 0; break;
320 +          case 'E':
321 +          case 'R': last = 1; match = 0;
322 +          case 'P': out(data.s + 1); out("\r\n"); break;
323 +          case 'L':
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;
328 +              /* ... */
329 +              default: errors_to = 0;
330 +            }
331 +            if (errors_to) {
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();
334 +            }
335 +            break;
336 +        }
337 +      }
338 +    } while (match);
340 +    close(pipes[0]);
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; }
345 +    if (last)
346 +      switch (*data.s) {
347 +        case 'E': return 0;
348 +        case 'A':
349 +        case 'N': return 1;
350 +        case 'O': return 2;
351 +        case 'R':
352 +        case 'D': flush(); _exit(0);
353 +      }
354 +  }
356 +  return 1;
359 +int spp_errors(errors) stralloc *errors;
361 +  if (!errors->len) return 1;
362 +  if (!stralloc_0(errors)) die_nomem();
363 +  out(errors->s);
364 +  return 0;
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);
375 +void spp_rset()
376 +{ 
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();
381 +  /* ... */
382 +  rcptcount = 0;
385 +int spp_mail()
387 +  if (!spp_errors(&error_mail)) return 0;
388 +  rcptcount = 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");
399 +  return sppret;
402 +void spp_rcpt_accepted() { rcptcount++; }
404 +int spp_data()
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);
417 +/* ... */
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
421 @@ -0,0 +1,14 @@
422 +#ifndef QMAIL_SPP_H
423 +#define QMAIL_SPP_H
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();
435 +#endif