commit cc08de5188216a473aabf44c48c9fb7fd2a41b62 from: Martijn van Duren date: Thu Mar 24 13:37:21 2022 UTC Check that i-tag is (sub)domain of d-tag commit - 759a6c7b4d25900b15c4a118937f1669c967691e commit + cc08de5188216a473aabf44c48c9fb7fd2a41b62 blob - e3054ed42860f51f2f3643c04692b1546dc4f3a2 blob + ba45b75d3c25b60268122aea78b84f68fd7800d1 --- main.c +++ main.c @@ -381,11 +381,12 @@ dkim_header_cat(struct osmtpd_ctx *ctx, const char *li void dkim_signature_parse(struct header *header) { - char *buf; - char *end, tagname[3]; - char subdomain[HOST_NAME_MAX + 1]; struct signature *sig; struct asr_query *query; + char *buf, *i; + char *end, tagname[3]; + char subdomain[HOST_NAME_MAX + 1]; + size_t ilen, dlen; /* Format checked by dkim_header_add */ buf = osmtpd_mheader_skip_fieldname(header->buf, 0); @@ -477,6 +478,23 @@ dkim_signature_parse(struct header *header) dkim_signature_state(sig, DKIM_PERMERROR, "Missing s tag"); if (sig->state != DKIM_UNKNOWN) return; + + if (sig->i != NULL) { + i = osmtpd_mheader_skip_local_part(sig->i, 1) + 1; + ilen = strlen(i); + dlen = strlen(sig->d); + if (ilen < dlen) { + dkim_signature_state(sig, DKIM_PERMERROR, + "i tagn not subdomain of d"); + return; + } + i += ilen - dlen; + if ((i[-1] != '.' && i[-1] != '@') || strcmp(i, sig->d) != 0) { + dkim_signature_state(sig, DKIM_PERMERROR, + "i tagn not subdomain of d"); + return; + } + } if ((size_t)snprintf(subdomain, sizeof(subdomain), "%s._domainkey.%s", sig->s, sig->d) >= sizeof(subdomain)) {