Skip to content

Commit

Permalink
Modernize the git ssh wrapper to use simpler ssh config.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinemde committed Feb 18, 2012
1 parent 951b5c8 commit 72f2362
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 54 deletions.
1 change: 0 additions & 1 deletion Gemfile
@@ -1,4 +1,3 @@
source "http://rubygems.org"

# Specify your gem's dependencies in git-ssh-wrapper.gemspec
gemspec
15 changes: 12 additions & 3 deletions README.md
Expand Up @@ -6,15 +6,24 @@ can be used to connect git to protected git@github.com repositories.
## Example

def get_refs
wrapper = GitSSHWrapper.new(:private_key_path => '~/.ssh/id_rsa')
wrapper = GitSSHWrapper.new(:private_key_path => '~/.ssh/id_rsa', :log_level => 'ERROR')
`env #{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git`
ensure
wrapper.unlink
end

OR

GitSSHWrapper.new(:private_key => Pathname.new('id_rsa').read)
# :log_level default in 'INFO'
def get_refs
GitSSHWrapper.new(:private_key_path => '~/.ssh/id_rsa') do |wrapper|
`env #{wrapper.cmd_prefix} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git`
end
end

OR

wrapper = GitSSHWrapper.new(:private_key => Pathname.new('id_rsa').read)

The wrapper creates Temfiles when it is initialized. They will be cleaned at
The wrapper creates Tempfiles when it is initialized. They will be cleaned at
program exit, or you can unlink them by calling #unlink like the example above.
9 changes: 4 additions & 5 deletions Rakefile
@@ -1,10 +1,9 @@
require 'bundler'
Bundler::GemHelper.install_tasks

require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:spec) do |spec|
spec.libs << 'lib' << 'spec'
spec.spec_files = FileList['spec/**/*_spec.rb']
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new do |t|
t.rspec_opts = %w[--color]
t.pattern = 'spec/**/*_spec.rb'
end

task :default => :spec
3 changes: 2 additions & 1 deletion git-ssh-wrapper.gemspec
Expand Up @@ -8,7 +8,8 @@ Gem::Specification.new do |s|
s.summary = %q{Generate a permissive GIT_SSH wrapper script on the fly}
s.description = %q{Generate a permissive GIT_SSH wrapper script using a private key string or file for use with git commands that need ssh.}

s.add_development_dependency "rspec"
s.add_development_dependency "rake"
s.add_development_dependency "rspec", '~> 2.0'
s.add_development_dependency "open4"

s.files = `git ls-files`.split("\n")
Expand Down
38 changes: 12 additions & 26 deletions lib/git-ssh-wrapper.rb
Expand Up @@ -12,21 +12,6 @@ def initialize
SAFE_MODE = 0600
EXEC_MODE = 0700

SSH_CONFIG = <<-CONFIG
Host *
PasswordAuthentication no
StrictHostKeyChecking no
RSAAuthentication yes
ConnectTimeout 5
IdentityFile %s
CheckHostIP no
CONFIG

SCRIPT = <<-SCRIPT
#!/bin/bash
unset SSH_AUTH_SOCK
ssh -F %s $*
SCRIPT

def self.tempfile(content, mode=SAFE_MODE)
file = Tempfile.new("git-ssh-wrapper")
Expand All @@ -51,19 +36,20 @@ def initialize(options)
raise PrivateKeyRequired
end

@tempfiles = []
@key_path = options[:private_key_path] || tempfile(options[:private_key])
@ssh_config = ssh_config(@key_path)
@path = script(@ssh_config)
log_level = (options[:log_level] || 'INFO').upcase
@tempfiles = []
key_path = options[:private_key_path] || tempfile(options[:private_key])
@path = script(key_path, log_level)
end

def pathname
Pathname.new(path)
end

def git_ssh
def cmd_prefix
"GIT_SSH='#{path}'"
end
alias git_ssh cmd_prefix

def set_env
ENV['GIT_SSH'] = path
Expand All @@ -75,12 +61,12 @@ def unlink

private

def script(config_path)
tempfile(SCRIPT % config_path, EXEC_MODE)
end

def ssh_config(private_key_path)
tempfile(SSH_CONFIG % private_key_path)
def script(private_key_path, log_level)
tempfile(<<-SCRIPT, EXEC_MODE)
#!/bin/sh
unset SSH_AUTH_SOCK
ssh -o 'CheckHostIP no' -o 'StrictHostKeyChecking no' -o 'PasswordAuthentication no' -o 'LogLevel #{log_level}' -o 'IdentityFile #{private_key_path}' -o 'IdentitiesOnly yes' -o 'UserKnownHostsFile /dev/null' $*
SCRIPT
end

def tempfile(content, mode=SAFE_MODE)
Expand Down
38 changes: 23 additions & 15 deletions spec/git_ssh_wrapper_spec.rb
Expand Up @@ -3,41 +3,40 @@
describe GitSSHWrapper do
shared_examples_for "a GIT_SSH wrapper" do
it "allows access to secure github repositories" do
lambda {
Open4.spawn("#{@git_ssh_wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master", :stdout => '', :stderr => '')
}.should_not raise_error
`#{subject.cmd_prefix} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master 2>&1`
$?.should be_true
end

it "has a script path that really exists" do
lambda { @git_ssh_wrapper.pathname.realpath }.should_not raise_error
lambda { subject.pathname.realpath }.should_not raise_error
end

it "formats a string with the GIT_SSH= in front of the script" do
@git_ssh_wrapper.git_ssh.should == "GIT_SSH='#{@git_ssh_wrapper.path}'"
subject.git_ssh.should == "GIT_SSH='#{subject.path}'"
end

it "disappears when unlinked" do
pathname = @git_ssh_wrapper.pathname
@git_ssh_wrapper.unlink
pathname = subject.pathname
subject.unlink
pathname.should_not be_exist # ;_; syntax h8
end
end

context "with a key string" do
before { @git_ssh_wrapper = described_class.new(:private_key => private_key) }
after { @git_ssh_wrapper.unlink }
subject { described_class.new(:private_key => private_key) }
after { subject.unlink }
it_should_behave_like "a GIT_SSH wrapper"
end

context "with a key file" do
before { @git_ssh_wrapper = described_class.new(:private_key_path => private_key_path) }
after { @git_ssh_wrapper.unlink }
subject { described_class.new(:private_key_path => private_key_path) }
after { subject.unlink }
it_should_behave_like "a GIT_SSH wrapper"

it "should not delete the keyfile when unlinked" do
pathname = Pathname.new(private_key_path)
pathname.should be_exist
@git_ssh_wrapper.unlink
subject.unlink
pathname.should be_exist
end
end
Expand All @@ -54,9 +53,18 @@
context "#with_git_ssh" do
it "allows access to secure github repositories" do
GitSSHWrapper.with_wrapper(:private_key => private_key) do |wrapper|
lambda {
Open4.spawn("#{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master", :stdout => '', :stderr => '')
}.should_not raise_error
`#{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master 2>&1`
$?.should be_true
end
end

it "allows less noisy ssh" do
GitSSHWrapper.with_wrapper(:private_key => private_key, :log_level => "info") do |wrapper|
`#{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master 2>&1`.should include("Warning: Permanently added 'github.com' (RSA) to the list of known hosts.")
end

GitSSHWrapper.with_wrapper(:private_key => private_key, :log_level => "error") do |wrapper|
`#{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master 2>&1`.should_not include("Warning: Permanently added 'github.com' (RSA) to the list of known hosts.")
end
end

Expand Down
1 change: 0 additions & 1 deletion spec/spec.opts

This file was deleted.

4 changes: 2 additions & 2 deletions spec/spec_helper.rb
Expand Up @@ -7,7 +7,7 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'git-ssh-wrapper'
require 'spec'
require 'rspec'
require 'open4'

module TestPrivateKey
Expand All @@ -20,6 +20,6 @@ def private_key_path
end
end

Spec::Runner.configure do |config|
RSpec.configure do |config|
config.include TestPrivateKey
end

0 comments on commit 72f2362

Please sign in to comment.