* [RFC PATCH] gitweb: Support filtering projects by .htaccess files. @ 2008-11-03 16:43 Alexander Gavrilov 2008-11-03 16:54 ` Francis Galiegue 2008-11-03 22:57 ` Jakub Narebski 0 siblings, 2 replies; 14+ messages in thread From: Alexander Gavrilov @ 2008-11-03 16:43 UTC (permalink / raw) To: git; +Cc: Jakub Narebski, Petr Baudis, Giuseppe Bilotta 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 <angavrilov@gmail.com> --- 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 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 16:43 [RFC PATCH] gitweb: Support filtering projects by .htaccess files Alexander Gavrilov @ 2008-11-03 16:54 ` Francis Galiegue 2008-11-03 17:26 ` Alexander Gavrilov 2008-11-03 22:57 ` Jakub Narebski 1 sibling, 1 reply; 14+ messages in thread From: Francis Galiegue @ 2008-11-03 16:54 UTC (permalink / raw) To: Alexander Gavrilov; +Cc: git 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 <angavrilov@gmail.com> 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 16:54 ` Francis Galiegue @ 2008-11-03 17:26 ` Alexander Gavrilov 2008-11-03 17:45 ` Francis Galiegue 0 siblings, 1 reply; 14+ messages in thread From: Alexander Gavrilov @ 2008-11-03 17:26 UTC (permalink / raw) To: Francis Galiegue; +Cc: git On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue <fg@one2team.net> 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 17:26 ` Alexander Gavrilov @ 2008-11-03 17:45 ` Francis Galiegue 2008-11-03 18:18 ` Jakub Narebski 0 siblings, 1 reply; 14+ messages in thread From: Francis Galiegue @ 2008-11-03 17:45 UTC (permalink / raw) To: Alexander Gavrilov; +Cc: git Le Monday 03 November 2008 18:26:44 Alexander Gavrilov, vous avez écrit : > On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue <fg@one2team.net> 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. > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 17:45 ` Francis Galiegue @ 2008-11-03 18:18 ` Jakub Narebski 2008-11-03 18:44 ` Francis Galiegue 0 siblings, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2008-11-03 18:18 UTC (permalink / raw) To: Francis Galiegue; +Cc: Alexander Gavrilov, git Francis Galiegue <fg@one2team.net> writes: > Le Monday 03 November 2008 18:26:44 Alexander Gavrilov, vous avez écrit : >> On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue <fg@one2team.net> 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 '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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 18:18 ` Jakub Narebski @ 2008-11-03 18:44 ` Francis Galiegue 2008-11-03 19:17 ` Jakub Narebski 0 siblings, 1 reply; 14+ messages in thread From: Francis Galiegue @ 2008-11-03 18:44 UTC (permalink / raw) To: Jakub Narebski; +Cc: Alexander Gavrilov, git Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit : > > > > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 18:44 ` Francis Galiegue @ 2008-11-03 19:17 ` Jakub Narebski 2008-11-03 21:59 ` Francis Galiegue 0 siblings, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2008-11-03 19:17 UTC (permalink / raw) To: Francis Galiegue; +Cc: Alexander Gavrilov, git Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał: > Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit : > > > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 19:17 ` Jakub Narebski @ 2008-11-03 21:59 ` Francis Galiegue 2008-11-04 0:24 ` Jakub Narebski 0 siblings, 1 reply; 14+ messages in thread From: Francis Galiegue @ 2008-11-03 21:59 UTC (permalink / raw) To: Jakub Narebski; +Cc: Alexander Gavrilov, git Le Monday 03 November 2008 20:17:47 Jakub Narebski, vous avez écrit : > Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał: > > Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit : > > > > > 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? -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 21:59 ` Francis Galiegue @ 2008-11-04 0:24 ` Jakub Narebski 2008-11-04 7:42 ` Francis Galiegue 0 siblings, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2008-11-04 0:24 UTC (permalink / raw) To: Francis Galiegue; +Cc: Alexander Gavrilov, git On Mon, 3 Nov 2008, Francis Galiegue wrote: > Le Monday 03 November 2008 20:17:47 Jakub Narebski, vous avez écrit : > > Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał: > > > Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit : > > > > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-04 0:24 ` Jakub Narebski @ 2008-11-04 7:42 ` Francis Galiegue 0 siblings, 0 replies; 14+ messages in thread From: Francis Galiegue @ 2008-11-04 7:42 UTC (permalink / raw) To: Jakub Narebski; +Cc: Alexander Gavrilov, git Le mardi 04 novembre 2008, Jakub Narebski a écrit : [...] > > > > 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 16:43 [RFC PATCH] gitweb: Support filtering projects by .htaccess files Alexander Gavrilov 2008-11-03 16:54 ` Francis Galiegue @ 2008-11-03 22:57 ` Jakub Narebski 2008-11-05 22:36 ` Alexander Gavrilov 1 sibling, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2008-11-03 22:57 UTC (permalink / raw) To: Alexander Gavrilov; +Cc: git, Petr Baudis, Giuseppe Bilotta 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)... > > Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> > --- > > 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. > > # 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... > # 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-03 22:57 ` Jakub Narebski @ 2008-11-05 22:36 ` Alexander Gavrilov 2008-11-05 23:26 ` Jakub Narebski 0 siblings, 1 reply; 14+ messages in thread From: Alexander Gavrilov @ 2008-11-05 22:36 UTC (permalink / raw) To: Jakub Narebski; +Cc: git, Petr Baudis, Giuseppe Bilotta > > 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 <angavrilov@gmail.com> --- 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) ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-05 22:36 ` Alexander Gavrilov @ 2008-11-05 23:26 ` Jakub Narebski 2008-11-06 19:43 ` Alexander Gavrilov 0 siblings, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2008-11-05 23:26 UTC (permalink / raw) To: Alexander Gavrilov; +Cc: git, Petr Baudis, Giuseppe Bilotta 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. > --- >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 <angavrilov@gmail.com> If somebody could check out example given for this feature, I'd add Acked-by: Jakub Narebski <jnareb@gmail.com> > --- > 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? > + > + > 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. > # 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 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files. 2008-11-05 23:26 ` Jakub Narebski @ 2008-11-06 19:43 ` Alexander Gavrilov 0 siblings, 0 replies; 14+ messages in thread From: Alexander Gavrilov @ 2008-11-06 19:43 UTC (permalink / raw) To: Jakub Narebski; +Cc: git, Petr Baudis, Giuseppe Bilotta On Thursday 06 November 2008 02:26:58 Jakub Narebski wrote: > Alexander Gavrilov wrote: > > + 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 <angavrilov@gmail.com> --- 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) ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2008-11-06 19:46 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-11-03 16:43 [RFC PATCH] gitweb: Support filtering projects by .htaccess files Alexander Gavrilov 2008-11-03 16:54 ` Francis Galiegue 2008-11-03 17:26 ` Alexander Gavrilov 2008-11-03 17:45 ` Francis Galiegue 2008-11-03 18:18 ` Jakub Narebski 2008-11-03 18:44 ` Francis Galiegue 2008-11-03 19:17 ` Jakub Narebski 2008-11-03 21:59 ` Francis Galiegue 2008-11-04 0:24 ` Jakub Narebski 2008-11-04 7:42 ` Francis Galiegue 2008-11-03 22:57 ` Jakub Narebski 2008-11-05 22:36 ` Alexander Gavrilov 2008-11-05 23:26 ` Jakub Narebski 2008-11-06 19:43 ` Alexander Gavrilov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox