aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL2
-rw-r--r--doc/index.html2
-rw-r--r--doc/upgrade.html2
-rw-r--r--package/deps-build2
-rw-r--r--src/qmail-remote/dns.c59
-rw-r--r--src/qmail-remote/qmail-remote.c25
-rw-r--r--src/qmail-remote/qmail-remote.h2
-rw-r--r--src/qmail-remote/tls.c4
8 files changed, 85 insertions, 13 deletions
diff --git a/INSTALL b/INSTALL
index 2dce67d..4709ba3 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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" ;