diff --git a/doc/6-ssh-troubleshooting.mkd b/doc/6-ssh-troubleshooting.mkd index 9548792..8189af8 100644 --- a/doc/6-ssh-troubleshooting.mkd +++ b/doc/6-ssh-troubleshooting.mkd @@ -25,6 +25,10 @@ very detailed look at how gitolite uses ssh's features on the server side. Most people don't know ssh as well as they *think* they do; even if you dont have any problems right now, it's worth skimming over. +In addition to both these documents, there's now a program called +`sshkeys-lint` that you can run on your client. Run it without arguments to +get help on how to run it and what inputs it needs. + Please also note that ssh problems don't always look like ssh problems. One common example: when the remote says the repo you're trying to access "does not appear to be a git repository", and yet you are sure it exists, you diff --git a/src/sshkeys-lint b/src/sshkeys-lint new file mode 100755 index 0000000..acb8d72 --- /dev/null +++ b/src/sshkeys-lint @@ -0,0 +1,100 @@ +#!/usr/bin/perl -w + +use strict; +our (%users, %linenos); + +&usage unless $ARGV[0] and -f $ARGV[0]; +my @authlines = &filelines($ARGV[0]); +my $lineno = 0; +for (@authlines) +{ + $lineno++; + if (/^# gitolite start/ .. /^# gitolite end/) { + warn "line $lineno: non-gitolite key found in gitolite section" if /ssh-rsa|ssh-dss/ and not /command=.*gl-auth-command/; + } else { + warn "line $lineno: gitolite key found outside gitolite section" if /command=.*gl-auth-command/; + } + next if /\# gitolite (start|end)/; + die "line $lineno: unrecognised line\n" unless /^(?:command=".*gl-auth-command (\S+?)"\S+ )?(?:ssh-rsa|ssh-dss) (\S+)/; + my ($user, $key) = ($1 || '', $2); + if ($linenos{$key}) { + warn "authkeys file line $lineno is repeat of line $linenos{$key}, will be ignored by server sshd\n"; + next; + } + $linenos{$key} = $lineno; + $users{$key} = ($user ? "maps to gitolite user $user" : "gets you a command line"); +} + +print "\n"; + +# all *.pub in current dir should be exactly one line, starting with ssh-rsa +# or ssh-dss + +my @pubkeys = glob("*.pub"); +die "no *.pub files here\n" unless @pubkeys; +for my $pub (@pubkeys) { + my @lines = &filelines($pub); + die "$pub has more than one line\n" if @lines > 1; + die "$pub does not start with ssh-rsa or ssh-dss\n" unless $lines[0] =~ /^(?:ssh-rsa|ssh-dss) (\S+)/; + my $key = $1; + if ($users{$key}) { + print "$pub $users{$key}\n"; + } else { + print "$pub has NO ACCESS to the server\n"; + } +} + +print <; +} + +sub usage +{ + print STDERR <