From 2d75f09c2df079365b0fc2c9fb22a130c9267611 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 3 Sep 2024 17:56:22 +0100 Subject: [PATCH 1/1] Move dkim-specific debug printf handlers to general string-services --- src/src/arc.c | 25 ++++++++-------- src/src/pdkim/pdkim.c | 69 ++++++++++--------------------------------- src/src/pdkim/pdkim.h | 2 -- src/src/string.c | 49 +++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/src/arc.c b/src/src/arc.c index 2dcbf2efb..d24b61114 100644 --- a/src/src/arc.c +++ b/src/src/arc.c @@ -630,8 +630,7 @@ while ((hn = string_nextinlist(&headernames, &sep, NULL, 0))) { if (relaxed) s = pdkim_relax_header_n(s, r->h->slen, TRUE); - len = Ustrlen(s); - DEBUG(D_acl) pdkim_quoteprint(s, len); + DEBUG(D_acl) debug_printf("%Z\n", s); exim_sha_update_string(&hhash_ctx, s); r->used = TRUE; break; @@ -642,12 +641,12 @@ while ((hn = string_nextinlist(&headernames, &sep, NULL, 0))) s = ams->rawsig_no_b_val.data, len = ams->rawsig_no_b_val.len; if (relaxed) len = Ustrlen(s = pdkim_relax_header_n(s, len, FALSE)); -DEBUG(D_acl) pdkim_quoteprint(s, len); +DEBUG(D_acl) debug_printf("%.*Z\n", len, s); exim_sha_update(&hhash_ctx, s, len); exim_sha_finish(&hhash_ctx, hhash); DEBUG(D_acl) - { debug_printf("ARC: header hash: "); pdkim_hexprint(hhash->data, hhash->len); } + { debug_printf("ARC: header hash: %.*H\n", hhash->len, hhash->data); } return; } @@ -766,7 +765,7 @@ DEBUG(D_acl) " Body %.*s computed: ", as->instance, b->signed_body_bytes, (int)ams->a_hash.len, ams->a_hash.data); - pdkim_hexprint(CUS b->bh.data, b->bh.len); + debug_printf("%.*H\n", b->bh.len, b->bh.data); } /* We know the bh-tag blob is of a nul-term string, so safe as a string */ @@ -779,7 +778,7 @@ if ( !ams->bh.data DEBUG(D_acl) { debug_printf("ARC i=%d AMS Body hash from headers: ", as->instance); - pdkim_hexprint(sighash.data, sighash.len); + debug_printf("%.*H\n", sighash.len, sighash.data); debug_printf("ARC i=%d AMS Body hash did NOT match\n", as->instance); } return as->ams_verify_done = arc_state_reason = US"AMS body hash miscompare"; @@ -971,7 +970,7 @@ for (as2 = ctx->arcset_chain; al->relaxed = s = pdkim_relax_header_n(al->complete->text, al->complete->slen, TRUE); len = Ustrlen(s); - DEBUG(D_acl) pdkim_quoteprint(s, len); + DEBUG(D_acl) debug_printf("%Z\n", s); exim_sha_update(&hhash_ctx, s, len); al = as2->hdr_ams; @@ -979,7 +978,7 @@ for (as2 = ctx->arcset_chain; al->relaxed = s = pdkim_relax_header_n(al->complete->text, al->complete->slen, TRUE); len = Ustrlen(s); - DEBUG(D_acl) pdkim_quoteprint(s, len); + DEBUG(D_acl) debug_printf("%Z\n", s); exim_sha_update(&hhash_ctx, s, len); al = as2->hdr_as; @@ -990,7 +989,7 @@ for (as2 = ctx->arcset_chain; al->relaxed = s = pdkim_relax_header_n(al->complete->text, al->complete->slen, TRUE); len = Ustrlen(s); - DEBUG(D_acl) pdkim_quoteprint(s, len); + DEBUG(D_acl) debug_printf("%Z\n", s); exim_sha_update(&hhash_ctx, s, len); } @@ -1003,7 +1002,7 @@ DEBUG(D_acl) { debug_printf("ARC i=%d AS Header %.*s computed: ", as->instance, (int)hdr_as->a_hash.len, hdr_as->a_hash.data); - pdkim_hexprint(hhash_computed.data, hhash_computed.len); + debug_printf("%.*H\n", hhash_computed.len, hhash_computed.data); } @@ -1295,12 +1294,12 @@ DEBUG(D_transport) { hctx hhash_ctx; debug_printf("ARC: %s header data for signing:\n", why); - pdkim_quoteprint(hdata->s, hdata->ptr); + debug_printf("%.*Z\n", hdata->ptr, hdata->s); (void) exim_sha_init(&hhash_ctx, pdkim_hashes[hashtype].exim_hashmethod); exim_sha_update(&hhash_ctx, hdata->s, hdata->ptr); exim_sha_finish(&hhash_ctx, &hhash); - debug_printf("ARC: header hash: "); pdkim_hexprint(hhash.data, hhash.len); + debug_printf("ARC: header hash: %.*H\n", hhash.len, hhash.data); } if (FALSE /*need hash for Ed25519 or GCrypt signing*/ ) @@ -1333,7 +1332,7 @@ return TRUE; static gstring * arc_sign_append_sig(gstring * g, blob * sig) { -/*debug_printf("%s: raw sig ", __FUNCTION__); pdkim_hexprint(sig->data, sig->len);*/ +/*debug_printf("%s: raw sig %.*H\n", __FUNCTION__, sig->len, sig->data);*/ sig->data = pdkim_encode_base64(sig); sig->len = Ustrlen(sig->data); for (;;) diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 13820dc33..42e67e6aa 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -210,40 +210,6 @@ switch(status) /* -------------------------------------------------------------------------- */ -/* Print debugging functions */ -void -pdkim_quoteprint(const uschar *data, int len) -{ -for (int i = 0; i < len; i++) - { - const int c = data[i]; - switch (c) - { - case ' ' : debug_printf("{SP}"); break; - case '\t': debug_printf("{TB}"); break; - case '\r': debug_printf("{CR}"); break; - case '\n': debug_printf("{LF}"); break; - case '{' : debug_printf("{BO}"); break; - case '}' : debug_printf("{BC}"); break; - default: - if ( (c < 32) || (c > 127) ) - debug_printf("{%02x}", c); - else - debug_printf("%c", c); - break; - } - } -debug_printf("\n"); -} - -void -pdkim_hexprint(const uschar *data, int len) -{ -if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]); -else debug_printf(""); -debug_printf("\n"); -} - static pdkim_stringlist * @@ -639,7 +605,7 @@ DEBUG(D_acl) { debug_printf( "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val)); + debug_printf("%Z\n", US sig->rawsig_no_b_val); debug_printf( "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8); debug_printf( @@ -792,7 +758,7 @@ if (left > 0) { exim_sha_update(&b->body_hash_ctx, CUS canon_data->data, left); b->signed_body_bytes += left; - DEBUG(D_acl) pdkim_quoteprint(canon_data->data, left); + DEBUG(D_acl) debug_printf("%.*Z\n", left, canon_data->data); } return relaxed_data; @@ -823,7 +789,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) "DKIM [%s]%s Body %s computed: ", sig->domain, sig->selector, pdkim_canons[b->canon_method], b->signed_body_bytes, sig->domain, sig->selector, pdkim_hashes[b->hashtype].dkim_hashname); - pdkim_hexprint(CUS b->bh.data, b->bh.len); + debug_printf("%.*H\n", b->bh.len, CUS b->bh.data); } /* SIGNING -------------------------------------------------------------- */ @@ -849,7 +815,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain); - pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len); + debug_printf("%.*H\n", sig->bodyhash.len, sig->bodyhash.data); debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain); } sig->verify_status = PDKIM_VERIFY_FAIL; @@ -991,11 +957,8 @@ if (ctx->flags & PDKIM_MODE_SIGN) else { #ifdef notdef - DEBUG(D_acl) - { - debug_printf("DKIM >> raw hdr: "); - pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr); - } + DEBUG(D_acl) debug_printf("DKIM >> raw hdr: %.*Z\n", + ctx->cur_head->ptr, CUS ctx->cur_header->s); #endif if (strncasecmp(CCS ctx->cur_header->s, DKIM_SIGNATURE_HEADERNAME, @@ -1372,9 +1335,9 @@ DEBUG(D_acl) debug_printf( "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" " %s\n" - " Raw record: ", - dns_txt_name); - pdkim_quoteprint(CUS dns_txt_reply, Ustrlen(dns_txt_reply)); + " Raw record: %Z\n", + dns_txt_name, + CUS dns_txt_reply); } if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply)) @@ -1630,7 +1593,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /*XXX we could avoid doing this for all but the GnuTLS/RSA case */ hdata = exim_dkim_data_append(hdata, rh); - DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh)); + DEBUG(D_acl) debug_printf("%Z\n", rh); } } @@ -1687,7 +1650,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Feed header to the hash algorithm */ exim_sha_update_string(&hhash_ctx, CUS rh); - DEBUG(D_acl) pdkim_quoteprint(rh, Ustrlen(rh)); + DEBUG(D_acl) debug_printf("%Z\n", rh); hdrs->tag = 1; break; } @@ -1707,7 +1670,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { debug_printf( "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n"); - pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr)); + debug_printf("%Z\n", CUS sig_hdr); debug_printf( "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } @@ -1720,7 +1683,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n", pdkim_canons[sig->canon_headers]); - pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr)); + debug_printf("%Z\n", CUS sig_hdr); debug_printf( "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } @@ -1733,7 +1696,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { debug_printf("DKIM [%s] Header %s computed: ", sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname); - pdkim_hexprint(hhash.data, hhash.len); + debug_printf("%.*H\n", hhash.len, hhash.data); } /* Remember headers block for signing (when the signing library cannot do @@ -1772,7 +1735,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { debug_printf( "DKIM [%s] b computed: ", sig->domain); - pdkim_hexprint(sig->sighash.data, sig->sighash.len); + debug_printf("%.*H\n", sig->sighash.len, sig->sighash.data); } sig->signature_header = pdkim_create_header(sig, TRUE); @@ -1827,7 +1790,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { debug_printf( "DKIM [%s] b from mail: ", sig->domain); - pdkim_hexprint(sig->sighash.data, sig->sighash.len); + debug_printf("%.*H\n", sig->sighash.len, sig->sighash.data); } if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err))) diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index f918938e8..5f91d3bc7 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -356,8 +356,6 @@ const uschar * pdkim_errstr(int); extern uschar * pdkim_encode_base64(blob *); extern void pdkim_decode_base64(const uschar *, blob *); -extern void pdkim_hexprint(const uschar *, int); -extern void pdkim_quoteprint(const uschar *, int); extern pdkim_pubkey * pdkim_parse_pubkey_record(const uschar *); extern uschar * pdkim_relax_header_n(const uschar *, int, BOOL); extern uschar * pdkim_relax_header(const uschar *, BOOL); diff --git a/src/src/string.c b/src/src/string.c index 1ac837abe..f652b3815 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1341,7 +1341,7 @@ The return value can be NULL to signify overflow. Field width: decimal digits, or * Precision: dot, followed by decimal digits or * Length modifiers: h L l ll z -Conversion specifiers: n d o u x X p f e E g G % c s S T W V Y D M +Conversion specifiers: n d o u x X p f e E g G % c s S T W V Y D M H Z Alternate-form: %#s is silent about a null string Returns the possibly-new (if copy for growth or taint-handling was needed) @@ -1669,6 +1669,53 @@ while (*fp) } goto INSERT_GSTRING; + case 'Z': /* pdkim-style "quoteprint" */ + { + gstring * zg = NULL; + int p = precision; /* If given, we can handle embedded NULs */ + + s = va_arg(ap, char *); + for ( ; precision >= 0 || *s; s++) + if (p >= 0 && --p < 0) + break; + else switch (*s) + { + case ' ' : zg = string_catn(zg, US"{SP}", 4); break; + case '\t': zg = string_catn(zg, US"{TB}", 4); break; + case '\r': zg = string_catn(zg, US"{CR}", 4); break; + case '\n': zg = string_catn(zg, US"{LF}", 4); break; + case '{' : zg = string_catn(zg, US"{BO}", 4); break; + case '}' : zg = string_catn(zg, US"{BC}", 4); break; + default: + if ( (*s < 32) || (*s > 127) ) + zg = string_fmt_append(zg, "{%02x}", *s); + else + zg = string_catn(zg, US s, 1); + break; + } + if (zg) { s = CS zg->s; precision = slen = gstring_length(zg); } + else { s = ""; slen = 0; } + } + goto INSERT_GSTRING; + + case 'H': /* pdkim-style "hexprint" */ + { + s = va_arg(ap, char *); + if (precision < 0) break; /* precision must be given */ + if (s) + { + gstring * zg = NULL; + for (int p = precision; p > 0; p--) + zg = string_fmt_append(zg, "%02x", * US s++); + + if (zg) { s = CS zg->s; precision = slen = gstring_length(zg); } + else { s = ""; slen = 0; } + } + else + { s = ""; precision = slen = 6; } + } + goto INSERT_GSTRING; + #endif case 's': case 'S': /* Forces *lower* case */ -- 2.30.2