/*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;
+gstring * g = NULL;
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 */
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;
- 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 */
- if (strncmp(answer, "v=", 2) == 0 && strncasecmp(answer, "v=dkim", 6) != 0)
- continue;
- return PDKIM_OK;
+ if (strncmp(g->s, "v=", 2) != 0 || strncasecmp(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? */
}
dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
-dns_txt_reply = store_get(PDKIM_DNS_TXT_MAX_RECLEN);
-memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
-
-if ( ctx->dns_txt_callback(CS dns_txt_name, CS dns_txt_reply) != PDKIM_OK
+if ( !(dns_txt_reply = ctx->dns_txt_callback(CS dns_txt_name))
|| dns_txt_reply[0] == '\0'
)
{
/* -------------------------------------------------------------------------- */
DLLEXPORT pdkim_ctx *
-pdkim_init_verify(int(*dns_txt_callback)(char *, char *), BOOL dot_stuffing)
+pdkim_init_verify(uschar * (*dns_txt_callback)(char *), BOOL dot_stuffing)
{
pdkim_ctx * ctx;
void
pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
- int(*dns_txt_callback)(char *, char *))
+ uschar * (*dns_txt_callback)(char *))
{
memset(ctx, 0, sizeof(pdkim_ctx));
ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
pdkim_signature *sig;
/* Callback for dns/txt query method (verification only) */
- int(*dns_txt_callback)(char *, char *);
+ uschar * (*dns_txt_callback)(char *);
/* Coder's little helpers */
gstring *cur_header;
void pdkim_init (void);
-void pdkim_init_context (pdkim_ctx *, BOOL, int(*)(char *, char *));
+void pdkim_init_context (pdkim_ctx *, BOOL, uschar * (*)(char *));
DLLEXPORT
pdkim_signature *pdkim_init_sign (pdkim_ctx *,
const uschar **);
DLLEXPORT
-pdkim_ctx *pdkim_init_verify (int(*)(char *, char *), BOOL);
+pdkim_ctx *pdkim_init_verify (uschar * (*)(char *), BOOL);
DLLEXPORT
void pdkim_set_optional (pdkim_signature *, char *, char *,int, int,