X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/321ef002e23ff171922075988bcd8e77bae884b7..d7978c0f8af20ff4c3f770589b1bb81568aecff3:/src/src/pdkim/pdkim.c diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 5688c78a8..d056402e1 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -124,9 +124,8 @@ return string_sprintf("%s-%s", int pdkim_hashname_to_hashtype(const uschar * s, unsigned len) { -int i; if (!len) len = Ustrlen(s); -for (i = 0; i < nelem(pdkim_hashes); i++) +for (int i = 0; i < nelem(pdkim_hashes); i++) if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0) return i; return -1; @@ -136,9 +135,8 @@ void pdkim_cstring_to_canons(const uschar * s, unsigned len, int * canon_head, int * canon_body) { -int i; if (!len) len = Ustrlen(s); -for (i = 0; pdkim_combined_canons[i].str; i++) +for (int i = 0; pdkim_combined_canons[i].str; i++) if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0 && len == Ustrlen(pdkim_combined_canons[i].str)) { @@ -192,6 +190,7 @@ switch(status) case PDKIM_ERR_RSA_SIGNING: return US"SIGNING"; case PDKIM_ERR_LONG_LINE: return US"LONG_LINE"; case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL"; + case PDKIM_ERR_EXCESS_SIGS: return US"EXCESS_SIGS"; case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP"; case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D"; default: return US"(unknown)"; @@ -204,8 +203,7 @@ switch(status) void pdkim_quoteprint(const uschar *data, int len) { -int i; -for (i = 0; i < len; i++) +for (int i = 0; i < len; i++) { const int c = data[i]; switch (c) @@ -230,8 +228,7 @@ debug_printf("\n"); void pdkim_hexprint(const uschar *data, int len) { -int i; -if (data) for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]); +if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]); else debug_printf(""); debug_printf("\n"); } @@ -331,11 +328,10 @@ pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf) { BOOL past_field_name = FALSE; BOOL seen_wsp = FALSE; -const uschar * p; uschar * relaxed = store_get(len+3); uschar * q = relaxed; -for (p = header; p - header < len; p++) +for (const uschar * p = header; p - header < len; p++) { uschar c = *p; @@ -462,13 +458,12 @@ static pdkim_signature * pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr) { pdkim_signature * sig; -uschar *p, *q; +uschar *q; gstring * cur_tag = NULL; gstring * cur_val = NULL; BOOL past_hname = FALSE; BOOL in_b_val = FALSE; int where = PDKIM_HDR_LIMBO; -int i; sig = store_get(sizeof(pdkim_signature)); memset(sig, 0, sizeof(pdkim_signature)); @@ -481,7 +476,7 @@ sig->hashtype = -1; q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1); -for (p = raw_hdr; ; p++) +for (uschar * p = raw_hdr; ; p++) { char c = *p; @@ -566,11 +561,11 @@ for (p = raw_hdr; ; p++) uschar * elem; if ((elem = string_nextinlist(&list, &sep, NULL, 0))) - for(i = 0; i < nelem(pdkim_keytypes); i++) + for (int i = 0; i < nelem(pdkim_keytypes); i++) if (Ustrcmp(elem, pdkim_keytypes[i]) == 0) { sig->keytype = i; break; } if ((elem = string_nextinlist(&list, &sep, NULL, 0))) - for (i = 0; i < nelem(pdkim_hashes); i++) + for (int i = 0; i < nelem(pdkim_hashes); i++) if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0) { sig->hashtype = i; break; } } @@ -580,7 +575,7 @@ for (p = raw_hdr; ; p++) &sig->canon_headers, &sig->canon_body); break; case 'q': /* Query method (for pubkey)*/ - for (i = 0; pdkim_querymethods[i]; i++) + for (int i = 0; pdkim_querymethods[i]; i++) if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0) { sig->querymethod = i; /* we never actually use this */ @@ -729,7 +724,6 @@ if (b->canon_method == PDKIM_CANON_RELAXED) if (!relaxed_data) { BOOL seen_wsp = FALSE; - const uschar * p, * r; int q = 0; /* We want to be able to free this else we allocate @@ -740,7 +734,7 @@ if (b->canon_method == PDKIM_CANON_RELAXED) relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1); relaxed_data->data = US (relaxed_data+1); - for (p = orig_data->data, r = p + orig_data->len; p < r; p++) + for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++) { char c = *p; if (c == '\r') @@ -787,10 +781,7 @@ return relaxed_data; static void pdkim_finish_bodyhash(pdkim_ctx * ctx) { -pdkim_bodyhash * b; -pdkim_signature * sig; - -for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */ +for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */ { DEBUG(D_acl) debug_printf("PDKIM: finish bodyhash %d/%d/%ld len %ld\n", b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes); @@ -798,9 +789,9 @@ for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */ } /* Traverse all signatures */ -for (sig = ctx->sig; sig; sig = sig->next) +for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { - b = sig->calc_body_hash; + pdkim_bodyhash * b = sig->calc_body_hash; DEBUG(D_acl) { @@ -848,15 +839,13 @@ for (sig = ctx->sig; sig; sig = sig->next) static void pdkim_body_complete(pdkim_ctx * ctx) { -pdkim_bodyhash * b; - /* In simple body mode, if any empty lines were buffered, replace with one. rfc 4871 3.4.3 */ /*XXX checking the signed-body-bytes is a gross hack; I think it indicates that all linebreaks should be buffered, including the one terminating a text line */ -for (b = ctx->bodyhash; b; b = b->next) +for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) if ( b->canon_method == PDKIM_CANON_SIMPLE && b->signed_body_bytes == 0 && b->num_buffered_blanklines > 0 @@ -877,7 +866,6 @@ static void pdkim_bodyline_complete(pdkim_ctx * ctx) { blob line = {.data = ctx->linebuf, .len = ctx->linebuf_offset}; -pdkim_bodyhash * b; blob * rnl = NULL; blob * rline = NULL; @@ -901,12 +889,13 @@ if (ctx->flags & PDKIM_DOT_TERM) /* Empty lines need to be buffered until we find a non-empty line */ if (memcmp(line.data, "\r\n", 2) == 0) { - for (b = ctx->bodyhash; b; b = b->next) b->num_buffered_blanklines++; + for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) + b->num_buffered_blanklines++; goto all_skip; } /* Process line for each bodyhash separately */ -for (b = ctx->bodyhash; b; b = b->next) +for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) { if (b->canon_method == PDKIM_CANON_RELAXED) { @@ -955,9 +944,6 @@ return; static int pdkim_header_complete(pdkim_ctx * ctx) { -pdkim_signature * sig, * last_sig; - -/* Special case: The last header can have an extra \r appended */ if ( (ctx->cur_header->ptr > 1) && (ctx->cur_header->s[ctx->cur_header->ptr-1] == '\r') ) --ctx->cur_header->ptr; @@ -972,7 +958,7 @@ if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL; /* SIGNING -------------------------------------------------------------- */ if (ctx->flags & PDKIM_MODE_SIGN) - for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */ + for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */ /* Add header to the signed headers list (in reverse order) */ sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s); @@ -992,6 +978,7 @@ else DKIM_SIGNATURE_HEADERNAME, Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0) { + pdkim_signature * sig, * last_sig; /* Create and chain new signature block. We could error-check for all required tags here, but prefer to create the internal sig and expicitly fail verification of it later. */ @@ -1008,6 +995,13 @@ else while (last_sig->next) last_sig = last_sig->next; last_sig->next = sig; } + + if (--dkim_collect_input == 0) + { + ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s); + ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; + return PDKIM_ERR_EXCESS_SIGS; + } } /* all headers are stored for signature verification */ @@ -1027,15 +1021,14 @@ return PDKIM_OK; DLLEXPORT int pdkim_feed(pdkim_ctx * ctx, uschar * data, int len) { -int p, rc; - /* Alternate EOD signal, used in non-dotstuffing mode */ if (!data) pdkim_body_complete(ctx); -else for (p = 0; pflags & PDKIM_PAST_HDRS) { @@ -1419,8 +1412,7 @@ instead. Assume writing on the sig is ok in that case. */ if (sig->keytype < 0) { - int i; - for(i = 0; i < nelem(pdkim_keytypes); i++) + for(int i = 0; i < nelem(pdkim_keytypes); i++) if (Ustrcmp(p->keytype, pdkim_keytypes[i]) == 0) { sig->keytype = i; goto k_ok; } DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype); @@ -1454,8 +1446,6 @@ DLLEXPORT int pdkim_feed_finish(pdkim_ctx * ctx, pdkim_signature ** return_signatures, const uschar ** err) { -pdkim_bodyhash * b; -pdkim_signature * sig; BOOL verify_pass = FALSE; /* Check if we must still flush a (partial) header. If that is the @@ -1469,7 +1459,7 @@ if (ctx->cur_header && ctx->cur_header->ptr > 0) if ((rc = pdkim_header_complete(ctx)) != PDKIM_OK) return rc; - for (b = ctx->bodyhash; b; b = b->next) + for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) rnl = pdkim_update_ctx_bodyhash(b, &lineending, rnl); if (rnl) store_free(rnl); } @@ -1489,7 +1479,7 @@ if (!ctx->sig) return PDKIM_OK; } -for (sig = ctx->sig; sig; sig = sig->next) +for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { hctx hhash_ctx; uschar * sig_hdr = US""; @@ -1553,7 +1543,6 @@ for (sig = ctx->sig; sig; sig = sig->next) if (ctx->flags & PDKIM_MODE_SIGN) { gstring * g = NULL; - pdkim_stringlist *p; const uschar * l; uschar * s; int sep = 0; @@ -1569,8 +1558,8 @@ for (sig = ctx->sig; sig; sig = sig->next) } sig->keytype = sctx.keytype; - for (sig->headernames = NULL, /* Collected signed header names */ - p = sig->headers; p; p = p->next) + sig->headernames = NULL; /* Collected signed header names */ + for (pdkim_stringlist * p = sig->headers; p; p = p->next) { uschar * rh = p->value; @@ -1617,12 +1606,11 @@ for (sig = ctx->sig; sig; sig = sig->next) { uschar * p = sig->headernames; uschar * q; - pdkim_stringlist * hdrs; if (p) { /* clear tags */ - for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next) + for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next) hdrs->tag = 0; p = string_copy(p); @@ -1632,7 +1620,7 @@ for (sig = ctx->sig; sig; sig = sig->next) *q = '\0'; /*XXX walk the list of headers in same order as received. */ - for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next) + for (pdkim_stringlist * hdrs = ctx->headers; hdrs; hdrs = hdrs->next) if ( hdrs->tag == 0 && strncasecmp(CCS hdrs->value, CCS p, Ustrlen(p)) == 0 && (hdrs->value)[Ustrlen(p)] == ':'