diff options
| -rw-r--r-- | INSTALL | 2 | ||||
| -rw-r--r-- | doc/index.html | 2 | ||||
| -rw-r--r-- | doc/upgrade.html | 2 | ||||
| -rw-r--r-- | package/deps-build | 2 | ||||
| -rw-r--r-- | src/qmail-remote/dns.c | 59 | ||||
| -rw-r--r-- | src/qmail-remote/qmail-remote.c | 25 | ||||
| -rw-r--r-- | src/qmail-remote/qmail-remote.h | 2 | ||||
| -rw-r--r-- | src/qmail-remote/tls.c | 4 |
8 files changed, 85 insertions, 13 deletions
@@ -8,7 +8,7 @@ Build Instructions - GNU make version 3.81 or later - skalibs version 2.15.0.0 or later: https://skarnet.org/software/skalibs/ - s6 version 2.15.0.0 or later: https://skarnet.org/software/s6/ - - s6-networking version 2.7.2.2 or later: https://skarnet.org/software/s6-networking/ + - s6-networking version 2.7.3.0 or later: https://skarnet.org/software/s6-networking/ This software will run on any operating system that implements POSIX.1-2024, available at: diff --git a/doc/index.html b/doc/index.html index e2005b3..d2a3ef9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -44,7 +44,7 @@ library. </li> 2.4.1.2 or later. It's a build-time requirement. It's also a run-time requirement if you link against the shared version of the s6-dns library. </li> <li> <a href="//skarnet.org/software/s6-networking/">s6-networking</a> version -2.7.2.2 or later. It's a build-time and run-time requirement. </li> +2.7.3.0 or later. It's a build-time and run-time requirement. </li> </ul> <h3> Licensing </h3> diff --git a/doc/upgrade.html b/doc/upgrade.html index eaf52d2..7ee8df0 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -29,7 +29,7 @@ dependency bumped to 2.15.0.0 </li> dependency bumped to 2.15.0.0 </li> <li> New dependency: <a href="//skarnet.org/software/s6-dns/">s6-dns</a> 2.4.1.2 </li> <li> <a href="//skarnet.org/software/s6-networking/">s6-networking</a> -dependency bumped to 2.7.2.2 and made mandatory. </li> +dependency bumped to 2.7.3.0 and made mandatory. </li> </ul> <h2> in 0.0.2.1 </h2> diff --git a/package/deps-build b/package/deps-build index 8007068..c10cbaf 100644 --- a/package/deps-build +++ b/package/deps-build @@ -1,4 +1,4 @@ true true /package/prog/skalibs 2.15.0.0 libskarnet true false /package/admin/s6 2.15.0.0 libs6 true false /package/web/s6-dns 2.4.1.2 libs6dns -true false /package/net/s6-networking 2.7.2.2 +true false /package/net/s6-networking 2.7.3.0 diff --git a/src/qmail-remote/dns.c b/src/qmail-remote/dns.c index 61fd483..1d3fc97 100644 --- a/src/qmail-remote/dns.c +++ b/src/qmail-remote/dns.c @@ -113,13 +113,18 @@ static unsigned int use_host_as_mx (skadns_t *a, char const *host, genalloc *mxi #define qmailr_dtempsys(...) do { skadns_end(&a) ; qmailr_tempsys(__VA_ARGS__) ; } while (0) #define qmailr_dtempusys(...) do { skadns_end(&a) ; qmailr_tempusys(__VA_ARGS__) ; } while (0) -unsigned int dns_stuff (char const *host, char const *const *eaddr, unsigned int n, size_t *eaddrpos, genalloc *mxipind, stralloc *storage, unsigned int timeoutdns, char const *ipme4, unsigned int n4, char const *ipme6, unsigned int n6, uint32_t flags) +unsigned int dns_stuff (char const *helohost, char *heloip4, char *heloip6, char const *host, char const *const *eaddr, unsigned int n, size_t *eaddrpos, genalloc *mxipind, stralloc *storage, unsigned int timeoutdns, char const *ipme4, unsigned int n4, char const *ipme6, unsigned int n6, uint32_t flags) { skadns_t a = SKADNS_ZERO ; genalloc mxipi = GENALLOC_ZERO ; /* mxipinfo */ unsigned int pending = 0 ; unsigned int mxn = 0 ; + stralloc helosa = STRALLOC_ZERO ; uint16_t mxid = UINT16_MAX ; + uint16_t heloid4 = UINT16_MAX ; +#ifdef SKALIBS_IPV6_ENABLED + uint16_t heloid6 = UINT16_MAX ; +#endif tain deadline ; cnameinfo cnames[n] ; @@ -127,6 +132,20 @@ unsigned int dns_stuff (char const *host, char const *const *eaddr, unsigned int if (!skadns_startf_g(&a, &deadline)) qmailr_tempusys("start asynchronous DNS helper") ; + { + s6dns_domain_t q ; + if (!s6dns_domain_fromstring_noqualify_encode(&q, helohost, strlen(helohost))) + qmailr_dtempusys("DNS-encode helo string") ; + if (!skadns_send_g(&a, &heloid4, &q, S6DNS_T_A, &deadline, &deadline)) + qmailr_dtempusys("send ", "A", " DNS query") ; + pending++ ; +#ifdef SKALIBS_IPV6_ENABLED + if (!skadns_send_g(&a, &heloid6, &q, S6DNS_T_AAAA, &deadline, &deadline)) + qmailr_dtempusys("send ", "AAAA", " DNS query") ; + pending++ ; +#endif + } + for (unsigned int i = 0 ; i < n ; i++) { char const *at = strrchr(eaddr[i], '@') ; @@ -186,6 +205,42 @@ unsigned int dns_stuff (char const *host, char const *const *eaddr, unsigned int uint16_t packetlen = skadns_packetlen(&a, ids[j]) ; if (!packet) qmailr_dtempsys("DNS packet reading error") ; + if (ids[j] == heloid4) /* ipv4 for the helohost */ + { + s6dns_message_header_t h ; + r = s6dns_message_parse(&h, packet, packetlen, &s6dns_message_parse_answer_a, &helosa) ; + if (r == -1) qmailr_dtempsys("DNS packet parsing error") ; + if (!r) + { + if (errno == EBUSY || errno == EIO) qmailr_dtemp("Temporary DNS error while resolving ", "A", "for helohost") ; + else qmailr_dperm("DNS ", "A", " resolution error") ; + } + skadns_release(&a, heloid4) ; + pending-- ; + heloid4 = UINT16_MAX ; + if (helosa.len >= 4) memcpy(heloip4, helosa.s, 4) ; + helosa.len = 0 ; + } + +#ifdef SKALIBS_IPV6_ENABLED + if (ids[j] == heloid6) /* ipv4 for the helohost */ + { + s6dns_message_header_t h ; + r = s6dns_message_parse(&h, packet, packetlen, &s6dns_message_parse_answer_aaaa, &helosa) ; + if (r == -1) qmailr_dtempsys("DNS packet parsing error") ; + if (!r) + { + if (errno == EBUSY || errno == EIO) qmailr_dtemp("Temporary DNS error while resolving ", "AAAA", "for helohost") ; + else qmailr_dperm("DNS ", "AAAA", " resolution error") ; + } + skadns_release(&a, heloid6) ; + pending-- ; + heloid6 = UINT16_MAX ; + if (helosa.len >= 16) memcpy(heloip6, helosa.s, 16) ; + helosa.len = 0 ; + } +#endif + if (ids[j] == mxid) /* return from MX query */ { s6dns_message_header_t h ; @@ -324,6 +379,8 @@ unsigned int dns_stuff (char const *host, char const *const *eaddr, unsigned int } skadns_end(&a) ; /* we done, buddy */ + stralloc_free(&helosa) ; + for (unsigned int i = 0 ; i < n ; i++) { eaddrpos[i] = storage->len ; diff --git a/src/qmail-remote/qmail-remote.c b/src/qmail-remote/qmail-remote.c index 58cba67..cd7c746 100644 --- a/src/qmail-remote/qmail-remote.c +++ b/src/qmail-remote/qmail-remote.c @@ -152,18 +152,29 @@ int main (int argc, char const *const *argv) { genalloc mxipind = GENALLOC_ZERO ; - mxip const *mxs ; - size_t eaddrpos[argc] ; + mxip *mxs ; + int do4 = 1, do6 = 1 ; + char heloip4[4] = "\0\0\0" ; + char heloip6[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ; size_t ntot = 0 ; unsigned int pass = 1 + (qtls.flagwanttls && qtls.strictness == 1) ; - unsigned int mxn = dns_stuff(hostpos ? storage.s + hostpos : host, argv, argc, eaddrpos, &mxipind, &storage, timeoutdns, ipme4.s, ipme4.len >> 2, ipme6.s, ipme6.len >> 4, !hostpos) ; + size_t eaddrpos[argc] ; + unsigned int mxn = dns_stuff(storage.s + helopos, heloip4, heloip6, hostpos ? storage.s + hostpos : host, argv, argc, eaddrpos, &mxipind, &storage, timeoutdns, ipme4.s, ipme4.len >> 2, ipme6.s, ipme6.len >> 4, !hostpos) ; if (!mxn) qmailr_perm("No suitable MX found for remote host") ; stralloc_free(&ipme4) ; stralloc_free(&ipme6) ; mxs = genalloc_s(mxip, &mxipind) ; - for (unsigned int i = 0 ; i < mxn ; i++) ntot += mxs[i].n4 + mxs[i].n6 ; - if (!ntot) qmailr_perm("No suitable IP addresses for the MX") ; + if (!memcmp(heloip4, "\0\0\0", 4)) do4 = 0 ; + if (!memcmp(heloip6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) do6 = 0 ; + if (!do4 && !do6) qmailr_perm("No suitable IP addresses for ", "helohost") ; + for (unsigned int i = 0 ; i < mxn ; i++) + { + if (!do4) mxs[i].n4 = 0 ; + if (!do6) mxs[i].n6 = 0 ; + ntot += mxs[i].n4 + mxs[i].n6 ; + } + if (!ntot) qmailr_perm("No suitable IP addresses for ", "MX") ; while (pass--) { @@ -178,7 +189,8 @@ int main (int argc, char const *const *argv) int fd ; if (qmailr_tcpto_match(ip, 1)) continue ; fd = socket_tcp6() ; - if (fd == -1) qmailr_tempusys("create socket") ; + if (fd == -1) qmailr_tempusys("create", " socket") ; + if (socket_bind6(fd, heloip6, 0) == -1) qmailr_tempusys("bind", " socket") ; qdeadline(&deadline, timeoutconnect) ; if (!socket_deadlineconnstamp6_g(fd, ip, port, &deadline)) { @@ -201,6 +213,7 @@ int main (int argc, char const *const *argv) if (qmailr_tcpto_match(ip, 0)) continue ; fd = socket_tcp4() ; if (fd == -1) qmailr_tempusys("create socket") ; + if (socket_bind4(fd, heloip4, 0) == -1) qmailr_tempusys("bind", " socket") ; qdeadline(&deadline, timeoutconnect) ; if (!socket_deadlineconnstamp4_g(fd, ip, port, &deadline)) { diff --git a/src/qmail-remote/qmail-remote.h b/src/qmail-remote/qmail-remote.h index ad36d88..7b2bd98 100644 --- a/src/qmail-remote/qmail-remote.h +++ b/src/qmail-remote/qmail-remote.h @@ -29,7 +29,7 @@ struct mxip_s } ; #define MXIP_ZERO { 0 } -extern unsigned int dns_stuff (char const *, char const *const *, unsigned int, size_t *, genalloc *, stralloc *, unsigned int, char const *, unsigned int, char const *, unsigned int, uint32_t) ; +extern unsigned int dns_stuff (char const *, char *, char *, char const *, char const *const *, unsigned int, size_t *, genalloc *, stralloc *, unsigned int, char const *, unsigned int, char const *, unsigned int, uint32_t) ; /* smtproutes */ diff --git a/src/qmail-remote/tls.c b/src/qmail-remote/tls.c index 88a2370..9689578 100644 --- a/src/qmail-remote/tls.c +++ b/src/qmail-remote/tls.c @@ -44,7 +44,7 @@ void run_tls (int fdr, char const *fmtip, unsigned int timeoutconnect, unsigned char fmtw[UINT_FMT] ; char fmtt[UINT_FMT] ; char fmtk[UINT_FMT] ; - char const *argv[23 + n] ; + char const *argv[24 + n] ; if (fdw == -1) qmailr_tempusys("duplicate file descriptor") ; if (pipe(p) == -1) qmailr_tempusys("pipe") ; @@ -74,6 +74,8 @@ void run_tls (int fdr, char const *fmtip, unsigned int timeoutconnect, unsigned argv[m++] = fmtw ; argv[m++] = "-k" ; argv[m++] = storage + mxnamepos ; + if (qtls->strictness < 2) + argv[m++] = "--no-verify-cert" ; /* don't need full webpki if SMTPS isn't enforced */ argv[m++] = "--" ; argv[m++] = SMTPD_STARTTLS_PROXY_LIBEXECPREFIX "qmail-remote-io" ; |
