Commit | Line | Data |
---|---|---|
92f1b170 | 1 | /* $Cambridge: exim/src/src/spf.c,v 1.5 2005/05/25 20:07:55 tom Exp $ */ |
8523533c TK |
2 | |
3 | /************************************************* | |
4 | * Exim - an Internet mail transport agent * | |
5 | *************************************************/ | |
8e669ac1 | 6 | |
8523533c TK |
7 | /* Experimental SPF support. |
8 | Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 | |
9 | License: GPL */ | |
8e669ac1 | 10 | |
8523533c TK |
11 | /* Code for calling spf checks via libspf-alt. Called from acl.c. */ |
12 | ||
13 | #include "exim.h" | |
14 | #ifdef EXPERIMENTAL_SPF | |
15 | ||
384152a6 TK |
16 | SPF_server_t *spf_server = NULL; |
17 | SPF_request_t *spf_request = NULL; | |
18 | SPF_response_t *spf_response = NULL; | |
19 | SPF_response_t *spf_response_2mx = NULL; | |
8523533c TK |
20 | |
21 | /* spf_init sets up a context that can be re-used for several | |
22 | messages on the same SMTP connection (that come from the | |
23 | same host with the same HELO string) */ | |
8e669ac1 | 24 | |
8523533c TK |
25 | int spf_init(uschar *spf_helo_domain, uschar *spf_remote_addr) { |
26 | uschar *p; | |
8e669ac1 | 27 | |
92f1b170 | 28 | spf_server = SPF_server_new(SPF_DNS_CACHE, 0); |
8e669ac1 | 29 | |
384152a6 TK |
30 | if ( spf_server == NULL ) { |
31 | debug_printf("spf: SPF_server_new() failed.\n"); | |
32 | return 0; | |
8523533c TK |
33 | } |
34 | ||
384152a6 | 35 | spf_request = SPF_request_new(spf_server); |
8523533c | 36 | |
384152a6 TK |
37 | if (SPF_request_set_ipv4_str(spf_request, spf_remote_addr)) { |
38 | debug_printf("spf: SPF_request_set_ipv4_str() failed.\n"); | |
39 | spf_server = NULL; | |
40 | spf_request = NULL; | |
41 | return 0; | |
8523533c TK |
42 | } |
43 | ||
384152a6 | 44 | if (SPF_request_set_helo_dom(spf_request, spf_helo_domain)) { |
8523533c | 45 | debug_printf("spf: SPF_set_helo_dom() failed.\n"); |
384152a6 TK |
46 | spf_server = NULL; |
47 | spf_request = NULL; | |
48 | return 0; | |
8523533c | 49 | } |
8e669ac1 | 50 | |
8523533c TK |
51 | return 1; |
52 | } | |
53 | ||
54 | ||
55 | /* spf_process adds the envelope sender address to the existing | |
56 | context (if any), retrieves the result, sets up expansion | |
57 | strings and evaluates the condition outcome. */ | |
58 | ||
59 | int spf_process(uschar **listptr, uschar *spf_envelope_sender) { | |
60 | int sep = 0; | |
61 | uschar *list = *listptr; | |
62 | uschar *spf_result_id; | |
63 | uschar spf_result_id_buffer[128]; | |
384152a6 | 64 | int rc = SPF_RESULT_PERMERROR; |
8e669ac1 | 65 | |
384152a6 | 66 | if (!(spf_server && spf_request)) { |
8523533c | 67 | /* no global context, assume temp error and skip to evaluation */ |
384152a6 | 68 | rc = SPF_RESULT_PERMERROR; |
8523533c TK |
69 | goto SPF_EVALUATE; |
70 | }; | |
71 | ||
384152a6 | 72 | if (SPF_request_set_env_from(spf_request, spf_envelope_sender)) { |
8523533c | 73 | /* Invalid sender address. This should be a real rare occurence */ |
384152a6 | 74 | rc = SPF_RESULT_PERMERROR; |
8523533c | 75 | goto SPF_EVALUATE; |
8e669ac1 | 76 | } |
8523533c TK |
77 | |
78 | /* get SPF result */ | |
384152a6 | 79 | SPF_request_query_mailfrom(spf_request, &spf_response); |
8523533c TK |
80 | |
81 | /* set up expansion items */ | |
384152a6 TK |
82 | spf_header_comment = (uschar *)SPF_response_get_header_comment(spf_response); |
83 | spf_received = (uschar *)SPF_response_get_received_spf(spf_response); | |
84 | spf_result = (uschar *)SPF_strresult(SPF_response_result(spf_response)); | |
85 | spf_smtp_comment = (uschar *)SPF_response_get_smtp_comment(spf_response); | |
8523533c | 86 | |
384152a6 | 87 | rc = SPF_response_result(spf_response); |
8523533c TK |
88 | |
89 | /* We got a result. Now see if we should return OK or FAIL for it */ | |
90 | SPF_EVALUATE: | |
91 | debug_printf("SPF result is %s (%d)\n", SPF_strresult(rc), rc); | |
92 | while ((spf_result_id = string_nextinlist(&list, &sep, | |
93 | spf_result_id_buffer, | |
94 | sizeof(spf_result_id_buffer))) != NULL) { | |
95 | int negate = 0; | |
96 | int result = 0; | |
97 | ||
98 | /* Check for negation */ | |
99 | if (spf_result_id[0] == '!') { | |
100 | negate = 1; | |
101 | spf_result_id++; | |
102 | }; | |
103 | ||
104 | /* Check the result identifier */ | |
105 | result = Ustrcmp(spf_result_id, spf_result_id_list[rc].name); | |
106 | if (!negate && result==0) return OK; | |
107 | if (negate && result!=0) return OK; | |
108 | }; | |
109 | ||
110 | /* no match */ | |
111 | return FAIL; | |
112 | } | |
113 | ||
114 | #endif | |
115 |