Esempio n. 1
0
File: spf.c Progetto: fanf2/exim
int spf_init(uschar *spf_helo_domain, uschar *spf_remote_addr) {

  spf_server = SPF_server_new(SPF_DNS_CACHE, 0);

  if ( spf_server == NULL ) {
    debug_printf("spf: SPF_server_new() failed.\n");
    return 0;
  }

  if (SPF_server_set_rec_dom(spf_server, CS primary_hostname)) {
    debug_printf("spf: SPF_server_set_rec_dom() failed.\n");
    spf_server = NULL;
    return 0;
  }

  spf_request = SPF_request_new(spf_server);

  if (SPF_request_set_ipv4_str(spf_request, CS spf_remote_addr)) {
    debug_printf("spf: SPF_request_set_ipv4_str() failed.\n");
    spf_server = NULL;
    spf_request = NULL;
    return 0;
  }

  if (SPF_request_set_helo_dom(spf_request, CS spf_helo_domain)) {
    debug_printf("spf: SPF_set_helo_dom() failed.\n");
    spf_server = NULL;
    spf_request = NULL;
    return 0;
  }

  return 1;
}
Esempio n. 2
0
File: spf.c Progetto: Exim/exim
BOOL
spf_init(uschar *spf_helo_domain, uschar *spf_remote_addr)
{
spf_server = SPF_server_new(SPF_DNS_CACHE, 0);

if (!spf_server)
  {
  DEBUG(D_receive) debug_printf("spf: SPF_server_new() failed.\n");
  return FALSE;
  }

if (SPF_server_set_rec_dom(spf_server, CS primary_hostname))
  {
  DEBUG(D_receive) debug_printf("spf: SPF_server_set_rec_dom(\"%s\") failed.\n",
    primary_hostname);
  spf_server = NULL;
  return FALSE;
  }

spf_request = SPF_request_new(spf_server);

if (  SPF_request_set_ipv4_str(spf_request, CS spf_remote_addr)
   && SPF_request_set_ipv6_str(spf_request, CS spf_remote_addr)
   )
  {
  DEBUG(D_receive)
    debug_printf("spf: SPF_request_set_ipv4_str() and "
      "SPF_request_set_ipv6_str() failed [%s]\n", spf_remote_addr);
  spf_server = NULL;
  spf_request = NULL;
  return FALSE;
  }

if (SPF_request_set_helo_dom(spf_request, CS spf_helo_domain))
  {
  DEBUG(D_receive) debug_printf("spf: SPF_set_helo_dom(\"%s\") failed.\n",
    spf_helo_domain);
  spf_server = NULL;
  spf_request = NULL;
  return FALSE;
  }

return TRUE;
}
Esempio n. 3
0
File: spf.c Progetto: Gnitset/.bah
int main()
{
	int spf;
	char *me, *remote, *helo, *sender, *spf_env;
	const char *header;
	SPF_server_t *spf_server;
	SPF_request_t *spf_request;
	SPF_response_t *spf_response;

	/**
	 * env variables
	 **/
	if (getenv("RELAYCLIENT") ||              /* known user */
	    !(spf_env = getenv("SPF"))) return 0; /* plugin disabled */

	spf = atoi(spf_env);
	if (spf < 1 || spf > 6) {
		if (spf > 6)
			fprintf(stderr, "spf: ERROR: invalid value (%d) of SPF variable\n", spf);
		return 0;
	}

	remote  = getenv("TCPREMOTEIP"); 
	me      = getenv("TCPLOCALHOST");
	if (!me) me = getenv("TCPLOCALIP");
	if (!remote || !me) { /* should never happen */
		fprintf(stderr, "spf: ERROR: can't get tcpserver variables\n");
		if(!remote) fprintf(stderr, "spf: can't read TCPREMOTEIP\n");
		else fprintf(stderr, "spf: can't read TCPLOCALHOST nor TCPLOCALIP\n");
		return 0;
	}

	sender = getenv("SMTPMAILFROM");
	if (!sender) { /* should never happen */
		fprintf(stderr, "spf: ERROR: can't get envelope sender address\n");
		fprintf(stderr, "spf: can't read SMTPMAILFROM\n");
		return 0;
	}
	if (!*sender) return 0; /* null sender mail */

	helo = getenv("SMTPHELOHOST");

	/**
	 * SPF
	 **/
	spf_server = SPF_server_new(SPF_DNS_CACHE, 0);
	if (!spf_server) {
		fprintf(stderr, "spf: ERROR: can't initialize libspf2\n");
		return 0;
	}
	spf_request = SPF_request_new(spf_server);
	if (!spf_request) {
		fprintf(stderr, "spf: ERROR: can't initialize libspf2\n");
		return 0;
	}

	if (SPF_request_set_ipv4_str(spf_request, remote)) {
		fprintf(stderr, "spf: can't parse TCPREMOTEIP\n");
		return 0;
	}

	SPF_server_set_rec_dom(spf_server, me);

	if (helo) SPF_request_set_helo_dom(spf_request, helo);
	SPF_request_set_env_from(spf_request, sender);

	/* Perform actual lookup */
	SPF_request_query_mailfrom(spf_request, &spf_response);

	/* check whether mail needn`t to be blocked */
	switch (SPF_response_result(spf_response)) {
		case SPF_RESULT_PASS:      break;
		case SPF_RESULT_FAIL:      if (spf > 0) { block(spf_response); return 0; } break;
		case SPF_RESULT_SOFTFAIL:  if (spf > 1) { block(spf_response); return 0; } break;
		case SPF_RESULT_NEUTRAL:   if (spf > 2) { block(spf_response); return 0; } break;
		case SPF_RESULT_NONE:      if (spf > 3) { block(spf_response); return 0; } break;
		case SPF_RESULT_TEMPERROR:
		case SPF_RESULT_PERMERROR: if (spf > 4) { block(spf_response); return 0; } break;
#if 0
		case SPF_RESULT_UNKNOWN:   if (spf > 5) { block(spf_response); return 0; } break;
		case SPF_RESULT_UNMECH:    break;
#else
					   // FIXME: UNKNOWN and UNMECH above map how?
					   // INVALID should not ever occur, it indicates a bug.
		case SPF_RESULT_INVALID:   if (spf > 5) { block(spf_response); return 0; } break;
#endif
	}

	/* add header */
	header = SPF_response_get_received_spf(spf_response);
	if (header)
		printf("H%s\n", header);
	else {
		fprintf(stderr, "spf: libspf2 library failed to produce Received-SPF header\n",
			SPF_strerror(SPF_response_errcode(spf_response)));
		/* Example taken from libspf2: */
/*
		fprintf ( stderr, "spf: diag: result = %s (%d)\n",
		SPF_strresult(SPF_response_result(spf_response)),
		SPF_response_result(spf_response));
		fprintf ( stderr, "spf: diag: err = %s (%d)\n",
			SPF_strerror(SPF_response_errcode(spf_response)),
			SPF_response_errcode(spf_response));
		for (i = 0; i < SPF_response_messages(spf_response); i++) {
			SPF_error_t     *err = SPF_response_message(spf_response, i);
			fprintf ( stderr, "spf: diag: %s_msg = (%d) %s\n",
				(SPF_error_errorp(err) ? "warn" : "err"),
				SPF_error_code(err),
				SPF_error_message(err));
		}
*/
	}

	SPF_response_free(spf_response);
	SPF_request_free(spf_request);
	SPF_server_free(spf_server);

	return 0;
}
Esempio n. 4
0
int main( int argc, char *argv[] )
{
	SPF_client_options_t	*opts;
	SPF_client_request_t	*req = NULL;

	SPF_server_t	*spf_server = NULL;
	SPF_request_t	*spf_request = NULL;
	SPF_response_t	*spf_response = NULL;
	SPF_response_t	*spf_response_2mx = NULL;
	SPF_errcode_t	 err;

	int  			 opt_keep_comments = 0;

#ifdef TO_MX
	char			*p, *p_end;
#endif

	int 			 request_limit=0;
	int				 major, minor, patch;

	int				 res = 0;
	int				 c;

	const char		*partial_result;
	char			*result = NULL;
	int				 result_len = 0;
	char			hostname[255];
	char			pf_result[100];
	struct hostent		*fullhostname;

        /* Figure out our name */
        progname = strrchr(argv[0], '/');
        if (progname != NULL)                                                 
                ++progname;
        else
                progname = argv[0];

	/*open syslog*/
	openlog(progname, LOG_PID|LOG_CONS|LOG_NDELAY|LOG_NOWAIT, LOG_MAIL);

	/* Redefine libSPF2 output routines to go to syslog */
	SPF_error_handler = SPF_error_syslog;
	SPF_warning_handler = SPF_warning_syslog;
	SPF_info_handler = SPF_info_syslog;
	SPF_debug_handler = SPF_debug_syslog;
	
	opts = (SPF_client_options_t *)malloc(sizeof(SPF_client_options_t));
	memset(opts, 0, sizeof(SPF_client_options_t));

	/*
	 * check the arguments
	 */

	for (;;) {
		int option_index;	/* Largely unused */

		c = getopt_long_only (argc, argv, "f:i:s:h:r:lt::gemcnd::kz:a:v",
				  long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
			case 'l':
				opts->localpolicy = optarg;
				break;

			case 't':
				if (optarg == NULL)
					opts->use_trusted = 1;
				else
					opts->use_trusted = atoi(optarg);
				break;

			case 'g':
				opts->fallback = optarg;
				break;

			case 'e':
				opts->explanation = optarg;
				break;

			case 'm':
				opts->max_lookup = atoi(optarg);
				break;

			case 'c':		/* "clean"		*/
				opts->sanitize = atoi(optarg);
				break;

			case 'n':		/* name of host doing SPF checking */
				opts->rec_dom = optarg;
				break;

			case 'a':
				unimplemented('a');
				break;

			case 'z':
				unimplemented('z');
				break;


			case 'v':
				fprintf( stderr, "policyd-spf-fs version information:\n" );
				fprintf( stderr, "policyd-spf-fs version: $Rev: 27 $\n");
				fprintf( stderr, "SPF test system version: %s\n",
				 SPF_TEST_VERSION );
				fprintf( stderr, "Compiled with SPF library version: %d.%d.%d\n",
				 SPF_LIB_VERSION_MAJOR, SPF_LIB_VERSION_MINOR,
				 SPF_LIB_VERSION_PATCH );
				SPF_get_lib_version( &major, &minor, &patch );
				fprintf( stderr, "Running with SPF library version: %d.%d.%d\n",
				 major, minor, patch );
				fprintf( stderr, "\n" );
				FAIL_ERROR;
				break;

			case 0:
			case '?':
				help();
				FAIL_ERROR;
				break;

			case 'k':
				opt_keep_comments = 1;
				break;

			case 'd':
				if (optarg == NULL)
					opts->debug = 1;
				else
					opts->debug = atoi( optarg );
				break;

			default:
				fprintf( stderr, "Error: getopt returned character code 0%o ??\n", c);
				FAIL_ERROR;
		}
	}

	if (optind != argc) {
		help();
		FAIL_ERROR;
	}

	if (!opts->rec_dom) {
  	  gethostname(hostname, 255);
	  fullhostname = gethostbyname(hostname);
	
	  if (opts->debug > 1)
	    syslog(LOG_DEBUG, "Hostname: %s\n",fullhostname->h_name);

	  opts->rec_dom = fullhostname->h_name;
	}

	/*
	 * set up the SPF configuration
	 */

	spf_server = SPF_server_new(SPF_DNS_CACHE, opts->debug > 2 ? opts->debug-2 : 0);

	if ( opts->rec_dom )
		SPF_server_set_rec_dom( spf_server, opts->rec_dom );
	if ( opts->sanitize )
		SPF_server_set_sanitize( spf_server, opts->sanitize );
	if ( opts->max_lookup )
		SPF_server_set_max_dns_mech(spf_server, opts->max_lookup);

	if (opts->localpolicy) {
		err = SPF_server_set_localpolicy( spf_server, opts->localpolicy, opts->use_trusted, &spf_response);
		if ( err ) {
			response_print_errors("Error setting local policy",
							spf_response, err);
			WARN_ERROR;
		}
		FREE_RESPONSE(spf_response);
	}


	if ( !opts->explanation ) {
	  opts->explanation = DEFAULT_EXPLANATION;
	}
	
	err = SPF_server_set_explanation( spf_server, opts->explanation, &spf_response );
	if ( err ) {
	  response_print_errors("Error setting default explanation",
	         spf_response, err);
	  WARN_ERROR;
	}
	FREE_RESPONSE(spf_response);

	/*
	 * process the SPF request
	 */

	request_limit=0;

	while ( request_limit < REQUEST_LIMIT ) {
		request_limit++;	                                
	        if (request_limit == 0) {
  		  free(req);
  		}
		req = (SPF_client_request_t *)malloc(sizeof(SPF_client_request_t));
		memset(req, 0, sizeof(SPF_client_request_t));
		
		if (read_request_from_pf(opts, req)) {
		  syslog(LOG_WARNING, "IO Closed while reading, exiting");
		  EXIT_OK;
		}
		
		if (opts->debug > 1)
			syslog(LOG_DEBUG, "Reincarnation %d\n", request_limit);


		/* We have to do this here else we leak on CONTINUE_ERROR */
		FREE_REQUEST(spf_request);
		FREE_RESPONSE(spf_response);

		spf_request = SPF_request_new(spf_server);

		if (SPF_request_set_ipv4_str(spf_request, req->ip) && SPF_request_set_ipv6_str(spf_request, req->ip)) {
			syslog(LOG_WARNING, "Invalid IP address.\n" );
			CONTINUE_ERROR;
		}

	  if (req->helo) {
		if (SPF_request_set_helo_dom( spf_request, req->helo ) ) {
			syslog(LOG_WARNING, "Invalid HELO domain.\n" );
			CONTINUE_ERROR;
		}
	  }

	  	if (strchr(req->sender, '@') > 0) {
  		  if (SPF_request_set_env_from( spf_request, req->sender ) ) {
			syslog(LOG_WARNING, "Invalid envelope from address.\n" );
			CONTINUE_ERROR;
		  }
		} else { /* This is something we can not check*/ 
                  CONTINUE_DUNNO("no valid email address found");
                }

		err = SPF_request_query_mailfrom(spf_request, &spf_response);
		if (opts->debug > 1) 
			response_print("Main query", spf_response);
		if (err) {
		  if (opts->debug > 1)
			response_print_errors("Failed to query MAIL-FROM",
							spf_response, err);

			CONTINUE_DUNNO("no SPF record found");
		}

		if (result != NULL)
			result[0] = '\0';
		APPEND_RESULT(SPF_response_result(spf_response));
		
#ifdef TO_MX /* This code returns usualy neutral and oferwrites a fail from the above spf code
                which is not what we like. So we disable it for the time deing ... */
                
		if (req->rcpt_to != NULL  && *req->rcpt_to != '\0' ) {
			p = req->rcpt_to;
			p_end = p + strcspn(p, ",;");

			/* This is some incarnation of 2mx mode. */
			while (SPF_response_result(spf_response)!=SPF_RESULT_PASS) {
				if (*p_end)
					*p_end = '\0';
				else
					p_end = NULL;	/* Note this is last rcpt */

				err = SPF_request_query_rcptto(spf_request,
								&spf_response_2mx, p);
				if (opts->debug > 1)
					response_print("2mx query", spf_response_2mx);
				if (err) {
					response_print_errors("Failed to query RCPT-TO",
									spf_response, err);
					CONTINUE_ERROR;
				}

				/* append the result */
				APPEND_RESULT(SPF_response_result(spf_response_2mx));

				spf_response = SPF_response_combine(spf_response,
								spf_response_2mx);

				if (!p_end)
					break;
				p = p_end + 1;
			}
		}
#endif /* TO_MX */
		/* We now have an option to call SPF_request_query_fallback */
		if (opts->fallback) {
			err = SPF_request_query_fallback(spf_request,
							&spf_response, opts->fallback);
			if (opts->debug > 1)
				response_print("fallback query", spf_response_2mx);
			if (err) {
				response_print_errors("Failed to query best-guess",
								spf_response, err);
				CONTINUE_ERROR;
			}

			/* append the result */
			APPEND_RESULT(SPF_response_result(spf_response_2mx));

			spf_response = SPF_response_combine(spf_response,
							spf_response_2mx);
		}

/*		printf( "R: %s\nSC: %s\nHC: %s\nRS: %s\n",
			result,
			X_OR_EMPTY(SPF_response_get_smtp_comment(spf_response)),
			X_OR_EMPTY(SPF_response_get_header_comment(spf_response)),
			X_OR_EMPTY(SPF_response_get_received_spf(spf_response))
			);
*/			
		pf_response(opts, spf_response, req);
			
		res = SPF_response_result(spf_response);

		fflush(stdout);
	}

  error:
	FREE(result, free);
	FREE_RESPONSE(spf_response);
	FREE_REQUEST(spf_request);
	FREE(spf_server, SPF_server_free);

	syslog(LOG_INFO, "Terminating with result %d, Reincarnation: %d\n", res, request_limit);
	return res;
}