Add verification glue code
authorTom Kistner <tom@duncanthrax.net>
Thu, 9 Apr 2009 13:57:21 +0000 (13:57 +0000)
committerTom Kistner <tom@duncanthrax.net>
Thu, 9 Apr 2009 13:57:21 +0000 (13:57 +0000)
src/src/dkim.c
src/src/dkim.h
src/src/globals.c
src/src/globals.h
src/src/pdkim/pdkim.h
src/src/receive.c
src/src/smtp_in.c
src/src/spool_in.c
src/src/tls-gnu.c
src/src/tls-openssl.c

index 9ac583dc31c6c96b0ab6e2cd1195e94a1f606f22..796349bef6d5b3727918ead5990c9c234dd3ac67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/dkim.c,v 1.1.2.5 2009/03/17 21:44:10 tom Exp $ */
+/* $Cambridge: exim/src/src/dkim.c,v 1.1.2.6 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 #include "pdkim/pdkim.h"
 
+pdkim_ctx       *dkim_verify_ctx = NULL;
+pdkim_signature *dkim_signatures = NULL;
 
-void dkim_exim_verify_init(void) {
+int dkim_exim_query_dns_txt(char *name, char *answer) {
+  dns_answer dnsa;
+  dns_scan   dnss;
+  dns_record *rr;
+
+  if (dns_lookup(&dnsa, (uschar *)name, T_TXT, NULL) != DNS_SUCCEED) return 1;
+
+  /* Search for TXT record */
+  for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+       rr != NULL;
+       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+    if (rr->type == T_TXT) break;
+
+  /* Copy record content to the answer buffer */
+  if (rr != NULL) {
+    int len = (rr->data)[0];
+    //if (len > 511) len = 127; // ???
+    snprintf(answer, PDKIM_DNS_TXT_MAX_RECLEN, "%.*s", len, (char *)(rr->data+1));
+  }
+  else return 1;
+
+  return PDKIM_OK;
 }
 
-void dkim_exim_verify_finish(void) {
+
+int dkim_exim_verify_init(void) {
+
+  /* Free previous context if there is one */
+  if (dkim_verify_ctx) pdkim_free_ctx(dkim_verify_ctx);
+
+  /* Create new context */
+  dkim_verify_ctx = pdkim_init_verify(PDKIM_INPUT_SMTP,
+                                      &dkim_exim_query_dns_txt
+                                     );
+
+  if (dkim_verify_ctx != NULL) {
+    dkim_collect_input = 1;
+    pdkim_set_debug_stream(dkim_verify_ctx,debug_file);
+    return 1;
+  }
+  else {
+    dkim_collect_input = 0;
+    return 0;
+  }
+}
+
+
+int dkim_exim_verify_feed(uschar *data, int len) {
+  if (pdkim_feed(dkim_verify_ctx,
+                 (char *)data,
+                 len) != PDKIM_OK) return 0;
+  return 1;
 }
 
+
+int dkim_exim_verify_finish(void) {
+  dkim_signatures = NULL;
+  dkim_collect_input = 0;
+  if (pdkim_feed_finish(dkim_verify_ctx,&dkim_signatures) != PDKIM_OK) return 0;
+
+  while (dkim_signatures != NULL) {
+    debug_printf("DKIM: Signature from domain '%s': ",dkim_signatures->domain);
+    switch(dkim_signatures->verify_status) {
+      case PDKIM_VERIFY_NONE:
+        debug_printf("not verified\n");
+        log_write(0, LOG_MAIN, "DKIM: Signature from domain '%s', selector '%s': "
+                  "not verified", dkim_signatures->domain, dkim_signatures->selector);
+      break;
+      case PDKIM_VERIFY_INVALID:
+        debug_printf("invalid\n");
+        log_write(0, LOG_MAIN, "DKIM: Signature from domain '%s', selector '%s': "
+                  "invalid", dkim_signatures->domain, dkim_signatures->selector);
+      break;
+      case PDKIM_VERIFY_FAIL:
+        debug_printf("verification failed\n");
+        log_write(0, LOG_MAIN, "DKIM: Signature from domain '%s', selector '%s': "
+                  "verification failed", dkim_signatures->domain, dkim_signatures->selector);
+      break;
+      case PDKIM_VERIFY_PASS:
+        debug_printf("verification succeeded\n");
+        log_write(0, LOG_MAIN, "DKIM: Signature from domain '%s', selector '%s': "
+                  "verification succeeded", dkim_signatures->domain, dkim_signatures->selector);
+      break;
+    }
+    /* Try next signature */
+    dkim_signatures = dkim_signatures->next;
+  }
+
+  return dkim_signatures?1:0;
+}
+
+
 int dkim_exim_verify_result(uschar *domain, uschar **result, uschar **error) {
+
+  if (dkim_verify_ctx) {
+
+  }
+
   return OK;
 }
 
+
 uschar *dkim_exim_sign(int dkim_fd,
                        uschar *dkim_private_key,
                        uschar *dkim_domain,
@@ -132,7 +226,7 @@ uschar *dkim_exim_sign(int dkim_fd,
                      NULL,
                      pdkim_canon,
                      pdkim_canon,
-                     0,
+                     -1,
                      PDKIM_ALGO_RSA_SHA256,
                      0,
                      0);
index 8d6be1e353852584ecead8a6585806298a4a5e10..a6ccd8d0fd11a77edc1e7bb991bdc7fa46cd54bd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/dkim.h,v 1.1.2.2 2009/02/24 18:43:59 tom Exp $ */
+/* $Cambridge: exim/src/src/dkim.h,v 1.1.2.3 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -7,15 +7,16 @@
 /* Copyright (c) University of Cambridge 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
-uschar *dkim_exim_sign(int ,
+uschar *dkim_exim_sign(int,
                        uschar *,
                        uschar *,
                        uschar *,
                        uschar *,
                        uschar *);
 
-void dkim_exim_verify_init(void);
-void dkim_exim_verify_finish(void);
-int dkim_exim_verify_result(uschar *domain,
+int dkim_exim_verify_init(void);
+int dkim_exim_verify_feed(uschar *, int);
+int dkim_exim_verify_finish(void);
+int dkim_exim_verify_result(uschar *,
                             uschar **,
                             uschar **);
index 9bc119b9fd4afdbb65f3d915e3783b4687998bd9..106929c66e11cad4bacf142d7073ba422a018a42 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.81.2.1 2009/02/24 15:57:55 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.81.2.2 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -391,7 +391,7 @@ int     callout_cache_domain_negative_expire = 3*60*60;
 int     callout_cache_positive_expire = 24*60*60;
 int     callout_cache_negative_expire = 2*60*60;
 uschar *callout_random_local_part = US"$primary_hostname-$tod_epoch-testing";
-uschar *check_dns_names_pattern= US"(?i)^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9/-]*[^\\W_])?)+$";
+uschar *check_dns_names_pattern= US"(?i)^(?>(?(1)\\.|())[^\\W](?>[a-z0-9/_-]*[^\\W])?)+(\.?)$";
 int     check_log_inodes       = 0;
 int     check_log_space        = 0;
 BOOL    check_rfc2047_length   = TRUE;
@@ -530,6 +530,7 @@ BOOL    disable_logging        = FALSE;
 uschar *dkim_signing_domain      = NULL;
 uschar *dkim_signing_selector    = NULL;
 int     dkim_do_verify           = 0;
+int     dkim_collect_input       = 0;
 #endif
 
 uschar *dns_again_means_nonexist = NULL;
index 8444daba6c246f217e8bafd8aee712e96a987f57..c8bad00f89ebe58a0e106490c1c1d44ee4957e3d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.62.2.1 2009/02/24 15:57:55 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.62.2.2 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -299,6 +299,7 @@ extern BOOL    disable_logging;        /* Disables log writing when TRUE */
 extern uschar *dkim_signing_domain;      /* Domain used for signing a message. */
 extern uschar *dkim_signing_selector;    /* Selector used for signing a message. */
 extern int     dkim_do_verify;           /* DKIM verification switch. Set with ACL control statement. */
+extern int     dkim_collect_input;       /* Set during message reception, when SMTP input is to be fed to the validator. */
 #endif
 
 extern uschar *dns_again_means_nonexist; /* Domains that are badly set up */
index df7e17e9b2459f32be5dfb1526df58520573ab11..1872f149790cc034aeec301a568f1df14b0eb7c3 100644 (file)
@@ -20,7 +20,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-/* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.9 2009/04/09 07:49:11 tom Exp $ */
+/* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.10 2009/04/09 13:57:21 tom Exp $ */
 
 /* -------------------------------------------------------------------------- */
 /* Debugging. This can also be enabled/disabled at run-time. I recommend to
@@ -306,7 +306,7 @@ int        pdkim_set_optional (pdkim_ctx *, char *, char *,int, int,
                                unsigned long);
 
 DLLEXPORT
-int        ppdkim_feed        (pdkim_ctx *, char *, int);
+int        pdkim_feed        (pdkim_ctx *, char *, int);
 DLLEXPORT
 int        pdkim_feed_finish  (pdkim_ctx *, pdkim_signature **);
 
index 02fd8922fd7ae47aee4defbf4f81ca810c94cf7d..82e64a28ae6e87767091c45b147ca199e97ec068 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.45.2.1 2009/02/24 15:57:55 tom Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.45.2.2 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1385,9 +1385,9 @@ message_linecount = body_linecount = body_zerocount =
   max_received_linelength = 0;
 
 #ifndef DISABLE_DKIM
-/* Call into DKIM to set up the context. Check if DKIM is to be run are carried out
-   inside dkim_exim_verify_init(). */
-dkim_exim_verify_init();
+/* Call into DKIM to set up the context. */
+if (smtp_input && dkim_do_verify) dkim_do_verify = dkim_exim_verify_init();
+else dkim_do_verify = 0;
 #endif
 
 
@@ -2971,7 +2971,7 @@ else
     {
 
 #ifndef DISABLE_DKIM
-    dkim_exim_verify_finish();
+    if (dkim_do_verify) dkim_do_verify = dkim_exim_verify_finish();
 #endif
 
 #ifdef WITH_CONTENT_SCAN
index 8cf43c8d9b474425103a7955cd0c6b9dbb31fe4a..f30daf91c88241677585e221dc5326afa37e5eb4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.63.2.1 2009/02/24 15:57:55 tom Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.63.2.2 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -264,6 +264,9 @@ if (smtp_inptr >= smtp_inend)
     else smtp_had_eof = 1;
     return EOF;
     }
+#ifndef DISABLE_DKIM
+  if (dkim_collect_input) dkim_collect_input = dkim_exim_verify_feed(smtp_inbuffer, rc);
+#endif
   smtp_inend = smtp_inbuffer + rc;
   smtp_inptr = smtp_inbuffer;
   }
@@ -1039,6 +1042,7 @@ bmi_verdicts = NULL;
 #endif
 #ifndef DISABLE_DKIM
 dkim_do_verify = 0;
+dkim_collect_input = 0;
 #endif
 #ifdef EXPERIMENTAL_SPF
 spf_header_comment = NULL;
index a6bde5fd03e60bf19eae2c77d355cd5b66d10207..b8c427511f5c0bb7937efd5a4e4e0567436d3ef0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spool_in.c,v 1.23.2.1 2009/02/24 15:57:55 tom Exp $ */
+/* $Cambridge: exim/src/src/spool_in.c,v 1.23.2.2 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -280,6 +280,7 @@ bmi_verdicts = NULL;
 
 #ifndef DISABLE_DKIM
 dkim_do_verify = 0;
+dkim_collect_input = 0;
 #endif
 
 #ifdef SUPPORT_TLS
index 2a81c8b8ab18b147e26c5a54b48f03e52451ab11..566d739224b2af2fb2c5e32ee08d60915e9fa43e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/tls-gnu.c,v 1.20 2008/09/03 18:53:29 fanf2 Exp $ */
+/* $Cambridge: exim/src/src/tls-gnu.c,v 1.20.2.1 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1172,7 +1172,9 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
     ssl_xfer_error = 1;
     return EOF;
     }
-
+#ifndef DISABLE_DKIM
+  if (dkim_collect_input) dkim_collect_input = dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
+#endif
   ssl_xfer_buffer_hwm = inbytes;
   ssl_xfer_buffer_lwm = 0;
   }
index d7f9efdad65c02d68a7cfb0ee0107055d047535f..c07ef10d0ee8c4ba2d9c7b3dda667cecd45cb269 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/tls-openssl.c,v 1.13 2008/09/03 18:53:29 fanf2 Exp $ */
+/* $Cambridge: exim/src/src/tls-openssl.c,v 1.13.2.1 2009/04/09 13:57:21 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -887,7 +887,9 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
     ssl_xfer_error = 1;
     return EOF;
     }
-
+#ifndef DISABLE_DKIM
+  if (dkim_collect_input) dkim_collect_input = dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
+#endif
   ssl_xfer_buffer_hwm = inbytes;
   ssl_xfer_buffer_lwm = 0;
   }