/* libspf - Sender Policy Framework library
*
* ANSI C implementation of spf-draft-200405.txt
*
* Author: James Couzens <jcouzens@codeshare.ca>
*
* File: spfqtool.c
* Desc: SPF Query Tool (an example implementation of libSPF)
*
* License:
*
* The libspf Software License, Version 1.0
*
* Copyright (c) 2004 James Couzens & Sean Comeau All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHORS MAKING USE OF THIS LICESEN
* OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include "spfqtool.h"
/* SPF_usage
*
* Author: James Couzens <jcouzens@6o4.ca>
*
* Date: 07/04/04
* Date: 07/28/04 - Renamed to spfqtool
* Date: 09/08/04 - Added SPF_build_header call
*
* Desc:
* Main function, allocates memory and makes calls to the libSPF
* library which parses the "fake" query.
*
*/
int main(int argc, char *argv[])
{
u_int8_t i = 0; /* utility */
SPF_RESULT res = SPF_UNKNOWN; /* libSPF result code */
SPF_BOOL use_explain = SPF_FALSE; /* T / F provide SPF Explanation */
SPF_BOOL use_trusted = SPF_FALSE; /* T / F attempt Trusted Forwarder */
SPF_BOOL use_guess = SPF_FALSE; /* T / F attempt Best Guess */
SPF_BOOL test_mode = SPF_FALSE; /* T / F enable test mode */
char *margv = NULL; /* pointer to current argv element */
char *ip = NULL; /* ip address to test connecting from */
char *address = NULL; /* email address to test sending from */
char *helo = NULL; /* helo hostname to test sending from */
char *tmp = NULL; /* utility pointer */
char *buf = NULL; /* buffer to store generated SPF header */
peer_info_t *pinfo = NULL; /* libSPF peer_info structure */
if (argc <= 1)
{
SPF_usage();
return(SPF_FALSE);
}
for (i = 1; i < argc; i++)
{
tmp = argv[i];
if (*tmp == '-')
{
margv = (tmp + 3);
switch (*(tmp + 1))
{
/* best guess */
case 'b' :
{
use_guess = atoi(margv);
break;
} /* 'b' */
/* debug */
case 'd' :
{
confg.level = atoi(margv);
break;
} /* 'd' */
/* explanation */
case 'e' :
{
use_explain = atoi(margv);
break;
} /* 'e' */
/* RFC2821 HELO */
case 'h' :
{
helo = strdup(margv);
break;
} /* 'h' */
/* ip address */
case 'i' :
{
ip = strdup(margv);
break;
} /* 'i' */
/* source email address */
case 's' :
{
address = strdup(margv);
break;
} /* 's' */
/* trusted forwarder */
case 't' :
{
use_trusted = atoi(margv);
break;
} /* 't' */
/* version */
case 'v' :
{
printf("SPF Query Tool v%s - James Couzens <jcouzens@codeshare.ca>\n\n",
SPFQTOOL_VERSION);
return(0);
} /* 'v' */
/* test mode */
case 'z' :
{
test_mode = SPF_TRUE;
break;
} /* 'z' */
default:
{
break;
} /* default */
}
}
} /* for */
if (ip == NULL)
{
printf("You need to specify an IP Address to test against\n\n");
SPF_usage();
free(address);
return(SPF_FALSE);
}
else if (address == NULL)
{
printf("You need to specify a from email address\n\n");
SPF_usage();
free(ip);
return(SPF_FALSE);
}
else if (helo == NULL)
{
helo = strdup(HELO_HOST);
printf("You didn't give me a helo host, using (%s)\n", helo);
}
if (confg.level >= 1)
{
printf("SPF Query Tool v%s - James Couzens <jcouzens@codeshare.ca>\n",
SPFQTOOL_VERSION);
printf("[DEBUG]: Debugging level: %u\n", confg.level);
printf("[DEBUG]: RFC2821 Mail From: %s\n", address);
printf("[DEBUG]: RFC2821 HELO: %s\n", helo);
printf("[DEBUG]: Purported address: %s\n", ip);
printf("[DEBUG]: SPF Explanation: %s\n",
use_explain ? "Enabled" : "Disabled");
printf("[DEBUG]: Trusted Forwarder: %s\n",
use_trusted ? "Enabled" : "Disabled");
printf("[DEBUG]: Best Guess: %s\n",
use_guess ? "Enabled" : "Disabled");
printf("\n");
}
if ((pinfo = SPF_init(helo, ip, NULL, NULL, NULL,
use_trusted, use_guess)) != NULL)
{
/* perform fake HELO */
SPF_smtp_helo(pinfo, helo);
/* perform fake MAIL FROM */
SPF_smtp_from(pinfo, address);
/* assign and perform SPF parse */
res = pinfo->RES = SPF_policy_main(pinfo);
/* print the results of the query. The NULL check on the output is
* to the benefit of SOLARIS users where printf is unable to handle
* a NULL variable. Linux users can omit this check.
*/
if (test_mode != SPF_TRUE)
{
printf("SPF short result: %s\n",
pinfo->rs ? pinfo->rs : "NULL");
printf("SPF verbose result: %s\n",
pinfo->error ? pinfo->error : "NULL");
}
else
{
printf("%s\n%s\n%s\n",
pinfo->rs ? pinfo->rs : "NULL",
pinfo->error ? pinfo->error : "NULL",
pinfo->explain ? pinfo->explain : "NULL");
}
if (use_explain == SPF_TRUE)
{
buf = SPF_get_explain(pinfo);
printf("SPF explanation: %s\n",
pinfo->explain ? pinfo->explain : "NULL");
free(buf);
}
/* for the tests we need to be silent :-) */
if (test_mode != SPF_TRUE)
{
if (use_trusted == SPF_TRUE)
{
printf("Trusted Forwarder: Attempted.\n");
}
if (use_guess == SPF_TRUE)
{
printf("Best Guess: Attempted.\n");
}
if ((buf = SPF_build_header(pinfo)) != NULL)
{
printf("RFC2822 header: %s\n", buf);
free(buf);
}
}
/* close SPF session (free memory associated with parse) */
SPF_close(pinfo);
}
free(ip);
free(address);
free(helo);
return(SPF_FALSE);
}
/* SPF_usage
*
* Author: James Couzens <jcouzens@6o4.ca>
*
* Date: 12/25/03
* Date: 07/28/04 - Renamed to spfqtool
*
* Desc:
* Displays usage help information when the binary is called with
* no arguments.
*
*/
void SPF_usage()
{
printf("spfqtool usage:\n");
printf("\n");
printf("spfqtool [b|d|e|i|s|t|h|v]\n");
printf("\n");
printf("-b [0,1] - Enable Best Guess support (True (0) or False (1))\n");
printf("-d [x] - DEBUG where x is a number between 1 and 255\n");
printf("-e [0,1] - Enable SPF explanation (True (0) or False (1))\n");
printf("-h [host] - HELO hostname to test with\n");
printf("-i [addr] - IP Address where the fake connection will come from\n");
printf("-s [email] - What email address to test with\n");
printf("-t [0,1] - Enable Trusted Forwarder support (True (0) or False (1))\n");
printf("-v - Display version string\n");
printf("\n");
printf("Example: ./spfqtool -i 10.0.0.2 -s jcouzens@6o4.ca -h spftools.net\n");
printf("\n");
printf("Minimum required arguments are 'i', and 's'\n");
printf("\n");
return;
}
/* end spfqtool.c */