diff options
author | Christian Ruppert <idl0r@gentoo.org> | 2012-02-18 01:22:43 +0100 |
---|---|---|
committer | Christian Ruppert <idl0r@gentoo.org> | 2012-02-18 18:30:16 +0100 |
commit | 0c2f687a208b0932b7257784ea498f2a0aa92865 (patch) | |
tree | 4a1c50c607338a699a2025a443ccf80338d0d07e | |
parent | Allow one to specify a per repository umask (diff) | |
download | gitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.tar.gz gitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.tar.bz2 gitolite-gentoo-0c2f687a208b0932b7257784ea498f2a0aa92865.zip |
Improved setup_authkeys() function
-rw-r--r-- | src/gitolite.pm | 74 |
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 |