47#define SPF_TEST_VERSION "3.0"
60#ifdef HAVE_SYS_TYPES_H
76#ifdef HAVE_SYS_SOCKET_H
77# include <sys/socket.h>
79#ifdef HAVE_NETINET_IN_H
80# include <netinet/in.h>
83#ifdef HAVE_ARPA_NAMESER_H
84# include <arpa/nameser.h>
87#ifdef HAVE_ARPA_INET_H
88# include <arpa/inet.h>
91#ifdef HAVE_GETOPT_LONG_ONLY
118#define FREE(x, f) do { if ((x)) (f)((x)); (x) = NULL; } while(0)
119#define FREE_REQUEST(x) FREE((x), SPF_request_free)
120#define FREE_RESPONSE(x) FREE((x), SPF_response_free)
122#define CONTINUE_ERROR do { res = 255; continue; } while(0)
123#define WARN_ERROR do { res = 255; } while(0)
124#define FAIL_ERROR do { res = 255; goto error; } while(0)
126#define RESIZE_RESULT(n) do { \
127 if (result == NULL) { \
128 result_len = 256 + n; \
129 result = malloc(result_len); \
132 else if (strlen(result) + n >= result_len) { \
133 result_len = result_len + (result_len >> 1) + 8 + n; \
134 result = realloc(result, result_len); \
137#define APPEND_RESULT(n) do { \
138 partial_result = SPF_strresult(n); \
139 RESIZE_RESULT(strlen(partial_result)); \
140 strcat(result, partial_result); \
143#define X_OR_EMPTY(x) ((x) ? (x) : "")
145static struct option long_options[] = {
149 {
"sender", 1, 0,
's'},
151 {
"rcpt-to", 1, 0,
'r'},
153 {
"debug", 2, 0,
'd'},
154 {
"local", 1, 0,
'l'},
155 {
"trusted", 1, 0,
't'},
156 {
"guess", 1, 0,
'g'},
157 {
"default-explanation", 1, 0,
'e'},
158 {
"max-lookup", 1, 0,
'm'},
159 {
"sanitize", 1, 0,
'c'},
161 {
"override", 1, 0,
'a'},
162 {
"fallback", 1, 0,
'z'},
164 {
"keep-comments", 0, 0,
'k'},
165 {
"version", 0, 0,
'v'},
172unimplemented(
const char flag)
177 for (i = 0; (opt = &long_options[i])->
name; i++) {
179 fprintf(stderr,
"Unimplemented option: -%s or -%c\n",
185 fprintf(stderr,
"Unimplemented option: -%c\n",
flag);
196 "spfquery [control options | data options] ...\n"
198 "Use the -help option for more information\n"
209 "spfquery [control options | data options] ...\n"
211 "Valid data options are:\n"
212 " -file <filename> read spf data from a file. Use '-'\n"
213 " to read from stdin.\n"
215 " -ip <IP address> The IP address that is sending email\n"
216 " -sender <email address> The email address used as the\n"
217 " envelope-from. If no username (local\n"
218 " part) is given, 'postmaster' will be\n"
220 " -helo <domain name> The domain name given on the SMTP HELO\n"
221 " command. This is only needed if the\n"
222 " -sender option is not given.\n"
223 " -rcpt-to <email addresses> A comma separated lists of email addresses\n"
224 " that will have email from their secondary\n"
225 " MXes automatically allowed.\n"
227 "The data options are required. The -file option conflicts with all\n"
228 "the other data options. The -helo and -rcpt-to are optional.\n"
231 "Valid control options are:\n"
232 " -debug [debug level] debug level.\n"
233 " -local <SPF mechanisms> Local policy for whitelisting.\n"
234 " -trusted <0|1> Should trusted-forwarder.org be checked?\n"
235 " -guess <SPF mechanisms> Default checks if no SPF record is found.\n"
236 " -default-explanation <str> Default explanation string to use.\n"
237 " -max-lookup <number> Maximum number of DNS lookups to allow\n"
238 " -sanitize <0|1> Clean up invalid characters in output?\n"
239 " -name <domain name> The name of the system doing the SPF\n"
241 " -override <...> Override SPF records for domains\n"
242 " -fallback <...> Fallback SPF records for domains\n"
244 " -keep-comments Print comments found when reading\n"
246 " -version Print version of spfquery.\n"
247 " -help Print out these options.\n"
251 "spfquery -ip=11.22.33.44 -sender=user@aol.com -helo=spammer.tld\n"
252 "spfquery -f test_data\n"
253 "echo \"127.0.0.1 myname@mydomain.com helohost.com\" | spfquery -f -\n"
259response_print_errors(
const char *context,
265 printf(
"StartError\n");
268 printf(
"Context: %s\n", context);
272 if (spf_response !=
NULL) {
275 printf(
"%s: %s%s\n",
286 printf(
"libspf2 gave a NULL spf_response\n");
288 printf(
"EndError\n");
292response_print(
const char *context, SPF_response_t *spf_response)
295 printf(
"Context: %s\n", context);
296 if (spf_response ==
NULL) {
297 printf(
"NULL RESPONSE!\n");
300 printf(
"Response result: %s\n",
302 printf(
"Response reason: %s\n",
304 printf(
"Response err: %s\n",
306 response_print_errors(
NULL, spf_response,
313struct SPF_client_options_struct {
326struct SPF_client_request_struct {
333int main(
int argc,
char *argv[] )
338 SPF_server_t *spf_server =
NULL;
339 SPF_request_t *spf_request =
NULL;
340 SPF_response_t *spf_response =
NULL;
341 SPF_response_t *spf_response_2mx =
NULL;
342 SPF_response_t *spf_response_fallback =
NULL;
345 char *opt_file =
NULL;
346 int opt_keep_comments = 0;
352 int major, minor, patch;
357 const char *partial_result;
370 if (SPF_win32_startup() == 0) {
371 fprintf( stderr,
"Could not startup WinSock, wrong version." );
384 long_options, &option_index);
453 fprintf( stderr,
"spfquery version information:\n" );
454 fprintf( stderr,
"SPF test system version: %s\n",
456 fprintf( stderr,
"Compiled with SPF library version: %d.%d.%d\n",
460 fprintf( stderr,
"Running with SPF library version: %d.%d.%d\n",
461 major, minor, patch );
462 fprintf( stderr,
"\n" );
474 opt_keep_comments = 1;
485 fprintf( stderr,
"Error: getopt returned character code 0%o ??\n", c);
506 SPF_server_set_max_dns_mech(spf_server, opts->
max_lookup);
511 response_print_errors(
"Error setting local policy",
522 response_print_errors(
"Error setting default explanation",
537 if (strcmp(opt_file,
"-" ) == 0)
540 fin = fopen( opt_file,
"r" );
543 fprintf( stderr,
"Could not open: %s\n", opt_file );
561 if ( fgets( in_line,
sizeof( in_line ), fin ) ==
NULL )
564 in_line[strcspn(in_line,
"\r\n")] =
'\0';
567 p += strspn( p,
" \t\n" );
569 if ( *p ==
'\0' || *p ==
'#' ) {
570 if ( opt_keep_comments )
571 printf(
"%s\n", in_line );
576 p += strcspn( p,
" \t\n" );
579 p += strspn( p,
" \t\n" );
581 p += strcspn( p,
" \t\n" );
584 p += strspn( p,
" \t\n" );
586 p += strcspn( p,
" \t\n" );
589 p += strspn( p,
" \t\n" );
591 p += strcspn( p,
" \t\n" );
608 printf(
"Invalid IP address.\n" );
614 printf(
"Invalid HELO domain.\n" );
620 printf(
"Invalid envelope from address.\n" );
626 response_print(
"Main query", spf_response);
628 response_print_errors(
"Failed to query MAIL-FROM",
639 p_end = p + strcspn(p,
",;");
649 &spf_response_2mx, p);
651 response_print(
"2mx query", spf_response_2mx);
653 response_print_errors(
"Failed to query RCPT-TO",
673 &spf_response_fallback, opts->
fallback);
675 response_print(
"fallback query", spf_response_fallback);
677 response_print_errors(
"Failed to query best-guess",
678 spf_response_fallback, err);
686 spf_response_fallback);
689 printf(
"%s\n%s\n%s\n%s\n",
SPF_server_t * SPF_server_new(SPF_server_dnstype_t dnstype, int debug)
SPF_errcode_t SPF_server_set_explanation(SPF_server_t *sp, const char *exp, SPF_response_t **spf_responsep)
void SPF_server_free(SPF_server_t *sp)
SPF_errcode_t SPF_server_set_sanitize(SPF_server_t *sp, int sanitize)
SPF_errcode_t SPF_server_set_localpolicy(SPF_server_t *sp, const char *policy, int use_default_whitelist, SPF_response_t **spf_responsep)
SPF_errcode_t SPF_server_set_rec_dom(SPF_server_t *sp, const char *dom)
#define SPF_LIB_VERSION_PATCH
#define SPF_LIB_VERSION_MINOR
#define SPF_LIB_VERSION_MAJOR
SPF_errcode_t SPF_response_errcode(SPF_response_t *rp)
const char * SPF_response_get_smtp_comment(SPF_response_t *rp)
const char * SPF_response_get_received_spf(SPF_response_t *rp)
const char * SPF_response_get_header_comment(SPF_response_t *rp)
const char * SPF_error_message(SPF_error_t *err)
SPF_error_t * SPF_response_message(SPF_response_t *rp, int idx)
int SPF_response_messages(SPF_response_t *rp)
char SPF_error_errorp(SPF_error_t *err)
SPF_response_t * SPF_response_combine(SPF_response_t *main, SPF_response_t *r2mx)
SPF_result_t SPF_response_result(SPF_response_t *rp)
SPF_reason_t SPF_response_reason(SPF_response_t *rp)
const char * SPF_strerror(SPF_errcode_t spf_err)
void SPF_get_lib_version(int *major, int *minor, int *patch)
const char * SPF_strresult(SPF_result_t result)
const char * SPF_strreason(SPF_reason_t reason)
SPF_request_t * SPF_request_new(SPF_server_t *spf_server)
SPF_errcode_t SPF_request_set_ipv6_str(SPF_request_t *sr, const char *astr)
SPF_errcode_t SPF_request_query_fallback(SPF_request_t *spf_request, SPF_response_t **spf_responsep, const char *record)
int SPF_request_set_env_from(SPF_request_t *sr, const char *from)
SPF_errcode_t SPF_request_set_helo_dom(SPF_request_t *sr, const char *dom)
SPF_errcode_t SPF_request_set_ipv4_str(SPF_request_t *sr, const char *astr)
SPF_errcode_t SPF_request_query_rcptto(SPF_request_t *spf_request, SPF_response_t **spf_responsep, const char *rcpt_to)
SPF_errcode_t SPF_request_query_mailfrom(SPF_request_t *spf_request, SPF_response_t **spf_responsep)
int main(int argc, char *argv[])