Nigel Kukard wrote:
Hi,

are blacklist_dnsname and whitelist_dnsname being developed for policyd v2 ? Im migrating from v1 and i'm really missing it ....

Trivial to add, will commit shortly and update this thread with a patch.

The attached should apply to trunk (might apply to 2.0.4) and implements matching on reverse dns.

Here is the info snippet for the policy section on the website...
***
<p><div class="section">whatever.example.com</div>
This will match the reverse dns of the IP where the client is connecting from.
<ul>
<li>You can use * as a wildcard match against anything except the ., for example hello.*.example.com . You can use * as much as you like.</li>
        <li>Specifying example.com will only match example.com</li>
<li>Specifying .example.com will match anything.example.com and fu.bar.example.com</li>
</ul>
As a technical note, * is expanded into [a-z0-9\-_\.] and if . doesn't prefix the specification it gets ^. All reverse dns specifications are matched with end of line $ at the end.
</p>
***

If you can test it and confirm everything works as expected (I did test myself), I'll backport to 2.0.5, update the site and release 2.0.5.


Regards
Nigel
Index: cbp/policies.pm
===================================================================
--- cbp/policies.pm	(revision 297)
+++ cbp/policies.pm	(revision 300)
@@ -36,7 +36,9 @@
 use cbp::dblayer;
 use cbp::system;
 
+use Data::Dumper;
 
+
 # Database handle
 my $dbh = undef;
 
@@ -75,10 +77,12 @@
 # 	Hash - indexed by policy priority, the value is an array of policy ID's
 sub getPolicy
 {
-    my ($server,$sourceIP,$emailFrom,$emailTo,$saslUsername) = @_;
+	my ($server,$sessionData) = @_;
 	my $log = defined($server->{'config'}{'logging'}{'policies'});
 
 
+	$server->log(LOG_DEBUG,"[POLICIES] Going to resolve session data into policy: ".Dumper($sessionData)) if ($log);
+
 	# Start with blank policy list
 	my %matchedPolicies = ();
 
@@ -139,7 +143,7 @@
 			my $history = {};  # Used to track depth & loops
 			foreach my $item (@rawSources) {
 				# Process item
-				my $res = policySourceItemMatches($server,$debugTxt,$history,$item,$sourceIP,$emailFrom,$saslUsername);
+				my $res = policySourceItemMatches($server,$debugTxt,$history,$item,$sessionData);
 				# Check for error
 				if ($res < 0) {
 					$server->log(LOG_WARN,"[POLICIES] $debugTxt: Error while processing source item '$item', skipping...");
@@ -180,7 +184,7 @@
 			my $history = {};  # Used to track depth & loops
 			foreach my $item (@rawDestinations) {
 				# Process item
-				my $res = policyDestinationItemMatches($server,$debugTxt,{},$item,$emailTo);
+				my $res = policyDestinationItemMatches($server,$debugTxt,$history,$item,$sessionData);
 				# Check for error
 				if ($res < 0) {
 					$server->log(LOG_WARN,"[POLICIES] $debugTxt: Error while processing destination item '$item', skipping...");
@@ -255,7 +259,7 @@
 # Check if this source item matches, this function automagically resolves groups aswell
 sub policySourceItemMatches
 {
-	my ($server,$debugTxt,$history,$rawItem,$sourceIP,$emailFrom,$saslUsername) = @_;
+	my ($server,$debugTxt,$history,$rawItem,$sessionData) = @_;
 	my $log = defined($server->{'config'}{'logging'}{'policies'});
 
 
@@ -292,7 +296,7 @@
 		if (@{$groupMembers} > 0) {
 			foreach my $gmember (@{$groupMembers}) {
 				# Process this group member
-				my $res = policySourceItemMatches($server,"$debugTxt=>(group:$item)",$history,$gmember,$sourceIP,$emailFrom,$saslUsername);
+				my $res = policySourceItemMatches($server,"$debugTxt=>(group:$item)",$history,$gmember,$sessionData);
 				# Check for hard error
 				if ($res < 0) {
 					return $res;
@@ -313,19 +317,24 @@
 
 		# Match IP
 		if ($item =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{1,2})$/) {
-			$res = ipMatches($sourceIP,$item);
+			$res = ipMatches($sessionData->{'ClientAddress'},$item);
 			$server->log(LOG_DEBUG,"[POLICIES] $debugTxt: - Resolved source '$item' to a IP/CIDR specification, match = $res") if ($log);
 
 		# Match SASL user, must be above email addy to match SASL usernames in the same format as email addies
 		} elsif ($item =~ /^\$\S+$/) {
-			$res = saslUsernameMatches($saslUsername,$item);
+			$res = saslUsernameMatches($sessionData->{'SASLUsername'},$item);
 			$server->log(LOG_DEBUG,"[POLICIES] $debugTxt: - Resolved source '$item' to a SASL user specification, match = $res") if ($log);
 
 		# Match email addy
 		} elsif ($item =~ /[EMAIL PROTECTED]/) {
-			$res = emailAddressMatches($emailFrom,$item);
+			$res = emailAddressMatches($sessionData->{'Sender'},$item);
 			$server->log(LOG_DEBUG,"[POLICIES] $debugTxt: - Resolved source '$item' to a email address specification, match = $res") if ($log);
 
+		# Match domain name (for reverse dns)
+		} elsif ($item =~ /^(?:[a-z0-9\-_\*]+\.)+[a-z0-9]+$/i) {
+			$res = reverseDNSMatches($sessionData->{'ClientReverseName'},$item);
+			$server->log(LOG_DEBUG,"[POLICIES] $debugTxt: - Resolved source '$item' to a reverse dns specification, match = $res") if ($log);
+
 		# Not valid
 		} else {
 			$server->log(LOG_WARN,"[POLICIES] $debugTxt: - Source '".$item."' is not a valid specification");
@@ -344,7 +353,7 @@
 # Check if this destination item matches, this function automagically resolves groups aswell
 sub policyDestinationItemMatches
 {
-	my ($server,$debugTxt,$history,$rawItem,$emailTo) = @_;
+	my ($server,$debugTxt,$history,$rawItem,$sessionData) = @_;
 	my $log = defined($server->{'config'}{'logging'}{'policies'});
 
 
@@ -381,7 +390,7 @@
 		if (@{$groupMembers} > 0) {
 			foreach my $gmember (@{$groupMembers}) {
 				# Process this group member
-				my $res = policyDestinationItemMatches($server,"$debugTxt=>(group:$item)",$history,$gmember,$emailTo);
+				my $res = policyDestinationItemMatches($server,"$debugTxt=>(group:$item)",$history,$gmember,$sessionData);
 				# Check for hard error
 				if ($res < 0) {
 					return $res;
@@ -402,7 +411,7 @@
 
 		# Match email addy
 		if ($item =~ /[EMAIL PROTECTED]/) {
-			$res = emailAddressMatches($emailTo,$item);
+			$res = emailAddressMatches($sessionData->{'Recipient'},$item);
 			$server->log(LOG_DEBUG,"[POLICIES] $debugTxt: - Resolved destination '$item' to a email address specification, match = $res") if ($log);
 
 		} else {
@@ -496,6 +505,40 @@
 }
 
 
+# Check if first arg lies within the scope of second arg reverse dns specification
+sub reverseDNSMatches
+{
+	my ($reverseDNSMatches,$template) = @_;
+
+	my $match = 0;
+	my $partial = 0;
+
+	# Check if we have a . at the beginning of the line to match partials
+	if ($template =~ /^\./) {
+		$partial = 1;
+	}
+
+	# Replace all .'s with \.'s
+	$template =~ s/\./\\./g;
+	# Change *'s into a proper regex expression
+	$template =~ s/\*/[a-z0-9\-_\.]*/g;
+
+	# Check for partial match
+	if ($partial) {
+		if ($reverseDNSMatches =~ /$template$/i) {
+			$match = 1;
+		}
+	# Check for exact match
+	} else {
+		if ($reverseDNSMatches =~ /^$template$/i) {
+			$match = 1;
+		}
+	}
+	
+	return $match;
+}
+
+
 # Encode policy data into session recipient data
 sub encodePolicyData
 {
Index: cbp/tracking.pm
===================================================================
--- cbp/tracking.pm	(revision 297)
+++ cbp/tracking.pm	(revision 300)
@@ -214,8 +214,10 @@
 		if ($request->{'protocol_state'} eq 'RCPT') {
 			$server->log(LOG_DEBUG,"[TRACKING] Protocol state is 'RCPT', resolving policy...") if ($log);
 
+			$sessionData->{'Recipient'} = $request->{'recipient'};
+
 			# Get policy
-			my $policy = getPolicy($server,$request->{'client_address'},$request->{'sender'},$request->{'recipient'},$request->{'sasl_username'});
+			my $policy = getPolicy($server,$sessionData);
 			if (ref $policy ne "HASH") {
 				return -1;
 			}
@@ -223,7 +225,6 @@
 			$server->log(LOG_DEBUG,"[TRACKING] Policy resolved into: ".Dumper($policy)) if ($log);
 	
 			$sessionData->{'Policy'} = $policy;
-			$sessionData->{'Recipient'} = $request->{'recipient'};
 	
 		# If we in end of message, load policy from data
 		} elsif ($request->{'protocol_state'} eq 'END-OF-MESSAGE') {
@@ -244,6 +245,7 @@
 	# Check for HTTP protocol transport
 	} elsif ($request->{'_protocol_transport'} eq "HTTP") {
 		$sessionData->{'ClientAddress'} = $request->{'client_address'};
+		$sessionData->{'ClientReverseName'} = $request->{'client_reverse_name'} if (defined($request->{'client_reverse_name'}));
 		$sessionData->{'Helo'} = $request->{'helo_name'} if (defined($request->{'helo_name'}));
 		$sessionData->{'Sender'} = $request->{'sender'};
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Users mailing list
[email protected]
http://lists.policyd.org/mailman/listinfo/users

Reply via email to