From abe1010cc7d7d02629e1c9ca4a00240a44fe041e Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 1 Dec 2015 00:01:33 +0000 Subject: [PATCH] DKIM: $dkim_key_length visibility variable. Bug 1311 --- doc/doc-docbook/spec.xfpt | 5 +- doc/doc-txt/ChangeLog | 3 + doc/doc-txt/NewStuff | 2 + src/src/dkim.c | 7 +- src/src/expand.c | 1 + src/src/globals.c | 5 +- src/src/globals.h | 5 +- src/src/pdkim/pdkim.c | 160 +++++++++--------- test/aux-fixed/dkim/dkim512.private | 9 + test/aux-fixed/dkim/sign.pl | 9 +- test/confs/4500 | 1 + test/dnszones-src/db.test.ex | 4 + test/log/4500 | 6 +- test/log/4501 | 6 +- test/log/4502 | 6 +- .../4500-Domain-Keys-Identified-Mail/4500 | 34 +++- .../4500-Domain-Keys-Identified-Mail/REQUIRES | 1 + 17 files changed, 169 insertions(+), 95 deletions(-) create mode 100644 test/aux-fixed/dkim/dkim512.private create mode 100644 test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index af41e4493..289ba65ee 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -11417,7 +11417,8 @@ see section &<>&. &$dkim_key_nosubdomains$& &&& &$dkim_key_srvtype$& &&& &$dkim_key_granularity$& &&& - &$dkim_key_notes$& + &$dkim_key_notes$& &&& + &$dkim_key_length$& These variables are only available within the DKIM ACL. For details see chapter &<>&. @@ -37962,6 +37963,8 @@ Key granularity (tag g=) from the key record. Defaults to "*" if not specified in the key record. .vitem &%$dkim_key_notes%& Notes from the key record (tag n=). +.vitem &%$dkim_key_length%& +Number of bits in the key. .endlist In addition, two ACL conditions are provided: diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index a199a8d0d..20623997f 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -109,6 +109,9 @@ JH/21 Bug 1720: Add support for priority groups and weighted-random proxy "pri" and "weight". Note that the previous implicit priority given by the list order is no longer honoured. +JH/22 Bugs 963, 1721: Fix some corner cases in message body canonicalisation + for DKIM processing. + Exim version 4.86 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 7e530ce5d..7385212cc 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -26,6 +26,8 @@ Version 4.87 5. New "-bP config" support, to dump the effective configuration. + 6. New $dkim_key_length variable. + Version 4.86 ------------ diff --git a/src/src/dkim.c b/src/src/dkim.c index 6bae64174..2d4af50ca 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -127,12 +127,14 @@ for (sig = dkim_signatures; sig; sig = sig->next) /* Log a line for each signature */ uschar *logmsg = string_append(NULL, &size, &ptr, 5, - string_sprintf("d=%s s=%s c=%s/%s a=%s ", + string_sprintf("d=%s s=%s c=%s/%s a=%s b=%d ", sig->domain, sig->selector, sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", - sig->algo == PDKIM_ALGO_RSA_SHA256 ? "rsa-sha256" : "rsa-sha1"), + sig->algo == PDKIM_ALGO_RSA_SHA256 ? "rsa-sha256" : "rsa-sha1", + sig->sigdata_len * 8 + ), sig->identity ? string_sprintf("i=%s ", sig->identity) : US"", sig->created > 0 ? string_sprintf("t=%lu ", sig->created) : US"", @@ -256,6 +258,7 @@ for (sig = dkim_signatures; sig; sig = sig->next) dkim_signing_domain = US sig->domain; dkim_signing_selector = US sig->selector; + dkim_key_length = sig->sigdata_len * 8; return; } } diff --git a/src/src/expand.c b/src/src/expand.c index 90ffe78c0..bd16f4956 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -493,6 +493,7 @@ static var_entry var_table[] = { { "dkim_headernames", vtype_dkim, (void *)DKIM_HEADERNAMES }, { "dkim_identity", vtype_dkim, (void *)DKIM_IDENTITY }, { "dkim_key_granularity",vtype_dkim, (void *)DKIM_KEY_GRANULARITY }, + { "dkim_key_length", vtype_int, &dkim_key_length }, { "dkim_key_nosubdomains",vtype_dkim, (void *)DKIM_NOSUBDOMAINS }, { "dkim_key_notes", vtype_dkim, (void *)DKIM_KEY_NOTES }, { "dkim_key_srvtype", vtype_dkim, (void *)DKIM_KEY_SRVTYPE }, diff --git a/src/src/globals.c b/src/src/globals.c index 5dd0b13fb..eea84d3e3 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -637,13 +637,14 @@ BOOL disable_ipv6 = FALSE; BOOL disable_logging = FALSE; #ifndef DISABLE_DKIM +BOOL dkim_collect_input = FALSE; uschar *dkim_cur_signer = NULL; +BOOL dkim_disable_verify = FALSE; +int dkim_key_length = 0; uschar *dkim_signers = NULL; uschar *dkim_signing_domain = NULL; uschar *dkim_signing_selector = NULL; uschar *dkim_verify_signers = US"$dkim_signers"; -BOOL dkim_collect_input = FALSE; -BOOL dkim_disable_verify = FALSE; #endif #ifdef EXPERIMENTAL_DMARC BOOL dmarc_has_been_checked = FALSE; diff --git a/src/src/globals.h b/src/src/globals.h index 6aaa4e009..fed049531 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -374,13 +374,14 @@ extern BOOL disable_ipv6; /* Don't do any IPv6 things */ extern BOOL disable_logging; /* Disables log writing when TRUE */ #ifndef DISABLE_DKIM +extern BOOL dkim_collect_input; /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */ extern uschar *dkim_cur_signer; /* Expansion variable, holds the current "signer" domain or identity during a acl_smtp_dkim run */ +extern BOOL dkim_disable_verify; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */ +extern int dkim_key_length; /* Expansion variable, length of signing key in bits */ extern uschar *dkim_signers; /* Expansion variable, holds colon-separated list of domains and identities that have signed a message */ extern uschar *dkim_signing_domain; /* Expansion variable, domain used for signing a message. */ extern uschar *dkim_signing_selector; /* Expansion variable, selector used for signing a message. */ extern uschar *dkim_verify_signers; /* Colon-separated list of domains for each of which we call the DKIM ACL */ -extern BOOL dkim_collect_input; /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */ -extern BOOL dkim_disable_verify; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */ #endif #ifdef EXPERIMENTAL_DMARC extern BOOL dmarc_has_been_checked; /* Global variable to check if test has been called yet */ diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 4b48664df..825a2f996 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -141,22 +141,22 @@ for (i = 0; i 127) ) - fprintf(stream,"{%02x}",c); + fprintf(stream, "{%02x}", c); else - fputc(c,stream); + fputc(c, stream); break; } } if (lf) - fputc('\n',stream); + fputc('\n', stream); } void @@ -168,10 +168,10 @@ const unsigned char *p = (const unsigned char *)data; for (i =0 ; ivalue = strdup(str))) return NULL; if (base) { @@ -203,7 +203,7 @@ pdkim_prepend_stringlist(pdkim_stringlist *base, char *str) pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist)); if (!new_entry) return NULL; -memset(new_entry,0,sizeof(pdkim_stringlist)); +memset(new_entry, 0, sizeof(pdkim_stringlist)); if (!(new_entry->value = strdup(str))) return NULL; if (base) new_entry->next = base; @@ -221,7 +221,7 @@ unsigned int len = cstr ? strlen(cstr) : 0; pdkim_str *p = malloc(sizeof(pdkim_str)); if (!p) return NULL; -memset(p,0,sizeof(pdkim_str)); +memset(p, 0, sizeof(pdkim_str)); if (!(p->str = malloc(len+1))) { free(p); @@ -230,7 +230,7 @@ if (!(p->str = malloc(len+1))) p->allocated = len+1; p->len = len; if (cstr) - strcpy(p->str,cstr); + strcpy(p->str, cstr); else p->str[p->len] = '\0'; return p; @@ -265,8 +265,8 @@ char * pdkim_numcat(pdkim_str *str, unsigned long num) { char minibuf[20]; -snprintf(minibuf,20,"%lu",num); -return pdkim_strcat(str,minibuf); +snprintf(minibuf, 20, "%lu", num); +return pdkim_strcat(str, minibuf); } char * @@ -402,14 +402,14 @@ char *q; int rc = PDKIM_FAIL; /* Get header name */ -char *hcolon = strchr(header,':'); +char *hcolon = strchr(header, ':'); if (!hcolon) return rc; /* This isn't a header */ if (!(hname = malloc((hcolon-header)+1))) return PDKIM_ERR_OOM; -memset(hname,0,(hcolon-header)+1); -strncpy(hname,header,(hcolon-header)); +memset(hname, 0, (hcolon-header)+1); +strncpy(hname, header, (hcolon-header)); /* Copy tick-off list locally, so we can punch zeroes into it */ if (!(lcopy = strdup(tick))) @@ -418,12 +418,12 @@ if (!(lcopy = strdup(tick))) return PDKIM_ERR_OOM; } p = lcopy; -q = strchr(p,':'); +q = strchr(p, ':'); while (q) { *q = '\0'; - if (strcasecmp(p,hname) == 0) + if (strcasecmp(p, hname) == 0) { rc = PDKIM_OK; /* Invalidate header name instance in tick-off list */ @@ -432,10 +432,10 @@ while (q) } p = q+1; - q = strchr(p,':'); + q = strchr(p, ':'); } -if (strcasecmp(p,hname) == 0) +if (strcasecmp(p, hname) == 0) { rc = PDKIM_OK; /* Invalidate header name instance in tick-off list */ @@ -496,7 +496,7 @@ for (p = header; *p != '\0'; p++) if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */ *q = '\0'; -if (crlf) strcat(relaxed,"\r\n"); +if (crlf) strcat(relaxed, "\r\n"); return relaxed; } @@ -614,7 +614,7 @@ pdkim_signature * pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr) { pdkim_signature *sig ; -char *p,*q; +char *p, *q; pdkim_str *cur_tag = NULL; pdkim_str *cur_val = NULL; BOOL past_hname = FALSE; @@ -623,7 +623,7 @@ int where = PDKIM_HDR_LIMBO; int i; if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL; -memset(sig,0,sizeof(pdkim_signature)); +memset(sig, 0, sizeof(pdkim_signature)); sig->bodylength = -1; if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1))) @@ -805,6 +805,8 @@ if (ctx->debug_stream) pdkim_quoteprint(ctx->debug_stream, sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val), 1); + fprintf(ctx->debug_stream, + "PDKIM >> Sig size: %4d bits\n", sig->sigdata_len*8); fprintf(ctx->debug_stream, "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } @@ -837,7 +839,7 @@ pdkim_str *cur_val = NULL; int where = PDKIM_HDR_LIMBO; if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL; -memset(pub,0,sizeof(pdkim_pubkey)); +memset(pub, 0, sizeof(pdkim_pubkey)); for (p = raw_record; ; p++) { @@ -910,8 +912,8 @@ for (p = raw_record; ; p++) case 's': pub->srvtype = strdup(cur_val->str); break; case 't': - if (strchr(cur_val->str,'y') != NULL) pub->testing = 1; - if (strchr(cur_val->str,'s') != NULL) pub->no_subdomaining = 1; + if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1; + if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1; break; default: #ifdef PDKIM_DEBUG @@ -1012,9 +1014,9 @@ while (sig) if (canon_len > 0) { if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_update(sig->sha1_body,(unsigned char *)canon_data,canon_len); + sha1_update(sig->sha1_body, (unsigned char *)canon_data, canon_len); else - sha2_update(sig->sha2_body,(unsigned char *)canon_data,canon_len); + sha2_update(sig->sha2_body, (unsigned char *)canon_data, canon_len); sig->signed_body_bytes += canon_len; #ifdef PDKIM_DEBUG @@ -1044,9 +1046,9 @@ while (sig) unsigned char bh[32]; /* SHA-256 = 32 Bytes, SHA-1 = 20 Bytes */ if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_finish(sig->sha1_body,bh); + sha1_finish(sig->sha1_body, bh); else - sha2_finish(sig->sha2_body,bh); + sha2_finish(sig->sha2_body, bh); #ifdef PDKIM_DEBUG if (ctx->debug_stream) @@ -1055,7 +1057,7 @@ while (sig) sig->domain, sig->signed_body_bytes); fprintf(ctx->debug_stream, "PDKIM [%s] bh computed: ", sig->domain); pdkim_hexprint(ctx->debug_stream, (char *)bh, - (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1); + (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1); } #endif @@ -1094,7 +1096,7 @@ while (sig) { fprintf(ctx->debug_stream, "PDKIM [%s] bh signature: ", sig->domain); pdkim_hexprint(ctx->debug_stream, sig->bodyhash, - (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1); + (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32, 1); fprintf(ctx->debug_stream, "PDKIM [%s] Body hash did NOT verify\n", sig->domain); } @@ -1137,7 +1139,7 @@ if (ctx->input_mode == PDKIM_INPUT_SMTP) if ( ctx->sig && ctx->sig->canon_body == PDKIM_CANON_SIMPLE && ctx->num_buffered_crlf > 0 ) - pdkim_update_bodyhash(ctx, "\r\n",2); + pdkim_update_bodyhash(ctx, "\r\n", 2); ctx->seen_eod = 1; goto BAIL; @@ -1256,11 +1258,11 @@ if (ctx->mode == PDKIM_MODE_VERIFY) last_sig->next = new_sig; } } - else #ifdef PDKIM_DEBUG + else if (ctx->debug_stream) { - fprintf(ctx->debug_stream,"Error while parsing signature header\n"); + fprintf(ctx->debug_stream, "Error while parsing signature header\n"); fprintf(ctx->debug_stream, "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } @@ -1272,8 +1274,7 @@ if (ctx->mode == PDKIM_MODE_VERIFY) { pdkim_stringlist *list; - if (!(list = pdkim_prepend_stringlist(ctx->headers, - ctx->cur_header->str))) + if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str))) return PDKIM_ERR_OOM; ctx->headers = list; } @@ -1421,7 +1422,7 @@ while (l>77) { size_t sl = strlen(intro); - pdkim_strncat(str, intro,sl); + pdkim_strncat(str, intro, sl); *col += sl; l -= sl; intro = NULL; /* only want this once */ @@ -1432,7 +1433,7 @@ while (l>77) size_t sl = strlen(payload); size_t chomp = *col+sl < 77 ? sl : 78-*col; - pdkim_strncat(str, payload,chomp); + pdkim_strncat(str, payload, chomp); *col += chomp; payload += chomp; l -= chomp-1; @@ -1503,14 +1504,13 @@ if (!(base64_bh = pdkim_encode_base64(sig->bodyhash, sig->bodyhash_len))) col = strlen(hdr->str); /* Required and static bits */ -if ( - pdkim_headcat(&col,hdr,";","a=",pdkim_algos[sig->algo]) && - pdkim_headcat(&col,hdr,";","q=",pdkim_querymethods[sig->querymethod]) && - pdkim_strcat(canon_all,"/") && - pdkim_strcat(canon_all,pdkim_canons[sig->canon_body]) && - pdkim_headcat(&col,hdr,";","c=",canon_all->str) && - pdkim_headcat(&col,hdr,";","d=",sig->domain) && - pdkim_headcat(&col,hdr,";","s=",sig->selector) +if ( pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo]) + && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod]) + && pdkim_strcat(canon_all, "/") + && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body]) + && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str) + && pdkim_headcat(&col, hdr, ";", "d=", sig->domain) + && pdkim_headcat(&col, hdr, ";", "s=", sig->selector) ) { /* list of eader names can be split between items. */ @@ -1523,18 +1523,18 @@ if ( if (!n) goto BAIL; while (*n) { - char *c = strchr(n,':'); + char *c = strchr(n, ':'); if (c) *c ='\0'; if (!i) - if (!pdkim_headcat(&col,hdr,NULL,NULL,":")) + if (!pdkim_headcat(&col, hdr, NULL, NULL, ":")) { free(f); goto BAIL; } - if (!pdkim_headcat(&col,hdr,s,i,n)) + if (!pdkim_headcat(&col, hdr, s, i, n)) { free(f); goto BAIL; @@ -1562,7 +1562,7 @@ if ( { char minibuf[20]; - snprintf(minibuf,20,"%lu",sig->created); + snprintf(minibuf, 20, "%lu", sig->created); if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf)) goto BAIL; } @@ -1571,7 +1571,7 @@ if ( { char minibuf[20]; - snprintf(minibuf,20,"%lu",sig->expires); + snprintf(minibuf, 20, "%lu", sig->expires); if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf)) goto BAIL; } @@ -1580,7 +1580,7 @@ if ( { char minibuf[20]; - snprintf(minibuf,20,"%lu",sig->bodylength); + snprintf(minibuf, 20, "%lu", sig->bodylength); if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf)) goto BAIL; } @@ -1598,7 +1598,7 @@ if ( goto BAIL; /* add trailing semicolon: I'm not sure if this is actually needed */ - if (!pdkim_headcat(&col,hdr,NULL,";","")) + if (!pdkim_headcat(&col, hdr, NULL, ";", "")) goto BAIL; } @@ -1667,7 +1667,7 @@ while (sig) if (sig->algo == PDKIM_ALGO_RSA_SHA1) sha1_starts(&sha1_headers); else - sha2_starts(&sha2_headers,0); + sha2_starts(&sha2_headers, 0); #ifdef PDKIM_DEBUG if (ctx->debug_stream) @@ -1687,14 +1687,14 @@ while (sig) { char *rh = NULL; /* Collect header names (Note: colon presence is guaranteed here) */ - char *q = strchr(p->value,':'); + char *q = strchr(p->value, ':'); if (!(pdkim_strncat(headernames, p->value, (q-(p->value)) + (p->next ? 1 : 0)))) return PDKIM_ERR_OOM; rh = sig->canon_headers == PDKIM_CANON_RELAXED - ? pdkim_relax_header(p->value,1) /* cook header for relaxed canon */ + ? pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */ : strdup(p->value); /* just copy it for simple canon */ if (!rh) return PDKIM_ERR_OOM; @@ -1731,28 +1731,28 @@ while (sig) while(1) { - if ((q = strchr(p,':'))) + if ((q = strchr(p, ':'))) *q = '\0'; for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next) if ( hdrs->tag == 0 - && strncasecmp(hdrs->value,p,strlen(p)) == 0 + && strncasecmp(hdrs->value, p, strlen(p)) == 0 && (hdrs->value)[strlen(p)] == ':' ) { char *rh; rh = sig->canon_headers == PDKIM_CANON_RELAXED - ? pdkim_relax_header(hdrs->value,1) /* cook header for relaxed canon */ + ? pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */ : strdup(hdrs->value); /* just copy it for simple canon */ if (!rh) return PDKIM_ERR_OOM; /* Feed header to the hash algorithm */ if (sig->algo == PDKIM_ALGO_RSA_SHA1) - sha1_update(&(sha1_headers), (unsigned char *)rh, strlen(rh)); + sha1_update(&sha1_headers, (unsigned char *)rh, strlen(rh)); else - sha2_update(&(sha2_headers), (unsigned char *)rh, strlen(rh)); + sha2_update(&sha2_headers, (unsigned char *)rh, strlen(rh)); #ifdef PDKIM_DEBUG if (ctx->debug_stream) @@ -1819,8 +1819,8 @@ while (sig) /* Finalize header hash */ if (sig->algo == PDKIM_ALGO_RSA_SHA1) { - sha1_update(&(sha1_headers), (unsigned char *)sig_hdr, strlen(sig_hdr)); - sha1_finish(&(sha1_headers), (unsigned char *)headerhash); + sha1_update(&sha1_headers, (unsigned char *)sig_hdr, strlen(sig_hdr)); + sha1_finish(&sha1_headers, (unsigned char *)headerhash); #ifdef PDKIM_DEBUG if (ctx->debug_stream) @@ -1832,8 +1832,8 @@ while (sig) } else { - sha2_update(&(sha2_headers), (unsigned char *)sig_hdr, strlen(sig_hdr)); - sha2_finish(&(sha2_headers), (unsigned char *)headerhash); + sha2_update(&sha2_headers, (unsigned char *)sig_hdr, strlen(sig_hdr)); + sha2_finish(&sha2_headers, (unsigned char *)headerhash); #ifdef PDKIM_DEBUG if (ctx->debug_stream) @@ -1880,7 +1880,7 @@ while (sig) } #endif - if (!(sig->signature_header = pdkim_create_header(ctx->sig,1))) + if (!(sig->signature_header = pdkim_create_header(ctx->sig, 1))) return PDKIM_ERR_OOM; } @@ -1904,9 +1904,9 @@ while (sig) memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN); memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN); - if (snprintf(dns_txt_name,PDKIM_DNS_TXT_MAX_NAMELEN, + if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN, "%s._domainkey.%s.", - sig->selector,sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN) + sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN) { sig->verify_status = PDKIM_VERIFY_INVALID; sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE; @@ -1926,12 +1926,12 @@ while (sig) { fprintf(ctx->debug_stream, "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - fprintf(ctx->debug_stream," Raw record: "); + fprintf(ctx->debug_stream, " Raw record: "); pdkim_quoteprint(ctx->debug_stream, dns_txt_reply, strlen(dns_txt_reply), 1); } #endif - if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx,dns_txt_reply))) + if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply))) { sig->verify_status = PDKIM_VERIFY_INVALID; sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING; @@ -1939,7 +1939,7 @@ while (sig) #ifdef PDKIM_DEBUG if (ctx->debug_stream) { - fprintf(ctx->debug_stream," Error while parsing public key record\n"); + fprintf(ctx->debug_stream, " Error while parsing public key record\n"); fprintf(ctx->debug_stream, "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } @@ -2020,7 +2020,7 @@ pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx)); if (!ctx) return NULL; -memset(ctx,0,sizeof(pdkim_ctx)); +memset(ctx, 0, sizeof(pdkim_ctx)); if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN))) { @@ -2049,7 +2049,7 @@ if (!domain || !selector || !rsa_privkey) if (!(ctx = malloc(sizeof(pdkim_ctx)))) return NULL; -memset(ctx,0,sizeof(pdkim_ctx)); +memset(ctx, 0, sizeof(pdkim_ctx)); if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN))) { @@ -2063,7 +2063,7 @@ if (!(sig = malloc(sizeof(pdkim_signature)))) free(ctx); return NULL; } -memset(sig,0,sizeof(pdkim_signature)); +memset(sig, 0, sizeof(pdkim_signature)); sig->bodylength = -1; @@ -2084,7 +2084,7 @@ sha1_starts(ctx->sig->sha1_body); if (!(ctx->sig->sha2_body = malloc(sizeof(sha2_context)))) goto BAIL; -sha2_starts(ctx->sig->sha2_body,0); +sha2_starts(ctx->sig->sha2_body, 0); return ctx; diff --git a/test/aux-fixed/dkim/dkim512.private b/test/aux-fixed/dkim/dkim512.private new file mode 100644 index 000000000..159852be3 --- /dev/null +++ b/test/aux-fixed/dkim/dkim512.private @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOAIBAAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97f +xXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQI/d+Dmx+BPvOsYzjZ03HX/ +pt51OxwP/HwQa8oBJGGLfGBJbxdKZoqZu1srifgA9o25x3YrSjfK9zrUgdqJEZRp +AiEA5hUWdth65YX8dNMs93lsV0YkXdYzZ6Yxw6xyBAmpMh8CIQDUFtrIV8EYwgjq +Ck0Un4RXbZleqOljmvhK+t7IBJsjDQIgGSMEqUdNZfYVds37g64IYCCRqI7WXuSR +W0djzX0gtxECIEpwQxWyByoDYFGUj/0/B5oP85aPvmqhR6g5aNvXEgQ5AiBFgvNg +ecXPBzNb52PZWOwH/DyuYE4agI2zLTmTsDJ09Q== +-----END RSA PRIVATE KEY----- diff --git a/test/aux-fixed/dkim/sign.pl b/test/aux-fixed/dkim/sign.pl index 1c2a87280..6220015ae 100644 --- a/test/aux-fixed/dkim/sign.pl +++ b/test/aux-fixed/dkim/sign.pl @@ -2,10 +2,15 @@ use Mail::DKIM::Signer; use Mail::DKIM::TextWrap; #recommended use Getopt::Long; +# default option values my $method = "simple/simple"; +my $selector = "sel"; +my $keyfile = "aux-fixed/dkim/dkim.private"; GetOptions( "method=s" => \$method, + "selector=s" => \$selector, + "keyfile=s" => \$keyfile, ); # create a signer object @@ -13,8 +18,8 @@ my $dkim = Mail::DKIM::Signer->new( Algorithm => "rsa-sha1", Method => $method, Domain => "test.ex", - Selector => "sel", - KeyFile => "aux-fixed/dkim/dkim.private", + Selector => $selector, + KeyFile => $keyfile, ); # read an email and pass it into the signer, one line at a time diff --git a/test/confs/4500 b/test/confs/4500 index e452bc091..cb98407cc 100644 --- a/test/confs/4500 +++ b/test/confs/4500 @@ -14,6 +14,7 @@ tls_advertise_hosts = # ----- Main settings ----- acl_smtp_rcpt = accept +acl_smtp_dkim = accept logwrite = signer: $dkim_cur_signer bits: $dkim_key_length queue_only queue_run_in_order diff --git a/test/dnszones-src/db.test.ex b/test/dnszones-src/db.test.ex index 6b8a531af..07e3c0e79 100644 --- a/test/dnszones-src/db.test.ex +++ b/test/dnszones-src/db.test.ex @@ -460,7 +460,11 @@ DELAY=1500 delay1500 A HOSTIPV4 ; openssl genrsa -out aux-fixed/dkim/dkim.private 1024 ; openssl rsa -in aux-fixed/dkim/dkim.private -out /dev/stdout -pubout -outform PEM ; +; Another, 512-bit (with a Notes field) +; sel._domainkey TXT "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+YdhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB" +ses._domainkey TXT "v=DKIM1; n=halfkilo; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97fxXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQ==" + ; End diff --git a/test/log/4500 b/test/log/4500 index 5ab02f31d..4787e6423 100644 --- a/test/log/4500 +++ b/test/log/4500 @@ -1,5 +1,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 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net +1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=ses c=simple/simple a=rsa-sha1 b=512 [verification succeeded] +1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 512 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net diff --git a/test/log/4501 b/test/log/4501 index 223417674..153f6f242 100644 --- a/test/log/4501 +++ b/test/log/4501 @@ -1,7 +1,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 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024 1999-03-02 09:44:33 10HmaX-0005vi-00 <= pass@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net -1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 [verification failed - body hash mismatch (body probably modified in transit)] +1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification failed - body hash mismatch (body probably modified in transit)] +1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024 1999-03-02 09:44:33 10HmaY-0005vi-00 <= fail@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net diff --git a/test/log/4502 b/test/log/4502 index eff4be051..8745884d5 100644 --- a/test/log/4502 +++ b/test/log/4502 @@ -1,7 +1,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 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha1 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha1 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaX-0005vi-00 signer: test.ex bits: 1024 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=564CFC9B.1040905@yahoo.com -1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 [verification succeeded] +1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss diff --git a/test/scripts/4500-Domain-Keys-Identified-Mail/4500 b/test/scripts/4500-Domain-Keys-Identified-Mail/4500 index 1dea02245..b352893e3 100644 --- a/test/scripts/4500-Domain-Keys-Identified-Mail/4500 +++ b/test/scripts/4500-Domain-Keys-Identified-Mail/4500 @@ -5,7 +5,7 @@ exim -DSERVER=server -bd -oX PORT_D # # This should pass. # Mail original in aux-fixed/4500.msg1.txt -# Sig generatd by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt +# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt client 127.0.0.1 PORT_D ??? 220 HELO xxx @@ -34,6 +34,38 @@ QUIT ??? 221 **** # +# This should pass. +# Mail original in aux-fixed/4500.msg1.txt +# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple --selector=ses \ +# --keyfile=aux-fixed/dkim/dkim512.private < aux-fixed/4500.msg1.txt +client 127.0.0.1 PORT_D +??? 220 +HELO xxx +??? 250 +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to + :date:message-id:subject; s=ses; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b= + cIErF1eueIT9AU4qG54FyT3yrlVDDM7RZnuU6fWTevZpAuMqhYcRO8tU3U4vtKWB + +I2vd+F1gzqCzBcRtfLhZg== +From: mrgus@text.ex +To: bakawolf@yahoo.com +Date: Thu, 19 Nov 2015 17:00:07 -0700 +Message-ID: +Subject: simple test + +This is a simple test. +. +??? 250 +QUIT +??? 221 +**** +# +# killdaemon no_stdout_check no_msglog_check diff --git a/test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES b/test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES new file mode 100644 index 000000000..ec7e42a24 --- /dev/null +++ b/test/scripts/4500-Domain-Keys-Identified-Mail/REQUIRES @@ -0,0 +1 @@ +support DKIM -- 2.25.1