#!/usr/bin/env ruby require "yaml" if File.symlink?(__FILE__) $:.unshift File.dirname(File.readlink(__FILE__)) + "/../lib/gitorious/ssh" BASE_DIR = File.dirname(File.readlink(__FILE__)) + "/../" conf_file = File.join(BASE_DIR, "config/gitorious.yml") else $:.unshift File.dirname(__FILE__) + "/../lib/gitorious/ssh" BASE_DIR = File.dirname(__FILE__) + "/../" conf_file = File.join(BASE_DIR, "config/gitorious.yml") end GitoriousConfig = YAML.load_file(conf_file) ENV["PATH"] = "/usr/local/bin/:/opt/local/bin:#{ENV["PATH"]}" require "logger" require "strainer" require "client" File.umask(0022) original_command = ENV["SSH_ORIGINAL_COMMAND"] user = ARGV[0] logger = Logger.new(File.join(BASE_DIR, "log", "gitorious_auth.log")) logger.formatter = Logger::Formatter.new logger.level = Logger::INFO logger.formatter.datetime_format = "%Y-%m-%d %H:%M:%S" logger.info("Connection from #{ENV['SSH_CLIENT'].inspect} (#{user || nil}): #{original_command || nil}") $stderr.puts "original_command: #{original_command.inspect}" if $DEBUG if original_command.nil? || original_command.strip.empty? $stderr.puts "Need SSH_ORIGINAL_COMMAND" exit!(1) end $stderr.puts "user: #{user.inspect}" if $DEBUG if user.nil? || user.strip.empty? $stderr.puts "Need user arg" exit!(1) end begin strainer = Gitorious::SSH::Strainer.new(original_command).parse! client = Gitorious::SSH::Client.new(strainer, user) # The meat of it all; do the permission check # replace process with git-shell if everything is fine args = client.to_git_shell_argument args.include?('git-receive-pack') && client.assure_user_can_write! $stderr.puts "git-shell -c #{args.inspect}" if $DEBUG exec("git-shell", "-c", args) unless $?.success? $stderr.puts "Failed to execute git command" exit!(1) end rescue Gitorious::SSH::AccessDeniedError => e $stderr.puts "Access denied or bad repository path" exit!(1) rescue Gitorious::SSH::BadCommandError => e $stderr.puts "Access denied or bad command" exit!(1) rescue Object => e if $DEBUG $stderr.puts "#{e.class.name} #{e.message}" $stderr.puts e.backtrace.join(" \n") end $stderr.puts "fatal error" exit(1) end