summaryrefslogtreecommitdiffstats
path: root/qmail-remote.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2023-09-26 14:11:58 +0200
committermanuel <manuel@mausz.at>2023-09-26 14:11:58 +0200
commitff1e0ece50986156e0b6f5f37985833ed0ae6c97 (patch)
tree1f3c3a158ec75c6b175ba9b081bd5ff4ea819c81 /qmail-remote.c
parent52e4c7626ff891fbaf2eb2ced1d0f42eb05dd17d (diff)
downloadqmail-ff1e0ece50986156e0b6f5f37985833ed0ae6c97.tar.gz
qmail-ff1e0ece50986156e0b6f5f37985833ed0ae6c97.tar.bz2
qmail-ff1e0ece50986156e0b6f5f37985833ed0ae6c97.zip
Add support for "require TLS"-settings
Diffstat (limited to 'qmail-remote.c')
-rw-r--r--qmail-remote.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/qmail-remote.c b/qmail-remote.c
index 125d813..a743e06 100644
--- a/qmail-remote.c
+++ b/qmail-remote.c
@@ -9,6 +9,7 @@
9#include "substdio.h" 9#include "substdio.h"
10#include "subfd.h" 10#include "subfd.h"
11#include "scan.h" 11#include "scan.h"
12#include "byte.h"
12#include "case.h" 13#include "case.h"
13#include "error.h" 14#include "error.h"
14#include "auto_qmail.h" 15#include "auto_qmail.h"
@@ -401,6 +402,7 @@ static int tls_init(struct ip_mx *current_mx)
401 stralloc saciphers = {0}; 402 stralloc saciphers = {0};
402 const char *ciphers, *servercert = 0; 403 const char *ciphers, *servercert = 0;
403 const char *mx_host = current_mx->fqdn; 404 const char *mx_host = current_mx->fqdn;
405 const char *failure_class = "Z"; // per default we do temp failures
404 406
405 if (mx_host) { 407 if (mx_host) {
406 struct stat st; 408 struct stat st;
@@ -425,10 +427,26 @@ static int tls_init(struct ip_mx *current_mx)
425 } 427 }
426 } 428 }
427 429
428 /* DANE: lookup TLSA records */
429 int tls_required = (smtps || servercert != NULL); 430 int tls_required = (smtps || servercert != NULL);
430 stralloc tlsa_rr = { 0 };
431 431
432 /* per-domain "require TLS"-settings */
433 if (!tls_required) {
434 int at = byte_rchr(sender.s, sender.len, '@') + 1;
435 if (at < sender.len) {
436 stralloc tmp = { 0 };
437 if (!stralloc_copys(&tmp, "control/tlsrequire/")
438 || !stralloc_catb(&tmp, sender.s + at, sender.len - at)
439 || !stralloc_0(&tmp)) // sender is not 0-terminated
440 temp_nomem();
441 if (control_readint(&tls_required, tmp.s) == -1) temp_control();
442 tls_required = (tls_required & 0x02) ? 1 : 0; // 2nd bit is SMTP outgoing
443 if (tls_required)
444 failure_class = "D"; // do perm failures for faster user feedback
445 }
446 }
447
448 /* DANE: lookup TLSA records */
449 stralloc tlsa_rr = { 0 };
432 if (mx_host && !servercert && current_mx->validated) { 450 if (mx_host && !servercert && current_mx->validated) {
433 stralloc tlsa_label = { 0 }; 451 stralloc tlsa_label = { 0 };
434 char port[FMT_ULONG]; 452 char port[FMT_ULONG];
@@ -456,8 +474,10 @@ static int tls_init(struct ip_mx *current_mx)
456 for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ; 474 for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ;
457 if (!len) { 475 if (!len) {
458 if (!tls_required) return 0; 476 if (!tls_required) return 0;
459 out("ZNo TLS achieved while TLS is required by configuration"); 477 out(failure_class);
460 smtptext.len = 0; TLS_QUIT; 478 out("TLS is required, but was not offered by host");
479 smtptext.len = 0;
480 TLS_QUIT;
461 } 481 }
462 } 482 }
463 483
@@ -615,10 +635,12 @@ static int tls_init(struct ip_mx *current_mx)
615 635
616 /* read the responce to STARTTLS */ 636 /* read the responce to STARTTLS */
617 if (!smtps) { 637 if (!smtps) {
618 if (smtpcode() != 220) { 638 unsigned int code = smtpcode();
639 if (code != 220) {
619 SSL_free(myssl); 640 SSL_free(myssl);
620 if (!tls_required) return 0; 641 if (!tls_required) return 0;
621 out("ZSTARTTLS rejected while TLS is required by configuration"); 642 out((code >= 500) ? "D" : failure_class);
643 out("TLS is required, but host refused to start TLS");
622 TLS_QUIT; 644 TLS_QUIT;
623 } 645 }
624 smtptext.len = 0; 646 smtptext.len = 0;
@@ -626,8 +648,10 @@ static int tls_init(struct ip_mx *current_mx)
626 648
627 ssl = myssl; 649 ssl = myssl;
628 if (ssl_timeoutconn(timeout, smtpfd, smtpfd, myssl) <= 0) { 650 if (ssl_timeoutconn(timeout, smtpfd, smtpfd, myssl) <= 0) {
629 if (tls_required) 651 if (tls_required) {
630 tls_quit("ZTLS connect failed", ssl_error_str()); 652 out(failure_class);
653 tls_quit("TLS connect failed", ssl_error_str());
654 }
631 else { 655 else {
632 out("lTLS connect failed"); 656 out("lTLS connect failed");
633 const char *err = ssl_error_str(); 657 const char *err = ssl_error_str();
@@ -707,8 +731,12 @@ static int tls_init(struct ip_mx *current_mx)
707 } 731 }
708 } 732 }
709 733
710 if (smtps) if (smtpcode() != 220) 734 if (smtps) {
711 quit("ZTLS Connected to "," but greeting failed"); 735 unsigned int code = smtpcode();
736 if (code >= 500 && code < 600) quit("DTLS connected to "," but greeting failed");
737 if (code >= 400 && code < 500) return -1; /* try next MX, see RFC-2821 */
738 if (code != 220) quit("ZTLS connected to "," but greeting failed");
739 }
712 740
713 return 1; 741 return 1;
714} 742}