From bfb29b3b4fb4a3e191f2f6ac5bfa7d5ca2fd8ebb Mon Sep 17 00:00:00 2001 From: Tom Kistner Date: Thu, 9 Apr 2009 13:57:21 +0000 Subject: [PATCH] Add verification glue code --- src/src/dkim.c | 102 ++++++++++++++++++++++++++++++++++++++++-- src/src/dkim.h | 11 ++--- src/src/globals.c | 5 ++- src/src/globals.h | 3 +- src/src/pdkim/pdkim.h | 4 +- src/src/receive.c | 10 ++--- src/src/smtp_in.c | 6 ++- src/src/spool_in.c | 3 +- src/src/tls-gnu.c | 6 ++- src/src/tls-openssl.c | 6 ++- 10 files changed, 131 insertions(+), 25 deletions(-) diff --git a/src/src/dkim.c b/src/src/dkim.c index 9ac583dc3..796349bef 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -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 * @@ -16,17 +16,111 @@ #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); diff --git a/src/src/dkim.h b/src/src/dkim.h index 8d6be1e35..a6ccd8d0f 100644 --- a/src/src/dkim.h +++ b/src/src/dkim.h @@ -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 **); diff --git a/src/src/globals.c b/src/src/globals.c index 9bc119b9f..106929c66 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -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; diff --git a/src/src/globals.h b/src/src/globals.h index 8444daba6..c8bad00f8 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -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 */ diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index df7e17e9b..1872f1497 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -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 **); diff --git a/src/src/receive.c b/src/src/receive.c index 02fd8922f..82e64a28a 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -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 diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 8cf43c8d9..f30daf91c 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -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; diff --git a/src/src/spool_in.c b/src/src/spool_in.c index a6bde5fd0..b8c427511 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -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 diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 2a81c8b8a..566d73922 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -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; } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index d7f9efdad..c07ef10d0 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -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; } -- 2.30.2