[exim-cvs] Add event for inbound cert visibility

Góra strony
Delete this message
Reply to this message
Autor: Exim Git Commits Mailing List
Data:  
Dla: exim-cvs
Temat: [exim-cvs] Add event for inbound cert visibility
Gitweb: http://git.exim.org/exim.git/commitdiff/723fe533c452eb258a5a7e0b808d714bbbc7cb01
Commit:     723fe533c452eb258a5a7e0b808d714bbbc7cb01
Parent:     aec45841f9139404fd61122e3db1401b13ebb0a8
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Thu Oct 23 18:22:33 2014 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sat Oct 25 21:37:59 2014 +0100


    Add event for inbound cert visibility
---
 doc/doc-txt/ChangeLog             |    4 +++-
 doc/doc-txt/experimental-spec.txt |    6 +++++-
 src/src/globals.c                 |   14 +++++++-------
 src/src/tls-gnu.c                 |   17 +++++++++++++----
 src/src/tls-openssl.c             |   15 +++++++--------
 test/confs/5750                   |    9 +++++++++
 test/confs/5760                   |    9 +++++++++
 test/log/5750                     |    2 ++
 test/log/5760                     |    3 +++
 9 files changed, 58 insertions(+), 21 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 50a6e49..ed45747 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -55,7 +55,9 @@ JH/08 Rename the TPDA expermimental facility to Event Actions.  The #ifdef
       is EXPERIMENTAL_EVENT, the main-configuration and transport options
       both become "event_action", the variables become $event_name, $event_data
       and $event_defer_errno.  There is a new variable $verify_mode, usable in
-      routers, transports and related events.
+      routers, transports and related events.  The tls:cert event is now also
+      raised for inbound connections, if the main configuration event_action
+      option is defined.



 Exim version 4.84
diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 1d3715f..faa64df 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -791,7 +791,7 @@ expansion is done.  The current list of events is:
  msg:fail:internal    after  main      per recipient
  tcp:connect        before transport  per connection
  tcp:close        after  transport  per connection
- tls:cert        before transport  per certificate in verification chain
+ tls:cert        before both      per certificate in verification chain
  smtp:connect        after  transport  per connection


The expansion is called for all event types, and should use the $event_name
@@ -852,6 +852,10 @@ following will be forced:
No other use is made of the result string.


+Known issues:
+- the tls:cert event is only called for the cert chain elements
+ received over the wire, with GnuTLS. OpenSSL gives the entire
+ chain including thse loaded locally.


 Redis Lookup
diff --git a/src/src/globals.c b/src/src/globals.c
index 1eae4a8..fb705d9 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -668,6 +668,13 @@ uschar *errors_copy            = NULL;
 int     error_handling         = ERRORS_SENDER;
 uschar *errors_reply_to        = NULL;
 int     errors_sender_rc       = EXIT_FAILURE;
+#ifdef EXPERIMENTAL_EVENT
+uschar *event_action             = NULL;    /* expansion for delivery events */
+uschar *event_data               = NULL;    /* auxilary data variable for event */
+int     event_defer_errno        = 0;
+uschar *event_name               = NULL;    /* event name variable */
+#endif
+


 gid_t   exim_gid               = EXIM_GID;
 BOOL    exim_gid_set           = TRUE;          /* This gid is always set */
@@ -1336,13 +1343,6 @@ int     thismessage_size_limit = 0;
 int     timeout_frozen_after   = 0;
 BOOL    timestamps_utc         = FALSE;


-#ifdef EXPERIMENTAL_EVENT
-uschar *event_action             = NULL;    /* expansion for delivery events */
-uschar *event_data               = NULL;    /* auxilary data variable for event */
-int     event_defer_errno        = 0;
-uschar *event_name               = NULL;    /* event name variable */
-#endif
-
 transport_instance  *transports = NULL;


transport_instance transport_defaults = {
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 20e11ca..1966c55 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -1545,15 +1545,15 @@ return 0;
#ifdef EXPERIMENTAL_EVENT
/*
We use this callback to get observability and detail-level control
-for an exim client TLS connection, raising a tls:cert event
-for each cert in the chain presented by the server. Any event
+for an exim TLS connection (either direction), raising a tls:cert event
+for each cert in the chain presented by the peer. Any event
can deny verification.

Return 0 for the handshake to continue or non-zero to terminate.
*/

static int
-client_verify_cb(gnutls_session_t session)
+verify_cb(gnutls_session_t session)
{
const gnutls_datum * cert_list;
unsigned int cert_list_size = 0;
@@ -1664,6 +1664,15 @@ else
gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_IGNORE);
}

+#ifdef EXPERIMENTAL_EVENT
+if (event_action)
+ {
+ state->event_action = event_action;
+ gnutls_session_set_ptr(state->session, state);
+ gnutls_certificate_set_verify_function(state->x509_cred, verify_cb);
+ }
+#endif
+
/* Register SNI handling; always, even if not in tls_certificate, so that the
expansion variable $tls_sni is always available. */

@@ -1890,7 +1899,7 @@ if (tb->event_action)
{
state->event_action = tb->event_action;
gnutls_session_set_ptr(state->session, state);
- gnutls_certificate_set_verify_function(state->x509_cred, client_verify_cb);
+ gnutls_certificate_set_verify_function(state->x509_cred, verify_cb);
}
#endif

diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 13a3cd0..4de3cad 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -287,6 +287,7 @@ verify_callback(int state, X509_STORE_CTX *x509ctx,
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
+uschar * ev;
static uschar txt[256];

 X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
@@ -323,11 +324,11 @@ else if (depth != 0)
     }
 #endif
 #ifdef EXPERIMENTAL_EVENT
-  if (tlsp == &tls_out && client_static_cbinfo->event_action)
+  ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
+  if (ev)
     {
     tlsp->peercert = X509_dup(cert);
-    if (event_raise(client_static_cbinfo->event_action,
-            US"tls:cert", string_sprintf("%d", depth)) == DEFER)
+    if (event_raise(ev, US"tls:cert", string_sprintf("%d", depth)) == DEFER)
       {
       log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
                   "depth=%d cert=%s", depth, txt);
@@ -392,10 +393,9 @@ else
 #endif    /*EXPERIMENTAL_CERTNAMES*/


 #ifdef EXPERIMENTAL_EVENT
-  if (tlsp == &tls_out)
-    {
-    if (event_raise(client_static_cbinfo->event_action,
-            US"tls:cert", US"0") == DEFER)
+  ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
+  if (ev)
+    if (event_raise(ev, US"tls:cert", US"0") == DEFER)
       {
       log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
                   "depth=0 cert=%s", txt);
@@ -403,7 +403,6 @@ else
       *calledp = TRUE;
       return 0;                /* reject */
       }
-    }
 #endif


DEBUG(D_tls) debug_printf("SSL%s verify ok: depth=0 SN=%s\n",
diff --git a/test/confs/5750 b/test/confs/5750
index 8cfef31..3898530 100644
--- a/test/confs/5750
+++ b/test/confs/5750
@@ -29,10 +29,19 @@ tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.e
tls_verify_hosts = *
tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem

+event_action = ${acl {server_cert_log}}
+
#

begin acl

+server_cert_log:
+  accept condition = ${if eq {tls:cert}{$event_name}}
+     logwrite =  [$sender_host_address] \
+            depth=$event_data \
+            ${certextract{subject}{$tls_in_peercert}}
+  accept
+
 ev_tls:
   accept logwrite =  $event_name depth=$event_data \
             <${certextract {subject} {$tls_out_peercert}}>
diff --git a/test/confs/5760 b/test/confs/5760
index b8cab04..d07aa8d 100644
--- a/test/confs/5760
+++ b/test/confs/5760
@@ -29,10 +29,19 @@ tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.e
 tls_verify_hosts = *
 tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem


+event_action = ${acl {server_cert_log}}
+
#

begin acl

+server_cert_log:
+  accept condition = ${if eq {tls:cert}{$event_name}}
+     logwrite =  [$sender_host_address] \
+            depth=$event_data \
+            ${certextract{subject}{$tls_in_peercert}}
+  accept
+
 ev_tls:
   accept logwrite =  $event_name depth=$event_data \
             <${certextract {subject} {$tls_out_peercert}}>
diff --git a/test/log/5750 b/test/log/5750
index 9e85d1a..d085892 100644
--- a/test/log/5750
+++ b/test/log/5750
@@ -40,7 +40,9 @@


******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): A TLS fatal alert has been received.: Certificate is bad
1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (send): The specified session has been invalidated for some reason.
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@???
+1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 DN="CN=server2.example.com" S=sss id=E10HmaY-0005vi-00@???
diff --git a/test/log/5760 b/test/log/5760
index 6d382ca..691ccda 100644
--- a/test/log/5760
+++ b/test/log/5760
@@ -47,4 +47,7 @@
1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@???
+1999-03-02 09:44:33 [127.0.0.1] depth=2 CN=clica CA,O=example.com
+1999-03-02 09:44:33 [127.0.0.1] depth=1 CN=clica Signing Cert,O=example.com
+1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 DN="/CN=server2.example.com" S=sss id=E10HmaY-0005vi-00@???