Thu, 13 Sep 2012 20:05:49 +0200
Integrate useful recipient and helo access maps, and introduce SRS logic.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/postfix/postfix-srs.patch Thu Sep 13 20:05:49 2012 +0200 1.3 @@ -0,0 +1,493 @@ 1.4 +diff -urN README_FILES/SRS_README.orig README_FILES/SRS_README 1.5 +--- README_FILES/SRS_README.orig 1970-01-01 01:00:00.000000000 +0100 1.6 ++++ README_FILES/SRS_README 2012-02-21 14:22:05.000000000 +0100 1.7 +@@ -0,0 +1,56 @@ 1.8 ++ 1.9 ++CREDITS: 1.10 ++ 1.11 ++- originally written by Shevek <srs@anarres.org> 1.12 ++- fixes and porting to postfix 2.1 by Branko F. Gracnar <bfg@frost.ath.cx> 1.13 ++- redesigned and ported to debian postfix 2.7.0 by Chris <chris@codefrickler.de> 1.14 ++ 1.15 ++SYNOPSIS: 1.16 ++Works with all address classes (not limited to local domain). 1.17 ++Doesn't depend on .forward-files or alias_maps. 1.18 ++SMTPD accepts valid srs addresses without further configuration. 1.19 ++Sender gets rewritten only when necessary: 1.20 ++- rewrite after queuing (after separation to on- and off-site destinations) 1.21 ++- rewrite only if sender and recipient are off-site and host is not a relay for recipient 1.22 ++Alias domain can be chosen automatically from original on-site-recipient. 1.23 ++ 1.24 ++ 1.25 ++USAGE: 1.26 ++ 1.27 ++1) Apply the patch. 1.28 ++ 1.29 ++2) Create makefiles with 1.30 ++ 1.31 ++make makefiles CCARGS="-DHAS_SRS -I<directory-containing--srs2.h>" AUXLIBS="-L<directory-containing--libsrs2.so> -lsrs2" 1.32 ++ 1.33 ++ 1.34 ++3) Build. 1.35 ++ 1.36 ++4) Add the following global configuration variables to main.cf: 1.37 ++All variables are optional, except where stated: 1.38 ++ 1.39 ++ srs_domain (string) 1.40 ++ A domain to use in rewritten addresses. This must point only 1.41 ++ to machines which know the encoding secret used by this 1.42 ++ system. It defaults to $myorigin. If set to the emtpy 1.43 ++ string, use domain from original recipient if host is final 1.44 ++ destination, otherwise use $myorigin. 1.45 ++ srs_hashlength (int) 1.46 ++ The hash length to generate in a rewritten address. 1.47 ++ srs_hashmin (int) 1.48 ++ The hash length to require when checking an address. 1.49 ++ srs_maxage (int) 1.50 ++ The maximum permitted age of a rewritten address. 1.51 ++ srs_secrets (string) 1.52 ++ [required] A list of secrets with which to generate 1.53 ++ and check addresses. 1.54 ++ srs_separator (string) 1.55 ++ The separator to appear immediately after SRS[01] in 1.56 ++ rewritten addresses. 1.57 ++ 1.58 ++ 1.59 ++See http://www.libsrs2.org/ for more information about the meaning 1.60 ++of these variables. They are standard across MTAs. 1.61 ++ 1.62 ++5) Fire up and enjoy. 1.63 ++ 1.64 +diff -urN src/cleanup/cleanup_addr.c.orig src/cleanup/cleanup_addr.c 1.65 +--- src/cleanup/cleanup_addr.c.orig 2012-02-21 14:21:34.000000000 +0100 1.66 ++++ src/cleanup/cleanup_addr.c 2012-02-21 14:22:05.000000000 +0100 1.67 +@@ -163,6 +163,10 @@ 1.68 + { 1.69 + VSTRING *clean_addr = vstring_alloc(100); 1.70 + const char *bcc; 1.71 ++#ifdef HAS_SRS 1.72 ++ int srs_state; 1.73 ++ VSTRING *srs_rcpt; 1.74 ++#endif 1.75 + 1.76 + /* 1.77 + * Note: an unqualified envelope address is for all practical purposes 1.78 +@@ -174,6 +178,14 @@ 1.79 + cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL, 1.80 + clean_addr, *buf ? buf : var_empty_addr); 1.81 + if (state->flags & CLEANUP_FLAG_MAP_OK) { 1.82 ++#ifdef HAS_SRS 1.83 ++ if ((srs_state = postfix_srs_reverse(STR(clean_addr), &srs_rcpt)) < 0) { 1.84 ++ /* XXX errors */ 1.85 ++ } else if (srs_state == 1) { 1.86 ++ vstring_free(clean_addr); 1.87 ++ clean_addr = srs_rcpt; 1.88 ++ } 1.89 ++#endif 1.90 + if (cleanup_rcpt_canon_maps 1.91 + && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT)) 1.92 + cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps, 1.93 +diff -urN src/global/mail_params.c.orig src/global/mail_params.c 1.94 +--- src/global/mail_params.c.orig 2012-02-21 14:21:34.000000000 +0100 1.95 ++++ src/global/mail_params.c 2012-02-21 14:22:05.000000000 +0100 1.96 +@@ -308,6 +308,15 @@ 1.97 + bool var_long_queue_ids; 1.98 + bool var_daemon_open_fatal; 1.99 + 1.100 ++#ifdef HAS_SRS 1.101 ++int var_srs_hashlength; 1.102 ++int var_srs_hashmin; 1.103 ++int var_srs_maxage; 1.104 ++char *var_srs_secrets; 1.105 ++char *var_srs_separator; 1.106 ++char *var_srs_domain; 1.107 ++#endif 1.108 ++ 1.109 + const char null_format_string[1] = ""; 1.110 + 1.111 + /* check_myhostname - lookup hostname and validate */ 1.112 +@@ -579,6 +588,11 @@ 1.113 + VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0, 1.114 + /* multi_instance_wrapper may have dependencies but not dependents. */ 1.115 + VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0, 1.116 ++#ifdef HAS_SRS 1.117 ++ VAR_SRS_SECRETS, DEF_SRS_SECRETS, &var_srs_secrets, 0, 0, 1.118 ++ VAR_SRS_SEPARATOR, DEF_SRS_SEPARATOR, &var_srs_separator, 1, 1, 1.119 ++ VAR_SRS_DOMAIN, DEF_SRS_DOMAIN, &var_srs_domain, 0, 0, 1.120 ++#endif 1.121 + 0, 1.122 + }; 1.123 + static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = { 1.124 +@@ -602,6 +616,11 @@ 1.125 + VAR_MIME_BOUND_LEN, DEF_MIME_BOUND_LEN, &var_mime_bound_len, 1, 0, 1.126 + VAR_DELAY_MAX_RES, DEF_DELAY_MAX_RES, &var_delay_max_res, MIN_DELAY_MAX_RES, MAX_DELAY_MAX_RES, 1.127 + VAR_INET_WINDOW, DEF_INET_WINDOW, &var_inet_windowsize, 0, 0, 1.128 ++#ifdef HAS_SRS 1.129 ++ VAR_SRS_HASHLENGTH, DEF_SRS_HASHLENGTH, &var_srs_hashlength, 1, 20, 1.130 ++ VAR_SRS_HASHMIN, DEF_SRS_HASHMIN, &var_srs_hashmin, 1, 20, 1.131 ++ VAR_SRS_MAXAGE, DEF_SRS_MAXAGE, &var_srs_maxage, 1, 0, 1.132 ++#endif 1.133 + 0, 1.134 + }; 1.135 + static const CONFIG_LONG_TABLE long_defaults[] = { 1.136 +diff -urN src/global/mail_params.h.orig src/global/mail_params.h 1.137 +--- src/global/mail_params.h.orig 2012-02-21 14:21:34.000000000 +0100 1.138 ++++ src/global/mail_params.h 2012-02-21 14:22:41.000000000 +0100 1.139 +@@ -1981,6 +1981,35 @@ 1.140 + #define DEF_ALLOW_UNTRUST_ROUTE 0 1.141 + extern bool var_allow_untrust_route; 1.142 + 1.143 ++/** 1.144 ++ * SRS. Shevek <srs@anarres.org>, updated by Chris <chris@codefrickler.de> 1.145 ++ */ 1.146 ++#ifdef HAS_SRS 1.147 ++#define VAR_SRS_HASHLENGTH "srs_hashlength" 1.148 ++#define DEF_SRS_HASHLENGTH 4 1.149 ++extern int var_srs_hashlength; 1.150 ++ 1.151 ++#define VAR_SRS_HASHMIN "srs_hashmin" 1.152 ++#define DEF_SRS_HASHMIN 4 1.153 ++extern int var_srs_hashmin; 1.154 ++ 1.155 ++#define VAR_SRS_MAXAGE "srs_maxage" 1.156 ++#define DEF_SRS_MAXAGE 21 1.157 ++extern int var_srs_maxage; 1.158 ++ 1.159 ++#define VAR_SRS_SECRETS "srs_secrets" 1.160 ++#define DEF_SRS_SECRETS "" 1.161 ++extern char *var_srs_secrets; 1.162 ++ 1.163 ++#define VAR_SRS_DOMAIN "srs_domain" 1.164 ++#define DEF_SRS_DOMAIN "$myorigin" 1.165 ++extern char *var_srs_domain; 1.166 ++ 1.167 ++#define VAR_SRS_SEPARATOR "srs_separator" 1.168 ++#define DEF_SRS_SEPARATOR "=" 1.169 ++extern char *var_srs_separator; 1.170 ++#endif 1.171 ++ 1.172 + /* 1.173 + * Names of specific restrictions, and the corresponding configuration 1.174 + * parameters that control the status codes sent in response to rejected 1.175 +diff -urN src/global/Makefile.in.orig src/global/Makefile.in 1.176 +--- src/global/Makefile.in.orig 2012-02-21 14:21:34.000000000 +0100 1.177 ++++ src/global/Makefile.in 2012-02-21 14:22:05.000000000 +0100 1.178 +@@ -29,7 +29,7 @@ 1.179 + user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \ 1.180 + verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \ 1.181 + fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \ 1.182 +- match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \ 1.183 ++ match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c srs.c \ 1.184 + smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \ 1.185 + dict_memcache.c mail_version.c memcache_proto.c server_acl.c \ 1.186 + mkmap_fail.c 1.187 +@@ -63,7 +63,7 @@ 1.188 + user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \ 1.189 + verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \ 1.190 + fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \ 1.191 +- match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \ 1.192 ++ match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o srs.o \ 1.193 + smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \ 1.194 + dict_memcache.o mail_version.o memcache_proto.o server_acl.o \ 1.195 + mkmap_fail.o 1.196 +diff -urN src/global/srs.c.orig src/global/srs.c 1.197 +--- src/global/srs.c.orig 1970-01-01 01:00:00.000000000 +0100 1.198 ++++ src/global/srs.c 2012-02-21 14:22:27.000000000 +0100 1.199 +@@ -0,0 +1,144 @@ 1.200 ++/*++ 1.201 ++/* NAME 1.202 ++/* srs 3 1.203 ++/* SUMMARY 1.204 ++/* Sender Rewriting Scheme 1.205 ++/* SYNOPSIS 1.206 ++/* void postfix_srs_reverse(rcpt, decoded) 1.207 ++/* const char *rcpt 1.208 ++/* VSTRING **decoded 1.209 ++/* 1.210 ++/* int postfix_srs_forward(sender, alias, encoded) 1.211 ++/* const char *sender 1.212 ++/* const char *alias 1.213 ++/* VSTRING **decoded 1.214 ++/* DESCRIPTION 1.215 ++/* This module rewrites addresses according to the Sender Rewriting 1.216 ++/* Scheme, documented at http://www.libsrs2.org/. 1.217 ++/* 1.218 ++/* srs_reverse() reverse-rewrites the rewritten form of an address 1.219 ++/* 1.220 ++/* srs_forward() rewrites the envelope sender using alias domain 1.221 ++/* 1.222 ++/* DIAGNOSTICS 1.223 ++/* LICENSE 1.224 ++/* .ad 1.225 ++/* .fi 1.226 ++/* The Secure Mailer license must be distributed with this software. 1.227 ++/* AUTHOR(S) 1.228 ++/* Shevek <srs@anarres.org> 1.229 ++/* Chris <chris@codefrickler.de> 1.230 ++/*--*/ 1.231 ++ 1.232 ++#ifdef HAS_SRS 1.233 ++ 1.234 ++/* System library. */ 1.235 ++ 1.236 ++#include <stdlib.h> 1.237 ++#include <sys_defs.h> 1.238 ++#include <string.h> 1.239 ++ 1.240 ++#include <srs2.h> 1.241 ++ 1.242 ++/* Utility library. */ 1.243 ++ 1.244 ++#include <msg.h> 1.245 ++#include <vstring.h> 1.246 ++#include <mymalloc.h> 1.247 ++#include <stringops.h> 1.248 ++ 1.249 ++/* Global library. */ 1.250 ++ 1.251 ++#include <mail_params.h> 1.252 ++ 1.253 ++#define SRS_FAIL_UNLESS(x) do { int __ret = (x); if (__ret != SRS_SUCCESS) msg_fatal("SRS configuration error: %s", srs_strerror(__ret)); } while(0) 1.254 ++ 1.255 ++/* my function declarations */ 1.256 ++int postfix_srs_forward (const char *sender, const char *alias, VSTRING **encoded); 1.257 ++int postfix_srs_reverse (const char *rcpt, VSTRING **decoded); 1.258 ++ 1.259 ++static srs_t *srs; 1.260 ++ 1.261 ++static void postfix_srs_init (void) { 1.262 ++ char *saved_secrets; 1.263 ++ char *secret; 1.264 ++ char *ptr; 1.265 ++ 1.266 ++ if (srs == NULL) { 1.267 ++ /* XXX Can't use memory functions from postfix because of inconsistensies in libsrs2 1.268 ++ srs_set_malloc((srs_malloc_t)mymalloc, (srs_realloc_t)myrealloc, (srs_free_t)myfree); 1.269 ++ */ 1.270 ++ 1.271 ++ srs = srs_new(); 1.272 ++ /* avoid sender-domain-check, since we have already done this ourselves */ 1.273 ++ SRS_FAIL_UNLESS(srs_set_alwaysrewrite(srs, 1)); 1.274 ++ SRS_FAIL_UNLESS(srs_set_hashlength(srs, var_srs_hashlength)); 1.275 ++ SRS_FAIL_UNLESS(srs_set_hashmin(srs, var_srs_hashmin)); 1.276 ++ SRS_FAIL_UNLESS(srs_set_maxage(srs, var_srs_maxage)); 1.277 ++ SRS_FAIL_UNLESS(srs_set_separator(srs, var_srs_separator[0])); 1.278 ++ 1.279 ++ ptr = saved_secrets = mystrdup(var_srs_secrets); 1.280 ++ while ((secret = mystrtok(&ptr, ", \t\r\n")) != 0) { 1.281 ++ SRS_FAIL_UNLESS(srs_add_secret(srs, secret)); 1.282 ++ } 1.283 ++ myfree(saved_secrets); 1.284 ++ } 1.285 ++} 1.286 ++ 1.287 ++int postfix_srs_reverse(const char *rcpt, VSTRING **decoded) { 1.288 ++ char *out; 1.289 ++ int ret; 1.290 ++ 1.291 ++ if (!SRS_IS_SRS_ADDRESS(rcpt)) 1.292 ++ return (0); 1.293 ++ 1.294 ++ postfix_srs_init(); 1.295 ++ 1.296 ++ ret = srs_reverse_alloc(srs, &out, rcpt); 1.297 ++ 1.298 ++ if (ret != SRS_SUCCESS) { 1.299 ++ switch (SRS_ERROR_TYPE(ret)) { 1.300 ++ case SRS_ERRTYPE_CONFIG: 1.301 ++ msg_fatal("SRS configuration error: %s", srs_strerror(ret)); 1.302 ++ return (-1); 1.303 ++ case SRS_ERRTYPE_INPUT: 1.304 ++ msg_fatal("SRS reverse failed for <%s>: %s", rcpt, srs_strerror(ret)); 1.305 ++ return (-1); 1.306 ++ case SRS_ERRTYPE_SYNTAX: 1.307 ++ case SRS_ERRTYPE_SRS: 1.308 ++ msg_warn("SRS reverse failed for <%s>: %s", rcpt, srs_strerror(ret)); 1.309 ++ break; 1.310 ++ } 1.311 ++ return (0); 1.312 ++ } 1.313 ++ 1.314 ++ if (decoded) { 1.315 ++ *decoded = vstring_alloc(100); 1.316 ++ vstring_strcpy(*decoded, out); 1.317 ++ } 1.318 ++ free(out); 1.319 ++ 1.320 ++ return (1); 1.321 ++} 1.322 ++ 1.323 ++int postfix_srs_forward(const char *sender, const char *alias, VSTRING **encoded) { 1.324 ++ char *out; 1.325 ++ int ret; 1.326 ++ 1.327 ++ postfix_srs_init(); 1.328 ++ 1.329 ++ ret = srs_forward_alloc(srs, &out, sender, alias); 1.330 ++ 1.331 ++ if (ret != SRS_SUCCESS) { 1.332 ++ msg_warn("SRS forward failed for <%s>: %s", sender, srs_strerror(ret)); 1.333 ++ return (0); 1.334 ++ } 1.335 ++ 1.336 ++ *encoded = vstring_alloc(100); 1.337 ++ vstring_strcpy(*encoded, out); 1.338 ++ free(out); 1.339 ++ 1.340 ++ return (1); 1.341 ++} 1.342 ++ 1.343 ++#endif 1.344 +diff -urN src/qmgr/qmgr_deliver.c.orig src/qmgr/qmgr_deliver.c 1.345 +--- src/qmgr/qmgr_deliver.c.orig 2012-02-21 14:21:34.000000000 +0100 1.346 ++++ src/qmgr/qmgr_deliver.c 2012-02-21 14:22:05.000000000 +0100 1.347 +@@ -76,6 +76,7 @@ 1.348 + #include <dsn_buf.h> 1.349 + #include <dsb_scan.h> 1.350 + #include <rcpt_print.h> 1.351 ++#include <resolve_clnt.h> 1.352 + 1.353 + /* Application-specific. */ 1.354 + 1.355 +@@ -129,6 +130,73 @@ 1.356 + } 1.357 + } 1.358 + 1.359 ++#ifdef HAS_SRS 1.360 ++/* qmgr_deliver_check_srs - check whether sender should be rewritten */ 1.361 ++ 1.362 ++static int qmgr_deliver_check_srs(QMGR_MESSAGE *message, RECIPIENT_LIST list, char **alias, RESOLVE_REPLY *reply) 1.363 ++{ 1.364 ++ char *pos; 1.365 ++ 1.366 ++ /* 1.367 ++ * Rewrite if we are not final destination nor relay host for recipient and sender address 1.368 ++ * it should be enough to look at the first recipient, since transport/nexthop are the same for all recipients 1.369 ++ */ 1.370 ++ resolve_clnt_query(list.info->address, reply); 1.371 ++ if (reply->flags & RESOLVE_FLAG_FAIL) 1.372 ++ return (-1); 1.373 ++ else if (!(reply->flags & RESOLVE_CLASS_DEFAULT)) 1.374 ++ return (0); 1.375 ++ 1.376 ++ resolve_clnt_query(message->sender, reply); 1.377 ++ if (reply->flags & RESOLVE_FLAG_FAIL) 1.378 ++ return (-1); 1.379 ++ else if (!(reply->flags & RESOLVE_CLASS_DEFAULT)) 1.380 ++ return (0); 1.381 ++ 1.382 ++ if (var_srs_domain[0]) { 1.383 ++ *alias = var_srs_domain; 1.384 ++ } else { 1.385 ++ /* retrieve alias domain from original recipient if we are final destination ... */ 1.386 ++ resolve_clnt_query(list.info->orig_addr, reply); 1.387 ++ if (reply->flags & RESOLVE_FLAG_FAIL) 1.388 ++ return (-1); 1.389 ++ if ((reply->flags & RESOLVE_CLASS_FINAL) && (pos = strrchr(list.info->orig_addr, '@'))) { 1.390 ++ *alias = pos + 1; 1.391 ++ } else { 1.392 ++ /* ... or use myorigin as fallback */ 1.393 ++ *alias = var_myorigin; 1.394 ++ } 1.395 ++ } 1.396 ++ 1.397 ++ return (1); 1.398 ++} 1.399 ++ 1.400 ++/* qmgr_deliver_do_srs - compute srs address if necessary */ 1.401 ++ 1.402 ++static int qmgr_deliver_do_srs(QMGR_MESSAGE *message, RECIPIENT_LIST list, VSTRING **encoded) 1.403 ++{ 1.404 ++ RESOLVE_REPLY reply; 1.405 ++ char *alias; 1.406 ++ int state; 1.407 ++ 1.408 ++ resolve_clnt_init(&reply); 1.409 ++ state = qmgr_deliver_check_srs(message, list, &alias, &reply); 1.410 ++ resolve_clnt_free(&reply); 1.411 ++ if (state < 0) { 1.412 ++ msg_warn("srs lookup problem"); 1.413 ++ return (-1); 1.414 ++ } else if (state == 0) { 1.415 ++ return (0); 1.416 ++ } 1.417 ++ 1.418 ++ state = postfix_srs_forward(message->sender, alias, encoded); 1.419 ++ if (state < 0) 1.420 ++ return (-1); 1.421 ++ 1.422 ++ return (1); 1.423 ++} 1.424 ++#endif 1.425 ++ 1.426 + /* qmgr_deliver_send_request - send delivery request to delivery process */ 1.427 + 1.428 + static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) 1.429 +@@ -140,6 +208,9 @@ 1.430 + MSG_STATS stats; 1.431 + char *sender; 1.432 + int flags; 1.433 ++#ifdef HAS_SRS 1.434 ++ int srs_state; 1.435 ++#endif 1.436 + 1.437 + /* 1.438 + * If variable envelope return path is requested, change prefix+@origin 1.439 +@@ -147,7 +218,19 @@ 1.440 + * recipient per delivery. 1.441 + */ 1.442 + if (message->verp_delims == 0) { 1.443 +- sender = message->sender; 1.444 ++#ifdef HAS_SRS 1.445 ++ srs_state = qmgr_deliver_do_srs(message, list, &sender_buf); 1.446 ++ if (srs_state < 0) { 1.447 ++ return (-1); 1.448 ++ } else if (srs_state == 1) { 1.449 ++ sender = vstring_str(sender_buf); 1.450 ++ msg_info("%s: srs_from=<%s>", message->queue_id, sender); 1.451 ++ } else { 1.452 ++ sender = message->sender; 1.453 ++ } 1.454 ++#else 1.455 ++ sender = message->sender; 1.456 ++#endif 1.457 + } else { 1.458 + sender_buf = vstring_alloc(100); 1.459 + verp_sender(sender_buf, message->verp_delims, 1.460 +diff -urN src/smtpd/smtpd_check.c.orig src/smtpd/smtpd_check.c 1.461 +--- src/smtpd/smtpd_check.c.orig 2012-02-21 14:21:34.000000000 +0100 1.462 ++++ src/smtpd/smtpd_check.c 2012-02-21 14:22:05.000000000 +0100 1.463 +@@ -929,6 +929,19 @@ 1.464 + reject_server_error(state); 1.465 + } 1.466 + 1.467 ++#ifdef HAS_SRS 1.468 ++/* check_mail_addr_srs - check if address is a valid srs address */ 1.469 ++ 1.470 ++static int check_mail_addr_srs(SMTPD_STATE *state, const char *reply_name, const char *addr) 1.471 ++{ 1.472 ++ int result; 1.473 ++ 1.474 ++ if ((result = postfix_srs_reverse(addr, 0)) < 0) 1.475 ++ reject_dict_retry(state, reply_name); 1.476 ++ return (result); 1.477 ++} 1.478 ++#endif 1.479 ++ 1.480 + /* reject_unknown_reverse_name - fail if reverse client hostname is unknown */ 1.481 + 1.482 + static int reject_unknown_reverse_name(SMTPD_STATE *state) 1.483 +@@ -4552,6 +4565,13 @@ 1.484 + || MATCH(canonical_maps, CONST_STR(reply->recipient)) 1.485 + || MATCH(virt_alias_maps, CONST_STR(reply->recipient))) 1.486 + return (0); 1.487 ++ 1.488 ++#ifdef HAS_SRS 1.489 ++ /* allow valid srs address */ 1.490 ++ if ((reply->flags & RESOLVE_CLASS_FINAL) 1.491 ++ && check_mail_addr_srs(state, recipient, CONST_STR(reply->recipient)) == 1) 1.492 ++ return (0); 1.493 ++#endif 1.494 + 1.495 + /* 1.496 + * At this point, anything that resolves to the error mailer is known to
2.1 --- a/postfix/postfix.spec Wed Sep 12 19:10:15 2012 +0200 2.2 +++ b/postfix/postfix.spec Thu Sep 13 20:05:49 2012 +0200 2.3 @@ -48,6 +48,7 @@ 2.4 %option with_pgsql no 2.5 %option with_ldap no 2.6 %option with_whoson no 2.7 +%option with_spfsrs no 2.8 %option with_fdsetsize no 2.9 2.10 # list of sources 2.11 @@ -59,6 +60,7 @@ 2.12 Patch0: postfix.patch 2.13 Patch1: postfix.patch.pfls 2.14 Patch2: http://download.openpkg.org/components/versioned/postfix/postfix-%{V_whoson}-whoson.patch 2.15 +Patch3: postfix-srs.patch 2.16 2.17 # build information 2.18 BuildPreReq: OpenPKG, openpkg >= 20100101, perl, gcc 2.19 @@ -97,6 +99,10 @@ 2.20 BuildPreReq: whoson 2.21 PreReq: whoson 2.22 %endif 2.23 +%if "%{with_spfsrs}" == "yes" 2.24 +BuildPreReq: libsrs2 2.25 +PreReq: libsrs2 2.26 +%endif 2.27 Provides: MTA 2.28 Conflicts: exim, sendmail, ssmtp 2.29 2.30 @@ -117,6 +123,7 @@ 2.31 o Optional PostgreSQL dictionary support (see package options) 2.32 o Optional OpenLDAP dictionary support (see package options) 2.33 o Optional WHOSON dictionary support (see package options) 2.34 + o Optional SPF SRS protection support (see package options) 2.35 2.36 %track 2.37 prog postfix = { 2.38 @@ -134,6 +141,11 @@ 2.39 url = http://download.openpkg.org/components/versioned/postfix/ 2.40 regex = postfix-(__VER__)-whoson.patch 2.41 } 2.42 + prog postfix:spfsrs = { 2.43 + version = %{V_spfsrs} 2.44 + url = http://www.codefrickler.de/srs/ 2.45 + regex = postfix-srs-(__VER__).patch 2.46 + } 2.47 2.48 %prep 2.49 # unpack distribution files 2.50 @@ -149,6 +161,11 @@ 2.51 %patch -p0 -P 2 2.52 %endif 2.53 2.54 + # apply vendor SPF SRS patch 2.55 +%if "%{with_spfsrs}" == "yes" 2.56 + %patch -p0 -P 3 2.57 +%endif 2.58 + 2.59 # remove OpenPKG privelege model incompatible exit conditions 2.60 %{l_shtool} subst \ 2.61 -e 's;msg_fatal\(.*attribute specifies mail system\);msg_info\1;g' \ 2.62 @@ -229,6 +246,10 @@ 2.63 AUXLIBS="$AUXLIBS %{l_fsl_ldflags} %{l_fsl_libs}" 2.64 CCARGS="$CCARGS -DUSE_SOFTLIMITONLY" 2.65 %endif 2.66 +%if "%{with_spfsrs}" == "yes" 2.67 + CCARGS="$CCARGS -DHAS_SRS" 2.68 + AUXLIBS="$AUXLIBS -lsrs2" 2.69 +%endif 2.70 %if "%{with_fdsetsize}" != "no" 2.71 %if "%{with_fdsetsize}" == "yes" 2.72 CCARGS="$CCARGS -DFD_SETSIZE=1024"
3.1 --- a/postfix/postfix.txt Wed Sep 12 19:10:15 2012 +0200 3.2 +++ b/postfix/postfix.txt Thu Sep 13 20:05:49 2012 +0200 3.3 @@ -25,6 +25,8 @@ 3.4 T_CLIENTS = clients 3.5 T_SENDERS = senders 3.6 T_CLICRT = clicrt 3.7 +T_RECIPIENT = recipient 3.8 +T_HELO = helo 3.9 3.10 # dependency tracking 3.11 TIMESTAMP = .up-to-date 3.12 @@ -43,7 +45,9 @@ 3.13 $(T_ALIASES).db \ 3.14 $(T_CLIENTS).db \ 3.15 $(T_SENDERS).db \ 3.16 - $(T_CLICRT).db 3.17 + $(T_CLICRT).db \ 3.18 + $(T_RECIPIENT).db \ 3.19 + $(T_HELO).db 3.20 3.21 # default target 3.22 all: $(TABLES) $(TIMESTAMP) 3.23 @@ -79,6 +83,10 @@ 3.24 $(POSTMAP) hash:$(T_SENDERS) 3.25 $(T_CLICRT).db: $(T_CLICRT) $(MAKEFILE) 3.26 $(POSTMAP) hash:$(T_CLICRT) 3.27 +$(T_RECIPIENT).db: $(T_RECIPIENT) $(MAKEFILE) 3.28 + $(POSTMAP) hash:$(T_RECIPIENT) 3.29 +$(T_HELO).db: $(T_HELO) $(MAKEFILE) 3.30 + $(POSTMAP) hash:$(T_HELO) 3.31 3.32 # cleanup target 3.33 clean: 3.34 @@ -440,3 +448,59 @@ 3.35 # | 18:81:F5:22:18:BA:EB:15:FF:40:30:00:EA:C0:B4:2E:EC:AE:86:8E user2 3.36 3.37 </file> 3.38 +<file name="recipient"> 3.39 +## 3.40 +## @l_prefix@/etc/postfix/recipient -- control for relaying recipients 3.41 +## 3.42 +## Searched for RCPT TO address, domain, parent domains, or localpart@ 3.43 +## and rejects the request if the result is REJECT or "[45]XX text" or 3.44 +## permits the request if the result is OK or RELAY or all-numerical. 3.45 +## 3.46 + 3.47 +# Syntax (see access(5)): 3.48 +# | user@domain action 3.49 +# | domain action 3.50 +# | user@ action 3.51 +# | net.work.addr.ess action 3.52 +# | net.work.addr action 3.53 +# | net.work action 3.54 +# | net action 3.55 +# where "action" is one of: 3.56 +# "[45]NN text", "REJECT", "OK", "restriction..." 3.57 +# 3.58 +# Examples: 3.59 +# | mail.example.com OK 3.60 +# | example.com REJECT 3.61 +# | 192.168.0.1 OK 3.62 +# | 192.168 REJECT 3.63 +# | postmaster@ OK 3.64 + 3.65 +</file> 3.66 +<file name="helo"> 3.67 +## 3.68 +## @l_prefix@/etc/postfix/helo -- control for relaying helo transmissions 3.69 +## 3.70 +## Searched for HELO or EHLO hostname or parent domains and rejects the 3.71 +## request if the result is REJECT or "[45]XX text" or permits the request 3.72 +## if the result is OK or RELAY or all-numerical. 3.73 +## 3.74 + 3.75 +# Syntax (see access(5)): 3.76 +# | user@domain action 3.77 +# | domain action 3.78 +# | user@ action 3.79 +# | net.work.addr.ess action 3.80 +# | net.work.addr action 3.81 +# | net.work action 3.82 +# | net action 3.83 +# where "action" is one of: 3.84 +# "[45]NN text", "REJECT", "OK", "restriction..." 3.85 +# 3.86 +# Examples: 3.87 +# | mail.example.com OK 3.88 +# | example.com REJECT 3.89 +# | 192.168.0.1 OK 3.90 +# | 192.168 REJECT 3.91 +# | postmaster@ OK 3.92 + 3.93 +</file>