Integrate useful recipient and helo access maps, and introduce SRS logic.

Thu, 13 Sep 2012 20:05:49 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 13 Sep 2012 20:05:49 +0200
changeset 676
7a7cc794483b
parent 675
43d642154330
child 677
bbdbd736796e

Integrate useful recipient and helo access maps, and introduce SRS logic.

postfix/postfix-srs.patch file | annotate | diff | comparison | revisions
postfix/postfix.spec file | annotate | diff | comparison | revisions
postfix/postfix.txt file | annotate | diff | comparison | revisions
     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>

mercurial