#!/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 RAILS_ENV = ENV['RAILS_ENV'] ||= 'production' GitoriousConfig = YAML::load_file(conf_file)[RAILS_ENV] 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? logger.info("Need SSH_ORIGINAL_COMMAND") $stderr.puts "Welcome, #{user}. Use git to push/pull your repositories" exit!(1) end $stderr.puts "user: #{user.inspect}" if $DEBUG if user.nil? || user.strip.empty? logger.info("Need user arg") $stderr.puts "Need user arg" exit!(1) end def gitorious_says(msg) $stderr.puts $stderr.puts "== Gitorious: " + ("=" * 58) $stderr.puts msg $stderr.puts "="*72 $stderr.puts end begin strainer = Gitorious::SSH::Strainer.new(original_command).parse! client = Gitorious::SSH::Client.new(strainer, user) args = client.to_git_shell_argument $stderr.puts "git-shell -c #{args.inspect}" if $DEBUG ENV['GITORIOUS_WRITABLE_BY_URL'] = client.writable_by_query_url ENV['GITORIOUS_USER'] = user ENV['GITORIOUS_BASE_DIR'] = BASE_DIR ENV['GITORIOUS_DENY_FORCE_PUSHES'] = client.force_pushing_denied? ? "true" : "false" logger.info("Accepted #{user.inspect} for #{args.inspect}") if client.pre_receive_hook_exists? exec("git-shell", "-c", args) else logger.fatal("The pre-receive hook is not executable") gitorious_says "Fatal error, please contact support" exit!(1) end unless $?.success? logger.fatal("Failed to execute git command") gitorious_says "Failed to execute git command" exit!(1) end rescue Gitorious::SSH::AccessDeniedError => e logger.info("Access denied or bad repository path for #{user.inspect}: #{original_command.inspect}") gitorious_says "Access denied or wrong repository path" exit!(1) rescue Gitorious::SSH::BadCommandError => e logger.info("Access denied or bad command for #{user.inspect}: #{original_command.inspect}") gitorious_says "Access denied or bad command" exit!(1) rescue Errno::ECONNREFUSED => e logger.fatal("Connection refused querying for paths/permissions") gitorious_says("Temporary error. Please try again shortly") exit!(1) rescue Object => e if $DEBUG $stderr.puts "#{e.class.name} #{e.message}" $stderr.puts e.backtrace.join(" \n") end logger.fatal("#{e.class.name} #{e.message}: #{e.backtrace.join("\n ")}") gitorious_says "fatal error" exit(1) end