/* * Copyright (C) 2003-2005 Pawel Foremski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include "spf.h" void block(peer_info_t *peer_info) { char *explain; explain = SPF_get_explain(peer_info); if (explain) { printf("E550 %s (#5.7.1)\n", explain); fprintf(stderr, "spf: blocked with: %s\n", explain); free(explain); } else { printf("E550 Blocked with SPF (#5.7.1)\n", explain); fprintf(stderr, "spf: WARNING: no explanation for blocked mail!\n"); } } int main() { int spf; char *me, *remote, *helo, *sender, *spf_env, *header; peer_info_t *peer_info; /** * env variables **/ if (getenv("RELAYCLIENT") || /* known user */ !(spf_env = getenv("SPF"))) return 0; /* plugin disabled */ spf = atoi(spf_env); if (spf < 1 || spf > 6) { if (spf > 6) fprintf(stderr, "spf: ERROR: invalid value (%d) of SPF variable\n", spf); return 0; } remote = getenv("TCPREMOTEIP"); me = getenv("TCPLOCALHOST"); if (!me) me = getenv("TCPLOCALIP"); if (!remote || !me) { /* should never happen */ fprintf(stderr, "spf: ERROR: can't get tcpserver variables\n"); if(!remote) fprintf(stderr, "spf: can't read TCPREMOTEIP\n"); else fprintf(stderr, "spf: can't read TCPLOCALHOST nor TCPLOCALIP\n"); return 0; } sender = getenv("SMTPMAILFROM"); if (!sender) { /* should never happen */ fprintf(stderr, "spf: ERROR: can't get envelope sender address\n"); fprintf(stderr, "spf: can't read SMTPMAILFROM\n"); return 0; } if (!*sender) return 0; /* null sender mail */ helo = getenv("SMTPHELOHOST"); /** * SPF **/ peer_info = SPF_init(me, remote, SPF_EXPLAIN, NULL, NULL, 0, 0); if (!peer_info) { /* init failed */ fprintf(stderr, "spf: ERROR: can't initialize SPF library\n"); return 0; } if (helo) SPF_smtp_helo(peer_info, helo); SPF_smtp_from(peer_info, sender); peer_info->RES = SPF_policy_main(peer_info); /* rock takes place here */ /* check whether mail needn`t to be blocked */ switch (peer_info->RES) { case SPF_PASS: break; case SPF_H_FAIL: if (spf > 0) { block(peer_info); return 0; } break; case SPF_S_FAIL: if (spf > 1) { block(peer_info); return 0; } break; case SPF_NEUTRAL: if (spf > 2) { block(peer_info); return 0; } break; case SPF_NONE: if (spf > 3) { block(peer_info); return 0; } break; case SPF_ERROR: if (spf > 4) { block(peer_info); return 0; } break; case SPF_UNKNOWN: if (spf > 5) { block(peer_info); return 0; } break; case SPF_UNMECH: break; } /* add header */ header = SPF_build_header(peer_info); printf("H"); if (header[0] != 'R') printf("Received-SPF: "); /* hack for old libspf ver. */ printf("%s\n", header); free(header); SPF_close(peer_info); return 0; }