1 /* $Cambridge: exim/src/src/spf.c,v 1.2 2004/12/16 15:11:47 tom Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Experimental SPF support.
8 Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004
11 /* Code for calling spf checks via libspf-alt. Called from acl.c. */
14 #ifdef EXPERIMENTAL_SPF
16 /* #include "spf.h" */
18 SPF_config_t spfcid
= NULL
;
19 SPF_dns_config_t spfdcid_resolv
= NULL
;
20 SPF_dns_config_t spfdcid
= NULL
;
23 /* spf_init sets up a context that can be re-used for several
24 messages on the same SMTP connection (that come from the
25 same host with the same HELO string) */
27 int spf_init(uschar
*spf_helo_domain
, uschar
*spf_remote_addr
) {
32 spfdcid_resolv
= NULL
;
35 spfcid
= SPF_create_config();
36 if ( spfcid
== NULL
) {
37 debug_printf("spf: SPF_create_config() failed.\n");
42 spfdcid_resolv
= SPF_dns_create_config_resolv(NULL
, 0);
43 spfdcid
= SPF_dns_create_config_cache(spfdcid_resolv
, 8, 0);
45 if (spfdcid
== NULL
) {
46 debug_printf("spf: SPF_dns_create_config_cache() failed.\n");
48 spfdcid_resolv
= NULL
;
52 if (SPF_set_ip_str(spfcid
, spf_remote_addr
)) {
53 debug_printf("spf: SPF_set_ip_str() failed.\n");
55 spfdcid_resolv
= NULL
;
59 if (SPF_set_helo_dom(spfcid
, spf_helo_domain
)) {
60 debug_printf("spf: SPF_set_helo_dom() failed.\n");
62 spfdcid_resolv
= NULL
;
70 /* spf_process adds the envelope sender address to the existing
71 context (if any), retrieves the result, sets up expansion
72 strings and evaluates the condition outcome. */
74 int spf_process(uschar
**listptr
, uschar
*spf_envelope_sender
) {
76 uschar
*list
= *listptr
;
77 uschar
*spf_result_id
;
78 uschar spf_result_id_buffer
[128];
79 SPF_output_t spf_output
;
80 int rc
= SPF_RESULT_ERROR
;
82 if (!(spfcid
&& spfdcid
)) {
83 /* no global context, assume temp error and skip to evaluation */
84 rc
= SPF_RESULT_ERROR
;
88 if (SPF_set_env_from(spfcid
, spf_envelope_sender
)) {
89 /* Invalid sender address. This should be a real rare occurence */
90 rc
= SPF_RESULT_ERROR
;
95 spf_output
= SPF_result(spfcid
, spfdcid
);
97 /* set up expansion items */
98 spf_header_comment
= spf_output
.header_comment
? (uschar
*)spf_output
.header_comment
: NULL
;
99 spf_received
= spf_output
.received_spf
? (uschar
*)spf_output
.received_spf
: NULL
;
100 spf_result
= (uschar
*)SPF_strresult(spf_output
.result
);
101 spf_smtp_comment
= spf_output
.smtp_comment
? (uschar
*)spf_output
.smtp_comment
: NULL
;
103 rc
= spf_output
.result
;
105 /* We got a result. Now see if we should return OK or FAIL for it */
107 debug_printf("SPF result is %s (%d)\n", SPF_strresult(rc
), rc
);
108 while ((spf_result_id
= string_nextinlist(&list
, &sep
,
109 spf_result_id_buffer
,
110 sizeof(spf_result_id_buffer
))) != NULL
) {
114 /* Check for negation */
115 if (spf_result_id
[0] == '!') {
120 /* Check the result identifier */
121 result
= Ustrcmp(spf_result_id
, spf_result_id_list
[rc
].name
);
122 if (!negate
&& result
==0) return OK
;
123 if (negate
&& result
!=0) return OK
;