/** * hermes antispam proxy * Copyright (C) 2006, 2007 Juan José Gutiérrez de Quevedo * * 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; version 2 of the License. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * @author Juan José Gutiérrez de Quevedo */ #include "Spf.h" #include #include #include SPF_server_t *Spf::spfserver = nullptr; /** * Constructor * * Initializes the SPF server if this is the first created object of the class. */ Spf::Spf() { static std::once_flag initFlag; // To ensure thread-safe initialization std::call_once(initFlag, []() { spfserver = SPF_server_new(SPF_DNS_CACHE, 0); if (!spfserver) { throw std::runtime_error("Can't initialize SPF library"); } }); } /** * Destructor * * Frees the memory of the SPF server. */ Spf::~Spf() { deinitialize(); // Clean up resources } /** * Frees all memory related to the SPF class. * * This is needed because common resources are only initialized once (and are static). */ void Spf::deinitialize() { if (spfserver) { SPF_server_free(spfserver); spfserver = nullptr; // Optional: Avoid dangling pointer } } /** * Makes a query to the DNS system for an SPF record. * * @param ip The IP of the remote server * @param helo The HELO string of the remote server * @param from The envelope from address * * @returns true if the query is not incorrect */ bool Spf::query(const std::string& ip, const std::string& helo, const std::string& from) { SPF_request_t* spfrequest = SPF_request_new(spfserver); // Create request here if (!spfrequest) { throw std::runtime_error("Can't initialize SPF request"); } // Set the values for the SPF request if (SPF_request_set_ipv4_str(spfrequest, ip.c_str())) { SPF_request_free(spfrequest); // Clean up on failure throw std::runtime_error("Error configuring IP for SPF request"); } if (SPF_request_set_helo_dom(spfrequest, helo.c_str())) { SPF_request_free(spfrequest); // Clean up on failure throw std::runtime_error("Error configuring HELO for SPF request"); } if (SPF_request_set_env_from(spfrequest, from.c_str())) { SPF_request_free(spfrequest); // Clean up on failure throw std::runtime_error("Error configuring FROM for SPF request"); } // Make the actual query SPF_response_t* spfresponse = nullptr; // Local response variable SPF_request_query_mailfrom(spfrequest, &spfresponse); bool retval = false; if (spfresponse) { retval = !(SPF_response_result(spfresponse) == SPF_RESULT_FAIL || SPF_response_result(spfresponse) == SPF_RESULT_SOFTFAIL); SPF_response_free(spfresponse); // Free the response } SPF_request_free(spfrequest); // Free the request return retval; }