aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-07-29 20:07:44 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2014-07-29 20:07:44 +0300
commitb73431421025660d28198955c15356c086f5223f (patch)
tree8115c2a20986b61fac58dd0d3fc302c896262fee
parentd745c522f462e01aa576c6f93b94cbad6c631f73 (diff)
downloadgitaclhook-b73431421025660d28198955c15356c086f5223f.tar.gz
gitaclhook-b73431421025660d28198955c15356c086f5223f.tar.bz2
Separate rules for the same user name coming from different IP addresses.
* Makefile.PL: Add Net::CIDR to the list of prerequisites. * gitaclhook: Document user@CIDRLIST syntax and the hooks.acl.ip-env-var variable. * lib/GitACL.pm: Use Net::CIDR (match_host): New sub. (match_user): Check IP against cidr part (if defined). (new): Get remote IP address from environment.
-rw-r--r--Makefile.PL3
-rwxr-xr-xgitaclhook36
-rw-r--r--lib/GitACL.pm18
3 files changed, 47 insertions, 10 deletions
diff --git a/Makefile.PL b/Makefile.PL
index db3859d..3f18606 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -32,3 +32,4 @@ WriteMakefile(
'PREREQ_PM' => { 'Getopt::Long' => 2.34,
- 'File::Spec' => 3.39 }
+ 'File::Spec' => 3.39,
+ 'Net::CIDR' => 0.17 }
);
diff --git a/gitaclhook b/gitaclhook
index b88adf3..ed6c390 100755
--- a/gitaclhook
+++ b/gitaclhook
@@ -88,3 +88,3 @@ An asterisk matches any project name.
-=item I<USER>
+=item I<USER>[B<@>I<CIDRLIST>]
@@ -96,2 +96,11 @@ the literal match is assumed.
+The I<CIDRLIST> part, if present, restricts the rule to users coming from
+IP addresses that match one of the elements in the list. I<CIDRLIST> is a
+comma-separated list of IP addresses, ranges or CIDRs. An IP range is
+defined as two IP addresses separated by a minus sign. A CIDR is defined as
+network address, followed by a slash and length of the netmask in decimal.
+For example:
+
+ gray@10.0.0.0/16,192.168.1.0-192.168.10.255
+
=back
@@ -187,3 +196,3 @@ The control verb.
-The user name or group (B<%>I<GROUPNAME>) specification.
+The user name specification (see description in the B<ACL FILE> section).
@@ -223,3 +232,3 @@ If no matching entry is found, the update is allowed.
-=item B<hooks.acl.type> STRING
+=item B<hooks.acl.type> I<STRING>
@@ -227,3 +236,3 @@ Type of the storage engine. Valid values are B<File> (default) and B<LDAP>.
-=item B<hooks.acl.file> STRING
+=item B<hooks.acl.file> I<STRING>
@@ -231,3 +240,3 @@ For the B<File> storage engine, name of the ACL file.
-=item B<hooks.acl.ldapconf> STRING
+=item B<hooks.acl.ldapconf> I<STRING>
@@ -236,3 +245,3 @@ instead of B</etc/ldap.conf>.
-=item B<hooks.acl.log> STRING
+=item B<hooks.acl.log> I<STRING>
@@ -240,3 +249,3 @@ Send log info to this file.
-=item B<hooks.acl.debug> NUMBER
+=item B<hooks.acl.debug> I<NUMBER>
@@ -245,3 +254,3 @@ be displayed.
-=item B<hooks.acl.quiet> BOOL
+=item B<hooks.acl.quiet> I<BOOL>
@@ -254,3 +263,3 @@ rule matched the request. Unless defined, B<deny> is assumed.
-=item B<hooks.acl.httpd-user> STRING
+=item B<hooks.acl.httpd-user> I<STRING>
@@ -261,2 +270,11 @@ from the environment variable B<REMOTE_USER>.
+=item B<hooks.acl.ip-env-var> I<STRING>
+
+Name of the environment variable from where to retrieve remote IP address.
+Default is B<REMOTE_ADDR>, if B<hooks.acl.httpd-user> is defined and current
+user matches it, and B<SSH_CLIENT> otherwise.
+
+The part of the string up to the first space character (if any) is taken as
+the IP address.
+
=back
diff --git a/lib/GitACL.pm b/lib/GitACL.pm
index cde9624..4214b3f 100644
--- a/lib/GitACL.pm
+++ b/lib/GitACL.pm
@@ -20,2 +20,3 @@ use strict;
use File::Spec;
+use Net::CIDR qw (cidrlookup);
@@ -118,2 +119,8 @@ sub match_primary_group($$) {
+sub match_host($$) {
+ my ($ip,$iplist) = @_;
+ return 0 unless defined($ip);
+ return cidrlookup($ip, split /,/, $iplist);
+}
+
sub match_user($$) {
@@ -122,2 +129,6 @@ sub match_user($$) {
return 0 if ($expr eq 'none');
+ if ($expr =~ /(.+)@(.+)/) {
+ return 0 unless match_host($self->{ip}, $2);
+ $expr = $1;
+ }
if ($expr =~ /^%(.+)/) {
@@ -222,2 +233,9 @@ sub new {
$obj->{user_name} = $ENV{REMOTE_USER};
+ $obj->{ip} = $ENV{REMOTE_ADDR};
+ } else {
+ my $ipvar = git_value('config', 'hooks.acl.ip-env-var') or 'SSH_CLIENT';
+ if (defined($ENV{$ipvar})) {
+ my @a = split /\S/, $ENV{$ipvar}, 2;
+ $obj->{ip} = $a[0];
+ }
}

Return to:

Send suggestions and report system problems to the System administrator.