static const response* check_fqdn(str* s) { int at; int dot; const char* name; if ((at = str_findlast(s, '@')) <= 0) { if ((name = session_getenv("DEFAULTHOST")) != 0) { at = s->len; if (!str_catc(s, '@') || !str_cats(s, name)) return &resp_oom; } else return &resp_nodomain; } if ((dot = str_findlast(s, '.')) < at) { if ((name = session_getenv("DEFAULTDOMAIN")) != 0) { if (!str_catc(s, '.') || !str_cats(s, name)) return &resp_oom; } else return &resp_nofqdn; } return 0; }
static const response* check_domains(const str* s, const char* domains) { unsigned int at; unsigned int i; int atend; if ((at = str_findlast(s, '@')) == (unsigned)-1) { return &resp_notemptysender; } ++at; for (;;) { /* Skip any leading or doubled colons */ while (*domains == ':') ++domains; /* Hit end of string without a match */ if (*domains == 0) return &resp_wrongdomain; for (atend = 0, i = 0; !atend && at+i < s->len; ++i) { if (tolower(s->s[at+i]) != tolower(*domains)) break; ++domains; atend = *domains == ':' || *domains == 0; } if (atend && at+i == s->len) return 0; /* Skip to next domain in list */ while (*domains != ':' && *domains != 0) ++domains; } }
static void copy_addr(const str* addr, str* saved, str* domain) { int at; str_copy(saved, addr); str_lower(saved); if ((at = str_findlast(saved, '@')) != -1) str_copyb(domain, saved->s + at, saved->len - at); else str_truncate(domain, 0); }
static const response* chkdns_sender(str* sender, str* params) { str domstr, dbltxt; int i; unsigned char ansbuf[512]; if(sender->len == 0) return 0; /* bounce */ i = str_findlast(sender, '@'); if(i < 0) { return &resp_badfrom; /* no domain */ } str_init(&domstr); str_copyb(&domstr, sender->s+i+1, sender->len-i-1); if(domstr.len == 0) { /* null domain */ str_free(&domstr); return &resp_badfrom; } /* first check dbl */ if(dblchk(&domstr, &dbltxt)) { session_setenv("RBLSMTPD", dbltxt.s, 0); session_setnum("dblfrom", 1); session_setnum("sump", 1); msg2("MAIL FROM in DBL ",dbltxt.s); str_free(&domstr); if(getenv("DBLREJECT")) { resp_baddbl.message = dbltxt.s; return &resp_baddbl; } return 0; } i = res_query(domstr.s, C_IN, T_MX, ansbuf, sizeof(ansbuf)); if(i > 0 && ((HEADER *)ansbuf)->ancount != 0) { /* has an MX */ str_free(&domstr); return 0; } i = res_query(domstr.s, C_IN, T_A, ansbuf, sizeof(ansbuf)); if(i > 0 && ((HEADER *)ansbuf)->ancount != 0) { /* has an A */ str_free(&domstr); return 0; } i = res_query(domstr.s, C_IN, T_AAAA, ansbuf, sizeof(ansbuf)); str_free(&domstr); if(i > 0 && ((HEADER *)ansbuf)->ancount != 0) return 0; /* has an AAAA */ return &resp_badfrom; (void)params; }