Showing 1 changed files with 60 additions and 5 deletions
+60 -5
script/gitprep-shell
... ...
@@ -9,24 +9,79 @@ use lib "$FindBin::Bin/../lib";
9 9
 use lib "$FindBin::Bin/../extlib/lib/perl5";
10 10
 use Gitprep;
11 11
 
12
-my $user = shift;
12
+# Project name pattern
13
+my $project_re = qr/[a-zA-Z0-9_\-\.]+$/;
13 14
 
15
+# User
16
+my $user = shift;
14 17
 die "User not specifed" unless defined $user;
15 18
 
19
+# Application
16 20
 my $app = Gitprep->new;
21
+
22
+# Git
23
+my $git = $app->git;
24
+
25
+# DBI
17 26
 my $dbi = $app->dbi;
18 27
 
19
-my $public_key = $dbi->model('user')->select('public_keys', id => $user)->value || '';
28
+# SSH connection
29
+my $ssh_connection = $ENV{SSH_CONNECTION};
30
+die "who the *heck* are you?" unless defined $ssh_connection;
31
+
32
+# SSH original command
33
+my $ssh_original_command = $ENV{SSH_ORIGINAL_COMMAND} || '';
34
+
35
+# IP address
36
+my $ip = $ssh_connection || '(no-IP)';
37
+$ip =~ s/ .*//;
38
+
39
+# Check new line of SSH original command
40
+my $ssh_original_command_tmp = $ssh_original_command;
41
+$ssh_original_command_tmp =~ s/[\n\r]+/<<newline>>/g;
42
+die "I don't like newlines in the command: $ssh_original_command\n"
43
+  if $ssh_original_command ne $ssh_original_command_tmp;
44
+
45
+my ($verb, $project) = parse_ssh_original_command($ssh_original_command);
46
+sanity($project);
47
+
48
+my $rep_home = $git->rep_home;
49
+my $repository = "'$rep_home/$project.git'";
50
+my @git_shell_cmd = ("git", "shell", "-c", "$verb $repository");
51
+system(@git_shell_cmd) == 0
52
+  or die "Can't execute command: @git_shell_cmd" ;
53
+
54
+sub parse_ssh_original_command {
55
+  my $ssh_original_command = shift;
56
+
57
+  $ssh_original_command ||= 'info';
58
+
59
+  my $git_commands = "git-upload-pack|git-receive-pack|git-upload-archive";
60
+  if ($ssh_original_command =~ m(^($git_commands) '/?(.*?)(?:\.git)?'$)) {
61
+    my ($verb, $project) = ($1, $2);
62
+    die "invalid repo name: '$project'" if $project !~ $project_re;
63
+    return ($verb, $project);
64
+  }
65
+  else {
66
+    die "Invalid command: $ssh_original_command";
67
+  }
68
+}
69
+
70
+sub sanity {
71
+  my $project = shift;
72
+  die "'$project' contains bad characters" if $project !~ $project_re;
73
+  die "'$project' ends with a '/'"         if $project =~ m(/$);
74
+  die "'$project' contains '..'"           if $project =~ m(\.\.);
75
+}
20 76
 
21
-print $public_key;
22 77
 
23 78
 =head1 NAME
24 79
 
25
-authorized_keys_command - AuthorizedKeysCommand for sshd
80
+gitprep-shell - AuthorizedKeysCommand for sshd
26 81
 
27 82
 =head1 USAGE
28 83
 
29
-  ./authorized_keys_command kimoto
84
+  ./gitprep-shell kimoto
30 85
 
31 86
 This command return user public_key
32 87