X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/a8e1eeba8a2ff7eb5b2c6165d63f003fd0dfe3eb..3386088d5af4d4c61faa12ae29560e2c5bd43304:/src/src/dkim.c diff --git a/src/src/dkim.c b/src/src/dkim.c index d2abaff76..3e7154525 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/dkim.c,v 1.12 2010/02/18 12:09:15 michael Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge, 1995 - 2007 */ +/* Copyright (c) University of Cambridge, 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ /* Code for DKIM support. Other DKIM relevant code is in @@ -25,6 +23,7 @@ int dkim_exim_query_dns_txt(char *name, char *answer) { dns_scan dnss; dns_record *rr; + lookup_dnssec_authenticated = NULL; if (dns_lookup(&dnsa, (uschar *)name, T_TXT, NULL) != DNS_SUCCEED) return PDKIM_FAIL; /* Search for TXT record */ @@ -44,6 +43,9 @@ int dkim_exim_query_dns_txt(char *name, char *answer) { "%.*s", (int)len, (char *)((rr->data)+rr_offset)); rr_offset+=len; answer_offset+=len; + if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN) { + return PDKIM_FAIL; + } } } else return PDKIM_FAIL; @@ -92,7 +94,7 @@ void dkim_exim_verify_finish(void) { means there was a processing error somewhere along the way. Log the incident and disable futher verification. */ if (!dkim_collect_input) { - log_write(0, LOG_MAIN|LOG_PANIC, "DKIM: Error while running this message through validation, disabling signature verification."); + log_write(0, LOG_MAIN, "DKIM: Error while running this message through validation, disabling signature verification."); dkim_disable_verify = TRUE; return; } @@ -108,7 +110,7 @@ void dkim_exim_verify_finish(void) { /* Log a line for each signature */ uschar *logmsg = string_append(NULL, &size, &ptr, 5, - string_sprintf( "DKIM: d=%s s=%s c=%s/%s a=%s ", + string_sprintf( "d=%s s=%s c=%s/%s a=%s ", sig->domain, sig->selector, (sig->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed", @@ -176,7 +178,7 @@ void dkim_exim_verify_finish(void) { } logmsg[ptr] = '\0'; - log_write(0, LOG_MAIN, (char *)logmsg); + log_write(0, LOG_MAIN, "DKIM: %s", logmsg); /* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */ dkim_signers = string_append(dkim_signers, @@ -381,12 +383,11 @@ uschar *dkim_exim_expand_defaults(int what) { } -uschar *dkim_exim_sign(int dkim_fd, - uschar *dkim_private_key, - uschar *dkim_domain, - uschar *dkim_selector, - uschar *dkim_canon, - uschar *dkim_sign_headers) { +uschar * +dkim_exim_sign(int dkim_fd, uschar *dkim_private_key, + const uschar *dkim_domain, uschar *dkim_selector, + uschar *dkim_canon, uschar *dkim_sign_headers) +{ int sep = 0; uschar *seen_items = NULL; int seen_items_size = 0; @@ -397,6 +398,9 @@ uschar *dkim_exim_sign(int dkim_fd, uschar *dkim_private_key_expanded; pdkim_ctx *ctx = NULL; uschar *rc = NULL; + uschar *sigbuf = NULL; + int sigsize = 0; + int sigptr = 0; pdkim_signature *signature; int pdkim_canon; int pdkim_rc; @@ -405,7 +409,9 @@ uschar *dkim_exim_sign(int dkim_fd, int save_errno = 0; int old_pool = store_pool; - dkim_domain = expand_string(dkim_domain); + store_pool = POOL_MAIN; + + dkim_domain = expand_cstring(dkim_domain); if (dkim_domain == NULL) { /* expansion error, do not send message. */ log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand " @@ -422,7 +428,7 @@ uschar *dkim_exim_sign(int dkim_fd, /* Only sign once for each domain, no matter how often it appears in the expanded list. */ if (seen_items != NULL) { - uschar *seen_items_list = seen_items; + const uschar *seen_items_list = seen_items; if (match_isinlist(dkim_signing_domain, &seen_items_list,0,NULL,NULL,MCL_STRING,TRUE,NULL) == OK) continue; @@ -458,12 +464,18 @@ uschar *dkim_exim_sign(int dkim_fd, pdkim_canon = PDKIM_CANON_RELAXED; } - dkim_sign_headers_expanded = expand_string(dkim_sign_headers); - if (dkim_sign_headers_expanded == NULL) { - log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand " - "dkim_sign_headers: %s", expand_string_message); - rc = NULL; - goto CLEANUP; + if (dkim_sign_headers) { + dkim_sign_headers_expanded = expand_string(dkim_sign_headers); + if (dkim_sign_headers_expanded == NULL) { + log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand " + "dkim_sign_headers: %s", expand_string_message); + rc = NULL; + goto CLEANUP; + } + } + else { + /* pass NULL, which means default header list */ + dkim_sign_headers_expanded = NULL; } /* Get private key to use. */ @@ -478,8 +490,7 @@ uschar *dkim_exim_sign(int dkim_fd, (Ustrcmp(dkim_private_key_expanded,"0") == 0) || (Ustrcmp(dkim_private_key_expanded,"false") == 0) ) { /* don't sign, but no error */ - rc = US""; - goto CLEANUP; + continue; } if (dkim_private_key_expanded[0] == '/') { @@ -493,7 +504,12 @@ uschar *dkim_exim_sign(int dkim_fd, rc = NULL; goto CLEANUP; } - (void)read(privkey_fd,big_buffer,(big_buffer_size-2)); + if (read(privkey_fd,big_buffer,(big_buffer_size-2)) < 0) { + log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s", + dkim_private_key_expanded); + rc = NULL; + goto CLEANUP; + } (void)close(privkey_fd); dkim_private_key_expanded = big_buffer; } @@ -516,6 +532,7 @@ uschar *dkim_exim_sign(int dkim_fd, 0, 0); + lseek(dkim_fd, 0, SEEK_SET); while((sread = read(dkim_fd,&buf,4096)) > 0) { if (pdkim_feed(ctx,buf,sread) != PDKIM_OK) { rc = NULL; @@ -533,17 +550,24 @@ uschar *dkim_exim_sign(int dkim_fd, pdkim_rc = pdkim_feed_finish(ctx,&signature); if (pdkim_rc != PDKIM_OK) { log_write(0, LOG_MAIN|LOG_PANIC, "DKIM: signing failed (RC %d)", pdkim_rc); + rc = NULL; goto CLEANUP; } - rc = store_get(strlen(signature->signature_header)+3); - Ustrcpy(rc,US signature->signature_header); - Ustrcat(rc,US"\r\n"); + sigbuf = string_append(sigbuf, &sigsize, &sigptr, 2, + US signature->signature_header, + US"\r\n"); pdkim_free_ctx(ctx); ctx = NULL; } + if (sigbuf != NULL) { + sigbuf[sigptr] = '\0'; + rc = sigbuf; + } else + rc = US""; + CLEANUP: if (ctx != NULL) pdkim_free_ctx(ctx);