Test development
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 8 Aug 2014 20:37:22 +0000 (21:37 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 8 Aug 2014 20:38:10 +0000 (21:38 +0100)
doc/doc-txt/experimental-spec.txt
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/transports/smtp.h
src/src/verify.c
test/confs/5850
test/scripts/5850-DANE-OpenSSL/5850

index 333307b74e9f1a7d78c5368ef2c572b1af19d340..6eeb5092c935874389ef975e69912d28ba2dc152 100644 (file)
@@ -1224,10 +1224,9 @@ for fast revocation of certificates (which would otherwise
 be limited by the DNS TTL on the TLSA records).
 
 
 be limited by the DNS TTL on the TLSA records).
 
 
-For client-side DANE there is a new smtp transport option,
-hosts_try_dane.  It does the obvious thing.
-[ may add a hosts_require_dane, too? ]
-[ should it be domain-based rather than host-based? ]
+For client-side DANE there are two new smtp transport options,
+hosts_try_dane and hosts_require_dane.  They do the obvious thing.
+[ should they be domain-based rather than host-based? ]
 
 DANE will only be usable if the target host has DNSSEC-secured
 MX, A and TLSA records.
 
 DANE will only be usable if the target host has DNSSEC-secured
 MX, A and TLSA records.
index 201636db046b34a354c33a7ba72358d129bc55e8..0bd23ac6335b0b15464d59f6715feef408b55b6a 100644 (file)
@@ -1618,15 +1618,8 @@ BOOL dane_required;
 #endif
 
 #ifdef EXPERIMENTAL_DANE
 #endif
 
 #ifdef EXPERIMENTAL_DANE
-/*XXX TBD: test for transport options, and for TLSA records */
-/*dane = TRUE;*/
-
-# ifdef notyet
 dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
                          host->name, host->address, NULL) == OK;
 dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
                          host->name, host->address, NULL) == OK;
-# else
-dane_required = FALSE;
-#endif
 
 if (host->dnssec == DS_YES)
   {
 
 if (host->dnssec == DS_YES)
   {
@@ -1637,11 +1630,10 @@ if (host->dnssec == DS_YES)
     {
     /* move this out to host.c given the similarity to dns_lookup() ? */
     uschar buffer[300];
     {
     /* move this out to host.c given the similarity to dns_lookup() ? */
     uschar buffer[300];
-    int prefix_length; /* why do we want this? */
     uschar * fullname = buffer;
 
     /* TLSA lookup string */
     uschar * fullname = buffer;
 
     /* TLSA lookup string */
-    (void)sprintf(CS buffer, "_%d._tcp.%n%.256s", host->port, &prefix_length,
+    (void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port,
       host->name);
 
     switch (rc = dns_lookup(&tlsa_dnsa, buffer, T_TLSA, &fullname))
       host->name);
 
     switch (rc = dns_lookup(&tlsa_dnsa, buffer, T_TLSA, &fullname))
@@ -1653,7 +1645,7 @@ if (host->dnssec == DS_YES)
       case DNS_FAIL:
        if (dane_required)
          {
       case DNS_FAIL:
        if (dane_required)
          {
-         /* log that TLSA lookup failed */
+         log_write(0, LOG_MAIN, "DANE error: TLSA lookup failed");
          return FAIL;
          }
        break;
          return FAIL;
          }
        break;
@@ -1661,7 +1653,7 @@ if (host->dnssec == DS_YES)
       case DNS_SUCCEED:
        if (!dns_is_secure(&tlsa_dnsa))
          {
       case DNS_SUCCEED:
        if (!dns_is_secure(&tlsa_dnsa))
          {
-         /*log it - tlsa should never be non-dnssec */
+         log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC");
          return DEFER;
          }
        dane = TRUE;
          return DEFER;
          }
        dane = TRUE;
@@ -1669,9 +1661,10 @@ if (host->dnssec == DS_YES)
       }
     }
   }
       }
     }
   }
-else if (dane_required && !dane)
+else if (dane_required)
   {
   {
-  /* log that dnssec pre-req failed.  Hmm - what? */
+  /* Hmm - what lookup, precisely? */
+  log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
   return FAIL;
   }
 
   return FAIL;
   }
 
index 2e3a6ced40849ddfa5cd44ff016708d266ee2b21..9abc69d51042959a5ed42fe0d8a15446a286ad7f 100644 (file)
@@ -109,6 +109,10 @@ optionlist smtp_transport_options[] = {
   { "hosts_require_auth",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
 #ifdef SUPPORT_TLS
   { "hosts_require_auth",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
 #ifdef SUPPORT_TLS
+# ifdef EXPERIMENTAL_DANE
+  { "hosts_require_dane",   opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, hosts_require_dane) },
+# endif
 # ifndef DISABLE_OCSP
   { "hosts_require_ocsp",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_require_ocsp) },
 # ifndef DISABLE_OCSP
   { "hosts_require_ocsp",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_require_ocsp) },
@@ -118,7 +122,7 @@ optionlist smtp_transport_options[] = {
 #endif
   { "hosts_try_auth",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
 #endif
   { "hosts_try_auth",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
-#ifdef EXPERIMENTAL_DANE
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
   { "hosts_try_dane",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_try_dane) },
 #endif
   { "hosts_try_dane",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_try_dane) },
 #endif
@@ -206,6 +210,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* hosts_require_auth */
 #ifdef EXPERIMENTAL_DANE
   NULL,                /* hosts_try_dane */
   NULL,                /* hosts_require_auth */
 #ifdef EXPERIMENTAL_DANE
   NULL,                /* hosts_try_dane */
+  NULL,                /* hosts_require_dane */
 #endif
 #ifndef DISABLE_PRDR
   NULL,                /* hosts_try_prdr */
 #endif
 #ifndef DISABLE_PRDR
   NULL,                /* hosts_try_prdr */
@@ -1571,8 +1576,13 @@ if (tls_out.active >= 0)
 /* If the host is required to use a secure channel, ensure that we
 have one. */
 
 /* If the host is required to use a secure channel, ensure that we
 have one. */
 
-else if (verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-          host->address, NULL) == OK)
+else if (  verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
+            host->address, NULL) == OK
+#ifdef EXPERIMENTAL_DANE
+       || verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
+            host->address, NULL) == OK
+#endif
+       )
   {
   save_errno = ERRNO_TLSREQUIRED;
   message = string_sprintf("a TLS session is required for %s [%s], but %s",
   {
   save_errno = ERRNO_TLSREQUIRED;
   message = string_sprintf("a TLS session is required for %s [%s], but %s",
@@ -3268,10 +3278,16 @@ for (cutoff_retry = 0; expired &&
       happens inside smtp_deliver().] */
 
       #ifdef SUPPORT_TLS
       happens inside smtp_deliver().] */
 
       #ifdef SUPPORT_TLS
-      if (rc == DEFER && first_addr->basic_errno == ERRNO_TLSFAILURE &&
-           ob->tls_tempfail_tryclear &&
-           verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-             host->address, NULL) != OK)
+      if (  rc == DEFER
+        && first_addr->basic_errno == ERRNO_TLSFAILURE
+        && ob->tls_tempfail_tryclear
+        && verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
+             host->address, NULL) != OK
+#ifdef EXPERIMENTAL_DANE
+        && verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
+             host->address, NULL) != OK
+#endif
+        )
         {
         log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
           "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
         {
         log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
           "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
index 018f9cfef8befd932ea8000cee854f5cf454351d..d968a4d549a4e3e1bffb2a8da97f90944812e9fc 100644 (file)
@@ -23,6 +23,7 @@ typedef struct {
   uschar *hosts_require_auth;
 #ifdef EXPERIMENTAL_DANE
   uschar *hosts_try_dane;
   uschar *hosts_require_auth;
 #ifdef EXPERIMENTAL_DANE
   uschar *hosts_try_dane;
+  uschar *hosts_require_dane;
 #endif
 #ifndef DISABLE_PRDR
   uschar *hosts_try_prdr;
 #endif
 #ifndef DISABLE_PRDR
   uschar *hosts_try_prdr;
index b1b9f29a449ce232a7655a750aa57faa1ec9832d..c2ee4789288620bcee27469cc42497453cd9cfd2 100644 (file)
@@ -644,9 +644,16 @@ else
            if the options permit it for this host. */
         if (rc != OK)
           {
            if the options permit it for this host. */
         if (rc != OK)
           {
-       if (rc == DEFER && ob->tls_tempfail_tryclear && !smtps &&
-          verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-            host->address, NULL) != OK)
+       if (  rc == DEFER
+          && ob->tls_tempfail_tryclear
+          && !smtps
+          && verify_check_this_host(&(ob->hosts_require_tls), NULL,
+            host->name, host->address, NULL) != OK
+#ifdef EXPERIMENTAL_DANE
+          && verify_check_this_host(&(ob->hosts_require_dane), NULL,
+            host->name, host->address, NULL) != OK
+#endif
+          )
          {
             (void)close(inblock.sock);
          log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
          {
             (void)close(inblock.sock);
          log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
@@ -676,8 +683,13 @@ else
 
     /* If the host is required to use a secure channel, ensure that we have one. */
     if (tls_out.active < 0)
 
     /* If the host is required to use a secure channel, ensure that we have one. */
     if (tls_out.active < 0)
-      if (verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-       host->address, NULL) == OK)
+      if (  verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
+             host->address, NULL) == OK
+#ifdef EXPERIMENTAL_DANE
+        || verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
+             host->address, NULL) == OK
+#endif
+        )
         {
         /*save_errno = ERRNO_TLSREQUIRED;*/
         log_write(0, LOG_MAIN, "a TLS session is required for %s [%s], but %s",
         {
         /*save_errno = ERRNO_TLSREQUIRED;*/
         log_write(0, LOG_MAIN, "a TLS session is required for %s [%s], but %s",
index ac967fcb8b5242093de288947c1072fabbd4ef11..53cb78ae182c5e231c54d0b2efa2714a9b752923 100644 (file)
@@ -60,6 +60,9 @@ send_to_server:
 #  tls_privatekey = DIR/aux-fixed/cert2
 #  tls_verify_certificates = DIR/aux-fixed/cert2
 
 #  tls_privatekey = DIR/aux-fixed/cert2
 #  tls_verify_certificates = DIR/aux-fixed/cert2
 
+#  hosts_try_dane = *
+  hosts_require_dane = *
+
 
 # ----- Retry -----
 
 
 # ----- Retry -----
 
index 419930e112c50c997d4d82964edcfeda29fdd310..0776fb6b4ff7b2a94bf747e2b6a1059920996936 100644 (file)
@@ -5,7 +5,7 @@ exim -DSERVER=server -bd -oX PORT_D
 exim CALLER@test.ex
 Testing
 ****
 exim CALLER@test.ex
 Testing
 ****
-exim -qf
+exim -d+all -qf
 ****
 killdaemon
 exim -DSERVER=server -DNOTDAEMON -qf
 ****
 killdaemon
 exim -DSERVER=server -DNOTDAEMON -qf