/*
* 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 <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/nameser.h> /* DNS struct */
#include "xf-spf.h"
#include "syslog.h"
#include <spf2/spf.h>
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);
}
syntax highlighted by Code2HTML, v. 0.9.1