diff -Nur postfix-2.1.4.orig/README_FILES/SRS_README postfix-2.1.4/README_FILES/SRS_README --- postfix-2.1.4.orig/README_FILES/SRS_README 1970-01-01 01:00:00.000000000 +0100 +++ postfix-2.1.4/README_FILES/SRS_README 2004-07-08 19:41:31.000000000 +0200 @@ -0,0 +1,50 @@ + +CREDITS: + +- originally written by Shevek +- fixes and porting to postfix 2.1 by Branko F. Gracnar + + + + +USAGE: + +1) Apply the patch. + +2) Create makefiles with + +make makefiles CCARGS="-DHAS_SRS -I" AUXLIBS="-L -lsrs2" + + +3) Build. + +4) Add the following global configuration variables to main.cf: +All variables are optional, except where stated: + + srs_alwaysrewrite (bool) + If true, perform SRS rewriting for ALL forwarding, + even when not required. + srs_domain (string) + A domain to use in rewritten addresses. This must point only + to machines which know the encoding secret used by this + system. It defaults to [something sensible]. + srs_hashlength (int) + The hash length to generate in a rewritten address. + srs_hashmin (int) + The hash length to require when checking an address. + srs_maxage (int) + The maximum permitted age of a rewritten address. + srs_secrets (string) + [required] A list of secrets with which to generate + and check addresses. + srs_separator (string) + The separator to appear immediately after SRS[01] in + rewritten addresses. + + +See http://www.libsrs2.org/ for more information about the meaning +of these variables. They are standard across MTAs. + +5) Fire up and enjoy. + + diff -Nur postfix-2.1.4.orig/src/global/mail_params.h postfix-2.1.4/src/global/mail_params.h --- postfix-2.1.4.orig/src/global/mail_params.h 2004-04-21 20:56:04.000000000 +0200 +++ postfix-2.1.4/src/global/mail_params.h 2004-07-08 18:32:04.000000000 +0200 @@ -1901,6 +1901,37 @@ #define DEF_STRICT_ENCODING 0 extern bool var_strict_encoding; +/** + * SRS. Shevek + */ +#define VAR_SRS_ALWAYSREWRITE "srs_alwaysrewrite" +#define DEF_SRS_ALWAYSREWRITE 0 +extern bool var_srs_alwaysrewrite; + +#define VAR_SRS_HASHLENGTH "srs_hashlength" +#define DEF_SRS_HASHLENGTH 0 +extern int var_srs_hashlength; + +#define VAR_SRS_HASHMIN "srs_hashmin" +#define DEF_SRS_HASHMIN 0 +extern int var_srs_hashmin; + +#define VAR_SRS_MAXAGE "srs_maxage" +#define DEF_SRS_MAXAGE 0 +extern int var_srs_maxage; + +#define VAR_SRS_SECRETS "srs_secrets" +#define DEF_SRS_SECRETS 0 +extern char *var_srs_secrets; + +#define VAR_SRS_DOMAIN "srs_domain" +#define DEF_SRS_DOMAIN "$myhostname" +extern char *var_srs_domain; + +#define VAR_SRS_SEPARATOR "srs_separator" +#define DEF_SRS_SEPARATOR 0 +extern char *var_srs_separator; + /* * Bizarre. */ diff -Nur postfix-2.1.4.orig/src/local/Makefile.in postfix-2.1.4/src/local/Makefile.in --- postfix-2.1.4.orig/src/local/Makefile.in 2004-04-22 21:37:40.000000000 +0200 +++ postfix-2.1.4/src/local/Makefile.in 2004-07-08 19:22:29.000000000 +0200 @@ -2,11 +2,13 @@ SRCS = alias.c command.c delivered.c dotforward.c file.c forward.c \ include.c indirect.c local.c mailbox.c recipient.c resolve.c token.c \ deliver_attr.c maildir.c biff_notify.c unknown.c \ - local_expand.c + local_expand.c srs.c + OBJS = alias.o command.o delivered.o dotforward.o file.o forward.o \ include.o indirect.o local.o mailbox.o recipient.o resolve.o token.o \ deliver_attr.o maildir.o biff_notify.o unknown.o \ - local_expand.o + local_expand.o srs.o + HDRS = local.h TESTSRC = DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) diff -Nur postfix-2.1.4.orig/src/local/indirect.c postfix-2.1.4/src/local/indirect.c --- postfix-2.1.4.orig/src/local/indirect.c 2002-11-17 00:44:57.000000000 +0100 +++ postfix-2.1.4/src/local/indirect.c 2004-07-08 19:23:41.000000000 +0200 @@ -79,6 +79,11 @@ SENT_ATTR(state.msg_attr), "forwards to %s", state.msg_attr.recipient)); +#ifdef HAS_SRS + /* Rewrite the sender address according to SRS. */ + postfix_srs_forward(&state); +#endif + /* * Send the address to the forwarding service. Inherit the delivered * attribute from the alias or from the .forward file owner. diff -Nur postfix-2.1.4.orig/src/local/local.c postfix-2.1.4/src/local/local.c --- postfix-2.1.4.orig/src/local/local.c 2004-04-11 22:03:08.000000000 +0200 +++ postfix-2.1.4/src/local/local.c 2004-07-08 18:37:40.000000000 +0200 @@ -523,6 +523,15 @@ char *var_mailbox_lock; int var_mailbox_limit; +/* SRS */ +bool var_srs_alwaysrewrite; /* Always perform SRS rewriting */ +int var_srs_hashlength; /* Hash length to generate */ +int var_srs_hashmin; /* Hash length to check */ +int var_srs_maxage; /* Max age of an SRS address */ +char *var_srs_secrets; /* Secret keys. Ssssssh! */ +char *var_srs_separator; /* Initial separator. */ +char *var_srs_domain; /* SRS local domain */ + int local_cmd_deliver_mask; int local_file_deliver_mask; int local_ext_prop_mask; @@ -734,6 +743,9 @@ }; static CONFIG_INT_TABLE int_table[] = { VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0, + VAR_SRS_HASHLENGTH, DEF_SRS_HASHLENGTH, &var_srs_hashlength, 1, 20, + VAR_SRS_HASHMIN, DEF_SRS_HASHMIN, &var_srs_hashmin, 0, 20, + VAR_SRS_MAXAGE, DEF_SRS_MAXAGE, &var_srs_maxage, 0, 0, VAR_MAILBOX_LIMIT, DEF_MAILBOX_LIMIT, &var_mailbox_limit, 0, 0, 0, }; @@ -751,6 +763,9 @@ VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, VAR_DELIVER_HDR, DEF_DELIVER_HDR, &var_deliver_hdr, 0, 0, VAR_MAILBOX_LOCK, DEF_MAILBOX_LOCK, &var_mailbox_lock, 1, 0, + VAR_SRS_SECRETS, DEF_SRS_SECRETS, &var_srs_secrets, 1, 0, + VAR_SRS_SEPARATOR, DEF_SRS_SEPARATOR, &var_srs_separator, 1, 1, + VAR_SRS_DOMAIN, DEF_SRS_DOMAIN, &var_srs_domain, 1, 0, 0, }; static CONFIG_BOOL_TABLE bool_table[] = { @@ -758,6 +773,7 @@ VAR_EXP_OWN_ALIAS, DEF_EXP_OWN_ALIAS, &var_exp_own_alias, VAR_STAT_HOME_DIR, DEF_STAT_HOME_DIR, &var_stat_home_dir, VAR_MAILTOOL_COMPAT, DEF_MAILTOOL_COMPAT, &var_mailtool_compat, + VAR_SRS_ALWAYSREWRITE, DEF_SRS_ALWAYSREWRITE, &var_srs_alwaysrewrite, 0, }; diff -Nur postfix-2.1.4.orig/src/local/recipient.c postfix-2.1.4/src/local/recipient.c --- postfix-2.1.4.orig/src/local/recipient.c 2002-12-09 20:11:25.000000000 +0100 +++ postfix-2.1.4/src/local/recipient.c 2004-07-08 19:23:06.000000000 +0200 @@ -111,6 +111,16 @@ if (msg_verbose) MSG_LOG_STATE(myname, state); +#ifdef HAS_SRS + /* SRS */ + if (strncasecmp(state.msg_attr.recipient, "SRS", 3) == 0) { + status = postfix_srs_reverse(state, usr_attr); + /* SRS might return 1 if it thinks it was called in error. */ + if (status <= 0) + return (status); + } +#endif + /* * \user is special: it means don't do any alias or forward expansion. diff -Nur postfix-2.1.4.orig/src/local/srs.c postfix-2.1.4/src/local/srs.c --- postfix-2.1.4.orig/src/local/srs.c 1970-01-01 01:00:00.000000000 +0100 +++ postfix-2.1.4/src/local/srs.c 2004-07-08 19:34:23.000000000 +0200 @@ -0,0 +1,178 @@ +/*++ +/* NAME +/* srs 3 +/* SUMMARY +/* Sender Rewriting Scheme +/* SYNOPSIS +/* #include "local.h" +/* +/* void postfix_srs_reverse(state, usr_attr) +/* LOCAL_STATE state; +/* USER_ATTR usr_attr +/* +/* int postfix_srs_forward(state) +/* LOCAL_STATE *state; +/* DESCRIPTION +/* This module rewrites addresses according to the Sender Rewriting +/* Scheme, documented at http://www.libsrs2.org/. +/* +/* srs_reverse() reverse-rewrites the rewritten +/* form of an address and resubmits for delivery. +/* +/* srs_forward() rewrites the msg_attr.sender field of the +/* given state so that it may be submitted to the forwarding +/* service. +/* +/* DIAGNOSTICS +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Shevek +/*--*/ + +#ifdef HAS_SRS + +/* System library. */ + +#include +#include + +#ifdef STRCASECMP_IN_STRINGS_H +#include +#endif + +#include + +/* Utility library. */ + +#include +#include +#include +#include +#include +#include + +/* Global library. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Application-specific. */ + +#include "local.h" + +#define SRS_FAIL_UNLESS(x) do { int __ret = (x); if (__ret != SRS_SUCCESS) msg_fatal("SRS configuration error: %s", srs_strerror(__ret)); } while(0) + +/* my function declarations */ +int postfix_srs_forward (LOCAL_STATE *state); +int postfix_srs_reverse (LOCAL_STATE state, USER_ATTR usr_attr); + +static srs_t *srs; + +static void postfix_srs_init (void) { + char *saved_secrets; + char *secret; + char *ptr; + + if (srs == NULL) { + /** The following couses postfix local(8) to segfault (try to free null pointer) */ + /** + srs_set_malloc((srs_malloc_t)mymalloc, (srs_realloc_t)myrealloc, (srs_free_t)myfree); + */ + + srs = srs_new(); + srs_set_alwaysrewrite(srs, var_srs_alwaysrewrite); + + if (var_srs_hashlength > 0) + SRS_FAIL_UNLESS(srs_set_hashlength(srs,var_srs_hashlength)); + if (var_srs_hashmin > 0) + SRS_FAIL_UNLESS(srs_set_hashmin(srs, var_srs_hashmin)); + if (var_srs_maxage > 0) + SRS_FAIL_UNLESS(srs_set_maxage(srs, var_srs_maxage)); + if (var_srs_separator != NULL) + SRS_FAIL_UNLESS(srs_set_separator(srs,var_srs_separator[0])); + + if (var_srs_secrets) { + ptr = saved_secrets = mystrdup(var_srs_secrets); + + while ((secret = mystrtok(&ptr, ", \t\r\n")) != 0) + SRS_FAIL_UNLESS(srs_add_secret(srs, secret)); + + myfree(saved_secrets); + } + } +} + +/* Called from recipient.c */ +int postfix_srs_reverse(LOCAL_STATE state, USER_ATTR usr_attr) { + char *out; + int ret; + TOK822 *addr; + int status; + + if (!SRS_IS_SRS_ADDRESS(state.msg_attr.recipient)) + return 1; + + postfix_srs_init(); + + ret = srs_reverse_alloc(srs, &out, state.msg_attr.recipient); + + if (ret != SRS_SUCCESS) { + switch (SRS_ERROR_TYPE(ret)) { + case SRS_ERRTYPE_CONFIG: + msg_fatal("SRS configuration error: %s", srs_strerror(ret)); + case SRS_ERRTYPE_INPUT: + msg_fatal("SRS input error: %s", srs_strerror(ret)); + case SRS_ERRTYPE_SYNTAX: + msg_warn("SRS syntax error: %s", srs_strerror(ret)); + return 1; /* Might not be SRS */ + case SRS_ERRTYPE_SRS: + msg_warn("SRS semantic error: %s", srs_strerror(ret)); + /* Bin the mail, with prejudice. */ + return DEL_STAT_FINAL; + } + + return DEL_STAT_DEFER; + } + + addr = tok822_scan_addr(out); + myfree(out); + status = deliver_resolve_tree(state, usr_attr, addr); + tok822_free_tree(addr); + + return (status); +} + +/* Called from [resolve.c ->] indirect.c [->forward.c] */ +int postfix_srs_forward(LOCAL_STATE *state) { + const char *sender; + char *out; + int ret; + + postfix_srs_init(); + + sender = state->msg_attr.sender; + ret = srs_forward_alloc(srs, &out, sender, var_srs_domain); + + if (ret != SRS_SUCCESS) { + msg_warn("SRS forward failed (%s, %s): %s\n", sender, var_srs_domain, srs_strerror(ret)); + return DEL_STAT_DEFER; + } + + /* XXX We leak this RAM later. */ + state->msg_attr.sender = out; + + return DEL_STAT_FINAL; +} + +#endif + +