diff --git a/src/commands/git-annex-shell b/src/commands/git-annex-shell new file mode 100755 index 0000000..7f5310e --- /dev/null +++ b/src/commands/git-annex-shell @@ -0,0 +1,80 @@ +#!/usr/bin/perl + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Easy; + +# This command requires unrestricted arguments, so instead of adding it to the +# COMMANDS hash in the usual way, you need to add it like so: +# 'git-annex-shell' => 'ua', +# (i.e., the value for the key should be the string 'ua'). +# +# This requires git-annex version 20111016 or newer. Older versions won't +# be secure. + +use strict; +use warnings; + +# ignore @ARGV and look at the original unmodified command +my $cmd = $ENV{SSH_ORIGINAL_COMMAND}; + +# Expect commands like: +# git-annex-shell 'configlist' '/~/repo' +# git-annex-shell 'sendkey' '/~/repo' 'key' +# The parameters are always single quoted, and the repo path is always +# the second parameter. +# Further parameters are not validated here (see below). +die "bad git-annex-shell command: $cmd" + unless $cmd =~ m#^(git-annex-shell '\w+' ')/\~/([0-9a-zA-Z][0-9a-zA-Z._\@/+-]*)('( .*|))$#; +my $start = $1; +my $repo = $2; +my $end = $3; +die "I dont like some of the characters in $repo\n" unless $repo =~ $REPONAME_PATT; +die "I dont like absolute paths in $cmd\n" if $repo =~ /^\//; +die "I dont like '..' paths in $cmd\n" if $repo =~ /\.\./; + +# Modify $cmd, fixing up the path to the repo to include GL_REPO_BASE. +my $newcmd = "$start$rc{GL_REPO_BASE}/$repo$end"; + +# Rather than keeping track of which git-annex-shell commands +# require write access and which are readonly, we tell it +# when readonly access is needed. +if ( can_write($repo) ) { +} elsif ( can_read($repo) ) { + $ENV{GIT_ANNEX_SHELL_READONLY} = 1; +} else { + die "$repo $ENV{GL_USER} DENIED\n"; +} +# Further limit git-annex-shell to safe commands (avoid it passing +# unknown commands on to git-shell) +$ENV{GIT_ANNEX_SHELL_LIMITED} = 1; + +# Note that $newcmd does *not* get evaluated by the unix shell. +# Instead it is passed as a single parameter to git-annex-shell for +# it to parse and handle the command. This is why we do not need to +# fully validate $cmd above. +gl_log( $ENV{SSH_ORIGINAL_COMMAND} ); +exec "git-annex-shell", "-c", $newcmd; + +__END__ + +INSTRUCTIONS... (NEED TO BE VALIDATED BY SOMEONE WHO KNOWS GIT-ANNEX WELL). + +based on http://git-annex.branchable.com/tips/using_gitolite_with_git-annex/ +ONLY VARIATIONS FROM THAT PAGE ARE WRITTEN HERE. + +requirements: + + * gitolite v3.04+ (whatever version has src/commands/git-annex-shell, + because I haven't tagged it yet). + * git-annex as per that + +setup + + * in COMMANDS hash in the rc file, add an entry like this: + 'git-annex-shell' => 'ua', + (there is no GL_ADC_PATH and no "ua" subdirectory here, and nothing to + "install"; the command already comes with gitolite) + +That should be it; everything else should be as in that page. + +Once this is tested I'll move it to 'master'. diff --git a/src/gitolite-shell b/src/gitolite-shell index a3ec321..8f3a128 100755 --- a/src/gitolite-shell +++ b/src/gitolite-shell @@ -152,10 +152,11 @@ sub parse_soc { # after this we should not return; caller expects us to handle it all here # and exit out - _die "suspicious characters loitering about '$soc'" if $soc !~ $REMOTE_COMMAND_PATT; my @words = split ' ', $soc; if ( $rc{COMMANDS}{ $words[0] } ) { + _die "suspicious characters loitering about '$soc'" + if $rc{COMMANDS}{ $words[0] } ne 'ua' and $soc !~ $REMOTE_COMMAND_PATT; trace( 2, "gitolite command", $soc ); _system( "gitolite", @words ); exit 0;