static int dblchk(str *domain, str *dbltxt) { str dblstr; char *dbl = getenv("DBLLOOKUP"); int l, i; unsigned char ansbuf[512]; if(!dbl || domain->len == 0) return 0; if(session_getnum("sump",0)) return 0; /* no point */ str_init(&dblstr); str_copy(&dblstr, domain); str_catc(&dblstr, '.'); str_cats(&dblstr, dbl); l = res_query(dblstr.s, C_IN, T_TXT, ansbuf, sizeof(ansbuf)); if(l > 0 && ((HEADER *)ansbuf)->ancount != 0) { /* something in the answer */ unsigned char *recbuf = ansbuf+NS_HFIXEDSZ; /* skip over questions, why am I still writing stuff * like this? */ for(i = ns_get16(ansbuf+4); i != 0; --i) recbuf += dn_skipname(recbuf, ansbuf+l)+4; for(i = ns_get16(ansbuf+6); i != 0; --i) { recbuf += dn_skipname(recbuf, ansbuf+l); if(ns_get16(recbuf) != T_TXT) { /* CNAME or something */ recbuf += 10 + ns_get16(recbuf+8); continue; } /* it's a TXT record, wow */ str_init(dbltxt); str_copyb(dbltxt, (char*)recbuf+11, recbuf[10]); str_free(&dblstr); return 1; } } /* didn't find anything */ str_free(&dblstr); return 0; }
/* rule application ******************************************************** */ static int matches(const struct pattern* pattern, const str* addr, const str* atdomain) { static str domain; int result; if (pattern->cdb != 0) { if (pattern->pattern.s[2] == '@') { result = (atdomain->len == 0) ? 0 : cdb_find(pattern->cdb, atdomain->s+1, atdomain->len-1) != 0; } else { result = (cdb_find(pattern->cdb, addr->s, addr->len) != 0) ? 1 : cdb_find(pattern->cdb, atdomain->s, atdomain->len) != 0; } } else if (pattern->file != 0) { if (pattern->pattern.s[2] == '@') { if (atdomain->len > 0) { str_copyb(&domain, atdomain->s+1, atdomain->len-1); result = dict_get(pattern->file, &domain) != 0; } else result = 0; } else { result = (dict_get(pattern->file, addr) != 0) ? 1 : dict_get(pattern->file, atdomain) != 0; } } else result = str_case_glob(addr, &pattern->pattern); if (pattern->negated) result = !result; return result; }
static void load_rcpthosts(void) { char* rh = read_file(0, "rcpthosts"); if (!dict_init(&rcpthosts)) oom(); if (rh) { const char* curr = rh; while (*curr) { const char* end; const char* next; if ((end = strchr(curr, '\n')) != 0) next = end + 1; else next = end = curr + strlen(curr); if (*curr != '#') { if (!str_copyb(&strbuf, curr, end-curr)) oom(); if (!dict_add(&rcpthosts, &strbuf, 0)) oom(); } curr = next; } free(rh); } if ((morercpthosts_fd = open_file(0, "morercpthosts.cdb")) != -1) cdb_init(&morercpthosts, morercpthosts_fd); }
static void filter_server_data(char* data, ssize_t size) { if(saved_label.len > 0) { /* Skip continuation data */ if(data[0] != '+') { int resp; /* Check if the response is tagged with the saved label */ str_copyb(&linebuf, data, size); resp = parse_label(); if(resp > 0) { if(!str_diff(&label, &saved_label)) { log_line(data, size); /* Check if the response was an OK */ if(!strncasecmp(linebuf.s + resp, "OK ", 3)) accept_client(username.s); else deny_client(username.s); str_truncate(&saved_label, 0); } } } } write_client(data, size); }