aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtin/dns.bi94
-rw-r--r--src/callout.c2
-rw-r--r--src/mailfromd.h3
-rw-r--r--src/main.c5
-rw-r--r--src/prog.c2
-rw-r--r--src/spf.c80
-rw-r--r--src/spf.h3
-rw-r--r--src/srvcfg.c5
8 files changed, 76 insertions, 118 deletions
diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi
index 46433a00..faf8998d 100644
--- a/src/builtin/dns.bi
+++ b/src/builtin/dns.bi
@@ -21,20 +21,6 @@
#include "srvcfg.h"
#include "global.h"
-static size_t max_ptr = MAX_DNS_PTR;
-static size_t max_a = MAX_DNS_A;
-static size_t max_mx = MAX_DNS_MX;
-static struct mu_cfg_param dns_cfg_param[] = {
- { "max-dns-reply-a", mu_c_size, &max_a, 0, NULL,
- N_("Maximum number of A records in a DNS reply.") },
- { "max-dns-reply-ptr", mu_c_size, &max_a, 0, NULL,
- N_("Maximum number of PTR records in a DNS reply.") },
- { "max-dns-reply-mx", mu_c_size, &max_mx, 0, NULL,
- N_("Maximum number of MX records in a DNS reply.") },
- { NULL }
-};
-
-
MF_DEFUN(primitive_hostname, STRING, STRING string)
{
char *hbuf;
@@ -75,8 +61,8 @@ END
static int
ipaddr_cmp(const void *a, const void *b)
{
- GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T*)a);
- GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T*)b);
+ GACOPYZ_UINT32_T ipa = ntohl(**(GACOPYZ_UINT32_T**)a);
+ GACOPYZ_UINT32_T ipb = ntohl(**(GACOPYZ_UINT32_T**)b);
if (ipa < ipb)
return -1;
if (ipa > ipb)
@@ -86,37 +72,33 @@ ipaddr_cmp(const void *a, const void *b)
MF_DEFUN(dns_getaddr, STRING, STRING string)
{
- GACOPYZ_UINT32_T *ipbuf;
- size_t i, ipcount;
+ size_t i;
unsigned long ttl;
dns_status dnstat;
-
- ipbuf = mu_calloc(max_a, sizeof(ipbuf[0]));
- dnstat = a_lookup(string, ipbuf, max_a, &ipcount,
- &ttl, NULL, 0);
+ struct dns_reply r;
+
+ dnstat = a_lookup(string, &r, &ttl);
switch (dnstat) {
case dns_success: {
MF_OBSTACK_BEGIN();
- qsort(ipbuf, ipcount, sizeof ipbuf[0], ipaddr_cmp);
- for (i = 0; i < ipcount; i++) {
+ qsort(r.base, r.count, sizeof r.base[0], ipaddr_cmp);
+ for (i = 0; i < r.count; i++) {
struct in_addr addr;
char *q;
- addr.s_addr = ipbuf[i];
+ addr.s_addr = dns_reply_ip(&r, i);
q = inet_ntoa(addr);
if (i > 0)
MF_OBSTACK_1GROW(' ');
MF_OBSTACK_GROW(q);
}
- free(ipbuf);
+ dns_reply_free(&r);
MF_OBSTACK_1GROW(0);
MF_RETURN_OBSTACK();
}
case dns_not_found:
- free(ipbuf);
MF_RETURN("");
default:
- free(ipbuf);
MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)),
_("failed to get A record for %s"), string);
}
@@ -134,42 +116,33 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
dns_status dnstat;
struct in_addr addr;
unsigned long ttl;
- char **names;
-
+ struct dns_reply r;
+
MF_ASSERT(inet_aton(ipstr, &addr),
mfe_invip,
_("invalid IP: %s"), ipstr);
- names = mu_calloc(max_ptr, sizeof(names[0]));
- dnstat = ptr_lookup(addr, names, max_ptr, &ttl, NULL, 0);
+ dnstat = ptr_lookup(addr, &r, &ttl);
switch (dnstat) {
case dns_success: {
size_t i;
- size_t ncount;
- for (ncount = 0; ncount < max_ptr && names[ncount];
- ncount++);
-
- qsort(names, ncount, sizeof names[0], hostname_cmp);
+ qsort(r.base, r.count, sizeof r.base[0], hostname_cmp);
MF_OBSTACK_BEGIN();
- for (i = 0; i < ncount; i++) {
+ for (i = 0; i < r.count; i++) {
if (i > 0)
MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(names[i]);
+ MF_OBSTACK_GROW((char*)r.base[i]);
}
MF_OBSTACK_1GROW(0);
- for (; i < ncount; i++)
- free(names[i]);
- free(names);
+ dns_reply_free(&r);
MF_RETURN_OBSTACK();
}
case dns_not_found:
- free(names);
MF_RETURN("");
default:
- free(names);
MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)),
_("failed to get PTR record for %s"), ipstr);
}
@@ -204,15 +177,12 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
GACOPYZ_UINT32_T *ipbuf;
size_t ipcount;
- ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0]));
- mxstat = getmxip(domain, ipbuf, max_mx, &ipcount);
+ mxstat = getmxip(domain, &ipbuf, &ipcount);
if (!mf_resolved(mxstat)) {
- free(ipbuf);
MF_THROW(mf_status_to_exception(mxstat),
_("cannot get MX records for %s"), domain);
}
if (mxstat == mf_not_found) {
- free(ipbuf);
MF_RETURN("");
} else {
int i;
@@ -233,8 +203,6 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
} else {
struct mxbuf mxbuf;
- mxbuf.mx_max = max_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(domain, &mxbuf);
if (!mf_resolved(mxstat)) {
mxbuf_free(&mxbuf);
@@ -301,11 +269,9 @@ MF_DEFUN(primitive_ismx, NUMBER, STRING domain, STRING ipstr)
_("cannot resolve host name %s"), ipstr);
ip = ntohl(ip);
- ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0]));
- mxstat = getmxip(domain, ipbuf, max_mx, &ipcount);
+ mxstat = getmxip(domain, &ipbuf, &ipcount);
if (mxstat != mf_success) {
- free(ipbuf);
MF_THROW(mf_status_to_exception(mxstat),
_("cannot get MXs for %s"), domain);
}
@@ -328,6 +294,22 @@ MF_DEFUN(relayed, NUMBER, STRING s)
}
END
-MF_INIT([<
- mf_add_runtime_params(dns_cfg_param);
- >])
+MF_DEFUN(ptr_validate, NUMBER, STRING s)
+{
+ int rc, res;
+ switch (rc = ptr_validate(s, NULL, NULL, NULL)) {
+ case dns_success:
+ res = 1;
+ break;
+ case dns_not_found:
+ res = 0;
+ break;
+ default:
+ MF_THROW(mf_status_to_exception(dns_to_mf_status(rc)),
+ _("failed to get PTR record for %s"), s);
+ }
+ MF_RETURN(res);
+}
+END
+
+MF_INIT
diff --git a/src/callout.c b/src/callout.c
index e59e8f04..633a33b7 100644
--- a/src/callout.c
+++ b/src/callout.c
@@ -637,8 +637,6 @@ callout_mx(struct smtp_io_data *iop, const char *hostname, int *pcount)
struct mxbuf mxbuf;
mf_status rc, mxstat;
- mxbuf.mx_max = max_callout_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(hostname, &mxbuf);
if (pcount)
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 5cc7136b..7f21e360 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -76,8 +76,7 @@ mf_status resolve_ipstr_domain(const char *ipstr, const char *domain,
mf_status resolve_hostname(const char *host, char **pipbuf);
mf_status getmx(const char *ipstr, struct mxbuf *mxbuf);
-mf_status getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t ipmax,
- size_t *pcount);
+mf_status getmxip(char *host, GACOPYZ_UINT32_T **ipbuf, size_t *pcount);
/* Debugging macros */
diff --git a/src/main.c b/src/main.c
index 66a97808..9873ed0f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -73,8 +73,6 @@ unsigned optimization_level = 1; /* Optimization level */
int stack_trace_option; /* Print stack traces on runtime errors */
-size_t max_match_mx = MAXMXCOUNT;
-
char *main_function_name = "main";
char *callout_server_url;
@@ -853,9 +851,6 @@ struct mu_cfg_param mf_cfg_param[] = {
N_("Set the time span between the two DBM locking attempts."),
N_("time: interval") },
- { "max-match-mx", mu_c_size, &max_match_mx, 0, NULL,
- N_("Maximum number of MXs used by MFL \"mx match\" operation.") },
-
{ "runtime", mu_cfg_section, NULL },
{ NULL }
diff --git a/src/prog.c b/src/prog.c
index 12dc69e3..3e90472f 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -1602,8 +1602,6 @@ mx_match(eval_environ_t env, char *string,
p++;
else
p = string;
- mxbuf.mx_max = max_match_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(p, &mxbuf);
rc = 0;
if (mxstat == mf_success) {
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, "");
}
diff --git a/src/spf.h b/src/spf.h
index 9b3c8e63..229075e6 100644
--- a/src/spf.h
+++ b/src/spf.h
@@ -14,7 +14,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#define SPF_MAX_TXT_REC 10
#define SPF_MAX_RECURSION 10
typedef enum spf_result {
@@ -49,8 +48,6 @@ typedef struct {
spf_result spf_check_host(spf_query_t *query, spf_answer_t *ans);
spf_result spf_test_record(const char *rec,
spf_query_t *query, spf_answer_t *ans);
-dns_status spf_lookup(const char *domain, char **txt, size_t maxtxt,
- unsigned long *ttl, char *answer, size_t answer_size);
void spf_answer_free(spf_answer_t *ans);
void spf_answer_add_mech(spf_answer_t *ans, char const *mech);
diff --git a/src/srvcfg.c b/src/srvcfg.c
index f04e4c68..a9527a53 100644
--- a/src/srvcfg.c
+++ b/src/srvcfg.c
@@ -42,8 +42,6 @@ struct mu_sockaddr *source_address; /* Source address for TCP connections */
int mtasim_option; /* mtasim compatibility mode */
char *db_type_str = DEFAULT_DB_TYPE;
-size_t max_callout_mx = MAXMXCOUNT;
-
/* Timeouts */
time_t smtp_timeout_soft[SMTP_NUM_TIMEOUT] = {
10,
@@ -514,9 +512,6 @@ static struct mu_cfg_param srv_cfg_param[] = {
{ "acl", mu_cfg_section, &srvman_param.acl },
{ "logger", mu_c_string, &log_stream, 0, NULL,
N_("Set logger stream.") },
- { "max-callout-mx", mu_c_size, &max_callout_mx, 0, NULL,
- N_("Maximum number of MXs to be polled during "
- "callout verification.") },
{ "state-directory", mu_cfg_callback, NULL, 0, cb_state_directory,
N_("Set program state directory."),
N_("dir: string") },

Return to:

Send suggestions and report system problems to the System administrator.