diff -ru 083/Makefile.patch 083-slackbear/Makefile.patch --- 083/Makefile.patch 2015-08-24 01:08:30.000000000 +0900 +++ 083-slackbear/Makefile.patch 2026-01-30 13:49:37.000000000 +0900 @@ -21,7 +21,7 @@ binm1: \ binm1.sh conf-qmail cat binm1.sh \ -@@ -1441,12 +1453,15 @@ +@@ -1441,13 +1454,16 @@ load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \ timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \ ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \ @@ -31,6 +31,7 @@ +dns.lib socket.lib ./load qmail-remote control.o constmap.o timeoutread.o \ timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \ + tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \ ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \ lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \ - str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib` @@ -39,7 +40,7 @@ qmail-remote.0: \ qmail-remote.8 -@@ -1536,12 +1551,12 @@ +@@ -1537,13 +1552,13 @@ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \ date822fmt.o now.o qmail.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 \ @@ -47,6 +48,7 @@ +fs.a auto_qmail.o base64.o socket.lib ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ + tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \ received.o date822fmt.o now.o qmail.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 `cat \ @@ -54,7 +56,7 @@ socket.lib` qmail-smtpd.0: \ -@@ -1553,7 +1568,7 @@ +@@ -1555,7 +1570,7 @@ substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \ error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \ substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ diff -ru 083/TARGETS.patch 083-slackbear/TARGETS.patch --- 083/TARGETS.patch 2015-08-24 01:08:30.000000000 +0900 +++ 083-slackbear/TARGETS.patch 2026-01-30 13:56:53.000000000 +0900 @@ -10,7 +10,7 @@ gfrom.o myctime.o slurpclose.o -@@ -182,6 +183,8 @@ +@@ -184,6 +185,8 @@ qmail-remote qmail-rspawn.o tcpto_clean.o diff -ru 083/qmail-remote.c.patch 083-slackbear/qmail-remote.c.patch --- 083/qmail-remote.c.patch 2015-08-24 01:08:30.000000000 +0900 +++ 083-slackbear/qmail-remote.c.patch 2026-02-04 10:28:18.000000000 +0900 @@ -1,7 +1,5 @@ ---- qmail-remote.c.orig 15-06-1998 -+++ qmail-remote.c 2015-08-08/23/15 ---- ../qmail-1.03/qmail-remote.c 1998-06-15 12:53:16.000000000 +0200 -+++ ../qmail-1.03.083/qmail-remote.c 2013-03-22 18:54:02.000000000 +0100 +--- qmail-remote.c.083 2026-02-04 10:13:46.444419709 +0900 ++++ qmail-remote.c 2026-02-04 10:15:01.987722512 +0900 @@ -28,6 +28,7 @@ #include "timeoutconn.h" #include "timeoutread.h" @@ -10,10 +8,10 @@ #define HUGESMTPTEXT 5000 -@@ -44,6 +45,16 @@ +@@ -43,6 +44,15 @@ + struct constmap maproutes; stralloc host = {0}; stralloc sender = {0}; - +stralloc authsenders = {0}; +struct constmap mapauthsenders; +stralloc user = {0}; @@ -23,11 +21,10 @@ +stralloc chal = {0}; +stralloc slop = {0}; +char *authsender; -+ + saa reciplist = {0}; - struct ip_address partner; -@@ -86,6 +97,12 @@ +@@ -97,6 +107,12 @@ it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n"); zerodie(); } @@ -40,7 +37,7 @@ void outhost() { char x[IPFMT]; -@@ -216,24 +233,192 @@ +@@ -540,6 +556,163 @@ stralloc recip = {0}; @@ -62,12 +59,12 @@ + int i; + + if(!stralloc_copys(sa,"")) temp_nomem(); -+ ++ + for (i = 0; i < len; i++) { + if (s[i] == '=') { + if (!stralloc_cats(sa,"+3D")) temp_nomem(); -+ } else if (s[i] == '+') { -+ if (!stralloc_cats(sa,"+2B")) temp_nomem(); ++ } else if (s[i] == '+') { ++ if (!stralloc_cats(sa,"+2B")) temp_nomem(); + } else if ((int) s[i] < 33 || (int) s[i] > 126) { + if (!stralloc_cats(sa,"+3F")) temp_nomem(); /* ok. not correct */ + } else if (!stralloc_catb(sa,s+i,1)) { @@ -107,7 +104,7 @@ + if (smtpcode() == 235) { mailfrom_xtext(); return 0; } + else if (smtpcode() == 432) { quit("ZConnected to "," but password expired."); return 1; } + else { quit("ZConnected to "," but authentication was rejected (plain)."); return 1; } -+ ++ + return 0; +} + @@ -146,26 +143,27 @@ + substdio_flush(&smtpto); + if (smtpcode() != 334) { quit("ZConnected to "," but authentication was rejected (AUTH CRAM-MD5)."); return -1; } + -+ if (str_chr(smtptext.s+4,' ')) { /* Challenge */ ++ if (str_chr(smtptext.s+4,' ')) { /* Challenge */ + if(!stralloc_copys(&slop,"")) temp_nomem(); + if (!stralloc_copyb(&slop,smtptext.s+4,smtptext.len-5)) temp_nomem(); -+ if (b64decode(slop.s,slop.len,&chal)) quit("ZConnected to "," but unable to base64decode challenge."); ++ if (b64decode(slop.s,slop.len,&chal)) quit("ZConnected to "," but unable to base64decode challenge.") ++; + } -+ ++ + hmac_md5(chal.s,chal.len,pass.s,pass.len,digest); + -+ for (j = 0;j < 16;j++) /* HEX => ASCII */ ++ for (j = 0;j < 16;j++) /* HEX => ASCII */ + { -+ digascii[2*j] = hextab[digest[j] >> 4]; -+ digascii[2*j+1] = hextab[digest[j] & 0xf]; ++ digascii[2*j] = hextab[digest[j] >> 4]; ++ digascii[2*j+1] = hextab[digest[j] & 0xf]; + } + digascii[32]=0; + + slop.len = 0; + if (!stralloc_copys(&slop,"")) temp_nomem(); -+ if (!stralloc_cat(&slop,&user)) temp_nomem(); /* user-id */ ++ if (!stralloc_cat(&slop,&user)) temp_nomem(); /* user-id */ + if (!stralloc_cats(&slop," ")) temp_nomem(); -+ if (!stralloc_catb(&slop,digascii,32)) temp_nomem(); /* digest */ ++ if (!stralloc_catb(&slop,digascii,32)) temp_nomem(); /* digest */ + + if (!stralloc_copys(&auth,"")) temp_nomem(); + if (b64encode(&slop,&auth)) quit("ZConnected to "," but unable to base64encode username+digest."); @@ -174,25 +172,25 @@ + substdio_flush(&smtpto); + if (smtpcode() == 235) { mailfrom_xtext(); return 0; } + else if (smtpcode() == 432) { quit("ZConnected to "," but password expired."); return 1; } -+ else { quit("ZConnected to "," but authentication was rejected (username+digest)."); return 1; } ++ else { quit("ZConnected to "," but authentication was rejected (username+digest)."); return 1; } +} + +void smtp_auth() +{ -+ int i, j; ++ int i, j; + + for (i = 0; i + 8 < smtptext.len; i += str_chr(smtptext.s+i,'\n')+1) -+ if (!str_diffn(smtptext.s+i+4,"AUTH",4)) { ++ if (!str_diffn(smtptext.s+i+4,"AUTH",4)) { + if (j = str_chr(smtptext.s+i+8,'C') > 0) + if (case_starts(smtptext.s+i+8+j,"CRAM")) + if (mailfrom_cram() >= 0) return; + + if (j = str_chr(smtptext.s+i+8,'P') > 0) -+ if (case_starts(smtptext.s+i+8+j,"PLAIN")) ++ if (case_starts(smtptext.s+i+8+j,"PLAIN")) + if (mailfrom_plain() >= 0) return; + + if (j = str_chr(smtptext.s+i+8,'L') > 0) -+ if (case_starts(smtptext.s+i+8+j,"LOGIN")) ++ if (case_starts(smtptext.s+i+8+j,"LOGIN")) + if (mailfrom_login() >= 0) return; + + err_authprot(); @@ -203,49 +201,44 @@ void smtp() { unsigned long code; - int flagbother; - int i; - +@@ -559,9 +732,11 @@ + if (port == 465) smtps = 1; + if (!smtps) + #endif +- - if (smtpcode() != 220) quit("ZConnected to "," but greeting failed"); +- ++ + code = smtpcode(); + if (code >= 500) quit("DConnected to "," but greeting failed"); -+ if (code != 220) quit("ZConnected to "," but greeting failed"); - -- substdio_puts(&smtpto,"HELO "); -+ substdio_puts(&smtpto,"EHLO "); - substdio_put(&smtpto,helohost.s,helohost.len); - substdio_puts(&smtpto,"\r\n"); - substdio_flush(&smtpto); -- if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected"); ++ if (code != 220) quit("ZConnected to "," but greeting failed"); ++ + #ifdef EHLO + # ifdef TLS + if (!smtps) +@@ -592,11 +767,12 @@ + #ifdef EHLO + } + #endif - - substdio_puts(&smtpto,"MAIL FROM:<"); - substdio_put(&smtpto,sender.s,sender.len); - substdio_puts(&smtpto,">\r\n"); - substdio_flush(&smtpto); + -+ if (smtpcode() != 250) { -+ substdio_puts(&smtpto,"HELO "); -+ substdio_put(&smtpto,helohost.s,helohost.len); -+ substdio_puts(&smtpto,"\r\n"); -+ substdio_flush(&smtpto); -+ code = smtpcode(); -+ if (code >= 500) quit("DConnected to "," but my name was rejected"); -+ if (code != 250) quit("ZConnected to "," but my name was rejected"); -+ } -+ + if (user.len && pass.len) + smtp_auth(); -+ else ++ else + mailfrom(); -+ ++ code = smtpcode(); if (code >= 500) quit("DConnected to "," but sender was rejected"); if (code >= 400) quit("ZConnected to "," but sender was rejected"); -@@ -324,48 +509,102 @@ +@@ -687,14 +863,23 @@ case 1: if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break; } -+ ++ + switch(control_readfile(&authsenders,"control/authsenders",0)) { + case -1: + temp_control(); @@ -267,20 +260,13 @@ unsigned long random; char **recips; unsigned long prefme; - int flagallaliases; - int flagalias; - char *relayhost; -- -+ - sig_pipeignore(); - if (argc < 4) perm_usage(); +@@ -707,27 +892,71 @@ if (chdir(auto_qmail) == -1) temp_chdir(); getcontrols(); - if (!stralloc_copys(&host,argv[1])) temp_nomem(); -- -+ + + authsender = 0; relayhost = 0; - for (i = 0;i <= host.len;++i) @@ -300,9 +286,13 @@ - if (relayhost[i]) { - scan_ulong(relayhost + i + 1,&port); - relayhost[i] = 0; -+ +- } +- if (!stralloc_copys(&host,relayhost)) temp_nomem(); +- } + + if (authsender && !*authsender) authsender = 0; -+ + +- addrmangle(&sender,argv[2],&flagalias,0); + if (authsender) { + i = str_chr(authsender,'|'); + if (authsender[i]) { @@ -320,15 +310,12 @@ + if (authsender[i]) { + scan_ulong(authsender + i + 1,&port); + authsender[i] = 0; - } -- if (!stralloc_copys(&host,relayhost)) temp_nomem(); -- } - ++ } + if (!stralloc_copys(&relayhost,authsender)) temp_nomem(); + if (!stralloc_copys(&host,authsender)) temp_nomem(); + + } -+ else { /* default smtproutes -- authenticated */ ++ else { /* default smtproutes -- authenticated */ + for (i = 0;i <= host.len;++i) + if ((i == 0) || (i == host.len) || (host.s[i] == '.')) + if (relayhost = constmap(&maproutes,host.s + i,host.len - i)) @@ -357,9 +344,6 @@ + if (!stralloc_copys(&host,relayhost)) temp_nomem(); + } + } - -- addrmangle(&sender,argv[2],&flagalias,0); -- + if (!saa_readyplus(&reciplist,0)) temp_nomem(); if (ipme_init() != 1) temp_oserr(); - diff -ru 083/qmail-smtpd.8.patch 083-slackbear/qmail-smtpd.8.patch --- 083/qmail-smtpd.8.patch 2015-08-24 01:08:30.000000000 +0900 +++ 083-slackbear/qmail-smtpd.8.patch 2026-01-30 18:11:38.000000000 +0900 @@ -2,7 +2,7 @@ +++ qmail-smtpd.8 2015-08-08/23/15 --- ../qmail-1.03/qmail-smtpd.8 1998-06-15 12:53:16.000000000 +0200 +++ ../qmail-1.03.083/qmail-smtpd.8 2013-03-22 20:57:38.000000000 +0100 -@@ -23,7 +23,30 @@ +@@ -32,7 +32,30 @@ header fields. .B qmail-smtpd @@ -34,10 +34,10 @@ .SH TRANSPARENCY .B qmail-smtpd converts the SMTP newline convention into the UNIX newline convention -@@ -169,6 +192,67 @@ - .B qmail-smtpd - will wait for each new buffer of data from the remote SMTP client. - Default: 1200. +@@ -229,7 +252,67 @@ + string should be separated by a colon. If the environment variable + .B TLSCIPHERS + is set to such a string, it takes precedence. + +.SH "ENVIRONMENT VARIABLES READ" +Environment variables may be defined globally in the @@ -98,7 +98,7 @@ +connections. + +Note: The use of 'cram' requires a CRAM-MD5 enabled PAM. -+ + .SH "SEE ALSO" tcp-env(1), tcp-environ(5), diff -ru 083/qmail-smtpd.c.patch 083-slackbear/qmail-smtpd.c.patch --- 083/qmail-smtpd.c.patch 2015-08-24 01:08:30.000000000 +0900 +++ 083-slackbear/qmail-smtpd.c.patch 2026-02-03 23:54:25.000000000 +0900 @@ -1,8 +1,6 @@ ---- qmail-smtpd.c.orig 15-06-1998 -+++ qmail-smtpd.c 2015-08-08/23/15 ---- ../qmail-1.03/qmail-smtpd.c 1998-06-15 12:53:16.000000000 +0200 -+++ ../qmail-1.03.083/qmail-smtpd.c 2015-08-23 18:04:04.617645322 +0200 -@@ -23,6 +23,9 @@ +--- qmail-smtpd.c.org 2026-02-03 23:02:53.164220761 +0900 ++++ qmail-smtpd.c 2026-02-03 23:32:37.359990597 +0900 +@@ -23,12 +23,15 @@ #include "timeoutread.h" #include "timeoutwrite.h" #include "commands.h" @@ -12,16 +10,23 @@ #define MAXHOPS 100 unsigned int databytes = 0; -@@ -49,6 +52,7 @@ + int timeout = 1200; + +-static const char *protocol = "SMTP"; ++//static const char *protocol = "SMTP"; + + #ifdef TLS + #include +@@ -67,6 +70,7 @@ void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); } void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } +void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } + #ifndef TLS void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } - void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } -@@ -59,6 +63,17 @@ - void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); } +@@ -86,6 +90,17 @@ + void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); } void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } +int err_child() { out("454 oops, problem with child and I can't auth (#4.3.0)\r\n"); return -1; } @@ -38,7 +43,7 @@ stralloc greeting = {0}; -@@ -76,11 +91,14 @@ +@@ -103,11 +118,14 @@ smtp_greet("221 "); out("\r\n"); flush(); _exit(0); } @@ -53,7 +58,7 @@ stralloc helohost = {0}; char *fakehelo; /* pointer into helohost, or 0 */ -@@ -91,6 +109,7 @@ +@@ -118,6 +136,7 @@ fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0; } @@ -61,15 +66,7 @@ int liphostok = 0; stralloc liphost = {0}; int bmfok = 0; -@@ -109,7 +128,6 @@ - if (liphostok == -1) die_control(); - if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control(); - if (timeout <= 0) timeout = 1; -- - if (rcpthosts_init() == -1) die_control(); - - bmfok = control_readfile(&bmf,"control/badmailfrom",0); -@@ -122,19 +140,32 @@ +@@ -149,15 +168,29 @@ if (x) { scan_ulong(x,&u); databytes = u; } if (!(databytes + 1)) --databytes; @@ -96,6 +93,10 @@ + if (case_starts(auth,"!cram")) smtpauth = 12; + if (case_starts(auth,"!+cram")) smtpauth = 13; + } + + #ifdef TLS + if (env_get("SMTPS")) { smtps = 1; tls_init(); } +@@ -166,7 +199,6 @@ dohelo(remotehost); } @@ -103,7 +104,7 @@ stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */ int addrparse(arg) -@@ -216,11 +247,72 @@ +@@ -251,11 +283,72 @@ return r; } @@ -129,13 +130,13 @@ + return 0; +} + -+void mailfrom_auth(arg,len) -+char *arg; ++void mailfrom_auth(arg,len) ++char *arg; +int len; +{ + if (!stralloc_copys(&fuser,"")) die_nomem(); + if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); } -+ else ++ else + while (len) { + if (*arg == '+') { + if (case_starts(arg,"+3D")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"=")) die_nomem(); } @@ -163,28 +164,34 @@ + i = byte_chr(arg,len,'>'); + if (i > 4 && i < len) { + while (len) { -+ arg++; len--; ++ arg++; len--; + if (*arg == ' ' || *arg == '\0' ) { + if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; } -+ if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5); ++ if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5); + if (!stralloc_copys(&mfparms,"")) die_nomem(); + } + else -+ if (!stralloc_catb(&mfparms,arg,1)) die_nomem(); ++ if (!stralloc_catb(&mfparms,arg,1)) die_nomem(); + } + } +} void smtp_helo(arg) char *arg; { -@@ -229,17 +321,30 @@ - } +@@ -265,6 +358,8 @@ + /* ESMTP extensions are published here */ void smtp_ehlo(arg) char *arg; { -- smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); + char size[FMT_ULONG]; + size[fmt_ulong(size,(unsigned int) databytes)] = 0; -+ smtp_greet("250-"); + #ifdef TLS + struct stat st; + #endif +@@ -273,17 +368,27 @@ + if (!ssl && (stat("control/servercert.pem",&st) == 0)) + out("\r\n250-STARTTLS"); + #endif +- out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); + out("\r\n250-PIPELINING\r\n250-8BITMIME\r\n"); + if (smtpauth == 1 || smtpauth == 11) out("250-AUTH LOGIN PLAIN\r\n"); + if (smtpauth == 2 || smtpauth == 12) out("250-AUTH CRAM-MD5\r\n"); @@ -192,10 +199,11 @@ + out("250 SIZE "); out(size); out("\r\n"); seenmail = 0; dohelo(arg); } - void smtp_rset() +-void smtp_rset(arg) char *arg; ++void smtp_rset() { - seenmail = 0; -+ seenmail = 0; seenauth = 0; ++ seenmail = 0; seenauth = 0; + mailfrom.len = 0; rcptto.len = 0; out("250 flushed\r\n"); } @@ -210,16 +218,7 @@ flagbarf = bmfcheck(); seenmail = 1; if (!stralloc_copys(&rcptto,"")) die_nomem(); -@@ -378,7 +483,7 @@ - qp = qmail_qp(&qqt); - out("354 go ahead\r\n"); - -- received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); -+ received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo); - blast(&hops); - hops = (hops >= MAXHOPS); - if (hops) qmail_fail(&qqt); -@@ -388,16 +493,228 @@ +@@ -440,12 +545,223 @@ qqx = qmail_close(&qqt); if (!*qqx) { acceptmessage(qp); return; } if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; } @@ -289,7 +288,7 @@ + substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf); + if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write(); + if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write(); -+ if (smtpauth == 2 || smtpauth == 3 || smtpauth == 12 || smtpauth == 13) ++ if (smtpauth == 2 || smtpauth == 3 || smtpauth == 12 || smtpauth == 13) + if (substdio_put(&ssauth,chal.s,chal.len) == -1) return err_write(); + if (substdio_flush(&ssauth) == -1) return err_write(); + @@ -441,7 +440,10 @@ + +/* this file is too long --------------------------------------------- GO ON */ + - struct commands smtpcommands[] = { + #ifdef TLS + stralloc proto = {0}; + int ssl_verified = 0; +@@ -715,6 +1031,7 @@ { "rcpt", smtp_rcpt, 0 } , { "mail", smtp_mail, 0 } , { "data", smtp_data, flush } @@ -449,7 +451,7 @@ , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush } -@@ -408,8 +725,11 @@ +@@ -728,8 +1045,11 @@ , { 0, err_unimpl, flush } } ;