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
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
26 -qmail-remote \- send mail via SMTP
27 +qmail-remote \- send mail via SMTP or QMTP
32 or to a mail exchanger for
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).
39 can be either a fully-qualified domain name:
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,
56 +Artificial mail routes.
57 +Each route has the form
58 +.IR domain\fB:\fIrelay ,
59 +without any extra spaces.
72 +(It will also avoid doing any CNAME lookups on
75 +may include a colon and a port number to use instead of the
76 +normal SMTP port, 25:
79 + inside.af.mil:firewall.af.mil:26
83 +may include another colon and a protocol specifier after the port number
84 +to specify qmtp instead of smtp:
87 + almqvist.net:beta.lunds.lu.se:209:qmtp
90 +Specifying a protocol requires specifying a port too! Also, just specifying
91 +port 209 doesn't imply qmtp.
97 +to look up MX records as usual.
99 +may include wildcards:
107 +any address ending with
112 +is routed by its MX records;
113 +any other address is artificially routed to
118 +system does not protect you if you create an artificial
119 +mail loop between machines.
121 +you are always safe using
123 +if you do not accept mail from the network.
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
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>
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)
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\
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 @@
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);
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");
209 for (i = 0;i < reciplist.len;++i) {
211 substdio_flush(&smtpto);
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");
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");
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;
249 +void qmtp() /* thanks to russell nelson */
258 + char num[FMT_ULONG];
261 + if (fstat(0,&st) == -1) quit("Z", " unable to fstat stdin");
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);
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);
275 + substdio_put(&smtpto,",",1);
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);
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);
299 + for (i = 0;i < reciplist.len;++i) {
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();
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();
320 + for (len = 0;len < smtptext.len;++len) {
321 + ch = smtptext.s[len];
322 + if ((ch < 32) || (ch > 126)) smtptext.s[len] = '?';
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') {
333 + else { /* if (smtptext.s[0] == 'Z') */
337 + /* if (substdio_put(subfdoutsmall,smtptext.s+1,smtptext.len-1) == -1) temp_noconn(); */
341 + out("D Giving up on ");outhost();out("\nProtocol: qmtp\n");
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");
350 stralloc canonhost = {0};
351 @@ -316,11 +433,20 @@
353 if (control_rldef(&helohost,"control/helohost",1,(char *) 0) != 1)
355 - switch(control_readfile(&routes,"control/smtproutes",0)) {
356 + switch(control_readfile(&routes,"control/mailroutes",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)) {
366 + case 0: /* both files there but emtpy */
367 + if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); break; /* never mind */
369 + if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
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))
378 if (relayhost && !*relayhost) relayhost = 0;
381 + if (!stralloc_copys(&protocol,"smtp")) temp_nomem(); /* smtp is the default */
384 i = str_chr(relayhost,':');
386 - scan_ulong(relayhost + i + 1,&port);
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();
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 */
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
436 struct stat stmrhcdb;
437 + struct stat stmrts;
439 substdio_puts(subfdout,"qmail home directory: ");
440 substdio_puts(subfdout,auto_qmail);
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@",".");
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: ","");
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");
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;