diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/OS/Makefile-Base exim-4.43/OS/Makefile-Base --- exim-4.43-clean/OS/Makefile-Base 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/OS/Makefile-Base 2004-12-04 08:42:47.000000000 +0000 @@ -292,7 +292,7 @@ os.o parse.o queue.o \ rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \ route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \ - store.o string.o tls.o tod.o transport.o tree.o verify.o \ + spf.o srs.o store.o string.o tls.o tod.o transport.o tree.o verify.o \ local_scan.o $(EXIM_PERL) exim: pcre/libpcre.a lookups/lookups.a auths/auths.a \ @@ -536,6 +536,8 @@ smtp_out.o: $(HDRS) smtp_out.c spool_in.o: $(HDRS) spool_in.c spool_out.o: $(HDRS) spool_out.c +spf.o: $(HDRS) spf.c +srs.o: $(HDRS) srs.c store.o: $(HDRS) store.c string.o: $(HDRS) string.c tls.o: $(HDRS) tls.c tls-gnu.c tls-openssl.c diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/scripts/MakeLinks exim-4.43/scripts/MakeLinks --- exim-4.43-clean/scripts/MakeLinks 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/scripts/MakeLinks 2004-12-04 08:42:47.000000000 +0000 @@ -182,6 +182,8 @@ ln -s ../src/macros.h macros.h ln -s ../src/mytypes.h mytypes.h ln -s ../src/osfunctions.h osfunctions.h +ln -s ../src/spf.h spf.h +ln -s ../src/srs.h srs.h ln -s ../src/store.h store.h ln -s ../src/structs.h structs.h @@ -229,6 +231,8 @@ ln -s ../src/smtp_out.c smtp_out.c ln -s ../src/spool_in.c spool_in.c ln -s ../src/spool_out.c spool_out.c +ln -s ../src/spf.c spf.c +ln -s ../src/srs.c srs.c ln -s ../src/store.c store.c ln -s ../src/string.c string.c ln -s ../src/tls.c tls.c diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/EDITME exim-4.43/src/EDITME --- exim-4.43-clean/src/EDITME 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/EDITME 2004-12-04 08:42:47.000000000 +0000 @@ -1015,4 +1015,16 @@ # SUPPORT_MOVE_FROZEN_MESSAGES=yes +#------------------------------------------------------------------------------ +# If libspf2 has been installed and you wish to use it then uncomment this line +# You probably also need to add -lspf2 to EXTRALIBS + +# SUPPORT_SPF=yes + +#------------------------------------------------------------------------------ +# If libsrs2 has been installed and you wish to use it then uncomment this line +# You probably also need to add -lsrs2 to EXTRALIBS + +# SUPPORT_SRS=yes + # End of EDITME for Exim 4. diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/acl.c exim-4.43/src/acl.c --- exim-4.43-clean/src/acl.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/acl.c 2004-12-04 08:45:25.000000000 +0000 @@ -35,18 +35,23 @@ enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL, ACLC_DELAY, ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS, ACLC_HOSTS, ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE, ACLC_MESSAGE, - ACLC_RECIPIENTS, ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET, ACLC_VERIFY }; + ACLC_RECIPIENTS, ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET, +#ifdef SUPPORT_SPF + ACLC_SPF, +#endif + ACLC_VERIFY }; /* ACL conditions/modifiers: "delay", "control", "endpass", "message", "log_message", "logwrite", and "set" are modifiers that look like conditions but always return TRUE. They are used for their side effects. */ - static uschar *conditions[] = { US"acl", US"authenticated", US"condition", US"control", US"delay", US"dnslists", US"domains", US"encrypted", US"endpass", US"hosts", US"local_parts", US"log_message", US"logwrite", US"message", US"recipients", US"sender_domains", US"senders", US"set", +#ifdef SUPPORT_SPF + US"spf", +#endif US"verify" }; - /* Flags to indicate for which conditions /modifiers a string expansion is done at the outer level. In the other cases, expansion already occurs in the checking functions. */ @@ -70,6 +75,9 @@ FALSE, /* sender_domains */ FALSE, /* senders */ TRUE, /* set */ +#ifdef SUPPORT_SPF + FALSE, /* spf */ +#endif TRUE /* verify */ }; @@ -94,6 +102,9 @@ FALSE, /* sender_domains */ FALSE, /* senders */ TRUE, /* set */ +#ifdef SUPPORT_SPF + FALSE, /* spf */ +#endif FALSE /* verify */ }; @@ -160,6 +171,14 @@ 0, /* set */ +#ifdef SUPPORT_SPF + (1<>>>>>>>>>>>>>>> Exim pid=%d terminating with rc=%d " ">>>>>>>>>>>>>>>>\n", (int)getpid(), rc); @@ -822,6 +825,12 @@ #ifdef EXIM_PERL fprintf(f, " Perl"); #endif +#ifdef SUPPORT_SPF + fprintf(f, " SPF"); +#endif +#ifdef SUPPORT_SRS + fprintf(f, " SRS"); +#endif #ifdef USE_TCP_WRAPPERS fprintf(f, " TCPwrappers"); #endif @@ -3515,6 +3524,12 @@ readconf_rest(msg_action_arg > 0 || (queue_interval == 0 && !daemon_listen)); +/* At this point we have sufficent information to initialize SPF */ + +#ifdef SUPPORT_SPF +eximspf_init(); +#endif + /* The configuration data will have been read into POOL_PERM because we won't ever want to reset back past it. Change the current pool to POOL_MAIN. In fact, this is just a bit of pedantic tidiness. It wouldn't really matter if the diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/exim.h exim-4.43/src/exim.h --- exim-4.43-clean/src/exim.h 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/exim.h 2004-12-04 08:42:47.000000000 +0000 @@ -455,5 +455,8 @@ #endif #endif +#ifdef SUPPORT_SPF + #include "spf.h" +#endif /* End of exim.h */ diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/expand.c exim-4.43/src/expand.c --- exim-4.43-clean/src/expand.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/expand.c 2004-12-04 08:42:47.000000000 +0000 @@ -416,6 +416,12 @@ { "sn8", vtype_filter_int, &filter_sn[8] }, { "sn9", vtype_filter_int, &filter_sn[9] }, { "spool_directory", vtype_stringptr, &spool_directory }, +#ifdef SUPPORT_SRS + { "srs_orig_recipient", vtype_stringptr, &srs_orig_recipient }, + { "srs_orig_sender", vtype_stringptr, &srs_orig_sender }, + { "srs_recipient", vtype_stringptr, &srs_recipient }, + { "srs_status", vtype_stringptr, &srs_status }, +#endif { "thisaddress", vtype_stringptr, &filter_thisaddress }, { "tls_certificate_verified", vtype_int, &tls_certificate_verified }, { "tls_cipher", vtype_stringptr, &tls_cipher }, diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/functions.h exim-4.43/src/functions.h --- exim-4.43-clean/src/functions.h 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/functions.h 2004-12-04 08:42:47.000000000 +0000 @@ -80,8 +80,20 @@ extern void exim_exit(int); extern void exim_nullstd(void); extern void exim_setugid(uid_t, gid_t, BOOL, uschar *); +#ifdef SUPPORT_SPF +extern int eximspf_init(); +extern int eximspf_done(); +extern int eximspf_check(); +extern char *eximspf_header(); +#endif extern int exim_tvcmp(struct timeval *, struct timeval *); extern void exim_wait_tick(struct timeval *, int); +#ifdef SUPPORT_SRS +extern int eximsrs_init(); +extern int eximsrs_done(); +extern int eximsrs_forward(uschar **result, uschar *orig_sender, uschar *domain); +extern int eximsrs_reverse(uschar **result, uschar *address); +#endif extern BOOL expand_check_condition(uschar *, uschar *, uschar *); extern uschar *expand_string(uschar *); extern uschar *expand_string_copy(uschar *); diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/globals.c exim-4.43/src/globals.c --- exim-4.43-clean/src/globals.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/globals.c 2004-12-04 08:42:47.000000000 +0000 @@ -928,6 +928,26 @@ BOOL split_spool_directory = FALSE; uschar *spool_directory = US SPOOL_DIRECTORY "\0<--------------Space to patch spool_directory->"; +#ifdef SUPPORT_SPF +int spf_debug_level = 0; +uschar *spf_default_explaination = US""; +int spf_dns_cache_bits = 16; +uschar *spf_local_record = US"v=spf1 mx"; +int spf_result = 0; +BOOL spf_use_whitelist = FALSE; +#endif +#ifdef SUPPORT_SRS +BOOL srs_alwaysrewrite = FALSE; +int srs_hashlength = -1; +int srs_hashmin = -1; +int srs_maxage = -1; +uschar *srs_secrets = NULL; +uschar *srs_separator = NULL; +uschar *srs_orig_recipient = NULL; +uschar *srs_orig_sender = NULL; +uschar *srs_recipient = NULL; +uschar *srs_status = NULL; +#endif int string_datestamp_offset= -1; BOOL strip_excess_angle_brackets = FALSE; BOOL strip_trailing_dot = FALSE; diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/globals.h exim-4.43/src/globals.h --- exim-4.43-clean/src/globals.h 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/globals.h 2004-12-04 08:42:47.000000000 +0000 @@ -547,6 +547,26 @@ extern BOOL smtp_use_size; /* Global for passed connections */ extern BOOL split_spool_directory; /* TRUE to use multiple subdirs */ extern uschar *spool_directory; /* Name of spool directory */ +#ifdef SUPPORT_SPF +extern int spf_debug_level; /* The SPF debug level */ +extern uschar *spf_default_explaination; /* The default 4xx and 5xx explaination */ +extern int spf_dns_cache_bits; /* Bits used within the caching dns resolver */ +extern uschar *spf_local_record; /* For the insertion of a local SPF record */ +extern int spf_result; /* Allows ACLs to set their minimum SPF result level */ +extern BOOL spf_use_whitelist; /* Should SPF use it's default whitelist */ +#endif +#ifdef SUPPORT_SRS +extern BOOL srs_alwaysrewrite; /* Rewrite for all domains */ +extern int srs_hashlength; /* Hash length to generate */ +extern int srs_hashmin; /* Hash length to check */ +extern int srs_maxage; /* Max age for SRS address */ +extern uschar *srs_orig_recipient; /* SRS original sender */ +extern uschar *srs_orig_sender; /* SRS original recipient */ +extern uschar *srs_recipient; /* SRS recipient */ +extern uschar *srs_secrets; /* List of SRS secrets */ +extern uschar *srs_separator; /* Separator for SRS addresses */ +extern uschar *srs_status; /* SRS status */ +#endif extern int string_datestamp_offset;/* After insertion by string_format */ extern BOOL strip_excess_angle_brackets; /* Surrounding route-addrs */ extern BOOL strip_trailing_dot; /* Remove dots at ends of domains */ diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/readconf.c exim-4.43/src/readconf.c --- exim-4.43-clean/src/readconf.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/readconf.c 2004-12-04 08:42:47.000000000 +0000 @@ -316,8 +316,23 @@ { "smtp_receive_timeout", opt_time, &smtp_receive_timeout }, { "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts }, { "smtp_return_error_details",opt_bool, &smtp_return_error_details }, +#ifdef SUPPORT_SPF + { "spf_debug_level", opt_int, &spf_debug_level }, + { "spf_default_explaination", opt_stringptr, &spf_default_explaination }, + { "spf_dns_cache_bits", opt_int, &spf_dns_cache_bits }, + { "spf_local_record", opt_stringptr, &spf_local_record }, + { "spf_use_default_whitelist", opt_bool, &spf_use_whitelist }, +#endif { "split_spool_directory", opt_bool, &split_spool_directory }, { "spool_directory", opt_stringptr, &spool_directory }, +#ifdef SUPPORT_SRS + { "srs_alwaysrewrite", opt_bool, &srs_alwaysrewrite }, + { "srs_hashlength", opt_int, &srs_hashlength }, + { "srs_hashmin", opt_int, &srs_hashmin }, + { "srs_maxage", opt_int, &srs_maxage }, + { "srs_secrets", opt_stringptr, &srs_secrets }, + { "srs_separator", opt_stringptr, &srs_separator }, +#endif { "strip_excess_angle_brackets", opt_bool, &strip_excess_angle_brackets }, { "strip_trailing_dot", opt_bool, &strip_trailing_dot }, { "syslog_duplication", opt_bool, &syslog_duplication }, diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/receive.c exim-4.43/src/receive.c --- exim-4.43-clean/src/receive.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/receive.c 2004-12-04 08:42:47.000000000 +0000 @@ -10,8 +10,6 @@ #include "exim.h" - - /************************************************* * Local static variables * *************************************************/ @@ -2327,6 +2325,11 @@ if (!date_header_exists && (sender_host_address == NULL || submission_mode)) header_add(htype_other, "%sDate: %s\n", resent_prefix, tod_stamp(tod_full)); +#ifdef SUPPORT_SPF +/* Add the SPF header showing what we thought of the message */ +header_add( htype_other, "%s\n", eximspf_header() ); +#endif + search_tidyup(); /* Free any cached resources */ /* Show the complete set of headers if debugging. Note that the first one (the diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/route.c exim-4.43/src/route.c --- exim-4.43-clean/src/route.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/route.c 2004-12-04 08:42:47.000000000 +0000 @@ -1852,6 +1852,7 @@ host_item *h; debug_printf(" envelope to: %s\n", addr->address); + debug_printf(" sender: %s\n", sender_address); debug_printf(" transport: %s\n", (addr->transport == NULL)? US"" : addr->transport->name); diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/routers/redirect.c exim-4.43/src/routers/redirect.c --- exim-4.43-clean/src/routers/redirect.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/routers/redirect.c 2004-12-04 09:08:41.000000000 +0000 @@ -9,6 +9,7 @@ #include "../exim.h" #include "rf_functions.h" #include "redirect.h" +#include "../srs.h" @@ -95,6 +96,10 @@ (void *)offsetof(redirect_router_options_block, sieve_vacation_directory) }, { "skip_syntax_errors", opt_bool, (void *)offsetof(redirect_router_options_block, skip_syntax_errors) }, +#ifdef SUPPORT_SRS + { "srs", opt_stringptr, + (void *)offsetof(redirect_router_options_block, srs) }, +#endif { "syntax_errors_text", opt_stringptr, (void *)offsetof(redirect_router_options_block, syntax_errors_text) }, { "syntax_errors_to", opt_stringptr, @@ -139,7 +144,8 @@ FALSE, /* hide_child_in_errmsg */ FALSE, /* one_time */ FALSE, /* qualify_preserve_domain */ - FALSE /* skip_syntax_errors */ + FALSE, /* skip_syntax_errors */ + NULL /* srs */ }; @@ -520,6 +526,34 @@ ugid.gid_set = TRUE; } +#ifdef SUPPORT_SRS +/* For reverse SRS, fill the srs_recipient expansion variable, + * on failure, return decline/fail as relevant */ + +if (ob->srs != NULL) + { + if (Ustrcmp(ob->srs, "reverse") == 0) + { + uschar *res; + int ret; + + DEBUG(D_any) + debug_printf("SRS: (Reverse) \n"); + + srs_orig_recipient = addr->address; + eximsrs_init(); + ret = eximsrs_reverse(&res, addr->address); + if (ret != OK) + return ret; + srs_recipient = res; + eximsrs_done(); + DEBUG(D_any) + debug_printf("SRS: Recipient '%s' rewritten to '%s'\n", + srs_orig_recipient, srs_recipient); + } + } +#endif + /* Call the function that interprets redirection data, either inline or from a file. This is a separate function so that the system filter can use it. It will run the function in a subprocess if necessary. If qualify_preserve_domain is @@ -681,6 +715,7 @@ } } + /* Sort out the errors address and any header modifications, and handle the generated addresses, if any. If there are no generated addresses, we must avoid calling sort_errors_and_headers() in case this router declines - that function @@ -743,6 +778,30 @@ (addr_prop.errors_address != NULL)? "\n" : ""); } +#ifdef SUPPORT_SRS +/* On successful redirection, check for SRS forwarding and adjust + * sender */ +if (ob->srs != NULL) + { + if ((Ustrcmp(ob->srs, "forward") == 0) && !verify ) + { + uschar *res; + int ret; + DEBUG(D_any) + debug_printf("SRS: (Forward) \n"); + srs_orig_sender = sender_address; + eximsrs_init(); + ret = eximsrs_forward(&res, sender_address, deliver_domain); + if (ret != OK) + return ret; + sender_address = res; + DEBUG(D_any) + debug_printf("SRS: Sender '%s' rewritten to '%s'\n", + srs_orig_sender, sender_address); + } + } +#endif + /* Control gets here only when the address has been completely handled. Put the original address onto the succeed queue so that any retry items that get attached to it get processed. */ diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/routers/redirect.h exim-4.43/src/routers/redirect.h --- exim-4.43-clean/src/routers/redirect.h 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/routers/redirect.h 2004-12-04 08:42:47.000000000 +0000 @@ -43,6 +43,7 @@ BOOL one_time; BOOL qualify_preserve_domain; BOOL skip_syntax_errors; + uschar *srs; } redirect_router_options_block; /* Data for reading the private options. */ diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/smtp_in.c exim-4.43/src/smtp_in.c --- exim-4.43-clean/src/smtp_in.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/smtp_in.c 2004-12-04 08:42:47.000000000 +0000 @@ -31,7 +31,6 @@ int deny_severity = LOG_NOTICE; #endif - /* Size of buffer for reading SMTP commands */ #define cmd_buffer_size 512 /* Ref. RFC 821 */ @@ -2582,6 +2581,7 @@ toomany = FALSE; sender_data = recipient_data = NULL; + /* Loop, checking for ESMTP additions to the MAIL FROM command. */ if (esmtp) for(;;) @@ -2800,6 +2800,10 @@ /* Apply an ACL check if one is defined, before responding */ +#ifdef SUPPORT_SPF + eximspf_check(); +#endif + rc = (acl_smtp_mail == NULL)? OK : acl_check(ACL_WHERE_MAIL, NULL, acl_smtp_mail, &user_msg, &log_msg); diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/spf.c exim-4.43/src/spf.c --- exim-4.43-clean/src/spf.c 1970-01-01 00:00:00.000000000 +0000 +++ exim-4.43/src/spf.c 2004-12-04 09:14:05.000000000 +0000 @@ -0,0 +1,348 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* This file is an extension to Exim and is not part of the standard + Exim distribution */ + +/* (c) 2004 Mark Chappell + */ + +/* License: GPL */ + +#include "exim.h" +#include + +#ifdef SUPPORT_SPF + +#include +#include +#include + +SPF_config_t *spf_config; +SPF_c_results_t *spf_c_local; +SPF_c_results_t *spf_c_explain; +SPF_dns_config_t *spf_dns_config; +SPF_dns_config_t *spf_dns_cache_config; +SPF_output_t *spf_results; + +int +eximspf_init() +{ +if ( spf_config == NULL ) + { + SPF_err_t spf_error; + int error; + + DEBUG(D_any) + debug_printf( "SPF: Initializing \n"); + + /* Initialize the main config */ + spf_config = calloc ( 1, sizeof(*spf_config) ); + if (spf_config) + { + *spf_config = SPF_create_config(); + } + else + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : Main configuration failed to initialize. " ); + eximspf_done(); + return FAIL; + } + + /* Set the debug level */ + SPF_set_debug( *spf_config, spf_debug_level ); + + /* Set the local domain */ + error = SPF_set_rec_dom( *spf_config, smtp_active_hostname ); + if (error != SPF_E_SUCCESS ) + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : local domain not set." ); + eximspf_done(); + return FAIL; + } + + /* Setup the local policy */ + spf_c_local = calloc ( 1, sizeof(*spf_c_local) ); + if ( spf_c_local ) + { + SPF_init_c_results( spf_c_local ); + } + else + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : local config not set." ); + eximspf_done(); + return FAIL; + } + + spf_error = SPF_compile_local_policy( *spf_config, spf_local_record, + spf_use_whitelist, spf_c_local ); + if ( spf_error != SPF_E_SUCCESS ) + { + log_write(0, LOG_MAIN | LOG_PANIC, "SPF : local policy - %s ", + SPF_strerror ( spf_error ) ); + eximspf_done(); + return FAIL; + } + SPF_set_local_policy( *spf_config, *spf_c_local ); + + /* Setup the default explaination string for the * + * 5xx and 4xx messages */ + + spf_c_explain = calloc ( 1, sizeof(*spf_c_explain) ); + if ( spf_c_local ) + { + SPF_init_c_results( spf_c_explain ); + } + else + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : explainations config not set." ); + eximspf_done(); + return FAIL; + } + spf_error = SPF_compile_exp( *spf_config, spf_default_explaination, + spf_c_explain); + if (spf_error != SPF_E_SUCCESS ) + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : Explaination not compiled - %s", + SPF_strerror ( spf_error ) ); + eximspf_done(); + return FAIL; + } + error = SPF_set_exp( *spf_config, *spf_c_explain); + if ( error ) + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : Explaination not set. "); + eximspf_done(); + return FAIL; + } + + /* Setup the spf dns so that we can actually look * + * up the SPF DNS TXT records. */ + + spf_dns_config = calloc ( 1, sizeof(*spf_dns_config) ); + if (spf_dns_config) + { + * spf_dns_config = SPF_dns_create_config_resolv( NULL, spf_debug_level ); + } + else + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : dns resolver failed to initialize. " ); + eximspf_done(); + return FAIL; + } + + /* Setup the dns cache */ + spf_dns_cache_config = calloc ( 1, sizeof(*spf_dns_config) ); + if (spf_dns_config) + { + * spf_dns_cache_config = SPF_dns_create_config_cache( *spf_dns_config, + spf_dns_cache_bits, spf_debug_level ); + } + else + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : dns cache failed to initialize. " ); + eximspf_done(); + return FAIL; + } + + } + + spf_results = calloc ( 1, sizeof(*spf_results) ); + if (spf_results == NULL) + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : results failed to initialize. " ); + eximspf_done(); + return FAIL; + } + +return OK; +} + +int +eximspf_done() +{ +DEBUG(D_any) + debug_printf( "SPF: Freeing memory\n"); +/* And in reverse formation; Free the dns, compiler, and config handles */ +if (spf_dns_cache_config != NULL) + { + SPF_dns_destroy_config_cache(*spf_dns_cache_config); + free(spf_dns_cache_config); + spf_dns_cache_config = NULL; + } +if (spf_dns_config != NULL) + { + SPF_dns_destroy_config_resolv(*spf_dns_config); + free(spf_dns_config); + spf_dns_config = NULL; + } +if (spf_c_explain != NULL) + { + SPF_free_c_results(spf_c_explain); + free(spf_c_explain); + spf_c_explain = NULL; + } +if (spf_c_local != NULL) + { + SPF_free_c_results(spf_c_local); + free(spf_c_local); + spf_c_local = NULL; + } +if (spf_config != NULL) + { + SPF_destroy_config(*spf_config); + free(spf_config); + spf_config = NULL; + } + +return OK; +} + +int +eximspf_check() +{ +int error; + +if (spf_config == NULL) + { + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : failed to run checks due to incomplete initialization." ); + return DEFER; + } + +DEBUG(D_any) + debug_printf( "SPF: beginning checks \n"); +/* So just who are we dealing with ? */ + +/* the IP of the sender */ +if (!(sender_host_unknown || sender_host_notsocket || is_inetd) || sender_host_address) + { + switch (string_is_ip_address (sender_host_address ,0)) + { + case 4: + SPF_set_ipv4_str(*spf_config, sender_host_address); + break; + case 6: + SPF_set_ipv6_str(*spf_config, sender_host_address); + break; + default: + /* We do not know if it's an ipv4 or ipv6 address * + * as such we can't do out checks. * + * We shouldn't really get here. */ + log_write(0, LOG_MAIN | LOG_PANIC, + "SPF : defering due to lack of ip address. " ); + return DEFER; + } + } +else + { + DEBUG(D_any) + debug_printf( "SPF: skipping check. sender IP unknown\n"); + return OK; + } + +/* The helo string */ +SPF_set_helo_dom(*spf_config, sender_helo_name); +/* The envelope from */ +SPF_set_env_from(*spf_config, sender_address); + +/* Who do we think the sender is? */ +DEBUG(D_any) + debug_printf( "SPF: running tests...\n"); + +*spf_results = SPF_result(*spf_config, *spf_dns_cache_config); + +DEBUG(D_any) + debug_printf( "SPF: %s\n", SPF_header_comment(*spf_config, *spf_results) ); + +spf_result = spf_results->result; + +switch (spf_result) + { + case SPF_RESULT_FAIL: + return FAIL; + case SPF_RESULT_SOFTFAIL: + case SPF_RESULT_UNKNOWN: + case SPF_RESULT_ERROR: + case SPF_RESULT_NEUTRAL: + case SPF_RESULT_NONE: + case SPF_RESULT_PASS: + default: + return OK; + } + +} + +char * +eximspf_header() +{ +if (spf_config == NULL) + { + return "Received-SPF: failed to run checks due to incomplete initialization."; + } +return SPF_received_spf( *spf_config, *spf_c_explain, *spf_results); +} + +/* Performs the SPF ACL lookups */ +int +eximspf_acl(uschar *args) +{ +char * in; +char * in2; +char * arg; +int rc; + +DEBUG(D_any) + debug_printf( "SPF: Testing ACL rule : '%s'\n", args); + +in = (char *) malloc (sizeof(args)); +strcpy( in, args ); +in2 = in; +rc = FAIL; + +while ( arg = strtok ( in, ":" ) ) + { + if (in) + { + in = NULL; + } + if ( strstr( arg, "pass") ) + if (spf_result == SPF_RESULT_PASS) + rc = OK; + if ( strstr( arg, "neutral") ) + if (spf_result == SPF_RESULT_NEUTRAL) + rc = OK; + if ( strstr( arg, "softfail") ) + if (spf_result == SPF_RESULT_SOFTFAIL ) + rc = OK; + if ( strstr( arg, "fail") && ( ! strstr ( arg, "softfail" ) ) ) + if (spf_result == SPF_RESULT_FAIL ) + rc = OK; + if ( strstr( arg, "none") ) + if (spf_result == SPF_RESULT_NONE ) + rc = OK; + if ( strstr( arg, "unknown") ) + if (spf_result == SPF_RESULT_UNKNOWN ) + rc = OK; + if ( strstr( arg, "error") ) + if (spf_result == SPF_RESULT_ERROR ) + rc = OK; + } + +free (in2); +in2 = NULL; + +return rc; +} + +#endif diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/spf.h exim-4.43/src/spf.h --- exim-4.43-clean/src/spf.h 1970-01-01 00:00:00.000000000 +0000 +++ exim-4.43/src/spf.h 2004-12-04 08:42:47.000000000 +0000 @@ -0,0 +1,25 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* This file is an extension to Exim and is not part of the standard + Exim distribution */ + +/* (c) 2004 Mark Chappell + */ + +/* License: GPL */ + +#ifndef __SPF_H__ +#define __SPF_H__ 1 + +#ifdef SUPPORT_SPF + +#include "mytypes.h" +#include +#include +#include + +#endif + +#endif diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/srs.c exim-4.43/src/srs.c --- exim-4.43-clean/src/srs.c 1970-01-01 00:00:00.000000000 +0000 +++ exim-4.43/src/srs.c 2004-12-04 09:09:12.000000000 +0000 @@ -0,0 +1,137 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* This file is an extension to Exim and is not part of the standard + Exim distribution */ + +/* (c) 2004 Shevek + * Based on work by Miles Wilton + * Updated by Shevek to use libsrs2 + * Sorry Miles, I was in a roaring hurry, but we still need the + * help! + */ + +/* License: GPL */ + +#include "exim.h" + +#ifdef SUPPORT_SRS + +#include + +#define SRS_WARN_UNLESS(x) do { \ + int __ret = (x); \ + if (__ret != SRS_SUCCESS) \ + DEBUG(D_any) \ + debug_printf("srs: %s\n", srs_strerror(__ret)); \ + } while(0) + +srs_t *srs = NULL; + +int +eximsrs_init() +{ + char sbuf[1024]; + uschar *list; + int co; + + char *secret; + + if (srs == NULL) { + srs = srs_new(); + + if (srs_secrets == NULL) { + log_write(0, LOG_MAIN | LOG_PANIC, + "SRS: No secrets specified"); + return DEFER; + } + + /* Get config */ + list = srs_secrets; + + co = 0; + while ((secret = string_nextinlist(&list, &co, + sbuf, sizeof(sbuf))) != NULL) { + SRS_WARN_UNLESS(srs_add_secret(srs, secret)); + } + + SRS_WARN_UNLESS(srs_set_alwaysrewrite(srs, srs_alwaysrewrite)); + if (srs_hashlength != -1) + SRS_WARN_UNLESS(srs_set_hashlength(srs, srs_hashlength)); + if (srs_hashmin != -1) + SRS_WARN_UNLESS(srs_set_hashmin(srs, srs_hashmin)); + if (srs_maxage != -1) + SRS_WARN_UNLESS(srs_set_maxage(srs, srs_maxage)); + if (srs_separator != NULL) + SRS_WARN_UNLESS(srs_set_separator(srs, srs_separator[0])); + + DEBUG(D_any) + debug_printf("SRS initialised\n"); + } + + return OK; +} + +int +eximsrs_done() +{ + if (srs != NULL) + srs_free(srs); + srs = NULL; + return OK; +} + +int +eximsrs_forward(uschar **result, uschar *sender, uschar *domain) +{ + char res[1024]; + int ret; + + ret = srs_forward(srs, res, sizeof(res), sender, domain); + if (SRS_ERROR_TYPE(ret) == SRS_ERRTYPE_NONE) + return DECLINE; + else { + DEBUG(D_any) + debug_printf("srs_forward failed (%s, %s): %s\n", + sender, domain, srs_strerror(ret)); + return DEFER; + } + + *result = string_copy(res); + return OK; +} + +int +eximsrs_reverse(uschar **result, uschar *sender) +{ + char res[1024]; + int ret; + + ret = srs_reverse(srs, res, sizeof(res), sender); + DEBUG(D_any) + debug_printf("srs_reverse returned %d(%s)\n", ret, srs_strerror(ret)); + + if (ret != SRS_SUCCESS) { + switch (SRS_ERROR_TYPE(ret)) { + case SRS_ERRTYPE_NONE: + /* Not an SRS address or not rewritten */ + return DECLINE; + case SRS_ERRTYPE_CONFIG: + /* This should never happen */ + return DEFER; + case SRS_ERRTYPE_INPUT: + /* This should never happen */ + return DEFER; + case SRS_ERRTYPE_SYNTAX: + return DECLINE; + case SRS_ERRTYPE_SRS: + return FAIL; + } + } + + *result = string_copy(res); + + return OK; +} +#endif diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/srs.h exim-4.43/src/srs.h --- exim-4.43-clean/src/srs.h 1970-01-01 00:00:00.000000000 +0000 +++ exim-4.43/src/srs.h 2004-12-04 08:42:47.000000000 +0000 @@ -0,0 +1,27 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* This file is an extension to Exim and is not part of the standard + Exim distribution */ + +/* (c) 2004 Shevek + * Based on work by Miles Wilton + * Updated by Shevek to use libsrs2 + * Sorry Miles, I was in a roaring hurry, but we still need the + * help! + */ + +/* License: GPL */ + +#ifndef __SRS_H__ +#define __SRS_H__ 1 + +#ifdef SUPPORT_SRS + +#include "mytypes.h" +#include + +#endif + +#endif diff -aurN --exclude=Makefile --exclude=build-Linux-UML exim-4.43-clean/src/verify.c exim-4.43/src/verify.c --- exim-4.43-clean/src/verify.c 2004-10-05 08:32:08.000000000 +0000 +++ exim-4.43/src/verify.c 2004-12-04 08:42:47.000000000 +0000 @@ -962,7 +962,8 @@ if (!is_recipient) sender_address = null_sender; rc = route_address(addr, &addr_local, &addr_remote, &addr_new, &addr_succeed, verify_type); - sender_address = save_sender; /* Put back the real sender */ + if (sender_address == null_sender) + sender_address = save_sender; /* Put back the real sender */ } /* If routing an address succeeded, set the flag that remembers, for use when