/* milter-callback - a sendmail milter to perform variuos sender verifications
 Copyright (C) 2008  Eugene M. Zheganin, milter-callback@norma.perm.ru
 
 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 3 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, see <http://www.gnu.org/licenses/>.
*/


#ifdef WITH_SPF

#include <milter-callback.h>
#include <mcspf.h>

extern char *logString;
extern int logLevel;
extern int mcDebug;
extern SPF_server_t *SPFServer;

SPF_server_t *
createSPFServer () {
    SPF_server_t *SPFServer = NULL;
    
    snprintf(logString, MAXLOGLINE, "Creating SPF server.");
    logNow(logString, 3);
    SPFServer = SPF_server_new(SPF_DNS_CACHE, 0);
    
    if (SPFServer == NULL) {
	snprintf(logString, MAXLOGLINE, "Cannot allocate memory.");
        logNow(logString, 0);
	exit(EXIT_FAILURE);
    }
    return(SPFServer);
}

SPF_result_t
goWithSPF (struct mlfiPriv *privData, char *envFrom) {
    SPF_request_t *SPFRequest;
    SPF_response_t *SPFResponse;
    SPF_result_t SPFResult;
    int errorCount;
    
    errorCount = 0;
    
    snprintf(logString, MAXLOGLINE, "Setting SPF IP.");
    logNow(logString, 3);

    snprintf(logString, MAXLOGLINE, "Creating SPF request.");
    logNow(logString, 3);    
    SPFRequest = SPF_request_new(SPFServer);
    
    snprintf(logString, MAXLOGLINE, "Setting SPF IP to %s.", privData -> relayPresIP);
    logNow(logString, 3);
    if (SPF_request_set_ipv4_str(SPFRequest, privData -> relayPresIP)){
	snprintf(logString, MAXLOGLINE, "Error setting SPF IP.");
        logNow(logString, 0);
	errorCount++;
    }
    snprintf(logString, MAXLOGLINE, "Setting SPF HELO to %s.", privData -> mcfi_helofrom);
    logNow(logString, 3);
    if (SPF_request_set_helo_dom(SPFRequest, privData -> mcfi_helofrom)){
	snprintf(logString, MAXLOGLINE, "Error setting SPF HELO.");
        logNow(logString, 0);
	errorCount++;
    }
    snprintf(logString, MAXLOGLINE, "Setting SPF envelope-from to %s.", envFrom);
    logNow(logString, 3);
    if (SPF_request_set_env_from(SPFRequest, envFrom)){
	snprintf(logString, MAXLOGLINE, "Error setting SPF envelope-from.");
        logNow(logString, 0);
	errorCount++;
    }
    /*spf_response*SPFResponse = malloc(sizeof(SPF_response_t));
    if (SPFResponse == NULL) {
	snprintf(logString, MAXLOGLINE, "Cannot allocate memory.");
        logNow(logString, 0);
	exit(EXIT_FAILURE);
    };*/
    snprintf(logString, MAXLOGLINE, "Trying to get SPF response.");
    logNow(logString, 3);
    SPF_request_query_mailfrom(SPFRequest, &SPFResponse);
    SPFResult = SPF_response_result(SPFResponse);
    
    snprintf(logString, MAXLOGLINE, "Got SPF result: %s:%s,%s,%s.", 
	SPF_strresult(SPF_response_result(SPFResponse)),
	SPF_response_get_smtp_comment(SPFResponse),
	SPF_response_get_header_comment(SPFResponse),
	SPF_response_get_received_spf(SPFResponse)
    );
    logNow(logString, 2);
    
    if (errorCount == 0) {
	snprintf(logString, MAXLOGLINE, "Trying to free() SPFResponse.");
        logNow(logString, 0);
	SPF_response_free(SPFResponse);
	snprintf(logString, MAXLOGLINE, "Trying to free() SPFRequest.");
        logNow(logString, 0);
	SPF_request_free(SPFRequest);
    }
    return(SPFResult);
}

void
destroySPFServer () {    
    snprintf(logString, MAXLOGLINE, "Freeing SPF server.");
    logNow(logString, 3);
    SPF_server_free(SPFServer);    
}

#endif
