postfix/postfix-srs.patch

Thu, 04 Oct 2012 20:30:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Oct 2012 20:30:05 +0200
changeset 715
c10fb90893b9
permissions
-rw-r--r--

Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.

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

mercurial