(IMPORTANT; read this in full) no more "wildrepos"
The wildrepos branch has been merged into master, and deleted. It will no longer exist as a separate branch. Instead, a new variable called $GL_WILDREPOS has been added which acts as a switch; when off (which is the default), many wildrepos features are disabled. (the "C" permissions, and the getperms (etc.) commands mainly). Important: if you are using wildrepos, please set "$GL_WILDREPOS = 1;" in the RC file when you upgrade to this version (or just before you do the upgrade).
This commit is contained in:
parent
fc0b627f55
commit
388f4d873d
13
README.mkd
13
README.mkd
|
@ -86,10 +86,7 @@ detail [here][gsdiff].
|
||||||
### security
|
### security
|
||||||
|
|
||||||
Due to the environment in which this was created and the need it fills, I
|
Due to the environment in which this was created and the need it fills, I
|
||||||
consider this a "security" program, albeit a very modest one. The code is
|
consider this a "security" program, albeit a very modest one.
|
||||||
very small and easily reviewable -- the 2 programs that actually control
|
|
||||||
access when a user logs in total about 220 lines of code (about 90 lines
|
|
||||||
according to "sloccount").
|
|
||||||
|
|
||||||
For the first person to find a security hole in it, defined as allowing a
|
For the first person to find a security hole in it, defined as allowing a
|
||||||
normal user (not the gitolite admin) to read a repo, or write/rewind a ref,
|
normal user (not the gitolite admin) to read a repo, or write/rewind a ref,
|
||||||
|
@ -99,10 +96,10 @@ or in Unix, perl, shell, etc.)... well I can't afford 1000 USD rewards like
|
||||||
djb, so you'll have to settle for 1000 INR (Indian Rupees) as a "token" prize
|
djb, so you'll have to settle for 1000 INR (Indian Rupees) as a "token" prize
|
||||||
:-)
|
:-)
|
||||||
|
|
||||||
Update 2010-01-31: this security promise does not apply if you enable any of
|
However, there are a few optional features (which must be explicitly enabled
|
||||||
the external command helpers (like rsync). It's probably quite secure, but I
|
in the RC file) where I just haven't had the time to reason about security
|
||||||
just haven't thought about it enough to be able to make such promises, like I
|
thoroughly enough. Please read the comments in `conf/example.gitolite.rc` for
|
||||||
can for the rest of "master".
|
details, looking for the word "security".
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,26 @@ $GIT_PATH="";
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# SECURITY SENSITIVE SETTINGS
|
||||||
|
#
|
||||||
|
# Settings below this point may have security implications. That
|
||||||
|
# usually means that I have not thought hard enough about all the
|
||||||
|
# possible ways to crack security if these settings are enabled.
|
||||||
|
|
||||||
|
# Please see details on each setting for specifics, if any.
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# EXTERNAL COMMAND HELPER -- HTPASSWD
|
||||||
|
|
||||||
|
# security note: runs an external command (htpasswd) with specific arguments,
|
||||||
|
# including a user-chosen "password".
|
||||||
|
|
||||||
# if you want to enable the "htpasswd" command, give this the absolute path to
|
# if you want to enable the "htpasswd" command, give this the absolute path to
|
||||||
# whatever file apache (etc) expect to find the passwords in.
|
# whatever file apache (etc) expect to find the passwords in.
|
||||||
|
|
||||||
|
@ -118,7 +138,10 @@ $HTPASSWD_FILE = "";
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
# EXTERNAL COMMAND HELPER -- RSYNC
|
# EXTERNAL COMMAND HELPER -- RSYNC
|
||||||
#
|
|
||||||
|
# security note: runs an external command (rsync) with specific arguments, all
|
||||||
|
# presumably filled in correctly by the client-side rsync.
|
||||||
|
|
||||||
# base path of all the files that are accessible via rsync. Must be an
|
# base path of all the files that are accessible via rsync. Must be an
|
||||||
# absolute path. Leave it undefined or set to the empty string to disable the
|
# absolute path. Leave it undefined or set to the empty string to disable the
|
||||||
# rsync helper.
|
# rsync helper.
|
||||||
|
@ -126,6 +149,21 @@ $RSYNC_BASE = "";
|
||||||
# $RSYNC_BASE = "/home/git/up-down";
|
# $RSYNC_BASE = "/home/git/up-down";
|
||||||
# $RSYNC_BASE = "/tmp/up-down";
|
# $RSYNC_BASE = "/tmp/up-down";
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# ALLOW REPO CONFIG TO USE WILDCARDS
|
||||||
|
|
||||||
|
# security note: this used to in a separate "wildrepos" branch. You can
|
||||||
|
# create repositories based on wild cards, give "ownership" to the specific
|
||||||
|
# user who created it, allow him/her to hand out R and RW permissions to other
|
||||||
|
# users to collaborate, etc. This is powerful stuff, and I've made it as
|
||||||
|
# secure as I can, but it hasn't had the kind of rigorous line-by-line
|
||||||
|
# analysis that the old "master" branch had.
|
||||||
|
|
||||||
|
# This has now been rolled into master, with all the functionality gated by
|
||||||
|
# this variable. Set this to 1 if you want to enable the wildrepos features.
|
||||||
|
# Please see doc/4-wildcard-repositories.mkd for details.
|
||||||
|
# $GL_WILDREPOS = 0;
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
# per perl rules, this should be the last line in such a file:
|
# per perl rules, this should be the last line in such a file:
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -149,7 +149,7 @@ plain "git archive", because the Makefile adds a file called
|
||||||
git clone git://sitaramc.indefero.net/sitaramc/gitolite.git
|
git clone git://sitaramc.indefero.net/sitaramc/gitolite.git
|
||||||
cd gitolite
|
cd gitolite
|
||||||
make master.tar
|
make master.tar
|
||||||
# or maybe "make wildrepos.tar" or "make pu.tar"
|
# or maybe "make pu.tar"
|
||||||
|
|
||||||
<a name="diff"></a>
|
<a name="diff"></a>
|
||||||
|
|
||||||
|
@ -626,8 +626,7 @@ per-repo "gitconfig" settings. Please see `doc/2-admin.mkd` and
|
||||||
|
|
||||||
#### repos named with wildcards
|
#### repos named with wildcards
|
||||||
|
|
||||||
**This feature only exists in the "wildrepos" branch!** Please see
|
Please see `doc/4-wildcard-repositories.mkd` for all the details.
|
||||||
`doc/4-wildcard-repositories.mkd` for all the details.
|
|
||||||
|
|
||||||
#### access control for external commands
|
#### access control for external commands
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,14 @@
|
||||||
|
|
||||||
***IMPORTANT NOTE***:
|
***IMPORTANT NOTE***:
|
||||||
|
|
||||||
This branch contains features that are likely to be much more brittle than the
|
This feature may be somewhat "brittle" in terms of security. Creating
|
||||||
"master" branch. Creating repositories based on wild cards, giving
|
repositories based on wild cards, giving "ownership" to the specific user who
|
||||||
"ownership" to the specific user who created it, allowing him/her to hand out
|
created it, allowing him/her to hand out R and RW permissions to other users
|
||||||
R and RW permissions to other users to collaborate, all these are possible.
|
to collaborate, all these are possible. And any of these could have a bug in
|
||||||
And any of these could have a bug in it.
|
it. I haven't found any yet, but that doesn't mean there aren't any.
|
||||||
|
|
||||||
"Brittle" also means some features in "master" may not work here. For
|
Also, there are some limitations. For example, you cannot specify gitconfig
|
||||||
example, you cannot specify gitconfig values for a wildcard repo; it only
|
values for a wildcard repo; it only works for actual repos.
|
||||||
works for actual repos.
|
|
||||||
|
|
||||||
There may be other such missing features. Sometimes it's just not possible to
|
There may be other such missing features. Sometimes it's just not possible to
|
||||||
make it work. Or it may be cumbersome enough that unless there are *no*
|
make it work. Or it may be cumbersome enough that unless there are *no*
|
||||||
|
@ -25,7 +24,8 @@ In this document:
|
||||||
* wildcard repos without creater name in them
|
* wildcard repos without creater name in them
|
||||||
* side-note: line-anchored regexes
|
* side-note: line-anchored regexes
|
||||||
* contrast with refexes
|
* contrast with refexes
|
||||||
* handing out rights to wildcard-matached repos
|
* handing out rights to wildcard-matched repos
|
||||||
|
* setting a gitweb description for a wildcard-matched repo
|
||||||
* reporting
|
* reporting
|
||||||
* other issues and discussion
|
* other issues and discussion
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ actually push such a branch! You can anchor it if you really care, by using
|
||||||
`master$` instead of `master`, but anchoring is *not* the default for
|
`master$` instead of `master`, but anchoring is *not* the default for
|
||||||
refexes.]
|
refexes.]
|
||||||
|
|
||||||
### Handing out rights to wildcard-matached repos
|
### Handing out rights to wildcard-matched repos
|
||||||
|
|
||||||
In the examples above, we saw two special "user" names: READERS and WRITERS.
|
In the examples above, we saw two special "user" names: READERS and WRITERS.
|
||||||
The permissions they have are controlled by the config file, but ***who is
|
The permissions they have are controlled by the config file, but ***who is
|
||||||
|
@ -166,7 +166,12 @@ The following points are important:
|
||||||
* whoever you specify as "R" will match the special user READERS. "RW" will
|
* whoever you specify as "R" will match the special user READERS. "RW" will
|
||||||
match WRITERS.
|
match WRITERS.
|
||||||
|
|
||||||
### Reporting
|
### setting a gitweb description for a wildcard-matched repo
|
||||||
|
|
||||||
|
Similar to the getperm/setperm commands, there are the getdesc/setdesc
|
||||||
|
commands, thanks to Teemu.
|
||||||
|
|
||||||
|
### reporting
|
||||||
|
|
||||||
Remember the cool stuff you see when you just do `ssh git@server` (grep for
|
Remember the cool stuff you see when you just do `ssh git@server` (grep for
|
||||||
"myrights" in `doc/3-faq-tips-etc.mkd` if you forgot, or go [here][mr]).
|
"myrights" in `doc/3-faq-tips-etc.mkd` if you forgot, or go [here][mr]).
|
||||||
|
@ -177,7 +182,11 @@ This still works, except the format is a little more compressed to accommodate
|
||||||
a new column (at the start) for "C" permissions, which indicate that you are
|
a new column (at the start) for "C" permissions, which indicate that you are
|
||||||
allowed to *create* repos matching that pattern.
|
allowed to *create* repos matching that pattern.
|
||||||
|
|
||||||
### Other issues and discussion
|
In addition, there is also the "expand" command, which takes any regex pattern
|
||||||
|
and returns you a list of all wildcard-created repos that you have access to
|
||||||
|
which fit that pattern.
|
||||||
|
|
||||||
|
### other issues and discussion
|
||||||
|
|
||||||
* *what if the repo name being pushed matches more than one pattern*?
|
* *what if the repo name being pushed matches more than one pattern*?
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ our $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$); # very simple patter
|
||||||
# same as REPONAME, plus some common regex metas
|
# same as REPONAME, plus some common regex metas
|
||||||
our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$);
|
our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$);
|
||||||
|
|
||||||
our $REPO_UMASK;
|
# these come from the RC file
|
||||||
|
our ($REPO_UMASK, $GL_WILDREPOS);
|
||||||
our %repos;
|
our %repos;
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
@ -134,6 +135,8 @@ sub new_repo
|
||||||
my ($repo, $hooks_dir, $creater) = @_;
|
my ($repo, $hooks_dir, $creater) = @_;
|
||||||
|
|
||||||
umask($REPO_UMASK);
|
umask($REPO_UMASK);
|
||||||
|
die "wildrepos disabled, can't set creater $creater on new repo $repo\n"
|
||||||
|
if $creater and not $GL_WILDREPOS;
|
||||||
|
|
||||||
system("mkdir", "-p", "$repo.git") and die "$ABRT mkdir $repo.git failed: $!\n";
|
system("mkdir", "-p", "$repo.git") and die "$ABRT mkdir $repo.git failed: $!\n";
|
||||||
# erm, note that's "and die" not "or die" as is normal in perl
|
# erm, note that's "and die" not "or die" as is normal in perl
|
||||||
|
@ -226,6 +229,7 @@ sub parse_acl
|
||||||
# please update that also if the interface or the env vars change
|
# please update that also if the interface or the env vars change
|
||||||
|
|
||||||
my ($GL_CONF_COMPILED, $repo, $c, $r, $w) = @_;
|
my ($GL_CONF_COMPILED, $repo, $c, $r, $w) = @_;
|
||||||
|
$c = $r = $w = "NOBODY" unless $GL_WILDREPOS;
|
||||||
|
|
||||||
# void $r if same as $w (otherwise "readers" overrides "writers"; this is
|
# void $r if same as $w (otherwise "readers" overrides "writers"; this is
|
||||||
# the same problem that needed a sort sub for the Dumper in the compile
|
# the same problem that needed a sort sub for the Dumper in the compile
|
||||||
|
@ -251,6 +255,8 @@ sub parse_acl
|
||||||
return unless $repo;
|
return unless $repo;
|
||||||
|
|
||||||
return $ENV{GL_REPOPATT} = "" if $repos{$repo};
|
return $ENV{GL_REPOPATT} = "" if $repos{$repo};
|
||||||
|
# didn't find it, but wild is off? too bad, die!!! muahahaha
|
||||||
|
die "$repo not found in compiled config\n" unless $GL_WILDREPOS;
|
||||||
|
|
||||||
# didn't find $repo in %repos, so it must be a wildcard-match case
|
# didn't find $repo in %repos, so it must be a wildcard-match case
|
||||||
my @matched = grep { $repo =~ /^$_$/ } sort keys %repos;
|
my @matched = grep { $repo =~ /^$_$/ } sort keys %repos;
|
||||||
|
|
|
@ -24,7 +24,7 @@ use warnings;
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
# these are set by the "rc" file
|
# these are set by the "rc" file
|
||||||
our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $REPO_UMASK, $GL_ADMINDIR, $RSYNC_BASE, $HTPASSWD_FILE);
|
our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $REPO_UMASK, $GL_ADMINDIR, $RSYNC_BASE, $HTPASSWD_FILE, $GL_WILDREPOS);
|
||||||
# and these are set by gitolite.pm
|
# and these are set by gitolite.pm
|
||||||
our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT, $REPOPATT_PATT);
|
our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT, $REPOPATT_PATT);
|
||||||
our %repos;
|
our %repos;
|
||||||
|
@ -110,6 +110,7 @@ my $CUSTOM_COMMANDS=qr/^\s*(expand|(get|set)(perms|desc))\s/;
|
||||||
# commands is sort of a dead end for normal (git) processing
|
# commands is sort of a dead end for normal (git) processing
|
||||||
|
|
||||||
if ($ENV{SSH_ORIGINAL_COMMAND} =~ $CUSTOM_COMMANDS) {
|
if ($ENV{SSH_ORIGINAL_COMMAND} =~ $CUSTOM_COMMANDS) {
|
||||||
|
die "wildrepos disabled, sorry\n" unless $GL_WILDREPOS;
|
||||||
my $cmd = $ENV{SSH_ORIGINAL_COMMAND};
|
my $cmd = $ENV{SSH_ORIGINAL_COMMAND};
|
||||||
my ($verb, $repo) = ($cmd =~ /^\s*(\S+)\s+\/?(.*?)(?:.git)?$/);
|
my ($verb, $repo) = ($cmd =~ /^\s*(\S+)\s+\/?(.*?)(?:.git)?$/);
|
||||||
if ($repo =~ $REPONAME_PATT and $verb =~ /getperms|setperms/) {
|
if ($repo =~ $REPONAME_PATT and $verb =~ /getperms|setperms/) {
|
||||||
|
@ -171,8 +172,8 @@ if ( -d "$repo_base_abs/$repo.git" ) {
|
||||||
} else {
|
} else {
|
||||||
&parse_acl($GL_CONF_COMPILED, $repo, $user, $user, $user);
|
&parse_acl($GL_CONF_COMPILED, $repo, $user, $user, $user);
|
||||||
|
|
||||||
# auto-vivify new repo if you have C access
|
# auto-vivify new repo if you have C access (and wildrepos is on)
|
||||||
if ( $repos{$repo}{C}{$user} || $repos{$repo}{C}{'@all'} ) {
|
if ( $GL_WILDREPOS and $repos{$repo}{C}{$user} || $repos{$repo}{C}{'@all'} ) {
|
||||||
wrap_chdir("$repo_base_abs");
|
wrap_chdir("$repo_base_abs");
|
||||||
new_repo($repo, "$GL_ADMINDIR/src/hooks", $user);
|
new_repo($repo, "$GL_ADMINDIR/src/hooks", $user);
|
||||||
wrap_chdir($ENV{HOME});
|
wrap_chdir($ENV{HOME});
|
||||||
|
|
|
@ -61,7 +61,7 @@ $Data::Dumper::Sortkeys = sub { return [ reverse sort keys %{$_[0]} ]; };
|
||||||
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
|
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
|
||||||
|
|
||||||
# these are set by the "rc" file
|
# these are set by the "rc" file
|
||||||
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $SHELL_USERS);
|
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $SHELL_USERS, $GL_WILDREPOS);
|
||||||
# and these are set by gitolite.pm
|
# and these are set by gitolite.pm
|
||||||
our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN);
|
our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN);
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@ sub expand_list
|
||||||
|
|
||||||
for my $item (@list)
|
for my $item (@list)
|
||||||
{
|
{
|
||||||
die "$ABRT bad user or repo name $item\n" unless $item =~ $REPOPATT_PATT or $item =~ $USERNAME_PATT;
|
die "$ABRT bad user or repo name $item\n"
|
||||||
|
unless ($GL_WILDREPOS ? $item =~ $REPOPATT_PATT : $item =~ $REPONAME_PATT) or $item =~ $USERNAME_PATT;
|
||||||
if ($item =~ /^@/) # nested group
|
if ($item =~ /^@/) # nested group
|
||||||
{
|
{
|
||||||
die "$ABRT undefined group $item\n" unless $groups{$item};
|
die "$ABRT undefined group $item\n" unless $groups{$item};
|
||||||
|
@ -206,6 +207,7 @@ sub parse_conf_file
|
||||||
my $perms = $1;
|
my $perms = $1;
|
||||||
my @refs; @refs = split(' ', $2) if $2;
|
my @refs; @refs = split(' ', $2) if $2;
|
||||||
my @users = split ' ', $3;
|
my @users = split ' ', $3;
|
||||||
|
die "wildrepos disabled, cant use 'C' in config\n" if $perms eq 'C' and not $GL_WILDREPOS;
|
||||||
|
|
||||||
# if no ref is given, this PERM applies to all refs
|
# if no ref is given, this PERM applies to all refs
|
||||||
@refs = qw(refs/.*) unless @refs;
|
@refs = qw(refs/.*) unless @refs;
|
||||||
|
|
Loading…
Reference in a new issue