Merge branch 'master' into dane
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 20 Aug 2014 19:22:21 +0000 (20:22 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 20 Aug 2014 19:22:21 +0000 (20:22 +0100)
Conflicts:
doc/doc-txt/ChangeLog
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/verify.c

12 files changed:
1  2 
doc/doc-txt/experimental-spec.txt
src/src/deliver.c
src/src/exim.c
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/structs.h
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/transports/smtp.h
src/src/verify.c
test/runtest

Simple merge
@@@ -4133,12 -4153,9 +4161,12 @@@ for (delivery_count = 0; addr_remote !
  
        /* The certificate verification status goes into the flags */
        if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
 +#ifdef EXPERIMENTAL_DANE
 +      if (tls_out.dane_verified)        setflag(addr, af_dane_verified);
 +#endif
  
        /* Use an X item only if there's something to send */
      #ifdef SUPPORT_TLS
+ #ifdef SUPPORT_TLS
        if (addr->cipher)
          {
          ptr = big_buffer;
diff --cc src/src/exim.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1726,74 -1596,21 +1769,75 @@@ Returns:           OK on succes
  
  int
  tls_client_start(int fd, host_item *host, address_item *addr,
-   void *v_ob)
+   transport_instance *tb)
  {
- smtp_transport_options_block * ob = v_ob;
+ smtp_transport_options_block * ob =
+   (smtp_transport_options_block *)tb->options_block;
  static uschar txt[256];
 -uschar *expciphers;
 -X509* server_cert;
 +uschar * expciphers;
 +X509 * server_cert;
  int rc;
  static uschar cipherbuf[256];
 +
  #ifndef DISABLE_OCSP
 -BOOL require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
 -  NULL, host->name, host->address, NULL) == OK;
 -BOOL request_ocsp = require_ocsp ? TRUE
 -  : verify_check_this_host(&ob->hosts_request_ocsp,
 -      NULL, host->name, host->address, NULL) == OK;
 +BOOL request_ocsp = FALSE;
 +BOOL require_ocsp = FALSE;
 +#endif
 +#ifdef EXPERIMENTAL_DANE
 +dns_answer tlsa_dnsa;
 +BOOL dane = FALSE;
 +BOOL dane_required;
 +#endif
 +
 +#ifdef EXPERIMENTAL_DANE
 +tls_out.dane_verified = FALSE;
 +tls_out.tlsa_usage = 0;
 +dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
 +                        host->name, host->address, NULL) == OK;
 +
 +if (host->dnssec == DS_YES)
 +  {
 +  if(  dane_required
 +    || verify_check_this_host(&ob->hosts_try_dane, NULL,
 +                        host->name, host->address, NULL) == OK
 +    )
 +    if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
 +      return rc;
 +  }
 +else if (dane_required)
 +  {
 +  /*XXX a shame we only find this after making tcp & smtp connection */
 +  /* move the test earlier? */
 +  log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
 +  return FAIL;
 +  }
 +#endif
 +
 +#ifndef DISABLE_OCSP
 +  {
 +  if ((require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
 +    NULL, host->name, host->address, NULL) == OK))
 +    request_ocsp = TRUE;
 +  else
 +    {
 +# ifdef EXPERIMENTAL_DANE
 +    if (  dane
 +       && ob->hosts_request_ocsp[0] == '*'
 +       && ob->hosts_request_ocsp[1] == '\0'
 +       )
 +      {
 +      /* Unchanged from default.  Use a safer one under DANE */
 +      request_ocsp = TRUE;
 +      ob->hosts_request_ocsp = US"${if or { {= {0}{$tls_out_tlsa_usage}} "
 +                                      "   {= {4}{$tls_out_tlsa_usage}} } "
 +                                 " {*}{}}";
 +      }
 +    else
 +# endif
 +      request_ocsp = verify_check_this_host(&ob->hosts_request_ocsp,
 +        NULL, host->name, host->address, NULL) == OK;
 +    }
 +  }
  #endif
  
  rc = tls_init(&client_ctx, host, NULL,
@@@ -3277,17 -3276,11 +3293,17 @@@ for (cutoff_retry = 0; expired &
        session, so the in-clear transmission after those errors, if permitted,
        happens inside smtp_deliver().] */
  
      #ifdef SUPPORT_TLS
+ #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
++# ifdef EXPERIMENTAL_DANE
 +       && verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
 +             host->address, NULL) != OK
- #endif
++# endif
 +       )
          {
          log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
            "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
            expanded_hosts != NULL, &message_defer, TRUE);
          if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
            write_logs(first_addr, host);
        #ifdef EXPERIMENTAL_TPDA
ifdef EXPERIMENTAL_TPDA
          if (rc == DEFER)
-           tpda_deferred(ob, first_addr, host);
        #endif
+           tpda_deferred(first_addr, host);
endif
          }
-       #endif
 -#endif
++#endif        /*SUPPORT_TLS*/
        }
  
      /* Delivery attempt finished */
Simple merge
@@@ -643,30 -660,27 +660,30 @@@ els
          /* TLS negotiation failed; give an error.  Try in clear on a new connection,
             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)
 -          {
 -          (void)close(inblock.sock);
 -#ifdef EXPERIMENTAL_TPDA
 -          (void) tpda_raise_event(addr->transport->tpda_event_action,
 -                                  US"tcp:close", NULL);
++        {
++        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
++           && 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 "
-           "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
-         suppress_tls = TRUE;
-         goto tls_retry_connection;
-         }
-       /*save_errno = ERRNO_TLSFAILURE;*/
-       /*message = US"failure while setting up TLS session";*/
-       send_quit = FALSE;
-       done= FALSE;
-       goto TLS_FAILED;
-       }
++           )
++          {
++            (void)close(inblock.sock);
+           log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
+             "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
+           suppress_tls = TRUE;
+           goto tls_retry_connection;
+           }
+         /*save_errno = ERRNO_TLSFAILURE;*/
+         /*message = US"failure while setting up TLS session";*/
+         send_quit = FALSE;
+         done= FALSE;
+         goto TLS_FAILED;
+         }
  
          /* TLS session is set up.  Copy info for logging. */
          addr->cipher = tls_out.cipher;
diff --cc test/runtest
Simple merge