aboutsummaryrefslogtreecommitdiff
path: root/src/spf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spf.c')
-rw-r--r--src/spf.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/src/spf.c b/src/spf.c
index 236efa5a..9e8c1bfe 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -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, "");
}

Return to:

Send suggestions and report system problems to the System administrator.