[RFC PATCH] gitweb: Support filtering projects by .htaccess files.

Subsystems: the rest

STALE3695d

14 messages, 3 authors, 2016-08-12 · open the first message on its own page

[RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:34

Some environments may require selective limiting of read access to
repositories. While even dumb http transport supports it through .htaccess
files, gitweb currently does not implement discretionary access control.

This patch adds a configuration-contolled check that matches simple
'Reguire user'/'Reguire group' lines in the .htaccess files with the
authenticated user name. Using group authentication requires specifying
a path to the Apache group file in the configuration.

Using htaccess has an additional bonus that the same authentication
data can be used both for gitweb and the dumb http transport.

Signed-off-by: Alexander Gavrilov <redacted>
---

	I also created a gitosis fork that can generate the necessary files:

		http://repo.or.cz/w/gitosis/httpauth.git

	-- Alexander

 gitweb/INSTALL     |   14 ++++++++++
 gitweb/gitweb.perl |   68 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 26967e2..0841db6 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -166,6 +166,20 @@ Gitweb repositories
   shows repositories only if this file exists in its object database
   (if directory has the magic file named $export_ok).
 
+- Finally, it is possible to use primitive .htaccess authentication by
+  enabling the $check_htaccess variable in the config file. Gitweb
+  recognizes the following htaccess commands:
+
+    Require user name1 name2 ...     # grant access to the listed users
+    Require group group1 group2 ...  # grant access to the listed groups
+    Deny from all                    # deny unless overridden by a Require
+
+  Access is granted if the currently authenticated user matches one
+  of the Require lines, or if the file does not contain any of the listed
+  commands, or if .htaccess does not exist. If the file exists but cannot
+  be opened, access is denied. To use group authentication you have to
+  point $auth_group_file to the group list in Apache format.
+
 Generating projects list using gitweb
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 63c793e..4b962c3 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -98,6 +98,12 @@ our $export_ok = "++GITWEB_EXPORT_OK++";
 # only allow viewing of repositories also shown on the overview page
 our $strict_export = "++GITWEB_STRICT_EXPORT++";
 
+# check basic authentication rules in .htaccess
+our $check_htaccess  = 0;
+
+# name of the file that lists groups for htaccess check
+our $auth_group_file = "";
+
 # list of git base URLs used for URL to where fetch project from,
 # i.e. full URL is "$git_base_url/$project"
 our @git_base_url_list = grep { $_ ne '' } ("++GITWEB_BASE_URL++");
@@ -397,10 +403,64 @@ sub check_head_link {
 		(-l $headfile && readlink($headfile) =~ /^refs\/heads\//));
 }
 
+# set of htaccess groups for the current user
+our %cur_auth_groups = ();
+
+sub find_current_groups($$) {
+	my ($gfile, $user) = @_;
+	return () unless $gfile && $user;
+
+	my @groups;
+	open my $gf, $gfile or return ();
+
+	while(<$gf>) {
+		next unless /^\s*(\S+)\s*:\s*(\S.*\S)\s*$/;
+		my ($grp, $usrs) = ($1, $2);
+		push @groups, $grp if grep { $_ eq $user } split (' ', $usrs);
+	}
+
+	close $gf;
+	return @groups;
+}
+
+sub check_htaccess_files($) {
+	my ($dir) = @_;
+	my $user = $cgi->remote_user() || ' ';
+
+	while (length $dir >= length $projectroot) {
+		my $file = "$dir/.htaccess";
+		next unless -e $file;
+		open my $htf, $file or return 0;
+
+		my $ok = 0;
+		my $need_ok = 0;
+		while (<$htf>) {
+			if (/^\s*Require\s+user\s+(\S.*\S)\s*$/i) {
+				$ok++ if grep { $_ eq $user; } split (' ', $1);
+				$need_ok++;
+			} elsif (/^\s*Require\s+group\s+(\S.*\S)\s*$/i) {
+				$ok++ if grep { $cur_auth_groups{$_}; } split(' ', $1);
+				$need_ok++;
+			} elsif (/^\s*Deny\s+from\s+all\s*$/ix) {
+				$need_ok++;
+			}
+		}
+		close $htf;
+
+		return $ok if $need_ok;
+		last;
+	} continue {
+		$dir =~ s/\/[^\/]*$// or last;
+	}
+
+	return 1;
+}
+
 sub check_export_ok {
 	my ($dir) = @_;
 	return (check_head_link($dir) &&
-		(!$export_ok || -e "$dir/$export_ok"));
+		(!$export_ok || -e "$dir/$export_ok") &&
+		(!$check_htaccess || check_htaccess_files($dir)));
 }
 
 # process alternate names for backward compatibility
@@ -626,6 +686,9 @@ if (defined $action) {
 	}
 }
 
+# compute authenticated groups
+$cur_auth_groups{$_}++ for find_current_groups($auth_group_file, $cgi->remote_user());
+
 # parameters which are pathnames
 our $project = $input_params{'project'};
 if (defined $project) {
@@ -853,8 +916,7 @@ sub validate_project {
 	my $input = shift || return undef;
 	if (!validate_pathname($input) ||
 		!(-d "$projectroot/$input") ||
-		!check_head_link("$projectroot/$input") ||
-		($export_ok && !(-e "$projectroot/$input/$export_ok")) ||
+		!check_export_ok("$projectroot/$input") ||
 		($strict_export && !project_in_list($input))) {
 		return undef;
 	} else {
-- 
1.6.0.3.15.gb8d36

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Francis Galiegue <hidden>
Date: 2016-06-15 22:45:34

Le Monday 03 November 2008 17:43:29, vous avez écrit :
Some environments may require selective limiting of read access to
repositories. While even dumb http transport supports it through .htaccess
files, gitweb currently does not implement discretionary access control.

This patch adds a configuration-contolled check that matches simple
'Reguire user'/'Reguire group' lines in the .htaccess files with the
authenticated user name. Using group authentication requires specifying
a path to the Apache group file in the configuration.

Using htaccess has an additional bonus that the same authentication
data can be used both for gitweb and the dumb http transport.

Signed-off-by: Alexander Gavrilov <redacted>
It just seems to me that this is emulating functionality that multiple Web servers already provide...

What's more, knowledge about these Web servers are _much_ more widespread than knowledge about gitweb.

Why reinvent the wheel?

Just a thought,
-- 
fge

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:34

On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue [off-list ref] wrote:
It just seems to me that this is emulating functionality that multiple Web servers already provide...

What's more, knowledge about these Web servers are _much_ more widespread than knowledge about gitweb.

Why reinvent the wheel?
If you are speaking of web servers as in 'GitHub', then it is
irrelevant, because its server software is nonfree.

If you are speaking of web servers as in 'Apache', then how would it
know which files are going to be accessed when it executes
cgi-bin/gitweb.cgi?p=very/private/project.git to check permissions?

Alexander

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Francis Galiegue <hidden>
Date: 2016-06-15 22:45:34

Le Monday 03 November 2008 18:26:44 Alexander Gavrilov, vous avez écrit :
On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue [off-list ref] wrote:
quoted
It just seems to me that this is emulating functionality that multiple Web servers already provide...

What's more, knowledge about these Web servers are _much_ more widespread than knowledge about gitweb.

Why reinvent the wheel?
If you are speaking of web servers as in 'GitHub', then it is
irrelevant, because its server software is nonfree.
I didn't even account for these.
If you are speaking of web servers as in 'Apache', then how would it
know which files are going to be accessed when it executes
cgi-bin/gitweb.cgi?p=very/private/project.git to check permissions?
Well, as far as Apache is concerned, it can do:

* basic .htpasswd authentication,
* LDAP,
* PAM,
* SSL certificate check (via mod_ssl),
* probably others.

Plenty of possibilities.

Well, that's just mho. But if ever I complete my current work on
git-cvsimport (or using git2(svn|git)), I'll go for option 2: my LDAP
database has all the info, and Apache knows about Cache-Control, not
gitweb...

NOTE: I'm just saying here that your patch is of no use as far as _I_
am concerned. I'm basically saying that git cannot account for all
authentication schemes out there. Neither can Apache, but it supports a
buckload of them already.

-- 
fge

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:45:34

Francis Galiegue [off-list ref] writes:
Le Monday 03 November 2008 18:26:44 Alexander Gavrilov, vous avez écrit :
quoted
On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue [off-list ref] wrote:
quoted
It just seems to me that this is emulating functionality that
multiple Web servers already provide...

What's more, knowledge about these Web servers are _much_ more
widespread than knowledge about gitweb.

Why reinvent the wheel?
[...]
quoted
If you are speaking of web servers as in 'Apache', then how would it
know which files are going to be accessed when it executes
cgi-bin/gitweb.cgi?p=very/private/project.git to check permissions?
Well, as far as Apache is concerned, it can do:

* basic .htpasswd authentication,
* LDAP,
* PAM,
* SSL certificate check (via mod_ssl),
* probably others.

Plenty of possibilities.
[...]

Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...

-- 
Jakub Narebski
Poland
ShadeHawk on #git

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Francis Galiegue <hidden>
Date: 2016-06-15 22:45:34

Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
quoted
Well, as far as Apache is concerned, it can do:

* basic .htpasswd authentication,
* LDAP,
* PAM,
* SSL certificate check (via mod_ssl),
* probably others.

Plenty of possibilities.
[...]

Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...
Can you expand on path_info and query-string? Keep in mind that Apache
has mod_rewrite, which can rewrite URLs in any way before it gets
actually sent to the underlying program (whether it be a CGI or
anything else), even badly (or mischievously).

-- 
fge

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:45:36

Nice idea, but for now certainly an RFC

On Mon, 3 Nov 2008, Alexander Gavrilov wrote:
Some environments may require selective limiting of read access to
repositories. While even dumb http transport supports it through .htaccess
files, gitweb currently does not implement discretionary access control.

This patch adds a configuration-contolled check that matches simple
'Reguire user'/'Reguire group' lines in the .htaccess files with the
Typo: Reguire -> Require
authenticated user name. Using group authentication requires specifying
a path to the Apache group file in the configuration.

Using .htaccess has an additional bonus that the same authentication
data can be used both for gitweb and the dumb http transport.
I'm not sure if it wouldn't be a better solution to try to ask web
server to do authentication, for example in MOD_PERL case via $r
object (if I remember correctly)...
quoted hunk
Signed-off-by: Alexander Gavrilov <redacted>
---

	I also created a gitosis fork that can generate the necessary files:

		http://repo.or.cz/w/gitosis/httpauth.git

	-- Alexander

 gitweb/INSTALL     |   14 ++++++++++
 gitweb/gitweb.perl |   68 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 26967e2..0841db6 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -166,6 +166,20 @@ Gitweb repositories
   shows repositories only if this file exists in its object database
   (if directory has the magic file named $export_ok).
 
+- Finally, it is possible to use primitive .htaccess authentication by
+  enabling the $check_htaccess variable in the config file. Gitweb
+  recognizes the following htaccess commands:
+
+    Require user name1 name2 ...     # grant access to the listed users
+    Require group group1 group2 ...  # grant access to the listed groups
+    Deny from all                    # deny unless overridden by a Require
+
+  Access is granted if the currently authenticated user matches one
+  of the Require lines, or if the file does not contain any of the listed
+  commands, or if .htaccess does not exist. If the file exists but cannot
+  be opened, access is denied. To use group authentication you have to
+  point $auth_group_file to the group list in Apache format.
+
 Generating projects list using gitweb
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 63c793e..4b962c3 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -98,6 +98,12 @@ our $export_ok = "++GITWEB_EXPORT_OK++";
 # only allow viewing of repositories also shown on the overview page
 our $strict_export = "++GITWEB_STRICT_EXPORT++";
 
+# check basic authentication rules in .htaccess
+our $check_htaccess  = 0;
+
+# name of the file that lists groups for htaccess check
+our $auth_group_file = "";
+
 # list of git base URLs used for URL to where fetch project from,
 # i.e. full URL is "$git_base_url/$project"
 our @git_base_url_list = grep { $_ ne '' } ("++GITWEB_BASE_URL++");
@@ -397,10 +403,64 @@ sub check_head_link {
 		(-l $headfile && readlink($headfile) =~ /^refs\/heads\//));
 }
 
+# set of htaccess groups for the current user
+our %cur_auth_groups = ();
Why it is hash, and not list? What are the keys, and what are values?
+
+sub find_current_groups($$) {
Style: I think we prefer not using function prototypes.
+	my ($gfile, $user) = @_;
+	return () unless $gfile && $user;
Style: you can use simple "return" which means '()' in list context,
and 'undef' in scalar context.

So it could have been written as:

+	($gfile && $user) or return;


But I'd rather someone better in Perl decided...
+
+	my @groups;
+	open my $gf, $gfile or return ();
+
+	while(<$gf>) {
+		next unless /^\s*(\S+)\s*:\s*(\S.*\S)\s*$/;
+		my ($grp, $usrs) = ($1, $2);
+		push @groups, $grp if grep { $_ eq $user } split (' ', $usrs);
Wouldn't it be better to use regexp match instead of this split+grep
pipeline?
+	}
+
+	close $gf;
+	return @groups;
+}
+
+sub check_htaccess_files($) {
Style: I think we prefer not using function prototypes.

This function lack description: where it tries to find '.htaccess'
files, what does it return, etc.
+	my ($dir) = @_;
+	my $user = $cgi->remote_user() || ' ';
Why "|| ' '" here?
+
+	while (length $dir >= length $projectroot) {
+		my $file = "$dir/.htaccess";
+		next unless -e $file;
+		open my $htf, $file or return 0;
+
+		my $ok = 0;
+		my $need_ok = 0;
+		while (<$htf>) {
+			if (/^\s*Require\s+user\s+(\S.*\S)\s*$/i) {
+				$ok++ if grep { $_ eq $user; } split (' ', $1);
+				$need_ok++;
+			} elsif (/^\s*Require\s+group\s+(\S.*\S)\s*$/i) {
+				$ok++ if grep { $cur_auth_groups{$_}; } split(' ', $1);
+				$need_ok++;
+			} elsif (/^\s*Deny\s+from\s+all\s*$/ix) {
+				$need_ok++;
+			}
+		}
+		close $htf;
+
+		return $ok if $need_ok;
+		last;
+	} continue {
+		$dir =~ s/\/[^\/]*$// or last;
+	}
First, this loop is IMHO very hacky and unclean, using 'continue' block
(which is not very visible on first glance) to advance through loop.

Second, while this loop might be good for _single_ repository, it is
cleanly suboptimal in the case of 'projects_list' action... unless you
want to list projects which are not accessible (I think it is the case
for accessing static pages / static files).

Third, again there is split+grep (well, this is at least consistent).
+
+	return 1;
+}
+
 sub check_export_ok {
 	my ($dir) = @_;
 	return (check_head_link($dir) &&
-		(!$export_ok || -e "$dir/$export_ok"));
+		(!$export_ok || -e "$dir/$export_ok") &&
+		(!$check_htaccess || check_htaccess_files($dir)));
 }
O.K. Nice and clean.
quoted hunk
 
 # process alternate names for backward compatibility
@@ -626,6 +686,9 @@ if (defined $action) {
 	}
 }
 
+# compute authenticated groups
+$cur_auth_groups{$_}++ for find_current_groups($auth_group_file, $cgi->remote_user());
+
This is a bit hacky. And I am not sure if its place should be here...
quoted hunk
 # parameters which are pathnames
 our $project = $input_params{'project'};
 if (defined $project) {
@@ -853,8 +916,7 @@ sub validate_project {
 	my $input = shift || return undef;
 	if (!validate_pathname($input) ||
 		!(-d "$projectroot/$input") ||
-		!check_head_link("$projectroot/$input") ||
-		($export_ok && !(-e "$projectroot/$input/$export_ok")) ||
+		!check_export_ok("$projectroot/$input") ||
 		($strict_export && !project_in_list($input))) {
 		return undef;
 	} else {
And this is independent change, and should be in separate patch...
...or should be dropped (I'd have to examine this code better).
-- 
1.6.0.3.15.gb8d36
-- 
Jakub Narebski
Poland

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:45:36

On Mon, 3 Nov 2008, Francis Galiegue wrote:
Le Monday 03 November 2008 20:17:47 Jakub Narebski, vous avez écrit :
quoted
Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał:
quoted
Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
 
quoted
quoted
quoted
Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...
Can you expand on path_info and query-string? Keep in mind that Apache
has mod_rewrite, which can rewrite URLs in any way before it gets
actually sent to the underlying program (whether it be a CGI or
anything else), even badly (or mischievously).
What I mean here that the following example gitweb URLs

  http://example.com/gitweb.cgi?p=some/project.git;a=commit;h=HEAD
  http://example.com/gitweb.cgi/some/project.git/commit/HEAD

with the following gitweb configuration

  $projectroot = /var/scm

both refer to git repository (directory) at

  /var/scm/some/project.git

Apache (or other web server) would have to somehow decide based on URL
that it refers to some project, and based on project and authentication
decide whether to grant access to it.


What is more, and what cannot be done by web server alone, is that we
would want to not show projects which you don't have access to in the
'projects_list' page, i.e. at

  http://example.com/gitweb.cgi
On the other hand we can decide to display projects for which user
doesn't have access (via HTTP authentication) for, just like
directories in *Index* directive can be shown even if they cannot be
accessed.
 
I see the point. Note that the second URL can be converted into the first
one with mod_rewrite, and probably the first to the second as well. 

As to what repository is accessible to whom, does gitweb really have
an internal mechanism for this? Wouldn't it be "better" is privately
accessible projects were available on another website to start with?  
The problem is that Apache has to decide whether to deny or grant access
based on URL, not on path in filesystem. Perhaps that is possible...

As to having in gitweb mechanism for this... even now gitweb supports
bare-bones access control in terms of $export_ok. BTW you can have
 not displayed but still accessible.project
-- 
Jakub Narebski
Poland

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Francis Galiegue <hidden>
Date: 2016-06-15 22:45:36

Le mardi 04 novembre 2008, Jakub Narebski a écrit :
[...]
quoted
As to what repository is accessible to whom, does gitweb really have
an internal mechanism for this? Wouldn't it be "better" is privately
accessible projects were available on another website to start with?  
The problem is that Apache has to decide whether to deny or grant access
based on URL, not on path in filesystem. Perhaps that is possible...
It is, with <Location> or <LocationMatch>. You can use mod_access directives 
within these (or mod_auth* ones).


-- 
Francis Galiegue, fg@one2team.com
[ATTENTION - CHANGEMENT D'ADRESSE !]
40 av Raymond Poincaré, 75016 PARIS
+33178945570, +33683877875

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:36

quoted
authenticated user name. Using group authentication requires specifying
a path to the Apache group file in the configuration.

Using .htaccess has an additional bonus that the same authentication
data can be used both for gitweb and the dumb http transport.
I'm not sure if it wouldn't be a better solution to try to ask web
server to do authentication, for example in MOD_PERL case via $r
object (if I remember correctly)...
You are right. I never used mod_perl before, so I didn't know that it's possible.

How about the following patch, that simply adds a hook, and provides
an example using mod_perl in the documentation?
--- >8 ---
Subject: [PATCH] gitweb: Add a per-repository authorization hook.

Add a configuration variable that can be used to specify an
arbitrary subroutine that will be called in the same situations
where $export_ok is checked, and its return value used
to decide whether the repository is to be shown.

This allows the user to implement custom authentication
schemes, for example by issuing a subrequest through mod_perl
and checking if Apache will authorize it.

Signed-off-by: Alexander Gavrilov <redacted>
---
 gitweb/INSTALL     |   21 +++++++++++++++++++++
 gitweb/gitweb.perl |    8 +++++++-
 2 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 26967e2..fa5917a 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -166,6 +166,27 @@ Gitweb repositories
   shows repositories only if this file exists in its object database
   (if directory has the magic file named $export_ok).
 
+- Finally, it is possible to specify an arbitrary perl subroutine that
+  will be called for each project to determine if it can be exported.
+  The subroutine receives an absolute path to the project as its only
+  parameter.
+
+  For example, if you use mod_perl to run the script, and have dumb
+  http protocol authentication configured for your repositories, you
+  can use the following hook to allow access only if the user is
+  authorized to read the files:
+
+    $export_auth_hook = sub {
+        use Apache2::SubRequest ();
+        use Apache2::Const -compile => qw(HTTP_OK);
+        my $path = "$_[0]/HEAD";
+        my $r    = Apache2::RequestUtil->request;
+        my $sub  = $r->lookup_file($path);
+        return $sub->filename eq $path 
+            && $sub->status == Apache2::Const::HTTP_OK;
+    };
+
+
 Generating projects list using gitweb
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 172ea6b..9329880 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -95,6 +95,11 @@ our $default_projects_order = "project";
 # (only effective if this variable evaluates to true)
 our $export_ok = "++GITWEB_EXPORT_OK++";
 
+# show repository only if this subroutine returns true
+# when given the path to the project, for example:
+#    sub { return -e "$_[0]/git-daemon-export-ok"; }
+our $export_auth_hook = undef;
+
 # only allow viewing of repositories also shown on the overview page
 our $strict_export = "++GITWEB_STRICT_EXPORT++";
 
@@ -400,7 +405,8 @@ sub check_head_link {
 sub check_export_ok {
 	my ($dir) = @_;
 	return (check_head_link($dir) &&
-		(!$export_ok || -e "$dir/$export_ok"));
+		(!$export_ok || -e "$dir/$export_ok") &&
+		(!$export_auth_hook || $export_auth_hook->($dir)));
 }
 
 # process alternate names for backward compatibility
-- 
tg: (0d4f9de..) t/authenticate/hook (depends on: t/authenticate/unify-exportok)

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:45:36

Alexander Gavrilov wrote:
 
How about the following patch, that simply adds a hook, and provides
an example using mod_perl in the documentation?
Very nice, simple yet powerfull solution.
 
quoted hunk
--- >8 ---
Subject: [PATCH] gitweb: Add a per-repository authorization hook.

Add a configuration variable that can be used to specify an
arbitrary subroutine that will be called in the same situations
where $export_ok is checked, and its return value used
to decide whether the repository is to be shown.

This allows the user to implement custom authentication
schemes, for example by issuing a subrequest through mod_perl
and checking if Apache will authorize it.

Signed-off-by: Alexander Gavrilov <redacted>
If somebody could check out example given for this feature, I'd add
Acked-by: Jakub Narebski <redacted>
quoted hunk
---
 gitweb/INSTALL     |   21 +++++++++++++++++++++
 gitweb/gitweb.perl |    8 +++++++-
 2 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 26967e2..fa5917a 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -166,6 +166,27 @@ Gitweb repositories
   shows repositories only if this file exists in its object database
   (if directory has the magic file named $export_ok).
 
+- Finally, it is possible to specify an arbitrary perl subroutine that
+  will be called for each project to determine if it can be exported.
+  The subroutine receives an absolute path to the project as its only
+  parameter.
+
+  For example, if you use mod_perl to run the script, and have dumb
+  http protocol authentication configured for your repositories, you
+  can use the following hook to allow access only if the user is
+  authorized to read the files:
+
+    $export_auth_hook = sub {
+        use Apache2::SubRequest ();
+        use Apache2::Const -compile => qw(HTTP_OK);
+        my $path = "$_[0]/HEAD";
+        my $r    = Apache2::RequestUtil->request;
+        my $sub  = $r->lookup_file($path);
+        return $sub->filename eq $path 
+            && $sub->status == Apache2::Const::HTTP_OK;
+    };
Can anybody check this? Or was it checked by author?
quoted hunk
+
+
 Generating projects list using gitweb
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 172ea6b..9329880 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -95,6 +95,11 @@ our $default_projects_order = "project";
 # (only effective if this variable evaluates to true)
 our $export_ok = "++GITWEB_EXPORT_OK++";
 
+# show repository only if this subroutine returns true
+# when given the path to the project, for example:
+#    sub { return -e "$_[0]/git-daemon-export-ok"; }
+our $export_auth_hook = undef;
+
Simple, yet powerfull. Nice short example.
quoted hunk
 # only allow viewing of repositories also shown on the overview page
 our $strict_export = "++GITWEB_STRICT_EXPORT++";
 
@@ -400,7 +405,8 @@ sub check_head_link {
 sub check_export_ok {
 	my ($dir) = @_;
 	return (check_head_link($dir) &&
-		(!$export_ok || -e "$dir/$export_ok"));
+		(!$export_ok || -e "$dir/$export_ok") &&
+		(!$export_auth_hook || $export_auth_hook->($dir)));
Nice.
 }
 
 # process alternate names for backward compatibility
-- 
tg: (0d4f9de..) t/authenticate/hook (depends on: t/authenticate/unify-exportok)
P.S. Why doesn't TopGit add git and TopGit version to signature?

-- 
Jakub Narebski
Poland

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:36

On Thursday 06 November 2008 02:26:58 Jakub Narebski wrote:
Alexander Gavrilov wrote:
quoted
+  For example, if you use mod_perl to run the script, and have dumb
+  http protocol authentication configured for your repositories, you
+  can use the following hook to allow access only if the user is
+  authorized to read the files:
+
+    $export_auth_hook = sub {
+        use Apache2::SubRequest ();
+        use Apache2::Const -compile => qw(HTTP_OK);
+        my $path = "$_[0]/HEAD";
+        my $r    = Apache2::RequestUtil->request;
+        my $sub  = $r->lookup_file($path);
+        return $sub->filename eq $path 
+            && $sub->status == Apache2::Const::HTTP_OK;
+    };
Can anybody check this? Or was it checked by author?
Well, it seems to do what is intended on my home server,
although it has a known limitation, so here is an updated
version that warns about it.

By the way, do you know how to deal with Apache or ModPerl's
urge to append standard error messages to the script output, other
than adding a bunch of lines like the following to the config?

  ErrorMessage 400 " "

I couldn't find any solutions so far.

--- >8 ---
Subject: [PATCH] gitweb: Add a per-repository authorization hook.

Add a configuration variable that can be used to specify an
arbitrary subroutine that will be called in the same situations
where $export_ok is checked, and its return value will be used
to decide whether the repository is to be shown.

This allows the user to implement custom authentication
schemes, for example by issuing a subrequest through mod_perl
and checking if Apache will authorize it.

Signed-off-by: Alexander Gavrilov <redacted>
---
 gitweb/INSTALL     |   23 +++++++++++++++++++++++
 gitweb/gitweb.perl |    8 +++++++-
 2 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 26967e2..72a1322 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -166,6 +166,29 @@ Gitweb repositories
   shows repositories only if this file exists in its object database
   (if directory has the magic file named $export_ok).
 
+- Finally, it is possible to specify an arbitrary perl subroutine that
+  will be called for each project to determine if it can be exported.
+  The subroutine receives an absolute path to the project as its only
+  parameter.
+
+  For example, if you use mod_perl to run the script, and have dumb
+  http protocol authentication configured for your repositories, you
+  can use the following hook to allow access only if the user is
+  authorized to read the files:
+
+    $export_auth_hook = sub {
+        use Apache2::SubRequest ();
+        use Apache2::Const -compile => qw(HTTP_OK);
+        my $path = "$_[0]/HEAD";
+        my $r    = Apache2::RequestUtil->request;
+        my $sub  = $r->lookup_file($path);
+        return $sub->filename eq $path 
+            && $sub->status == Apache2::Const::HTTP_OK;
+    };
+
+  Note that since this sample works exclusively in the filesystem
+  namespace, <Location> sections of the configuration have no effect.
+
 Generating projects list using gitweb
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 172ea6b..9329880 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -95,6 +95,11 @@ our $default_projects_order = "project";
 # (only effective if this variable evaluates to true)
 our $export_ok = "++GITWEB_EXPORT_OK++";
 
+# show repository only if this subroutine returns true
+# when given the path to the project, for example:
+#    sub { return -e "$_[0]/git-daemon-export-ok"; }
+our $export_auth_hook = undef;
+
 # only allow viewing of repositories also shown on the overview page
 our $strict_export = "++GITWEB_STRICT_EXPORT++";
 
@@ -400,7 +405,8 @@ sub check_head_link {
 sub check_export_ok {
 	my ($dir) = @_;
 	return (check_head_link($dir) &&
-		(!$export_ok || -e "$dir/$export_ok"));
+		(!$export_ok || -e "$dir/$export_ok") &&
+		(!$export_auth_hook || $export_auth_hook->($dir)));
 }
 
 # process alternate names for backward compatibility
-- 
tg: (0d4f9de..) t/authenticate/hook (depends on: t/authenticate/unify-exportok)

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Francis Galiegue <hidden>
Date: 2016-08-11 17:46:16

Le Monday 03 November 2008 20:17:47 Jakub Narebski, vous avez écrit :
Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał:
quoted
Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
quoted
quoted
quoted
Well, as far as Apache is concerned, it can do:

* basic .htpasswd authentication,
* LDAP,
* PAM,
* SSL certificate check (via mod_ssl),
* probably others.

Plenty of possibilities.
[...]

Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...
Can you expand on path_info and query-string? Keep in mind that Apache
has mod_rewrite, which can rewrite URLs in any way before it gets
actually sent to the underlying program (whether it be a CGI or
anything else), even badly (or mischievously).
What I mean here that the following example gitweb URLs

  http://example.com/gitweb.cgi?p=some/project.git;a=commit;h=HEAD
  http://example.com/gitweb.cgi/some/project.git/commit/HEAD

with the following gitweb configuration

  $projectroot = /var/scm

both refer to git repository (directory) at

  /var/scm/some/project.git

Apache (or other web server) would have to somehow decide based on URL
that it refers to some project, and based on project and authentication
decide whether to grant access to it.


What is more, and what cannot be done by web server alone, is that we
would want to not show projects which you don't have access to in the
'projects_list' page, i.e. at

  http://example.com/gitweb.cgi
I see the point. Note that the second URL can be converted into the first one with mod_rewrite, and probably the first to the second as well.

As to what repository is accessible to whom, does gitweb really have an internal mechanism for this? Wouldn't it be "better" is privately accessible projects were available on another website to start with?


-- 

Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.

From: Jakub Narebski <hidden>
Date: 2016-08-12 22:25:03

Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał:
Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
quoted
quoted
Well, as far as Apache is concerned, it can do:

* basic .htpasswd authentication,
* LDAP,
* PAM,
* SSL certificate check (via mod_ssl),
* probably others.

Plenty of possibilities.
[...]

Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...
Can you expand on path_info and query-string? Keep in mind that Apache
has mod_rewrite, which can rewrite URLs in any way before it gets
actually sent to the underlying program (whether it be a CGI or
anything else), even badly (or mischievously).
What I mean here that the following example gitweb URLs

  http://example.com/gitweb.cgi?p=some/project.git;a=commit;h=HEAD
  http://example.com/gitweb.cgi/some/project.git/commit/HEAD

with the following gitweb configuration

  $projectroot = /var/scm

both refer to git repository (directory) at

  /var/scm/some/project.git

Apache (or other web server) would have to somehow decide based on URL
that it refers to some project, and based on project and authentication
decide whether to grant access to it.


What is more, and what cannot be done by web server alone, is that we
would want to not show projects which you don't have access to in the
'projects_list' page, i.e. at

  http://example.com/gitweb.cgi

-- 
Jakub Narebski
Poland
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help