/* * XF-SPF, basic but fully function implementation of SPF checker to be * used with qmail-smtpd's SMTPEXTFORK patch. Please see README for details. */ #include #include #include #include /* DNS struct */ #include "xf-spf.h" #include "syslog.h" #include int main() { int res = 0; int i; int xfspf_dbg = 0; char *remote_ip = NULL; char *remote_sender = NULL; char *heloehlo = NULL; char *rcptto = NULL; const char *envp; int spfbehavior; SPF_server_t *spf_server = NULL; SPF_request_t *spf_request = NULL; SPF_response_t *spf_myres = NULL; SPF_response_t *spf_myres2 = NULL; // para DNS secundario int error(int res) { if (spf_request) SPF_request_free(spf_request); if (spf_server) SPF_server_free(spf_server); exit(res); } int errcli() { fprintf(stderr, "This program should not be run from the command line\n"); error(NOTCLI); } // getenv retorna char * entao, convertemos ponteiro pra inteiro e atribuimos if (!(envp = getenv("SPFBEHAVIOR"))) { loga("SPFBEHAVIOR enviroment var is not defined"); error(XFPASS); } else spfbehavior = atoi(envp); // if spfbehavior is not 1-6, no more checks, let it pass if ((spfbehavior < 1) || (spfbehavior > 6)) error(XFPASS); if (!(remote_ip = getenv("TCPREMOTEIP"))) errcli(); if (!(rcptto = getenv("REMOTERCPT"))) errcli(); if (!(heloehlo = getenv("REMOTEHELO"))) errcli(); if (!(remote_sender = getenv("REMOTEMF"))) remote_sender = "postmaster"; spf_server = SPF_server_new(SPF_DNS_CACHE, xfspf_dbg); if (spf_server == NULL) { loga("SPF lib failed on spf_server creation"); error(XFSPFERR); } spf_request = SPF_request_new(spf_server); if ( SPF_request_set_ipv4_str( spf_request, remote_ip ) ) { loga("SPF lib identified IP address as invalid"); error(XFSPFERR); } if (heloehlo == NULL) { if (remote_sender != NULL) { if (strstr(remote_sender, "@") != NULL) { heloehlo = strdup(strstr(remote_sender, "@") + 1); if ( SPF_request_set_helo_dom( spf_request, heloehlo ) ) { loga("SPF lib identified HELO domain as invalid"); error(XFSPFERR); } } } } else { if ( SPF_request_set_helo_dom( spf_request, heloehlo ) ) { loga("SPF lib identified HELO domain as invalid"); error(XFSPFERR); } } if ( SPF_request_set_env_from( spf_request, remote_sender ) ) { loga("SPF lib identified envelope FROM address as invalid"); error(XFSPFERR); } SPF_request_query_mailfrom(spf_request, &spf_myres); if (SPF_response_result(spf_myres) != SPF_RESULT_PASS) { SPF_request_query_rcptto(spf_request, &spf_myres2, rcptto); if (SPF_response_result(spf_myres2) == SPF_RESULT_PASS) { } } // Vamos liberar a memoria SPF_response_free(spf_myres); if (spf_myres2) SPF_response_free(spf_myres2); if (spfbehavior > 0) if (envp = SPF_response_get_received_spf(spf_myres)) loga(envp); #if LOGNSPFDOM == 1 else loga("Received-SPF: none (domain does not have SPF record)"); #endif switch (res = SPF_response_result(spf_myres)) { case SPF_RESULT_PASS: break; case SPF_RESULT_FAIL: if (spfbehavior > 2) error(XFPERMF); break; case SPF_RESULT_SOFTFAIL: if (spfbehavior > 3) error(XFPERMF); break; case SPF_RESULT_NEUTRAL: if (spfbehavior > 4) error(XFPERMF); break; case SPF_RESULT_INVALID: if (spfbehavior > 5) error(XFPERMF); break; case SPF_RESULT_TEMPERROR: if (spfbehavior > 5) error(XFPERMF); break; case SPF_RESULT_PERMERROR: if (spfbehavior > 5) error(XFPERMF); break; case SPF_RESULT_NONE: if (spfbehavior > 5) error(XFPERMF); break; default: error(res); } return(XFPASS); }