git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
DKIM: Ed25519 signatures (GnuTLS 3.6.0 and later)
[exim.git]
/
src
/
src
/
dkim.c
diff --git
a/src/src/dkim.c
b/src/src/dkim.c
index 9731a63d9447f6632f89da2965d5c877f157b2f8..c7bf641527822a7fecc97fe383ca7c548a5ea2f1 100644
(file)
--- a/
src/src/dkim.c
+++ b/
src/src/dkim.c
@@
-36,19
+36,19
@@
static const uschar * dkim_collect_error = NULL;
/*XXX the caller only uses the first record if we return multiple.
/*XXX the caller only uses the first record if we return multiple.
-Could we hand back an allocated string?
*/
*/
-static
int
-dkim_exim_query_dns_txt(char *
name, char *answer
)
+static
uschar *
+dkim_exim_query_dns_txt(char *
name
)
{
dns_answer dnsa;
dns_scan dnss;
dns_record *rr;
{
dns_answer dnsa;
dns_scan dnss;
dns_record *rr;
+gstring * g = NULL;
lookup_dnssec_authenticated = NULL;
if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
lookup_dnssec_authenticated = NULL;
if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
- return
PDKIM_FAIL;
/*XXX better error detail? logging? */
+ return
NULL;
/*XXX better error detail? logging? */
/* Search for TXT record */
/* Search for TXT record */
@@
-58,28
+58,33
@@
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
if (rr->type == T_TXT)
{
int rr_offset = 0;
if (rr->type == T_TXT)
{
int rr_offset = 0;
- int answer_offset = 0;
/* Copy record content to the answer buffer */
while (rr_offset < rr->size)
{
uschar len = rr->data[rr_offset++];
/* Copy record content to the answer buffer */
while (rr_offset < rr->size)
{
uschar len = rr->data[rr_offset++];
- snprintf(answer + answer_offset,
- PDKIM_DNS_TXT_MAX_RECLEN - answer_offset,
- "%.*s", (int)len, CS (rr->data + rr_offset));
+
+ g = string_catn(g, US(rr->data + rr_offset), len);
+ if (g->ptr >= PDKIM_DNS_TXT_MAX_RECLEN)
+ goto bad;
+
rr_offset += len;
rr_offset += len;
- answer_offset += len;
- if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN)
- return PDKIM_FAIL; /*XXX better error detail? logging? */
}
/* check if this looks like a DKIM record */
}
/* check if this looks like a DKIM record */
- if (strncasecmp(answer, "v=dkim", 6) != 0) continue;
- return PDKIM_OK;
+ if (Ustrncmp(g->s, "v=", 2) != 0 || strncasecmp(CS g->s, "v=dkim", 6) == 0)
+ {
+ store_reset(g->s + g->ptr + 1);
+ return string_from_gstring(g);
+ }
+
+ if (g) g->ptr = 0; /* overwrite previous record */
}
}
-return PDKIM_FAIL; /*XXX better error detail? logging? */
+bad:
+if (g) store_reset(g);
+return NULL; /*XXX better error detail? logging? */
}
}
@@
-146,6
+151,15
@@
uschar * s;
if (!sig) return;
if (!sig) return;
+if ( !dkim_verify_overall
+ && dkim_verify_status
+ ? Ustrcmp(dkim_verify_status, US"pass") == 0
+ : sig->verify_status == PDKIM_VERIFY_PASS
+ )
+ dkim_verify_overall = string_copy(sig->domain);
+
+if (!LOGGING(dkim_verbose)) return;
+
logmsg = string_catn(NULL, US"DKIM: ", 6);
if (!(s = sig->domain)) s = US"<UNSET>";
logmsg = string_append(logmsg, 2, "d=", s);
logmsg = string_catn(NULL, US"DKIM: ", 6);
if (!(s = sig->domain)) s = US"<UNSET>";
logmsg = string_append(logmsg, 2, "d=", s);
@@
-254,7
+268,7
@@
dkim_exim_verify_finish(void)
pdkim_signature * sig;
int rc;
gstring * g = NULL;
pdkim_signature * sig;
int rc;
gstring * g = NULL;
-const uschar * errstr;
+const uschar * errstr
= NULL
;
store_pool = POOL_PERM;
store_pool = POOL_PERM;
@@
-277,12
+291,8
@@
dkim_collect_input = FALSE;
/* Finish DKIM operation and fetch link to signatures chain */
rc = pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures, &errstr);
/* Finish DKIM operation and fetch link to signatures chain */
rc = pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures, &errstr);
-if (rc != PDKIM_OK)
- {
- log_write(0, LOG_MAIN, "DKIM: validation error: %.100s%s%s", pdkim_errstr(rc),
- errstr ? ": " : "", errstr ? errstr : US"");
- goto out;
- }
+if (rc != PDKIM_OK && errstr)
+ log_write(0, LOG_MAIN, "DKIM: validation error: %s", errstr);
/* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
/* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
@@
-531,8
+541,12
@@
switch (what)
}
}
-/* Generate signatures for the given file
, returning a string
.
+/* Generate signatures for the given file.
If a prefix is given, prepend it to the file for the calculations.
If a prefix is given, prepend it to the file for the calculations.
+
+Return:
+ NULL: error; error string written
+ string: signature header(s), or a zero-length string (not an error)
*/
gstring *
*/
gstring *
@@
-692,6
+706,9
@@
while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
pdkim_canon,
pdkim_canon, -1, 0, 0);
pdkim_canon,
pdkim_canon, -1, 0, 0);
+ if (!pdkim_set_bodyhash(&ctx, sig))
+ goto bad;
+
if (!ctx.sig) /* link sig to context chain */
ctx.sig = sig;
else
if (!ctx.sig) /* link sig to context chain */
ctx.sig = sig;
else
@@
-702,9
+719,15
@@
while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
}
}
}
}
}
}
+if (!ctx.sig)
+ {
+ DEBUG(D_transport) debug_printf("DKIM: no viable signatures to use\n");
+ sigbuf = string_get(1); /* return a zero-len string */
+ goto CLEANUP;
+ }
-if (prefix)
-
pdkim_feed(&ctx, prefix, Ustrlen(prefix))
;
+if (prefix
&& (pdkim_rc = pdkim_feed(&ctx, prefix, Ustrlen(prefix))) != PDKIM_OK
)
+
goto pk_bad
;
if (lseek(fd, off, SEEK_SET) < 0)
sread = -1;
if (lseek(fd, off, SEEK_SET) < 0)
sread = -1;
@@
-729,9
+752,8
@@
if ((pdkim_rc = pdkim_feed_finish(&ctx, &sig, errstr)) != PDKIM_OK)
for (sigbuf = NULL; sig; sig = sig->next)
sigbuf = string_append(sigbuf, 2, US sig->signature_header, US"\r\n");
for (sigbuf = NULL; sig; sig = sig->next)
sigbuf = string_append(sigbuf, 2, US sig->signature_header, US"\r\n");
-(void) string_from_gstring(sigbuf);
-
CLEANUP:
CLEANUP:
+ (void) string_from_gstring(sigbuf);
store_pool = old_pool;
errno = save_errno;
return sigbuf;
store_pool = old_pool;
errno = save_errno;
return sigbuf;