diff options
Diffstat (limited to 'src/spf.c')
-rw-r--r-- | src/spf.c | 78 |
1 files changed, 36 insertions, 42 deletions
@@ -630,9 +630,10 @@ mech_a(spf_data *dat, spf_term_arg *arg, unsigned long masklen) const char *domain_spec; unsigned long netmask; struct in_addr addr; - GACOPYZ_UINT32_T ipbuf[64]; /* FIXME: arbitrary limit */ - size_t i, ipcount; + struct dns_reply r; + size_t i; unsigned long ttl; + spf_term_result res; if (arg) domain_spec = arg->v.domain_spec; @@ -644,23 +645,24 @@ mech_a(spf_data *dat, spf_term_arg *arg, unsigned long masklen) mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, ("A domain_spec=%s, netmask=%lx", domain_spec, netmask)); - DNS_CATCH(a_lookup(domain_spec, ipbuf, NELEMS(ipbuf), &ipcount, - &ttl, NULL, 0)); + DNS_CATCH(a_lookup(domain_spec, &r, &ttl)); UPDATE_ANSWER_TTL(dat, ttl); addr.s_addr = dat->ipaddr.s_addr & netmask; mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE6, ("A: s_addr=%x", addr.s_addr)); - for (i = 0; i < ipcount; i++) { - if ((ntohl(ipbuf[i]) & netmask) == addr.s_addr) { - mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, - ("A matches")); - return spf_term_match; + res = spf_term_nomatch; + for (i = 0; i < r.count; i++) { + if (ntohl(dns_reply_ip(&r, i) & netmask) == addr.s_addr) { + res = spf_term_match; + break; } } - mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, ("A does not match")); - return spf_term_nomatch; + dns_reply_free(&r); + mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, + (res == spf_term_match ? "A matches" : "A does not match")); + return res; } /* 5.4. @@ -685,8 +687,6 @@ mech_mx(spf_data *dat, spf_term_arg *arg, unsigned long masklen) ("MX domain_spec=%s, netmask=%lx", domain_spec, netmask)); - mxbuf.mx_flags = MXF_MAX; - mxbuf.mx_max = 10; DNS_CATCH(dns_get_mx_records(domain_spec, 1, &mxbuf, &ttl)); UPDATE_ANSWER_TTL(dat, ttl); @@ -779,6 +779,7 @@ static spf_term_result mech_exists(spf_data *dat, spf_term_arg *arg, unsigned long masklen) { unsigned long ttl; + struct dns_reply r; if (!arg) { mu_debug(MF_SOURCE_SPF, MU_DEBUG_ERROR, ("exists used without argument")); @@ -788,7 +789,8 @@ mech_exists(spf_data *dat, spf_term_arg *arg, unsigned long masklen) mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, ("EXISTS domain_spec=%s", arg->v.domain_spec)); - DNS_CATCH(a_lookup(arg->v.domain_spec, NULL, 0, NULL, &ttl, NULL, 0)); + DNS_CATCH(a_lookup(arg->v.domain_spec, &r, &ttl)); + dns_reply_free(&r); UPDATE_ANSWER_TTL(dat, ttl); return spf_term_match; @@ -816,18 +818,17 @@ mod_redirect(spf_data *dat, spf_term_arg *arg, unsigned long masklen) static spf_term_result mod_exp(spf_data *dat, spf_term_arg *arg, unsigned long masklen) { - char *names[128]; /* FIXME: arbitrary limit */ + struct dns_reply r; + if (arg->v.domain_spec - && txt_lookup(arg->v.domain_spec, - names, NELEMS(names), NULL, - NULL, 0) == dns_success) { + && txt_lookup(arg->v.domain_spec, &r, NULL) == dns_success) { int i; char *text; - for (i = 0; names[i]; i++) { - mu_opool_appendz(dat->tmpool, names[i]); - free(names[i]); + for (i = 0; i < r.count; i++) { + mu_opool_appendz(dat->tmpool, r.base[i]); } + dns_reply_free(&r); mu_opool_append_char(dat->tmpool, 0); text = spf_data_ptr(dat); @@ -1213,8 +1214,10 @@ spf_test_record(const char *rec, spf_query_t *q, spf_answer_t *a) spf_result spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno) { - char *txt_rec[SPF_MAX_TXT_REC+1]; - int ntxt, i; + char **txt_rec; + size_t txt_num; + int i; + char *spf_rec = NULL; struct spf_data dat; spf_result result; #define SPF_RETURN(res, text) { \ @@ -1241,8 +1244,7 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno) if (strlen(q->domain) > 63) SPF_RETURN(spf_none, "domain too long"); - switch (spf_lookup(q->domain, txt_rec, NELEMS(txt_rec), - &ttl, NULL, 0)) { + switch (spf_lookup(q->domain, &txt_rec, &txt_num, &ttl)) { case dns_success: break; @@ -1256,40 +1258,32 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno) } /* Select SPF1 records */ - ntxt = 0; for (i = 0; txt_rec[i]; i++) { if (memcmp(txt_rec[i], "v=spf1", 6) == 0 && (txt_rec[i][6] == 0 || mu_isspace(txt_rec[i][6]))) { mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE6, ("record: %s", txt_rec[i])); - if (ntxt != i) { - txt_rec[ntxt++] = txt_rec[i]; - txt_rec[i] = NULL; - } else - ntxt = i + 1; - } else { - free(txt_rec[i]); - txt_rec[i] = NULL; + if (spf_rec) { + SPF_RETURN(spf_perm_error, + "too many SPF records published"); + } + spf_rec = txt_rec[i]; + break; } } - - if (ntxt == 0) - SPF_RETURN(spf_none, "no SPF records published"); - if (ntxt > 1) - SPF_RETURN(spf_perm_error, "too many SPF records published"); mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE0, - ("SPF record: %s", txt_rec[0])); + ("SPF record: %s", spf_rec)); if (a) UPDATE_TTL(a->ttl, ttl); if (spf_data_init(&dat, q, a, loopno + 1)) SPF_RETURN(spf_perm_error, "spf_data_init failed"); - result = spf_exec_query(txt_rec[0], &dat); + result = spf_exec_query(spf_rec, &dat); spf_data_free(&dat); - free(txt_rec[0]); + mu_argcv_free(txt_num, txt_rec); SPF_RETURN(result, ""); } |