CAMLprim value caml_spf_request_set_inet_addr(value req_val, value addr) { CAMLparam2(req_val, addr); SPF_request_t *req = (SPF_request_t *)req_val; struct sockaddr_storage ss; socklen_t ss_len; SPF_errcode_t e = SPF_E_SUCCESS; spf_get_sockaddr(addr, &ss, &ss_len); switch (ss.ss_family) { case AF_INET: e = SPF_request_set_ipv4(req, ((struct sockaddr_in *)&ss)->sin_addr); break; case AF_INET6: e = SPF_request_set_ipv6(req, ((struct sockaddr_in6 *)&ss)->sin6_addr); break; } if (e != SPF_E_SUCCESS) spf_error(SPF_strerror(e)); CAMLreturn(Val_unit); }
static int spf(milter_stage_t stage, char *name, var_t *attrs) { SPF_request_t *req = NULL; SPF_response_t *res = NULL; SPF_response_t *res_2mx = NULL; char *helo; char *envfrom; char from[321]; char *envrcpt; char rcpt[321]; char *spfstr; char *spfreason; struct sockaddr_storage *ss; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; int r; if (acl_symbol_dereference(attrs, "hostaddr", &ss, "envfrom", &envfrom, "envrcpt", &envrcpt, "helo", &helo, NULL)) { log_error("spf: acl_symbol_dereference failed"); goto error; } sin = (struct sockaddr_in *) ss; sin6 = (struct sockaddr_in6 *) ss; if (util_strmail(from, sizeof from, envfrom) == -1 || util_strmail(rcpt, sizeof rcpt, envrcpt) == -1) { log_error("spf: util_strmail failed"); goto error; } req = SPF_request_new(spf_server); if (req == NULL) { log_error("spf: SPF_request_new failed"); goto error; } /* * Set client address */ if (ss->ss_family == AF_INET6) { r = SPF_request_set_ipv6(req, sin6->sin6_addr); } else { r = SPF_request_set_ipv4(req, sin->sin_addr); } if (r) { log_error("spf: SPF_request_set_ip failed"); goto error; } /* * Set helo */ r = SPF_request_set_helo_dom(req, helo); if (r) { log_error("spf: SPF_request_set_helo_dom failed"); goto error; } /* * Set envelope from */ r = SPF_request_set_env_from(req, from); if (r) { log_error("spf_query: SPF_request_set_env_from failed"); goto error; } /* * Perform SPF query */ SPF_request_query_mailfrom(req, &res); if(SPF_response_result(res) == SPF_RESULT_PASS) { goto result; } /* * If SPF fails check if we received the email from a secondary mx. */ SPF_request_query_rcptto(req, &res_2mx, rcpt); if(SPF_response_result(res_2mx) != SPF_RESULT_PASS) { goto result; } /* * Secondary mx */ log_notice("spf: \"%s\" is a secodary mx for \"%s\"", helo, rcpt); goto exit; result: spfstr = (char *) SPF_strresult(SPF_response_result(res)); if (spfstr == NULL) { log_error("spf: SPF_strresult failed"); goto error; } spfreason = (char *) SPF_strreason(SPF_response_result(res)); if (spfreason == NULL) { log_error("spf: SPF_strreason failed"); goto error; } log_message(LOG_ERR, attrs, "spf: helo=%s from=%s spf=%s", helo, from, spfstr); if (vtable_setv(attrs, VT_STRING, "spf", spfstr, VF_KEEP, VT_STRING, "spf_reason", spfreason, VF_KEEP, VT_NULL)) { log_error("spf: vtable_setv failed"); goto error; } exit: SPF_request_free(req); SPF_response_free(res); if(res_2mx) { SPF_response_free(res_2mx); } return 0; error: if(req) { SPF_request_free(req); } if(res) { SPF_response_free(res); } if(res_2mx) { SPF_response_free(res_2mx); } return -1; }