aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Ruppert <idl0r@gentoo.org>2012-02-18 01:22:43 +0100
committerChristian Ruppert <idl0r@gentoo.org>2012-02-18 18:30:16 +0100
commit0c2f687a208b0932b7257784ea498f2a0aa92865 (patch)
tree4a1c50c607338a699a2025a443ccf80338d0d07e
parentAllow one to specify a per repository umask (diff)
downloadgitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.tar.gz
gitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.tar.bz2
gitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.zip
Improved setup_authkeys() function
-rw-r--r--src/gitolite.pm74
1 files changed, 44 insertions, 30 deletions
diff --git a/src/gitolite.pm b/src/gitolite.pm
index 56f60b7..04b3ac1 100644
--- a/src/gitolite.pm
+++ b/src/gitolite.pm
@@ -51,6 +51,8 @@ use Data::Dumper;
$Data::Dumper::Deepcopy = 1;
$|++;
+use Net::SSH::AuthorizedKeysFile; # To parse the pubkeyfile with options etc.
+
# ----------------------------------------------------------------------------
# find the rc file, then pull the libraries
# ----------------------------------------------------------------------------
@@ -1056,7 +1058,13 @@ sub setup_authkeys
my $AUTH_COMMAND="$ENV{GL_BINDIR}/gl-auth-command";
$AUTH_COMMAND="$ENV{GL_BINDIR}/gl-time $ENV{GL_BINDIR}/gl-auth-command" if $GL_PERFLOGT;
# set default authentication options
- $AUTH_OPTIONS ||= "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty";
+ my @AUTH_OPTIONS_PRESERVE = ( "from" );
+ my %AUTH_OPTIONS = (
+ "no-port-forwarding" => 1,
+ "no-X11-forwarding" => 1,
+ "no-agent-forwarding" => 1,
+ "no-pty" => 1,
+ );
# START
@@ -1073,14 +1081,14 @@ sub setup_authkeys
# add our "start" line, each key on its own line (prefixed by command and
# options, in the standard ssh authorized_keys format), then the "end" line.
print $newkeys_fh "# gitolite start\n";
- wrap_chdir($GL_KEYDIR);
+ my @pubkeys = find_pubkeys($GL_KEYDIR);
my @not_in_config; # pubkeys exist but users don't appear in the config file
- for my $pubkey (`find . -type f | sort`)
- {
- chomp($pubkey); $pubkey =~ s(^\./)();
+ foreach my $pubkey (@pubkeys) {
+ my $pubkey_name = $pubkey;
+ $pubkey_name =~ s(.*/)(); # foo/bar/baz.pub -> baz.pub
# security check (thanks to divVerent for catching this)
- unless ($pubkey =~ $REPONAME_PATT) {
+ unless ($pubkey_name =~ $REPONAME_PATT) {
warn "$pubkey contains some unsavoury characters; ignored...\n";
next;
}
@@ -1092,35 +1100,41 @@ sub setup_authkeys
next;
}
- my $user = $pubkey;
- $user =~ s(.*/)(); # foo/bar/baz.pub -> baz.pub
- $user =~ s/(\@[^.]+)?\.pub$//; # baz.pub, baz@home.pub -> baz
+ my $user = $pubkey_name;
+ $user =~ s/(\@[^.]+)?\.pub$//; # baz.pub, baz@home.pub -> baz
# lint check 2 -- don't print right now; just collect the messages
push @not_in_config, "$user($pubkey)" if %$user_list_p and not $user_list_p->{$user};
$user_list_p->{$user} = 'has pubkey' if %$user_list_p;
- # apparently some pubkeys don't end in a newline...
- my $pubkey_content;
- {
- local $/ = undef;
- local @ARGV = ($pubkey);
- $pubkey_content = <>;
- $pubkey_content =~ s/^\s*#.*\n//gm;
- }
- $pubkey_content =~ s/\s*$/\n/;
- # don't trust files with multiple lines (i.e., something after a newline)
- if ($pubkey_content =~ /\n./)
- {
- warn "WARNING: a pubkey file can only have one line (key); ignoring $pubkey\n" .
- " Perhaps you're using a key in a different format (like putty/plink)?\n" .
- " If so, please convert it to openssh format using 'ssh-keygen -i'.\n" .
- " If you want to add multiple public keys for a single user, use\n" .
- " \"user\@host.pub\" file names. See the \"one user, many keys\"\n" .
- " section in doc/3-faq-tips-etc.mkd for details.\n";
- next;
+
+ # Parse the pubkey including all options etc...
+ # Use strict mode to abort on faulty files.
+ my $akf = Net::SSH::AuthorizedKeysFile->new( strict => 1, );
+ $akf->read($pubkey);
+
+ foreach my $keyobj ($akf->keys()) {
+ # lint check 3 -- ignore faulty keys
+ if(!defined($keyobj)) {
+ print STDERR "Malformed key '$pubkey', skipping...\n";
+ next;
+ }
+
+ # Preserve only options specified in AUTH_OPTIONS_PRESERVE.
+ foreach my $option (keys(%{$keyobj->options})) {
+ if(!grep(/^\Q${option}\E$/, @AUTH_OPTIONS_PRESERVE)) {
+ delete($keyobj->options->{$option});
+ }
+ }
+
+ # Add our options as well.
+ foreach my $option (keys(%AUTH_OPTIONS)) {
+ $keyobj->option($option, $AUTH_OPTIONS{$option});
+ }
+
+ $keyobj->option("command", "$AUTH_COMMAND $user");
+
+ print $newkeys_fh $keyobj->as_string()."\n";
}
- print $newkeys_fh "command=\"$AUTH_COMMAND $user\",$AUTH_OPTIONS ";
- print $newkeys_fh $pubkey_content;
}
# lint check 2 -- print less noisily