I use something a bit simpler, all you need is to setup three files, the authorized_keys
file, the gitsecurity.rb
file and a permissions file gitpermissions
. For simplicity they can all go in the git accounts .ssh folder. (Basic unix admin skills required to understand herein)
The gitpermissions
file looks like this, and should be fairly self explanitory:
repo1.git|jane|rw
repo1.git|james|r
repo2.git|bob|rw
The autorized_keys
file looks something like this:
command="/Users/git/.ssh/gitsecurity.rb jacob",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa rFaivBw.....5Rws jacob
command="/Users/git/.ssh/gitsecurity.rb bob",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa rFaivBw.....5Rws bob
Finally the gitsecurity.rb
script, just copy and paste it:
#!/usr/bin/ruby
class GitPermission
attr_accessor :username;
attr_accessor :repository;
attr_accessor :read;
attr_accessor :write;
def initialize(line)
bits = line.split('|');
if(bits.length!=3)
$stderr.puts "Invalid configuration file"
Process.exit(4)
end
@repository = bits[0]
@username = bits[1]
@read = bits[2].include?("r")
@write = bits[2].include?("w")
end
end
if(!ENV.has_key?("SSH_ORIGINAL_COMMAND"))
$stderr.puts "SSH not allowed to the git account."
Process.exit(1);
end
command = ENV["SSH_ORIGINAL_COMMAND"];
if(!ARGV.length == 1)
$stderr.puts "Authorised keys file misconfigured, username not specified correctly."
Process.exit(1);
end
if(!ARGV[0].match(/^[A-Za-z0-9]+$/))
$stderr.puts "Authorised keys file misconfigured, username contains invalid characters: "+ARGV[0];
Process.exit(1);
end
username = ARGV[0]
if(!command.match(/git[ -]upload-pack /) && !command.match(/^git[ -]receive-pack /))
$stderr.puts "Only git commands are allowed."
Process.exit(2);
end
repository = command[(command.index(' ')+1)..-1]
if(!repository.match(/'.*'/))
$stderr.puts "Repository parameter incorrect."
Process.exit(2);
end
repository = repository[1,repository.length-2]
begin
file = File.new("/Users/git/.ssh/gitpermissions", "r")
while (line = file.gets)
p = GitPermission.new(line);
if(p.repository == repository && p.username == username)
if((p.write == true || (p.read == true && command.match(/^git[ -]upload-pack/))) )
exec "/usr/local/git/bin/" + command
Process.exit(0);
end
end
end
file.close
rescue => err
$stderr.puts "Problem with server configuration: #{err}"
Process.exit(4)
end
$stderr.puts "You do not have permission to complete this operation"
Process.exit(5)