mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-07-31 12:29 am

[perlbal] Add ability for AccessControl plugin to test against request headers.

[commit: http://hg.dwscoalition.org/perlbal/rev/3d1f0209a8c6]

Add ability for AccessControl plugin to test against request headers.

Patch by [staff profile] mark.

Files modified:
  • lib/Perlbal/Plugin/AccessControl.pm
--------------------------------------------------------------------------------
diff -r 0b0a1bcf00c0 -r 3d1f0209a8c6 lib/Perlbal/Plugin/AccessControl.pm
--- a/lib/Perlbal/Plugin/AccessControl.pm	Thu Jul 30 18:27:28 2009 +0000
+++ b/lib/Perlbal/Plugin/AccessControl.pm	Fri Jul 31 00:29:17 2009 +0000
@@ -11,15 +11,17 @@ no  warnings qw(deprecated);
 #     ACCESS POLICY {ALLOW,DENY}
 #
 # adding things to the rule chain.  processing stops once any rule is matched.
-#
 #     ACCESS {ALLOW,DENY} netmask 127.0.0.1/8
 #     ACCESS {ALLOW,DENY} ip 127.0.0.1
+#     ACCESS {ALLOW,DENY} header:User-Agent regex          ## can use any header name
+#     ACCESS {ALLOW,DENY} header:Host regex                ## regex must be valid
+#
 # also can make a match set the request to go into the low-priority perlbal queue:
 #     ACCESS QUEUE_LOW ip 127.0.0.1
-
+#
 # reset the rule chain and policy:  (policy is allow by default)
 #     ACCESS RESET
-
+#
 # Future:
 #  access {allow,deny} forwarded_ip 127.0.0.1
 #  access {allow,deny} method <method>[,<method>]*
@@ -32,10 +34,15 @@ sub load {
         my $mc = shift->parse(qr/^access\s+
                               (policy|allow|deny|reset|queue_low)      # cmd
                               (?:\s+(\S+))?                  # arg1
-                              (?:\s+(\S+))?                  # optional arg2
+                              (?:\s+(.+))?                   # optional arg2
                               $/x,
                               "usage: ACCESS <cmd> <arg1> [<arg2>]");
         my ($cmd, $arg1, $arg2) = $mc->args;
+
+        if ( $arg2 ) {
+            $arg2 =~ s/^\s+//;
+            $arg2 =~ s/\s+$//;
+        }
 
         my $svcname;
         unless ($svcname ||= $mc->{ctx}{last_created}) {
@@ -62,7 +69,7 @@ sub load {
         if ($cmd eq "allow" || $cmd eq "deny" || $cmd eq "queue_low") {
             my ($what, $val) = ($arg1, $arg2);
             return $mc->err("Unknown item to $cmd: '$what'") unless
-                $what && ($what eq "ip" || $what eq "netmask");
+                $what && ($what eq "ip" || $what eq "netmask" || $what =~ /^header:\S+$/);
 
             if ($what eq "netmask") {
                 return $mc->err("Net::Netmask not installed")
@@ -70,6 +77,14 @@ sub load {
 
                 $val = eval { Net::Netmask->new2($val) };
                 return $mc->err("Error parsing netmask") unless $val;
+            }
+
+            # compile the regular expression if we know it's going to be one
+            if ( $what =~ /^header:(\S+)$/ ) {
+                $val = qr/$val/i;
+                return $mc->err( "Invalid regular expression for $what" ) unless $val;
+
+                $what = $1;
             }
 
             my $rules = $cfg->{rules} ||= [];
@@ -141,6 +156,12 @@ sub register {
 
                 return eval { $rule->[2]->match($peer_ip); };
             }
+
+            # if we get here, we assume that 'what' is a header type object, and we
+            # can try to do a header match.
+            if ( my $val = $hds->header( $rule->[1] ) ) {
+                return $val =~ /$rule->[2]/;
+            }
         };
 
         my $cfg = $svc->{extra_config}->{_access} ||= {};
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org