3 # For licensing and copyright terms, see the file named LICENSE
7 # We are invoked by sshd as the repo serving user in place of the actual
8 # command they requested.
9 # Our purpose is to interpose and ensure that the underlying tool looks
10 # only at the appropriate location
13 # $1: path to the mtrack config.ini file
14 # $2: the mtrack username
15 # However, at least on OS/X, we get invoked as "-c '$1 $2'", so we need
18 my ($inifile, $username, $mtrack) = @ARGV;
20 if ($inifile eq '-c') {
21 require 'shellwords.pl';
22 @ARGV = &shellwords($username);
24 ($inifile, $username, $mtrack) = @ARGV;
26 $ENV{MTRACK_CONFIG_FILE} = $inifile;
28 # The command requested by the remote user is stored in this envvar.
29 my $cmd = $ENV{SSH_ORIGINAL_COMMAND};
31 sub validate_reponame {
34 if ($name =~ m/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/) {
35 if ($name !~ m/\.\./) {
36 my $base = get_cfg('repos', 'basedir');
37 if (! -d "$base/$name") {
38 print STDERR "Non-existant repo $name\n";
42 # Sanity check that we at least have checkout access
43 my $php = get_tool('php');
44 if (system($php, "$mtrack/bin/acl-check.php", $username, '--repo',
46 print STDERR "$username does not have checkout permission on $name\n";
53 print STDERR "Invalid repo name $name\n";
59 sub read_config_file {
60 my $f = IO::File->new($inifile);
62 print STDERR "Unable to open ini file $inifile: $!\n";
70 if ($line =~ m/^\[(.*)\]$/) {
74 if ($line =~ m/^(\S+)\s*=\s*"(.*)"$/) {
78 if ($line =~ m/^(\S+)\s*=\s*(.*)$/) {
86 my ($sect, $name) = @_;
89 if (not exists $CFG{$sect}) {
92 if (not exists $CFG{$sect}{$name}) {
95 $val = $CFG{$sect}{$name};
97 while ($val =~ m/\@\{(\S+):(\S+)\}/) {
98 my ($s, $k) = ($1, $2);
101 if (exists $CFG{$s} and exists $CFG{$s}{$k}) {
104 $val =~ s/\@\{$s:$k\}/$r/g;
113 my $tool = get_cfg('tools', $name);
117 print STDERR "tool $name is not configured\n";
121 $ENV{LOGNAME} = $username;
123 open LOG, ">>/var/tmp/mtrack.ssh.session.log";
124 print LOG "$username $cmd\n";
128 if ($cmd =~ m/^hg -R (\S+) serve --stdio$/) {
129 my $name = validate_reponame($1);
131 my $hg = get_tool('hg');
133 exec($hg, '-R', $name, 'serve', '--stdio');
136 if ($cmd =~ m/^git-(\S+)\s+'(\S+)'$/) {
137 my ($verb, $name) = ($1, $2);
138 $name = validate_reponame($name);
139 my $git = get_tool('git');
141 exec($git, 'shell', '-c', "git-$verb '$name'");
144 if ($cmd eq 'svnserve -t') {
145 my $base = get_cfg('repos', 'basedir');
147 print STDERR "basedir $base does not exist\n";
150 my $svnserve = get_tool('svnserve');
151 exec($svnserve, '-r', $base, '-t', "--tunnel-user=$username");
154 print STDERR "Unsupported command:\n$cmd\n";