Mon, 28 Jan 2013 17:37:18 +0100
Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.
michael@676 | 1 | diff -urN README_FILES/SRS_README.orig README_FILES/SRS_README |
michael@676 | 2 | --- README_FILES/SRS_README.orig 1970-01-01 01:00:00.000000000 +0100 |
michael@676 | 3 | +++ README_FILES/SRS_README 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 4 | @@ -0,0 +1,56 @@ |
michael@676 | 5 | + |
michael@676 | 6 | +CREDITS: |
michael@676 | 7 | + |
michael@676 | 8 | +- originally written by Shevek <srs@anarres.org> |
michael@676 | 9 | +- fixes and porting to postfix 2.1 by Branko F. Gracnar <bfg@frost.ath.cx> |
michael@676 | 10 | +- redesigned and ported to debian postfix 2.7.0 by Chris <chris@codefrickler.de> |
michael@676 | 11 | + |
michael@676 | 12 | +SYNOPSIS: |
michael@676 | 13 | +Works with all address classes (not limited to local domain). |
michael@676 | 14 | +Doesn't depend on .forward-files or alias_maps. |
michael@676 | 15 | +SMTPD accepts valid srs addresses without further configuration. |
michael@676 | 16 | +Sender gets rewritten only when necessary: |
michael@676 | 17 | +- rewrite after queuing (after separation to on- and off-site destinations) |
michael@676 | 18 | +- rewrite only if sender and recipient are off-site and host is not a relay for recipient |
michael@676 | 19 | +Alias domain can be chosen automatically from original on-site-recipient. |
michael@676 | 20 | + |
michael@676 | 21 | + |
michael@676 | 22 | +USAGE: |
michael@676 | 23 | + |
michael@676 | 24 | +1) Apply the patch. |
michael@676 | 25 | + |
michael@676 | 26 | +2) Create makefiles with |
michael@676 | 27 | + |
michael@676 | 28 | +make makefiles CCARGS="-DHAS_SRS -I<directory-containing--srs2.h>" AUXLIBS="-L<directory-containing--libsrs2.so> -lsrs2" |
michael@676 | 29 | + |
michael@676 | 30 | + |
michael@676 | 31 | +3) Build. |
michael@676 | 32 | + |
michael@676 | 33 | +4) Add the following global configuration variables to main.cf: |
michael@676 | 34 | +All variables are optional, except where stated: |
michael@676 | 35 | + |
michael@676 | 36 | + srs_domain (string) |
michael@676 | 37 | + A domain to use in rewritten addresses. This must point only |
michael@676 | 38 | + to machines which know the encoding secret used by this |
michael@676 | 39 | + system. It defaults to $myorigin. If set to the emtpy |
michael@676 | 40 | + string, use domain from original recipient if host is final |
michael@676 | 41 | + destination, otherwise use $myorigin. |
michael@676 | 42 | + srs_hashlength (int) |
michael@676 | 43 | + The hash length to generate in a rewritten address. |
michael@676 | 44 | + srs_hashmin (int) |
michael@676 | 45 | + The hash length to require when checking an address. |
michael@676 | 46 | + srs_maxage (int) |
michael@676 | 47 | + The maximum permitted age of a rewritten address. |
michael@676 | 48 | + srs_secrets (string) |
michael@676 | 49 | + [required] A list of secrets with which to generate |
michael@676 | 50 | + and check addresses. |
michael@676 | 51 | + srs_separator (string) |
michael@676 | 52 | + The separator to appear immediately after SRS[01] in |
michael@676 | 53 | + rewritten addresses. |
michael@676 | 54 | + |
michael@676 | 55 | + |
michael@676 | 56 | +See http://www.libsrs2.org/ for more information about the meaning |
michael@676 | 57 | +of these variables. They are standard across MTAs. |
michael@676 | 58 | + |
michael@676 | 59 | +5) Fire up and enjoy. |
michael@676 | 60 | + |
michael@676 | 61 | diff -urN src/cleanup/cleanup_addr.c.orig src/cleanup/cleanup_addr.c |
michael@676 | 62 | --- src/cleanup/cleanup_addr.c.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 63 | +++ src/cleanup/cleanup_addr.c 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 64 | @@ -163,6 +163,10 @@ |
michael@676 | 65 | { |
michael@676 | 66 | VSTRING *clean_addr = vstring_alloc(100); |
michael@676 | 67 | const char *bcc; |
michael@676 | 68 | +#ifdef HAS_SRS |
michael@676 | 69 | + int srs_state; |
michael@676 | 70 | + VSTRING *srs_rcpt; |
michael@676 | 71 | +#endif |
michael@676 | 72 | |
michael@676 | 73 | /* |
michael@676 | 74 | * Note: an unqualified envelope address is for all practical purposes |
michael@676 | 75 | @@ -174,6 +178,14 @@ |
michael@676 | 76 | cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL, |
michael@676 | 77 | clean_addr, *buf ? buf : var_empty_addr); |
michael@676 | 78 | if (state->flags & CLEANUP_FLAG_MAP_OK) { |
michael@676 | 79 | +#ifdef HAS_SRS |
michael@676 | 80 | + if ((srs_state = postfix_srs_reverse(STR(clean_addr), &srs_rcpt)) < 0) { |
michael@676 | 81 | + /* XXX errors */ |
michael@676 | 82 | + } else if (srs_state == 1) { |
michael@676 | 83 | + vstring_free(clean_addr); |
michael@676 | 84 | + clean_addr = srs_rcpt; |
michael@676 | 85 | + } |
michael@676 | 86 | +#endif |
michael@676 | 87 | if (cleanup_rcpt_canon_maps |
michael@676 | 88 | && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT)) |
michael@676 | 89 | cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps, |
michael@676 | 90 | diff -urN src/global/mail_params.c.orig src/global/mail_params.c |
michael@676 | 91 | --- src/global/mail_params.c.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 92 | +++ src/global/mail_params.c 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 93 | @@ -308,6 +308,15 @@ |
michael@676 | 94 | bool var_long_queue_ids; |
michael@676 | 95 | bool var_daemon_open_fatal; |
michael@676 | 96 | |
michael@676 | 97 | +#ifdef HAS_SRS |
michael@676 | 98 | +int var_srs_hashlength; |
michael@676 | 99 | +int var_srs_hashmin; |
michael@676 | 100 | +int var_srs_maxage; |
michael@676 | 101 | +char *var_srs_secrets; |
michael@676 | 102 | +char *var_srs_separator; |
michael@676 | 103 | +char *var_srs_domain; |
michael@676 | 104 | +#endif |
michael@676 | 105 | + |
michael@676 | 106 | const char null_format_string[1] = ""; |
michael@676 | 107 | |
michael@676 | 108 | /* check_myhostname - lookup hostname and validate */ |
michael@676 | 109 | @@ -579,6 +588,11 @@ |
michael@676 | 110 | VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0, |
michael@676 | 111 | /* multi_instance_wrapper may have dependencies but not dependents. */ |
michael@676 | 112 | VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0, |
michael@676 | 113 | +#ifdef HAS_SRS |
michael@676 | 114 | + VAR_SRS_SECRETS, DEF_SRS_SECRETS, &var_srs_secrets, 0, 0, |
michael@676 | 115 | + VAR_SRS_SEPARATOR, DEF_SRS_SEPARATOR, &var_srs_separator, 1, 1, |
michael@676 | 116 | + VAR_SRS_DOMAIN, DEF_SRS_DOMAIN, &var_srs_domain, 0, 0, |
michael@676 | 117 | +#endif |
michael@676 | 118 | 0, |
michael@676 | 119 | }; |
michael@676 | 120 | static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = { |
michael@676 | 121 | @@ -602,6 +616,11 @@ |
michael@676 | 122 | VAR_MIME_BOUND_LEN, DEF_MIME_BOUND_LEN, &var_mime_bound_len, 1, 0, |
michael@676 | 123 | VAR_DELAY_MAX_RES, DEF_DELAY_MAX_RES, &var_delay_max_res, MIN_DELAY_MAX_RES, MAX_DELAY_MAX_RES, |
michael@676 | 124 | VAR_INET_WINDOW, DEF_INET_WINDOW, &var_inet_windowsize, 0, 0, |
michael@676 | 125 | +#ifdef HAS_SRS |
michael@676 | 126 | + VAR_SRS_HASHLENGTH, DEF_SRS_HASHLENGTH, &var_srs_hashlength, 1, 20, |
michael@676 | 127 | + VAR_SRS_HASHMIN, DEF_SRS_HASHMIN, &var_srs_hashmin, 1, 20, |
michael@676 | 128 | + VAR_SRS_MAXAGE, DEF_SRS_MAXAGE, &var_srs_maxage, 1, 0, |
michael@676 | 129 | +#endif |
michael@676 | 130 | 0, |
michael@676 | 131 | }; |
michael@676 | 132 | static const CONFIG_LONG_TABLE long_defaults[] = { |
michael@676 | 133 | diff -urN src/global/mail_params.h.orig src/global/mail_params.h |
michael@676 | 134 | --- src/global/mail_params.h.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 135 | +++ src/global/mail_params.h 2012-02-21 14:22:41.000000000 +0100 |
michael@676 | 136 | @@ -1981,6 +1981,35 @@ |
michael@676 | 137 | #define DEF_ALLOW_UNTRUST_ROUTE 0 |
michael@676 | 138 | extern bool var_allow_untrust_route; |
michael@676 | 139 | |
michael@676 | 140 | +/** |
michael@676 | 141 | + * SRS. Shevek <srs@anarres.org>, updated by Chris <chris@codefrickler.de> |
michael@676 | 142 | + */ |
michael@676 | 143 | +#ifdef HAS_SRS |
michael@676 | 144 | +#define VAR_SRS_HASHLENGTH "srs_hashlength" |
michael@676 | 145 | +#define DEF_SRS_HASHLENGTH 4 |
michael@676 | 146 | +extern int var_srs_hashlength; |
michael@676 | 147 | + |
michael@676 | 148 | +#define VAR_SRS_HASHMIN "srs_hashmin" |
michael@676 | 149 | +#define DEF_SRS_HASHMIN 4 |
michael@676 | 150 | +extern int var_srs_hashmin; |
michael@676 | 151 | + |
michael@676 | 152 | +#define VAR_SRS_MAXAGE "srs_maxage" |
michael@676 | 153 | +#define DEF_SRS_MAXAGE 21 |
michael@676 | 154 | +extern int var_srs_maxage; |
michael@676 | 155 | + |
michael@676 | 156 | +#define VAR_SRS_SECRETS "srs_secrets" |
michael@676 | 157 | +#define DEF_SRS_SECRETS "" |
michael@676 | 158 | +extern char *var_srs_secrets; |
michael@676 | 159 | + |
michael@676 | 160 | +#define VAR_SRS_DOMAIN "srs_domain" |
michael@676 | 161 | +#define DEF_SRS_DOMAIN "$myorigin" |
michael@676 | 162 | +extern char *var_srs_domain; |
michael@676 | 163 | + |
michael@676 | 164 | +#define VAR_SRS_SEPARATOR "srs_separator" |
michael@676 | 165 | +#define DEF_SRS_SEPARATOR "=" |
michael@676 | 166 | +extern char *var_srs_separator; |
michael@676 | 167 | +#endif |
michael@676 | 168 | + |
michael@676 | 169 | /* |
michael@676 | 170 | * Names of specific restrictions, and the corresponding configuration |
michael@676 | 171 | * parameters that control the status codes sent in response to rejected |
michael@676 | 172 | diff -urN src/global/Makefile.in.orig src/global/Makefile.in |
michael@676 | 173 | --- src/global/Makefile.in.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 174 | +++ src/global/Makefile.in 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 175 | @@ -29,7 +29,7 @@ |
michael@676 | 176 | user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \ |
michael@676 | 177 | verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \ |
michael@676 | 178 | fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \ |
michael@676 | 179 | - match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \ |
michael@676 | 180 | + match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c srs.c \ |
michael@676 | 181 | smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \ |
michael@676 | 182 | dict_memcache.c mail_version.c memcache_proto.c server_acl.c \ |
michael@676 | 183 | mkmap_fail.c |
michael@676 | 184 | @@ -63,7 +63,7 @@ |
michael@676 | 185 | user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \ |
michael@676 | 186 | verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \ |
michael@676 | 187 | fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \ |
michael@676 | 188 | - match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \ |
michael@676 | 189 | + match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o srs.o \ |
michael@676 | 190 | smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \ |
michael@676 | 191 | dict_memcache.o mail_version.o memcache_proto.o server_acl.o \ |
michael@676 | 192 | mkmap_fail.o |
michael@676 | 193 | diff -urN src/global/srs.c.orig src/global/srs.c |
michael@676 | 194 | --- src/global/srs.c.orig 1970-01-01 01:00:00.000000000 +0100 |
michael@676 | 195 | +++ src/global/srs.c 2012-02-21 14:22:27.000000000 +0100 |
michael@676 | 196 | @@ -0,0 +1,144 @@ |
michael@676 | 197 | +/*++ |
michael@676 | 198 | +/* NAME |
michael@676 | 199 | +/* srs 3 |
michael@676 | 200 | +/* SUMMARY |
michael@676 | 201 | +/* Sender Rewriting Scheme |
michael@676 | 202 | +/* SYNOPSIS |
michael@676 | 203 | +/* void postfix_srs_reverse(rcpt, decoded) |
michael@676 | 204 | +/* const char *rcpt |
michael@676 | 205 | +/* VSTRING **decoded |
michael@676 | 206 | +/* |
michael@676 | 207 | +/* int postfix_srs_forward(sender, alias, encoded) |
michael@676 | 208 | +/* const char *sender |
michael@676 | 209 | +/* const char *alias |
michael@676 | 210 | +/* VSTRING **decoded |
michael@676 | 211 | +/* DESCRIPTION |
michael@676 | 212 | +/* This module rewrites addresses according to the Sender Rewriting |
michael@676 | 213 | +/* Scheme, documented at http://www.libsrs2.org/. |
michael@676 | 214 | +/* |
michael@676 | 215 | +/* srs_reverse() reverse-rewrites the rewritten form of an address |
michael@676 | 216 | +/* |
michael@676 | 217 | +/* srs_forward() rewrites the envelope sender using alias domain |
michael@676 | 218 | +/* |
michael@676 | 219 | +/* DIAGNOSTICS |
michael@676 | 220 | +/* LICENSE |
michael@676 | 221 | +/* .ad |
michael@676 | 222 | +/* .fi |
michael@676 | 223 | +/* The Secure Mailer license must be distributed with this software. |
michael@676 | 224 | +/* AUTHOR(S) |
michael@676 | 225 | +/* Shevek <srs@anarres.org> |
michael@676 | 226 | +/* Chris <chris@codefrickler.de> |
michael@676 | 227 | +/*--*/ |
michael@676 | 228 | + |
michael@676 | 229 | +#ifdef HAS_SRS |
michael@676 | 230 | + |
michael@676 | 231 | +/* System library. */ |
michael@676 | 232 | + |
michael@676 | 233 | +#include <stdlib.h> |
michael@676 | 234 | +#include <sys_defs.h> |
michael@676 | 235 | +#include <string.h> |
michael@676 | 236 | + |
michael@676 | 237 | +#include <srs2.h> |
michael@676 | 238 | + |
michael@676 | 239 | +/* Utility library. */ |
michael@676 | 240 | + |
michael@676 | 241 | +#include <msg.h> |
michael@676 | 242 | +#include <vstring.h> |
michael@676 | 243 | +#include <mymalloc.h> |
michael@676 | 244 | +#include <stringops.h> |
michael@676 | 245 | + |
michael@676 | 246 | +/* Global library. */ |
michael@676 | 247 | + |
michael@676 | 248 | +#include <mail_params.h> |
michael@676 | 249 | + |
michael@676 | 250 | +#define SRS_FAIL_UNLESS(x) do { int __ret = (x); if (__ret != SRS_SUCCESS) msg_fatal("SRS configuration error: %s", srs_strerror(__ret)); } while(0) |
michael@676 | 251 | + |
michael@676 | 252 | +/* my function declarations */ |
michael@676 | 253 | +int postfix_srs_forward (const char *sender, const char *alias, VSTRING **encoded); |
michael@676 | 254 | +int postfix_srs_reverse (const char *rcpt, VSTRING **decoded); |
michael@676 | 255 | + |
michael@676 | 256 | +static srs_t *srs; |
michael@676 | 257 | + |
michael@676 | 258 | +static void postfix_srs_init (void) { |
michael@676 | 259 | + char *saved_secrets; |
michael@676 | 260 | + char *secret; |
michael@676 | 261 | + char *ptr; |
michael@676 | 262 | + |
michael@676 | 263 | + if (srs == NULL) { |
michael@676 | 264 | + /* XXX Can't use memory functions from postfix because of inconsistensies in libsrs2 |
michael@676 | 265 | + srs_set_malloc((srs_malloc_t)mymalloc, (srs_realloc_t)myrealloc, (srs_free_t)myfree); |
michael@676 | 266 | + */ |
michael@676 | 267 | + |
michael@676 | 268 | + srs = srs_new(); |
michael@676 | 269 | + /* avoid sender-domain-check, since we have already done this ourselves */ |
michael@676 | 270 | + SRS_FAIL_UNLESS(srs_set_alwaysrewrite(srs, 1)); |
michael@676 | 271 | + SRS_FAIL_UNLESS(srs_set_hashlength(srs, var_srs_hashlength)); |
michael@676 | 272 | + SRS_FAIL_UNLESS(srs_set_hashmin(srs, var_srs_hashmin)); |
michael@676 | 273 | + SRS_FAIL_UNLESS(srs_set_maxage(srs, var_srs_maxage)); |
michael@676 | 274 | + SRS_FAIL_UNLESS(srs_set_separator(srs, var_srs_separator[0])); |
michael@676 | 275 | + |
michael@676 | 276 | + ptr = saved_secrets = mystrdup(var_srs_secrets); |
michael@676 | 277 | + while ((secret = mystrtok(&ptr, ", \t\r\n")) != 0) { |
michael@676 | 278 | + SRS_FAIL_UNLESS(srs_add_secret(srs, secret)); |
michael@676 | 279 | + } |
michael@676 | 280 | + myfree(saved_secrets); |
michael@676 | 281 | + } |
michael@676 | 282 | +} |
michael@676 | 283 | + |
michael@676 | 284 | +int postfix_srs_reverse(const char *rcpt, VSTRING **decoded) { |
michael@676 | 285 | + char *out; |
michael@676 | 286 | + int ret; |
michael@676 | 287 | + |
michael@676 | 288 | + if (!SRS_IS_SRS_ADDRESS(rcpt)) |
michael@676 | 289 | + return (0); |
michael@676 | 290 | + |
michael@676 | 291 | + postfix_srs_init(); |
michael@676 | 292 | + |
michael@676 | 293 | + ret = srs_reverse_alloc(srs, &out, rcpt); |
michael@676 | 294 | + |
michael@676 | 295 | + if (ret != SRS_SUCCESS) { |
michael@676 | 296 | + switch (SRS_ERROR_TYPE(ret)) { |
michael@676 | 297 | + case SRS_ERRTYPE_CONFIG: |
michael@676 | 298 | + msg_fatal("SRS configuration error: %s", srs_strerror(ret)); |
michael@676 | 299 | + return (-1); |
michael@676 | 300 | + case SRS_ERRTYPE_INPUT: |
michael@676 | 301 | + msg_fatal("SRS reverse failed for <%s>: %s", rcpt, srs_strerror(ret)); |
michael@676 | 302 | + return (-1); |
michael@676 | 303 | + case SRS_ERRTYPE_SYNTAX: |
michael@676 | 304 | + case SRS_ERRTYPE_SRS: |
michael@676 | 305 | + msg_warn("SRS reverse failed for <%s>: %s", rcpt, srs_strerror(ret)); |
michael@676 | 306 | + break; |
michael@676 | 307 | + } |
michael@676 | 308 | + return (0); |
michael@676 | 309 | + } |
michael@676 | 310 | + |
michael@676 | 311 | + if (decoded) { |
michael@676 | 312 | + *decoded = vstring_alloc(100); |
michael@676 | 313 | + vstring_strcpy(*decoded, out); |
michael@676 | 314 | + } |
michael@676 | 315 | + free(out); |
michael@676 | 316 | + |
michael@676 | 317 | + return (1); |
michael@676 | 318 | +} |
michael@676 | 319 | + |
michael@676 | 320 | +int postfix_srs_forward(const char *sender, const char *alias, VSTRING **encoded) { |
michael@676 | 321 | + char *out; |
michael@676 | 322 | + int ret; |
michael@676 | 323 | + |
michael@676 | 324 | + postfix_srs_init(); |
michael@676 | 325 | + |
michael@676 | 326 | + ret = srs_forward_alloc(srs, &out, sender, alias); |
michael@676 | 327 | + |
michael@676 | 328 | + if (ret != SRS_SUCCESS) { |
michael@676 | 329 | + msg_warn("SRS forward failed for <%s>: %s", sender, srs_strerror(ret)); |
michael@676 | 330 | + return (0); |
michael@676 | 331 | + } |
michael@676 | 332 | + |
michael@676 | 333 | + *encoded = vstring_alloc(100); |
michael@676 | 334 | + vstring_strcpy(*encoded, out); |
michael@676 | 335 | + free(out); |
michael@676 | 336 | + |
michael@676 | 337 | + return (1); |
michael@676 | 338 | +} |
michael@676 | 339 | + |
michael@676 | 340 | +#endif |
michael@676 | 341 | diff -urN src/qmgr/qmgr_deliver.c.orig src/qmgr/qmgr_deliver.c |
michael@676 | 342 | --- src/qmgr/qmgr_deliver.c.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 343 | +++ src/qmgr/qmgr_deliver.c 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 344 | @@ -76,6 +76,7 @@ |
michael@676 | 345 | #include <dsn_buf.h> |
michael@676 | 346 | #include <dsb_scan.h> |
michael@676 | 347 | #include <rcpt_print.h> |
michael@676 | 348 | +#include <resolve_clnt.h> |
michael@676 | 349 | |
michael@676 | 350 | /* Application-specific. */ |
michael@676 | 351 | |
michael@676 | 352 | @@ -129,6 +130,73 @@ |
michael@676 | 353 | } |
michael@676 | 354 | } |
michael@676 | 355 | |
michael@676 | 356 | +#ifdef HAS_SRS |
michael@676 | 357 | +/* qmgr_deliver_check_srs - check whether sender should be rewritten */ |
michael@676 | 358 | + |
michael@676 | 359 | +static int qmgr_deliver_check_srs(QMGR_MESSAGE *message, RECIPIENT_LIST list, char **alias, RESOLVE_REPLY *reply) |
michael@676 | 360 | +{ |
michael@676 | 361 | + char *pos; |
michael@676 | 362 | + |
michael@676 | 363 | + /* |
michael@676 | 364 | + * Rewrite if we are not final destination nor relay host for recipient and sender address |
michael@676 | 365 | + * it should be enough to look at the first recipient, since transport/nexthop are the same for all recipients |
michael@676 | 366 | + */ |
michael@676 | 367 | + resolve_clnt_query(list.info->address, reply); |
michael@676 | 368 | + if (reply->flags & RESOLVE_FLAG_FAIL) |
michael@676 | 369 | + return (-1); |
michael@676 | 370 | + else if (!(reply->flags & RESOLVE_CLASS_DEFAULT)) |
michael@676 | 371 | + return (0); |
michael@676 | 372 | + |
michael@676 | 373 | + resolve_clnt_query(message->sender, reply); |
michael@676 | 374 | + if (reply->flags & RESOLVE_FLAG_FAIL) |
michael@676 | 375 | + return (-1); |
michael@676 | 376 | + else if (!(reply->flags & RESOLVE_CLASS_DEFAULT)) |
michael@676 | 377 | + return (0); |
michael@676 | 378 | + |
michael@676 | 379 | + if (var_srs_domain[0]) { |
michael@676 | 380 | + *alias = var_srs_domain; |
michael@676 | 381 | + } else { |
michael@676 | 382 | + /* retrieve alias domain from original recipient if we are final destination ... */ |
michael@676 | 383 | + resolve_clnt_query(list.info->orig_addr, reply); |
michael@676 | 384 | + if (reply->flags & RESOLVE_FLAG_FAIL) |
michael@676 | 385 | + return (-1); |
michael@676 | 386 | + if ((reply->flags & RESOLVE_CLASS_FINAL) && (pos = strrchr(list.info->orig_addr, '@'))) { |
michael@676 | 387 | + *alias = pos + 1; |
michael@676 | 388 | + } else { |
michael@676 | 389 | + /* ... or use myorigin as fallback */ |
michael@676 | 390 | + *alias = var_myorigin; |
michael@676 | 391 | + } |
michael@676 | 392 | + } |
michael@676 | 393 | + |
michael@676 | 394 | + return (1); |
michael@676 | 395 | +} |
michael@676 | 396 | + |
michael@676 | 397 | +/* qmgr_deliver_do_srs - compute srs address if necessary */ |
michael@676 | 398 | + |
michael@676 | 399 | +static int qmgr_deliver_do_srs(QMGR_MESSAGE *message, RECIPIENT_LIST list, VSTRING **encoded) |
michael@676 | 400 | +{ |
michael@676 | 401 | + RESOLVE_REPLY reply; |
michael@676 | 402 | + char *alias; |
michael@676 | 403 | + int state; |
michael@676 | 404 | + |
michael@676 | 405 | + resolve_clnt_init(&reply); |
michael@676 | 406 | + state = qmgr_deliver_check_srs(message, list, &alias, &reply); |
michael@676 | 407 | + resolve_clnt_free(&reply); |
michael@676 | 408 | + if (state < 0) { |
michael@676 | 409 | + msg_warn("srs lookup problem"); |
michael@676 | 410 | + return (-1); |
michael@676 | 411 | + } else if (state == 0) { |
michael@676 | 412 | + return (0); |
michael@676 | 413 | + } |
michael@676 | 414 | + |
michael@676 | 415 | + state = postfix_srs_forward(message->sender, alias, encoded); |
michael@676 | 416 | + if (state < 0) |
michael@676 | 417 | + return (-1); |
michael@676 | 418 | + |
michael@676 | 419 | + return (1); |
michael@676 | 420 | +} |
michael@676 | 421 | +#endif |
michael@676 | 422 | + |
michael@676 | 423 | /* qmgr_deliver_send_request - send delivery request to delivery process */ |
michael@676 | 424 | |
michael@676 | 425 | static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) |
michael@676 | 426 | @@ -140,6 +208,9 @@ |
michael@676 | 427 | MSG_STATS stats; |
michael@676 | 428 | char *sender; |
michael@676 | 429 | int flags; |
michael@676 | 430 | +#ifdef HAS_SRS |
michael@676 | 431 | + int srs_state; |
michael@676 | 432 | +#endif |
michael@676 | 433 | |
michael@676 | 434 | /* |
michael@676 | 435 | * If variable envelope return path is requested, change prefix+@origin |
michael@676 | 436 | @@ -147,7 +218,19 @@ |
michael@676 | 437 | * recipient per delivery. |
michael@676 | 438 | */ |
michael@676 | 439 | if (message->verp_delims == 0) { |
michael@676 | 440 | - sender = message->sender; |
michael@676 | 441 | +#ifdef HAS_SRS |
michael@676 | 442 | + srs_state = qmgr_deliver_do_srs(message, list, &sender_buf); |
michael@676 | 443 | + if (srs_state < 0) { |
michael@676 | 444 | + return (-1); |
michael@676 | 445 | + } else if (srs_state == 1) { |
michael@676 | 446 | + sender = vstring_str(sender_buf); |
michael@676 | 447 | + msg_info("%s: srs_from=<%s>", message->queue_id, sender); |
michael@676 | 448 | + } else { |
michael@676 | 449 | + sender = message->sender; |
michael@676 | 450 | + } |
michael@676 | 451 | +#else |
michael@676 | 452 | + sender = message->sender; |
michael@676 | 453 | +#endif |
michael@676 | 454 | } else { |
michael@676 | 455 | sender_buf = vstring_alloc(100); |
michael@676 | 456 | verp_sender(sender_buf, message->verp_delims, |
michael@676 | 457 | diff -urN src/smtpd/smtpd_check.c.orig src/smtpd/smtpd_check.c |
michael@676 | 458 | --- src/smtpd/smtpd_check.c.orig 2012-02-21 14:21:34.000000000 +0100 |
michael@676 | 459 | +++ src/smtpd/smtpd_check.c 2012-02-21 14:22:05.000000000 +0100 |
michael@676 | 460 | @@ -929,6 +929,19 @@ |
michael@676 | 461 | reject_server_error(state); |
michael@676 | 462 | } |
michael@676 | 463 | |
michael@676 | 464 | +#ifdef HAS_SRS |
michael@676 | 465 | +/* check_mail_addr_srs - check if address is a valid srs address */ |
michael@676 | 466 | + |
michael@676 | 467 | +static int check_mail_addr_srs(SMTPD_STATE *state, const char *reply_name, const char *addr) |
michael@676 | 468 | +{ |
michael@676 | 469 | + int result; |
michael@676 | 470 | + |
michael@676 | 471 | + if ((result = postfix_srs_reverse(addr, 0)) < 0) |
michael@676 | 472 | + reject_dict_retry(state, reply_name); |
michael@676 | 473 | + return (result); |
michael@676 | 474 | +} |
michael@676 | 475 | +#endif |
michael@676 | 476 | + |
michael@676 | 477 | /* reject_unknown_reverse_name - fail if reverse client hostname is unknown */ |
michael@676 | 478 | |
michael@676 | 479 | static int reject_unknown_reverse_name(SMTPD_STATE *state) |
michael@676 | 480 | @@ -4552,6 +4565,13 @@ |
michael@676 | 481 | || MATCH(canonical_maps, CONST_STR(reply->recipient)) |
michael@676 | 482 | || MATCH(virt_alias_maps, CONST_STR(reply->recipient))) |
michael@676 | 483 | return (0); |
michael@676 | 484 | + |
michael@676 | 485 | +#ifdef HAS_SRS |
michael@676 | 486 | + /* allow valid srs address */ |
michael@676 | 487 | + if ((reply->flags & RESOLVE_CLASS_FINAL) |
michael@676 | 488 | + && check_mail_addr_srs(state, recipient, CONST_STR(reply->recipient)) == 1) |
michael@676 | 489 | + return (0); |
michael@676 | 490 | +#endif |
michael@676 | 491 | |
michael@676 | 492 | /* |
michael@676 | 493 | * At this point, anything that resolves to the error mailer is known to |