changeset 429:5593964ec779

Added route conditions based on the From header New route config directives: allowed_from_hdrs, denied_from_hdrs. This feature was motivated by Philipp Takacs <philipp29@t-online.de>.
author markus schnalke <meillo@marmaro.de>
date Thu, 20 Nov 2014 20:36:20 +0100
parents e972c3cbe1e0
children 180a7f6a9383
files man/masqmail.route.5 src/conf.c src/deliver.c src/masqmail.h src/route.c
diffstat 5 files changed, 71 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/man/masqmail.route.5	Wed Apr 03 21:45:57 2013 +0200
+++ b/man/masqmail.route.5	Thu Nov 20 20:36:20 2014 +0100
@@ -78,6 +78,36 @@
 (See also examples for \fIallowed_senders\fP)
 
 .TP
+\fBallowed_from_hdrs\fR = \fIlist\fR
+
+This is a semicolon `;' separated list of From header addresses.
+Messages which have one of these addresses as the From header
+are allowed to use this route
+(if not also in \fBdenied_from_hdrs\fR).
+
+Glob patterns containing `?' and `*' can be used.
+If the pattern doesn't contain an `@', it is seen as a pattern for the
+local part only.
+
+Example: \fImeillo;*@*example.org;web*@example.com\fP
+
+(``meillo'' equals ``meillo@*'', i.e. the local part.)
+
+.TP
+\fBdenied_from_hdrs\fR = \fIlist\fR
+
+This is a semicolon `;' separated list of From header addresses.
+Messages which have one of these addresses as the From header
+will not be sent using this route (even if also in
+\fBallowed_from_hdrs\fR).
+
+Glob patterns containing `?' and `*' can be used.
+If the pattern doesn't contain an `@', it is seen as a pattern for the
+local part only.
+
+Example: (see \fIallowed_from_hdrs\fP)
+
+.TP
 \fBlast_route\fR = \fIboolean\fR
 
 If this is set, a mail which would have been delivered using this route,
--- a/src/conf.c	Wed Apr 03 21:45:57 2013 +0200
+++ b/src/conf.c	Thu Nov 20 20:36:20 2014 +0100
@@ -624,6 +624,10 @@
 			route->allowed_recipients = parse_address_glob_list(rval);
 		} else if (strcmp(lval, "denied_recipients")==0) {
 			route->denied_recipients = parse_address_glob_list(rval);
+		} else if (strcmp(lval, "allowed_from_hdrs")==0) {
+			route->allowed_from_hdrs = parse_address_glob_list(rval);
+		} else if (strcmp(lval, "denied_from_hdrs")==0) {
+			route->denied_from_hdrs = parse_address_glob_list(rval);
 
 		} else if (strcmp(lval, "set_h_from_domain")==0) {
 			route->set_h_from_domain = g_strdup(rval);
--- a/src/deliver.c	Wed Apr 03 21:45:57 2013 +0200
+++ b/src/deliver.c	Thu Nov 20 20:36:20 2014 +0100
@@ -667,6 +667,21 @@
 			continue;
 		}
 
+		/* filter by allowed from header */
+		GList *from_hdrs = NULL;
+		char *from_hdr = NULL;
+		from_hdrs = find_header(msgout->msg->hdr_list, HEAD_FROM,
+				 NULL);
+		if (from_hdrs) {
+			from_hdr = (char *) ((header *)from_hdrs->data)->value;
+			if (!route_from_hdr_is_allowed(route, from_hdr)){
+				DEBUG(6) debugf("from hdr `%s' is not allowed for this "
+						"route\n", from_hdr);
+				destroy_msg_out(msgout_cloned);
+				continue;
+			}
+		}
+
 		logwrite(LOG_NOTICE, "%s using '%s'\n", msgout->msg->uid,
 				route->name);
 
--- a/src/masqmail.h	Wed Apr 03 21:45:57 2013 +0200
+++ b/src/masqmail.h	Thu Nov 20 20:36:20 2014 +0100
@@ -85,6 +85,8 @@
 	GList *denied_senders;
 	GList *allowed_recipients;
 	GList *denied_recipients;
+	GList *allowed_from_hdrs;
+	GList *denied_from_hdrs;
 
 	interface *mail_host;
 	gboolean connect_error_fail;
--- a/src/route.c	Wed Apr 03 21:45:57 2013 +0200
+++ b/src/route.c	Thu Nov 20 20:36:20 2014 +0100
@@ -344,6 +344,26 @@
 	g_list_free(tmp_list);
 }
 
+gboolean
+route_from_hdr_is_allowed(connect_route *route, char *from_hdr)
+{
+	address *addr = create_address_qualified(from_hdr, FALSE,
+			conf.host_name);
+	if (route->denied_from_hdrs && g_list_find_custom(route->denied_from_hdrs, addr, _g_list_addrcmp)) {
+		return FALSE;
+	}
+	if (route->allowed_from_hdrs) {
+		if (g_list_find_custom(route->allowed_from_hdrs, addr,
+				_g_list_addrcmp)) {
+			return TRUE;
+		} else {
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+
 msg_out*
 route_prepare_msgout(connect_route *route, msg_out *msgout)
 {