static void pf_response(SPF_client_options_t    *opts, SPF_response_t *spf_response, SPF_client_request_t *req)
{
      char                     result[RESULTSIZE];
      char                     spf_comment[RESULTSIZE];

      switch (spf_response->result) {
                case SPF_RESULT_PASS:
                        strcpy(result, POSTFIX_DUNNO);
                        printf("action=PREPEND X-%s\n",SPF_response_get_received_spf(spf_response));
                        snprintf(spf_comment, RESULTSIZE, SPF_response_get_received_spf(spf_response));
                        break;
                case SPF_RESULT_FAIL:
                	strcpy(result, POSTFIX_REJECT);
                        snprintf(spf_comment, RESULTSIZE,"SPF Reject: %s",
                                                        (spf_response->smtp_comment
                                                                ? spf_response->smtp_comment
                                                                : (spf_response->header_comment
                                                                        ? spf_response->header_comment
                                                                        : "")));
                        break;
                case SPF_RESULT_TEMPERROR:
                case SPF_RESULT_PERMERROR:
                case SPF_RESULT_INVALID:
                        snprintf(result, RESULTSIZE,
                                                        "450 temporary failure: %s",
                                                        (spf_response->smtp_comment
                                                                ? spf_response->smtp_comment
                                                                : ""));
			spf_comment[0]='\0';
                        break;
                case SPF_RESULT_SOFTFAIL:
                case SPF_RESULT_NEUTRAL: 
                case SPF_RESULT_NONE:    
                default:
                        strcpy(result, POSTFIX_DUNNO);
                        printf("action=PREPEND X-%s\n",SPF_response_get_received_spf(spf_response));
                        snprintf(spf_comment, RESULTSIZE, SPF_response_get_received_spf(spf_response));
                        break;
        }
        
        result[RESULTSIZE - 1] = '\0';
	if (opts->debug > 1)
		syslog(LOG_DEBUG, "<-- action=%s\n", result);
	if (strcmp(result,POSTFIX_REJECT) == 0) {
          printf("action=%s %s\n\n", result, spf_comment);
        } else {
          printf("action=%s\n\n", result);
        }
        fflush(stdout);
        if (opts->debug)
          syslog(LOG_INFO, "action=%s %s (ip=%s from=%s helo=%s to=%s)\n", result, spf_comment, req->ip, req->sender, req->helo, req->rcpt_to);
}
Beispiel #2
0
CAMLprim value
caml_spf_request_query_mailfrom(value req_val)
{
    CAMLparam1(req_val);
    CAMLlocal3(ret, cmt, res);
    const char *s;
    SPF_request_t *req = (SPF_request_t *)req_val;
    SPF_response_t *resp;
    SPF_result_t result;

    caml_enter_blocking_section();
    SPF_request_query_mailfrom(req, &resp);
    caml_leave_blocking_section();

    ret = caml_alloc(5, 0);

    result = SPF_response_result(resp);
    res = caml_alloc(1, tag_of_result(result));

    switch (result) {
    case SPF_RESULT_FAIL:
    case SPF_RESULT_SOFTFAIL:
    case SPF_RESULT_NEUTRAL:
        cmt = caml_alloc(2, 0);
        Store_field(cmt, 0,
                    caml_copy_string(SPF_response_get_smtp_comment(resp)));
        Store_field(cmt, 1,
                    caml_copy_string(SPF_response_get_explanation(resp)));
        res = caml_alloc(1, tag_of_result(result));
        Store_field(res, 0, cmt);
        Store_field(ret, 0, res);
        break;
    case SPF_RESULT_INVALID:
    case SPF_RESULT_PASS:
    case SPF_RESULT_TEMPERROR:
    case SPF_RESULT_PERMERROR:
    case SPF_RESULT_NONE:
        Store_field(ret, 0, Val_int(tag_of_result(result)));
        break;
    }

    Store_field(ret, 1, Val_int(SPF_response_reason(resp)));

/* For buggy libspf2 - avoid a segfault */
#define BUG_HEADER_COMMENT "internal error"
#define BUG_RECEIVED_SPF_VALUE "none (" BUG_HEADER_COMMENT ")"
#define BUG_RECEIVED_SPF "Received-SPF: " BUG_RECEIVED_SPF_VALUE

    s = SPF_response_get_received_spf(resp);
    Store_field(ret, 2, caml_copy_string(s ? s : BUG_RECEIVED_SPF));
    s = SPF_response_get_received_spf_value(resp);
    Store_field(ret, 3, caml_copy_string(s ? s : BUG_RECEIVED_SPF_VALUE));
    s = SPF_response_get_header_comment(resp);
    Store_field(ret, 4, caml_copy_string(s ? s : BUG_HEADER_COMMENT));

    SPF_response_free(resp);

    CAMLreturn(ret);
}
Beispiel #3
0
Datei: spf.c Projekt: Exim/exim
int
spf_process(const uschar **listptr, uschar *spf_envelope_sender, int action)
{
int sep = 0;
const uschar *list = *listptr;
uschar *spf_result_id;
int rc = SPF_RESULT_PERMERROR;

if (!(spf_server && spf_request))
  /* no global context, assume temp error and skip to evaluation */
  rc = SPF_RESULT_PERMERROR;

else if (SPF_request_set_env_from(spf_request, CS spf_envelope_sender))
  /* Invalid sender address. This should be a real rare occurrence */
  rc = SPF_RESULT_PERMERROR;

else
  {
  /* get SPF result */
  if (action == SPF_PROCESS_FALLBACK)
    {
    SPF_request_query_fallback(spf_request, &spf_response, CS spf_guess);
    spf_result_guessed = TRUE;
    }
  else
    SPF_request_query_mailfrom(spf_request, &spf_response);

  /* set up expansion items */
  spf_header_comment     = US SPF_response_get_header_comment(spf_response);
  spf_received           = US SPF_response_get_received_spf(spf_response);
  spf_result             = US SPF_strresult(SPF_response_result(spf_response));
  spf_smtp_comment       = US SPF_response_get_smtp_comment(spf_response);

  rc = SPF_response_result(spf_response);
  }

/* We got a result. Now see if we should return OK or FAIL for it */
DEBUG(D_acl) debug_printf("SPF result is %s (%d)\n", SPF_strresult(rc), rc);

if (action == SPF_PROCESS_GUESS && (!strcmp (SPF_strresult(rc), "none")))
  return spf_process(listptr, spf_envelope_sender, SPF_PROCESS_FALLBACK);

while ((spf_result_id = string_nextinlist(&list, &sep, NULL, 0)))
  {
  BOOL negate, result;

  if ((negate = spf_result_id[0] == '!'))
    spf_result_id++;

  result = Ustrcmp(spf_result_id, spf_result_id_list[rc].name) == 0;
  if (negate != result) return OK;
  }

/* no match */
return FAIL;
}
Beispiel #4
0
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;
}
Beispiel #5
0
Datei: spf.c Projekt: fanf2/exim
int spf_process(uschar **listptr, uschar *spf_envelope_sender, int action) {
  int sep = 0;
  uschar *list = *listptr;
  uschar *spf_result_id;
  uschar spf_result_id_buffer[128];
  int rc = SPF_RESULT_PERMERROR;

  if (!(spf_server && spf_request)) {
    /* no global context, assume temp error and skip to evaluation */
    rc = SPF_RESULT_PERMERROR;
    goto SPF_EVALUATE;
  };

  if (SPF_request_set_env_from(spf_request, CS spf_envelope_sender)) {
    /* Invalid sender address. This should be a real rare occurence */
    rc = SPF_RESULT_PERMERROR;
    goto SPF_EVALUATE;
  }

  /* get SPF result */
  if (action == SPF_PROCESS_FALLBACK)
    SPF_request_query_fallback(spf_request, &spf_response, CS spf_guess);
  else
    SPF_request_query_mailfrom(spf_request, &spf_response);

  /* set up expansion items */
  spf_header_comment     = (uschar *)SPF_response_get_header_comment(spf_response);
  spf_received           = (uschar *)SPF_response_get_received_spf(spf_response);
  spf_result             = (uschar *)SPF_strresult(SPF_response_result(spf_response));
  spf_smtp_comment       = (uschar *)SPF_response_get_smtp_comment(spf_response);

  rc = SPF_response_result(spf_response);

  /* We got a result. Now see if we should return OK or FAIL for it */
  SPF_EVALUATE:
  debug_printf("SPF result is %s (%d)\n", SPF_strresult(rc), rc);

  if (action == SPF_PROCESS_GUESS && (!strcmp (SPF_strresult(rc), "none")))
    return spf_process(listptr, spf_envelope_sender, SPF_PROCESS_FALLBACK);

  while ((spf_result_id = string_nextinlist(&list, &sep,
                                     spf_result_id_buffer,
                                     sizeof(spf_result_id_buffer))) != NULL) {
    int negate = 0;
    int result = 0;

    /* Check for negation */
    if (spf_result_id[0] == '!') {
      negate = 1;
      spf_result_id++;
    };

    /* Check the result identifier */
    result = Ustrcmp(spf_result_id, spf_result_id_list[rc].name);
    if (!negate && result==0) return OK;
    if (negate && result!=0) return OK;
  };

  /* no match */
  return FAIL;
}