summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2015-07-24 14:16:16 +0200
committermanuel <manuel@mausz.at>2015-07-24 14:16:16 +0200
commit6fc0d9657d169aea8e05874c7f953f47c82deb33 (patch)
treea2edfb998a96bb9d87c909d2ce61f0f8cc258489
parent0afd1f46d4c35cc17cb412e94a1ffbcf8bd2991c (diff)
downloadqmail-6fc0d9657d169aea8e05874c7f953f47c82deb33.tar.gz
qmail-6fc0d9657d169aea8e05874c7f953f47c82deb33.tar.bz2
qmail-6fc0d9657d169aea8e05874c7f953f47c82deb33.zip
update DANE support to libval 2.1 (+fixes)
-rw-r--r--qmail-remote.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/qmail-remote.c b/qmail-remote.c
index ece335d..4119228 100644
--- a/qmail-remote.c
+++ b/qmail-remote.c
@@ -74,6 +74,7 @@ char **myargv;
74val_context_t *dane_context = NULL; 74val_context_t *dane_context = NULL;
75int dane_context_failed = 0; 75int dane_context_failed = 0;
76struct val_danestatus *dane_status = NULL; 76struct val_danestatus *dane_status = NULL;
77struct val_ssl_data *dane_ssl_data = NULL;
77#endif 78#endif
78 79
79void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); } 80void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); }
@@ -301,7 +302,7 @@ void smtp_quit()
301 /* waiting for remote side is just too ridiculous */ 302 /* waiting for remote side is just too ridiculous */
302} 303}
303 304
304void quit2(char *prepend, char *append, int flagdie) 305void quit2(const char *prepend, const char *append, int flagdie)
305{ 306{
306 smtp_quit(); 307 smtp_quit();
307 out(prepend); 308 out(prepend);
@@ -430,25 +431,26 @@ int tls_init()
430 int tls_required = (smtps || servercert != NULL); 431 int tls_required = (smtps || servercert != NULL);
431 432
432 if (partner_fqdn && !servercert && !dane_context_failed) { 433 if (partner_fqdn && !servercert && !dane_context_failed) {
433 if (val_create_context(NULL, &dane_context) == VAL_NO_ERROR) { 434 if (dane_context == NULL && val_create_context(NULL, &dane_context)
435 != VAL_NO_ERROR) {
436 dane_context_failed = 1;
437 out("lUnable to initialize libval context\n");
438 zeroflush();
439 }
440
441 if (dane_context) {
442 val_free_dane(dane_status);
443 val_free_dane_ssl(dane_ssl_data);
444
434 /* DANE: lookup TLSA records */ 445 /* DANE: lookup TLSA records */
435 struct val_daneparams dane_params = { 446 struct val_daneparams dane_params = {
436 .port = smtp_port, 447 .port = smtp_port,
437 .proto = DANE_PARAM_PROTO_TCP 448 .proto = DANE_PARAM_PROTO_TCP
438 }; 449 };
439 if (dane_status != NULL)
440 val_free_dane(dane_status);
441 dane_retval = val_getdaneinfo(dane_context, partner_fqdn, &dane_params, &dane_status); 450 dane_retval = val_getdaneinfo(dane_context, partner_fqdn, &dane_params, &dane_status);
442 if (dane_status == NULL) // insecure domain without TLSA RR will return VAL_DANE_NOERROR 451 if (dane_retval == VAL_DANE_NOERROR)
443 dane_retval = VAL_DANE_CHECK_FAILED;
444 else if (dane_retval == VAL_DANE_NOERROR)
445 tls_required = 1; 452 tls_required = 1;
446 } 453 }
447 else {
448 dane_context_failed = 1;
449 out("lUnable to initialize libval context\n");
450 zeroflush();
451 }
452 } 454 }
453 455
454 if (!smtps) { 456 if (!smtps) {
@@ -480,6 +482,19 @@ int tls_init()
480 /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ 482 /* set the callback here; SSL_set_verify didn't work before 0.9.6c */
481 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb); 483 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
482 } 484 }
485 else if (dane_retval == VAL_DANE_NOERROR) {
486 /* DANE: treat PKIX-EE as it were DANE-EE */
487 struct val_danestatus *dane_cur;
488 for (dane_cur = dane_status; dane_cur; dane_cur = dane_cur->next) {
489 if (dane_cur->usage == DANE_USE_SVC_CONSTRAINT)
490 dane_cur->usage = DANE_USE_DOMAIN_ISSUED;
491 }
492 /* DANE: set verify callback */
493 int err = val_enable_dane_ssl(dane_context, ctx, partner_fqdn, dane_status,
494 &dane_ssl_data);
495 if (err != VAL_NO_ERROR)
496 tls_quit("ZCould not enable dane verification", p_val_error(err));
497 }
483 498
484 /* let the other side complain if it needs a cert and we don't have one */ 499 /* let the other side complain if it needs a cert and we don't have one */
485 if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT)) 500 if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT))
@@ -532,10 +547,12 @@ int tls_init()
532 if (tls_required) 547 if (tls_required)
533 tls_quit("ZTLS connect failed", ssl_error_str()); 548 tls_quit("ZTLS connect failed", ssl_error_str());
534 else { 549 else {
535 smtp_quit(); 550 out("lTLS connect failed");
536 551 const char *err = ssl_error_str();
537 out("lTLS connect failed: "); 552 if (err) {
538 out(ssl_error_str()); 553 out(": ");
554 out(err);
555 }
539 out("; retrying without TLS\n"); 556 out("; retrying without TLS\n");
540 zeroflush(); 557 zeroflush();
541 558
@@ -597,11 +614,9 @@ int tls_init()
597 614
598 X509_free(peercert); 615 X509_free(peercert);
599 } 616 }
600 /* DANE: verify tls connection */ 617 /* DANE: verify result */
601 else if (dane_retval == VAL_DANE_NOERROR) { 618 else if (dane_retval == VAL_DANE_NOERROR) {
602 int do_certcheck = 0; // ignored. DANE SMTP doesn't do any PKIX checks 619 if (!SSL_get_peer_certificate(ssl) || SSL_get_verify_result(ssl) != X509_V_OK) {
603 dane_retval = val_dane_check(dane_context, ssl, dane_status, &do_certcheck);
604 if (dane_retval != VAL_DANE_NOERROR) {
605 out("lNo TLSA record matched: "); 620 out("lNo TLSA record matched: ");
606 out(partner_fqdn); 621 out(partner_fqdn);
607 quit2("/", NULL, 0); 622 quit2("/", NULL, 0);