updated on Mon Jan 16 00:01:41 UTC 2012
[aur-mirror.git] / qmail / qmail-1.03-qmtpc-mailroutes-1.5.patch
blob85e9ff5708a67f86046774edb8258300c70a75c2
1 diff -u --new-file qmail-1.03-orig/qmail-control.9 qmail-1.03/qmail-control.9
2 --- qmail-1.03-orig/qmail-control.9 2006-03-21 16:38:39.000000000 -0300
3 +++ qmail-1.03/qmail-control.9 2006-03-21 16:54:04.000000000 -0300
4 @@ -22,6 +22,7 @@
5 in
6 .IR badmailfrom ,
7 .IR locals ,
8 +.IR mailroutes ,
9 .IR percenthack ,
10 .IR qmqpservers ,
11 .IR rcpthosts ,
12 @@ -63,6 +64,7 @@
13 .I idhost \fIme \fRqmail-inject
14 .I localiphost \fIme \fRqmail-smtpd
15 .I locals \fIme \fRqmail-send
16 +.I mailroutes \fR(none) \fRqmail-remote
17 .I logger \fRsplogger \fRall init scripts
18 .I morercpthosts \fR(none) \fRqmail-smtpd
19 .I percenthack \fR(none) \fRqmail-send
20 diff -u --new-file qmail-1.03-orig/qmail-remote.8 qmail-1.03/qmail-remote.8
21 --- qmail-1.03-orig/qmail-remote.8 2006-03-21 16:38:40.000000000 -0300
22 +++ qmail-1.03/qmail-remote.8 2006-03-21 16:51:59.000000000 -0300
23 @@ -1,6 +1,6 @@
24 .TH qmail-remote 8
25 .SH NAME
26 -qmail-remote \- send mail via SMTP
27 +qmail-remote \- send mail via SMTP or QMTP
28 .SH SYNOPSIS
29 .B qmail-remote
30 .I host
31 @@ -26,7 +26,8 @@
32 or to a mail exchanger for
33 .I host
34 listed in the Domain Name System,
35 -via the Simple Mail Transfer Protocol (SMTP).
36 +via the Simple Mail Transfer Protocol (SMTP) or
37 +Quick Mail Transfer Protocol (QMTP).
38 .I host
39 can be either a fully-qualified domain name:
41 @@ -67,6 +68,9 @@
42 .B qmail-remote
43 will happily send such messages.
44 It is the user's responsibility to avoid generating illegal messages.
46 +QMTP is completely transparent. No need for end-of-line conversions,
47 +and 8-bit clean too.
48 .SH "RESULTS"
49 .B qmail-remote
50 prints some number of
51 @@ -136,6 +140,81 @@
52 .B qmail-remote
53 refuses to run.
54 .TP 5
55 +.I mailroutes
56 +Artificial mail routes.
57 +Each route has the form
58 +.IR domain\fB:\fIrelay ,
59 +without any extra spaces.
60 +If
61 +.I domain
62 +matches
63 +.IR host ,
64 +.B qmail-remote
65 +will connect to
66 +.IR relay ,
67 +as if
68 +.I host
69 +had
70 +.I relay
71 +as its only MX.
72 +(It will also avoid doing any CNAME lookups on
73 +.IR recip .)
74 +.I host
75 +may include a colon and a port number to use instead of the
76 +normal SMTP port, 25:
78 +.EX
79 + inside.af.mil:firewall.af.mil:26
80 +.EE
82 +.I host
83 +may include another colon and a protocol specifier after the port number
84 +to specify qmtp instead of smtp:
86 +.EX
87 + almqvist.net:beta.lunds.lu.se:209:qmtp
88 +.EE
90 +Specifying a protocol requires specifying a port too! Also, just specifying
91 +port 209 doesn't imply qmtp.
93 +.I relay
94 +may be empty;
95 +this tells
96 +.B qmail-remote
97 +to look up MX records as usual.
98 +.I mailroutes
99 +may include wildcards:
101 +.EX
102 + .af.mil:
103 + :heaven.af.mil
104 +.EE
106 +Here
107 +any address ending with
108 +.B .af.mil
109 +(but not
110 +.B af.mil
111 +itself)
112 +is routed by its MX records;
113 +any other address is artificially routed to
114 +.BR heaven.af.mil .
116 +The
117 +.B qmail
118 +system does not protect you if you create an artificial
119 +mail loop between machines.
120 +However,
121 +you are always safe using
122 +.I mailroutes
123 +if you do not accept mail from the network.
125 +.I smtproutes
126 +is ignored if
127 +.I mailroutes
128 +exists.
129 +.TP 5
130 .I smtproutes
131 Artificial SMTP routes.
132 Each route has the form
133 diff -u --new-file qmail-1.03-orig/qmail-remote.c qmail-1.03/qmail-remote.c
134 --- qmail-1.03-orig/qmail-remote.c 2006-03-21 16:38:39.000000000 -0300
135 +++ qmail-1.03/qmail-remote.c 2006-03-21 16:48:24.000000000 -0300
136 @@ -1,4 +1,5 @@
137 #include <sys/types.h>
138 +#include <sys/stat.h>
139 #include <sys/socket.h>
140 #include <netinet/in.h>
141 #include <arpa/inet.h>
142 @@ -14,6 +15,7 @@
143 #include "dns.h"
144 #include "alloc.h"
145 #include "quote.h"
146 +#include "fmt.h"
147 #include "ip.h"
148 #include "ipalloc.h"
149 #include "ipme.h"
150 @@ -31,8 +33,10 @@
152 #define HUGESMTPTEXT 5000
154 -#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */
155 -unsigned long port = PORT_SMTP;
156 +unsigned long smtp_port = 25; /* silly rabbit, /etc/services is for users */
157 +unsigned long qmtp_port = 209;
159 +stralloc protocol = {0};
161 GEN_ALLOC_typedef(saa,stralloc,sa,len,a)
162 GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus)
163 @@ -70,6 +74,8 @@
164 Unable to switch to home directory. (#4.3.0)\n"); zerodie(); }
165 void temp_control() { out("Z\
166 Unable to read control files. (#4.3.0)\n"); zerodie(); }
167 +void temp_proto() { out("Z\
168 +recipient did not talk proper QMTP (#4.3.0)\n"); zerodie(); }
169 void perm_partialline() { out("D\
170 SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); }
171 void perm_usage() { out("D\
172 @@ -122,9 +128,9 @@
173 return r;
176 -char inbuf[1024];
177 +char inbuf[1500];
178 substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf);
179 -char smtptobuf[1024];
180 +char smtptobuf[1500];
181 substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf);
182 char smtpfrombuf[128];
183 substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf);
184 @@ -222,21 +228,21 @@
185 int flagbother;
186 int i;
188 - if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
189 + if (smtpcode() != 220) quit("Z Connected to "," but greeting failed");
191 substdio_puts(&smtpto,"HELO ");
192 substdio_put(&smtpto,helohost.s,helohost.len);
193 substdio_puts(&smtpto,"\r\n");
194 substdio_flush(&smtpto);
195 - if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
196 + if (smtpcode() != 250) quit("Z Connected to "," but my name was rejected");
198 substdio_puts(&smtpto,"MAIL FROM:<");
199 substdio_put(&smtpto,sender.s,sender.len);
200 substdio_puts(&smtpto,">\r\n");
201 substdio_flush(&smtpto);
202 code = smtpcode();
203 - if (code >= 500) quit("DConnected to "," but sender was rejected");
204 - if (code >= 400) quit("ZConnected to "," but sender was rejected");
205 + if (code >= 500) quit("D Connected to "," but sender was rejected");
206 + if (code >= 400) quit("Z Connected to "," but sender was rejected");
208 flagbother = 0;
209 for (i = 0;i < reciplist.len;++i) {
210 @@ -246,7 +252,7 @@
211 substdio_flush(&smtpto);
212 code = smtpcode();
213 if (code >= 500) {
214 - out("h"); outhost(); out(" does not like recipient.\n");
215 + out("h "); outhost(); out(" does not like recipient.\n");
216 outsmtptext(); zero();
218 else if (code >= 400) {
219 @@ -262,15 +268,126 @@
221 substdio_putsflush(&smtpto,"DATA\r\n");
222 code = smtpcode();
223 - if (code >= 500) quit("D"," failed on DATA command");
224 - if (code >= 400) quit("Z"," failed on DATA command");
225 + if (code >= 500) quit("D "," failed on DATA command");
226 + if (code >= 400) quit("Z "," failed on DATA command");
228 blast();
229 code = smtpcode();
230 flagcritical = 0;
231 - if (code >= 500) quit("D"," failed after I sent the message");
232 - if (code >= 400) quit("Z"," failed after I sent the message");
233 - quit("K"," accepted message");
234 + if (code >= 500) quit("D "," failed after I sent the message");
235 + if (code >= 400) quit("Z "," failed after I sent the message");
236 + quit("K "," accepted message");
241 +int qmtp_priority(int pref)
243 + if (pref < 12800) return 0;
244 + if (pref > 13055) return 0;
245 + if (pref % 16 == 1) return 1;
246 + return 0;
249 +void qmtp() /* thanks to russell nelson */
251 + struct stat st;
252 + unsigned long len;
253 + int len2;
254 + char *x;
255 + int i;
256 + int n;
257 + unsigned char ch;
258 + char num[FMT_ULONG];
259 + int flagallok;
261 + if (fstat(0,&st) == -1) quit("Z", " unable to fstat stdin");
262 + len = st.st_size;
264 + /* the following code was substantially taken from serialmail'ss serialqmtp.c */
265 + substdio_put(&smtpto,num,fmt_ulong(num,len+1));
266 + substdio_put(&smtpto,":\n",2);
267 + while (len > 0) {
268 + n = substdio_feed(&ssin);
269 + if (n <= 0) _exit(32); /* wise guy again */
270 + x = substdio_PEEK(&ssin);
271 + substdio_put(&smtpto,x,n);
272 + substdio_SEEK(&ssin,n);
273 + len -= n;
275 + substdio_put(&smtpto,",",1);
277 + len = sender.len;
278 + substdio_put(&smtpto,num,fmt_ulong(num,len));
279 + substdio_put(&smtpto,":",1);
280 + substdio_put(&smtpto,sender.s,sender.len);
281 + substdio_put(&smtpto,",",1);
283 + len = 0;
284 + for (i = 0;i < reciplist.len;++i)
285 + len += fmt_ulong(num,reciplist.sa[i].len) + 1 + reciplist.sa[i].len + 1;
286 + substdio_put(&smtpto,num,fmt_ulong(num,len));
287 + substdio_put(&smtpto,":",1);
288 + for (i = 0;i < reciplist.len;++i) {
289 + substdio_put(&smtpto,num,fmt_ulong(num,reciplist.sa[i].len));
290 + substdio_put(&smtpto,":",1);
291 + substdio_put(&smtpto,reciplist.sa[i].s,reciplist.sa[i].len);
292 + substdio_put(&smtpto,",",1);
294 + substdio_put(&smtpto,",",1);
295 + substdio_flush(&smtpto);
297 + flagallok = 1;
299 + for (i = 0;i < reciplist.len;++i) {
300 + len = 0;
301 + for (;;) {
302 + get(&ch);
303 + if (ch == ':') break;
304 + if (len > 200000000) temp_proto();
305 + if (ch - '0' > 9) temp_proto();
306 + len = 10 * len + (ch - '0');
308 + if (!len) temp_proto();
309 + get(&ch); --len;
310 + if ((ch != 'Z') && (ch != 'D') && (ch != 'K')) temp_proto();
312 + if (!stralloc_copyb(&smtptext,&ch,1)) temp_proto();
313 + if (!stralloc_cats(&smtptext,"Remote host said: ")) temp_nomem();
315 + while (len > 0) {
316 + get(&ch);
317 + --len;
320 + for (len = 0;len < smtptext.len;++len) {
321 + ch = smtptext.s[len];
322 + if ((ch < 32) || (ch > 126)) smtptext.s[len] = '?';
324 + get(&ch);
325 + if (ch != ',') temp_proto();
326 + smtptext.s[smtptext.len-1] = '\n';
328 + if (smtptext.s[0] == 'K') out("r");
329 + else if (smtptext.s[0] == 'D') {
330 + out("h");
331 + flagallok = 0;
333 + else { /* if (smtptext.s[0] == 'Z') */
334 + out("s");
335 + flagallok = 0;
337 + /* if (substdio_put(subfdoutsmall,smtptext.s+1,smtptext.len-1) == -1) temp_noconn(); */
338 + zero();
340 + if (!flagallok) {
341 + out("D Giving up on ");outhost();out("\nProtocol: qmtp\n");
342 + } else {
343 + out("K ");outhost();out(" accepted message.\n");
345 + if (substdio_put(subfdoutsmall,smtptext.s+1,smtptext.len-1) == -1) _exit(0);
346 + out("Protocol: qmtp\n");
347 + zerodie();
350 stralloc canonhost = {0};
351 @@ -316,11 +433,20 @@
352 temp_control();
353 if (control_rldef(&helohost,"control/helohost",1,(char *) 0) != 1)
354 temp_control();
355 - switch(control_readfile(&routes,"control/smtproutes",0)) {
356 + switch(control_readfile(&routes,"control/mailroutes",0)) {
357 case -1:
358 temp_control();
359 - case 0:
360 - if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); break;
361 + case 0: /* file there but empty? */
362 + // if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); break;
363 + switch(control_readfile(&routes,"control/smtproutes",0)) {
364 + case -1:
365 + temp_control();
366 + case 0: /* both files there but emtpy */
367 + if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); break; /* never mind */
368 + case 1:
369 + if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
372 case 1:
373 if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
375 @@ -353,14 +479,25 @@
376 if (relayhost = constmap(&maproutes,host.s + i,host.len - i))
377 break;
378 if (relayhost && !*relayhost) relayhost = 0;
381 + if (!stralloc_copys(&protocol,"smtp")) temp_nomem(); /* smtp is the default */
383 if (relayhost) {
384 i = str_chr(relayhost,':');
385 if (relayhost[i]) {
386 - scan_ulong(relayhost + i + 1,&port);
387 - relayhost[i] = 0;
389 + if (!stralloc_copyb(&host,relayhost,i)) temp_nomem();
390 + scan_ulong(relayhost + i + 1,&smtp_port);
391 + qmtp_port = smtp_port; /* it is in the route file */
392 + i += str_chr(relayhost+i+1,':');
393 + if (relayhost[i++]) {
394 + stralloc_copys(&protocol,"");
396 + while (relayhost[i++]) {
397 + if (!stralloc_append(&protocol,relayhost + i)) temp_nomem(); /* let the route file set the protol */
400 - if (!stralloc_copys(&host,relayhost)) temp_nomem();
401 + else if (!stralloc_copys(&host,relayhost)) temp_nomem();
405 @@ -414,7 +551,22 @@
406 smtpfd = socket(AF_INET,SOCK_STREAM,0);
407 if (smtpfd == -1) temp_oserr();
409 - if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) {
411 + if (qmtp_priority(ip.ix[i].pref) || stralloc_starts(&protocol,"qmtp")) {
412 + if (!stralloc_copys(&protocol,"qmtp")) temp_nomem();
413 + /* unnecessary error checking, already contains smtp? */
414 + /* set to qmtp to get logging right, see below */
415 + if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) qmtp_port,timeoutconnect) == 0) {
416 + tcpto_err(&ip.ix[i].ip,0);
417 + partner = ip.ix[i].ip;
418 + qmtp(); /* does not return */
420 + /* logging un-final things is too hard */
422 + close(smtpfd);
423 + smtpfd = socket(AF_INET,SOCK_STREAM,0);
424 + if (smtpfd == -1) temp_oserr(); /* thanks to ian lance taylor */
425 + if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) smtp_port,timeoutconnect) == 0) {
426 tcpto_err(&ip.ix[i].ip,0);
427 partner = ip.ix[i].ip;
428 smtp(); /* does not return */
429 Subdirectorios comunes: qmail-1.03-orig/qmail-rhinit y qmail-1.03/qmail-rhinit
430 diff -u --new-file qmail-1.03-orig/qmail-showctl.c qmail-1.03/qmail-showctl.c
431 --- qmail-1.03-orig/qmail-showctl.c 2006-03-21 16:38:40.000000000 -0300
432 +++ qmail-1.03/qmail-showctl.c 2006-03-21 16:53:31.000000000 -0300
433 @@ -142,6 +142,7 @@
434 direntry *d;
435 struct stat stmrh;
436 struct stat stmrhcdb;
437 + struct stat stmrts;
439 substdio_puts(subfdout,"qmail home directory: ");
440 substdio_puts(subfdout,auto_qmail);
441 @@ -237,6 +238,7 @@
442 do_str("idhost",1,"idhost","Message-ID host name is ");
443 do_str("localiphost",1,"localiphost","Local IP address becomes ");
444 do_lst("locals","Messages for me are delivered locally.","Messages for "," are delivered locally.");
445 + do_lst("mailroutes","No artificial mail routes.","mail route: ","");
446 do_str("logger",0,"multilog t /var/log/{}","Logging is done via: ");
447 do_str("me",0,"undefined! Uh-oh","My name is ");
448 do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@",".");
449 @@ -265,7 +267,12 @@
450 substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
452 do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
453 - do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
455 + if (stat("mailroutes",&stmrts) == -1)
456 + do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
457 + else
458 + substdio_puts(subfdout,"\nsmtproutes: mailroutes exists, ignoring smtproutes\n");
460 do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
461 do_int("timeoutremote","1200","SMTP client data timeout is "," seconds");
462 do_int("timeoutsmtpd","1200","SMTP server data timeout is "," seconds");
463 @@ -292,6 +299,7 @@
464 if (str_equal(d->d_name,"idhost")) continue;
465 if (str_equal(d->d_name,"localiphost")) continue;
466 if (str_equal(d->d_name,"locals")) continue;
467 + if (str_equal(d->d_name,"mailroutes")) continue;
468 if (str_equal(d->d_name,"me")) continue;
469 if (str_equal(d->d_name,"morercpthosts")) continue;
470 if (str_equal(d->d_name,"morercpthosts.cdb")) continue;