git-ssh-wrapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in git-ssh-wrapper.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Martin Emde
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ And now the caps-lock text that's in these things:
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ # GitSSHWrapper
2
+
3
+ Encapsulate the code you need to write out a permissive GIT_SSH script that
4
+ can be used to connect git to protected git@github.com repositories.
5
+
6
+ ## Example
7
+
8
+ def get_refs
9
+ wrapper = GitSSHWrapper.new(:private_key_path => '~/.ssh/id_rsa')
10
+ `env #{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git`
11
+ ensure
12
+ wrapper.unlink
13
+ end
14
+
15
+ OR
16
+
17
+ GitSSHWrapper.new(:private_key => Pathname.new('id_rsa').read)
18
+
19
+ The wrapper creates Temfiles when it is initialized. They will be cleaned at
20
+ program exit, or you can unlink them by calling #unlink like the example above.
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'spec/rake/spectask'
5
+ Spec::Rake::SpecTask.new(:spec) do |spec|
6
+ spec.libs << 'lib' << 'spec'
7
+ spec.spec_files = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |s|
3
+ s.name = "git-ssh-wrapper"
4
+ s.version = "0.0.1"
5
+ s.authors = ["Martin Emde"]
6
+ s.email = ["martin.emde@gmail.com"]
7
+ s.homepage = "http://github.org/martinemde/git-ssh-wrapper"
8
+ s.summary = %q{Generate a permissive GIT_SSH wrapper script on the fly}
9
+ 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.}
10
+
11
+ s.add_development_dependency "rspec"
12
+ s.add_development_dependency "open4"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+ end
@@ -0,0 +1,91 @@
1
+ require 'tempfile'
2
+ require 'pathname'
3
+
4
+ class GitSSHWrapper
5
+
6
+ class PrivateKeyRequired < ArgumentError
7
+ def initialize
8
+ super "You must specify either :private_key_path (path to ssh private key) or :private_key (string of ssh private key)."
9
+ end
10
+ end
11
+
12
+ SAFE_MODE = 0600
13
+ EXEC_MODE = 0700
14
+
15
+ SSH_CONFIG = <<-CONFIG
16
+ Host *
17
+ PasswordAuthentication no
18
+ StrictHostKeyChecking no
19
+ RSAAuthentication yes
20
+ ConnectTimeout 5
21
+ IdentityFile %s
22
+ CheckHostIP no
23
+ CONFIG
24
+
25
+ SCRIPT = <<-SCRIPT
26
+ #!/bin/bash
27
+ unset SSH_AUTH_SOCK
28
+ ssh -F %s $*
29
+ SCRIPT
30
+
31
+ def self.tempfile(content, mode=SAFE_MODE)
32
+ file = Tempfile.new("git-ssh-wrapper")
33
+ file << content
34
+ file.chmod(mode)
35
+ file.flush
36
+ file.close
37
+ file
38
+ end
39
+
40
+ def self.with_wrapper(options)
41
+ wrapper = new(options)
42
+ yield wrapper
43
+ ensure
44
+ wrapper.unlink
45
+ end
46
+
47
+ attr_reader :path
48
+
49
+ def initialize(options)
50
+ if options[:private_key_path].to_s.empty? && options[:private_key].to_s.empty?
51
+ raise PrivateKeyRequired
52
+ end
53
+
54
+ @tempfiles = []
55
+ @key_path = options[:private_key_path] || tempfile(options[:private_key])
56
+ @ssh_config = ssh_config(@key_path)
57
+ @path = script(@ssh_config)
58
+ end
59
+
60
+ def pathname
61
+ Pathname.new(path)
62
+ end
63
+
64
+ def git_ssh
65
+ "GIT_SSH='#{path}'"
66
+ end
67
+
68
+ def set_env
69
+ ENV['GIT_SSH'] = path
70
+ end
71
+
72
+ def unlink
73
+ @tempfiles.each { |file| file.unlink }.clear
74
+ end
75
+
76
+ private
77
+
78
+ def script(config_path)
79
+ tempfile(SCRIPT % config_path, EXEC_MODE)
80
+ end
81
+
82
+ def ssh_config(private_key_path)
83
+ tempfile(SSH_CONFIG % private_key_path)
84
+ end
85
+
86
+ def tempfile(content, mode=SAFE_MODE)
87
+ file = self.class.tempfile(content, mode)
88
+ @tempfiles << file
89
+ file.path
90
+ end
91
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe GitSSHWrapper do
4
+ shared_examples_for "a GIT_SSH wrapper" do
5
+ it "allows access to secure github repositories" do
6
+ lambda {
7
+ Open4.spawn("#{@git_ssh_wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master", :stdout => '', :stderr => '')
8
+ }.should_not raise_error
9
+ end
10
+
11
+ it "has a script path that really exists" do
12
+ lambda { @git_ssh_wrapper.pathname.realpath }.should_not raise_error
13
+ end
14
+
15
+ it "formats a string with the GIT_SSH= in front of the script" do
16
+ @git_ssh_wrapper.git_ssh.should == "GIT_SSH='#{@git_ssh_wrapper.path}'"
17
+ end
18
+
19
+ it "disappears when unlinked" do
20
+ pathname = @git_ssh_wrapper.pathname
21
+ @git_ssh_wrapper.unlink
22
+ pathname.should_not be_exist # ;_; syntax h8
23
+ end
24
+ end
25
+
26
+ context "with a key string" do
27
+ before { @git_ssh_wrapper = described_class.new(:private_key => private_key) }
28
+ after { @git_ssh_wrapper.unlink }
29
+ it_should_behave_like "a GIT_SSH wrapper"
30
+ end
31
+
32
+ context "with a key file" do
33
+ before { @git_ssh_wrapper = described_class.new(:private_key_path => private_key_path) }
34
+ after { @git_ssh_wrapper.unlink }
35
+ it_should_behave_like "a GIT_SSH wrapper"
36
+
37
+ it "should not delete the keyfile when unlinked" do
38
+ pathname = Pathname.new(private_key_path)
39
+ pathname.should be_exist
40
+ @git_ssh_wrapper.unlink
41
+ pathname.should be_exist
42
+ end
43
+ end
44
+
45
+ context "without a key" do
46
+ it "should raise a PrivateKeyRequired error (ArgumentError)" do
47
+ # the errors are the same, alternating just to ensure inheritence
48
+ lambda { described_class.new({}) }.should raise_error(GitSSHWrapper::PrivateKeyRequired)
49
+ lambda { described_class.new(:private_key => '') }.should raise_error(ArgumentError)
50
+ lambda { described_class.new(:private_key_path => '') }.should raise_error(GitSSHWrapper::PrivateKeyRequired)
51
+ end
52
+ end
53
+
54
+ context "#with_git_ssh" do
55
+ it "allows access to secure github repositories" do
56
+ GitSSHWrapper.with_wrapper(:private_key => private_key) do |wrapper|
57
+ lambda {
58
+ Open4.spawn("#{wrapper.git_ssh} git ls-remote git@github.com:martinemde/git-ssh-wrapper.git refs/heads/master", :stdout => '', :stderr => '')
59
+ }.should_not raise_error
60
+ end
61
+ end
62
+
63
+ it "has a script path that really exists" do
64
+ GitSSHWrapper.with_wrapper(:private_key => private_key) do |wrapper|
65
+ lambda { wrapper.pathname.realpath }.should_not raise_error
66
+ end
67
+ end
68
+
69
+ it "formats a string with the GIT_SSH= in front of the script" do
70
+ GitSSHWrapper.with_wrapper(:private_key => private_key) do |wrapper|
71
+ wrapper.git_ssh.should == "GIT_SSH='#{wrapper.path}'"
72
+ end
73
+ end
74
+
75
+ it "disappears when unlinked" do
76
+ pathname = nil
77
+ GitSSHWrapper.with_wrapper(:private_key => private_key) do |wrapper|
78
+ pathname = wrapper.pathname
79
+ end
80
+ pathname.should_not be_exist
81
+ end
82
+ end
83
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,25 @@
1
+ unless defined? Bundler
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.setup
5
+ end
6
+
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
+ require 'git-ssh-wrapper'
10
+ require 'spec'
11
+ require 'open4'
12
+
13
+ module TestPrivateKey
14
+ def private_key
15
+ private_key_path.read
16
+ end
17
+
18
+ def private_key_path
19
+ Pathname.new('spec/test_key').realpath
20
+ end
21
+ end
22
+
23
+ Spec::Runner.configure do |config|
24
+ config.include TestPrivateKey
25
+ end
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAtyIuIRs9To4WJOsNgdRviR5Ud5Z1Ouk1FK6UcvvAz8+Z5E2j
3
+ scVh8ukrBF8hwCGMi4tUy34Qg4tNGS5Y6LbiIWYb9C6ucbUCnxOzonyS80BlBpJi
4
+ R/D29ylgA7HXfkIfoE8Duo7lzB3ZYHmNSRCES1y7rhTzOcvuyf08CzedJ68EU0Z1
5
+ twg64Bksjcv0kDWAMCOKwhVjc0UY2y9PFjFr+GWIcwfT8opChLuDSA1NQCT54DVd
6
+ 4yUYMYdZyPM9egYw8aglxatT8BSA+rFjYuSlYmwUzdPR7hDYS7VHXcd2XGH0sOHG
7
+ VgapvMGXYWPu0O2BGxAiVty3njuh3vLUDCTBBwIBIwKCAQAvF2rykfnSXw0CLdBF
8
+ 9Mw5M69R8307CMSBqTwdkTGUhdcdcwzV8O1NF2LVPQitv3vpXleiCnlGZaYcawDr
9
+ Yjol2G2Wj6kzLoulP5SXfx55EI8BsJzt7YFVf6r5osJiS4R5resEFh3VZsLeSyRU
10
+ ndjgLcncToevxrm+6ViVK47PsDnSF5NMdsLFH0RedTEwjU09+xSfWmXyL36bx4Kr
11
+ UuzvO7zg2Fif6pqDibWa990mFaQHA6zmHVSzMYvxtfG7yGcderxolNCD0Z455TY4
12
+ R6MRdJbwUgguWnulvfsIxbrqOHGDX/iIVZbLsNMyEUUlxAeIXJSWQxRt00mwNQLl
13
+ 3dGDAoGBAOSnHoXjUZMSFl2pLgaxFg5aVudIjpyK6YfVQaOCgIRTyVZd4fRoryMS
14
+ Yx0lufsZGH/OSw7Wdz10FDqATroIr7P9UpFGNqwenn4iubQMRhWj4u8or2Wvzll3
15
+ phaj6aYsCawLugfxyfX0C/I2fz9/y3dFbTuESAigkB99ccUC/BllAoGBAM0JWnoc
16
+ IbJdpaiRubzM+fAdpuF/mQGP28EZ5cvc/KOQev44+PiqLlTIJGsAj2foRopoajzj
17
+ H1h2XRuANkklSyTXBn7owCeX8X8TQ2q0pGrsbmjiHkxtjUik1wsl+U6hfMgYB9tu
18
+ fhQF6YxLvfe+RCVuAfpRVu3EWWPQsudSWD/7AoGAGiG6WHHALhCyGVUp1OEJ1cEu
19
+ gNUXnNys+ZS3C19fJRDjz1svxCk4lks+hvz/T+WcZmC4HvPwXstwBq+T+AD+IzLk
20
+ 3WccMO2OdNDExB6o7IfCKfYFarUBo9Mo7KUEwoiwpfK2LMstBiqFBb0V218P8F+0
21
+ tlhCvyhK/EjZzV9tRLsCgYEAjJizEednkEA3FIEu590DKE7Y1SRLqUyz8iBjD3L2
22
+ YYeky5TH+vhaSMPBM24ZMU7RSPckRwIkH2cbRg7GI4dJeFjugui+RwkaoEe5MzoK
23
+ V/KU2jSnD9YXvMjN+QQYqvJkMW+QW/P+rqT36yyfhU9Eq/OplbQeWeW5o4fLIkcX
24
+ 8VsCgYEAnHEDk4IIOX2ji7jy2WpgigabS8Eu9MjrcvVg/yIF0RUzAiTqyyn+vfcp
25
+ p7v5pGEH8My79GDTzwOLTFbB/GjNw0e9t2hpcu3je12QGp/IIqQACdG7kvM4FYx7
26
+ 0TkYcc6cR7dxLt+mocxvn9XVw8WqK1BlQcXa/YsV80oZ1DlbqcA=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtyIuIRs9To4WJOsNgdRviR5Ud5Z1Ouk1FK6UcvvAz8+Z5E2jscVh8ukrBF8hwCGMi4tUy34Qg4tNGS5Y6LbiIWYb9C6ucbUCnxOzonyS80BlBpJiR/D29ylgA7HXfkIfoE8Duo7lzB3ZYHmNSRCES1y7rhTzOcvuyf08CzedJ68EU0Z1twg64Bksjcv0kDWAMCOKwhVjc0UY2y9PFjFr+GWIcwfT8opChLuDSA1NQCT54DVd4yUYMYdZyPM9egYw8aglxatT8BSA+rFjYuSlYmwUzdPR7hDYS7VHXcd2XGH0sOHGVgapvMGXYWPu0O2BGxAiVty3njuh3vLUDCTBBw==
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-ssh-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Martin Emde
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-04 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: open4
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description: Generate a permissive GIT_SSH wrapper script using a private key string or file for use with git commands that need ssh.
50
+ email:
51
+ - martin.emde@gmail.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - LICENSE
62
+ - README.md
63
+ - Rakefile
64
+ - git-ssh-wrapper.gemspec
65
+ - lib/git-ssh-wrapper.rb
66
+ - spec/git_ssh_wrapper_spec.rb
67
+ - spec/spec.opts
68
+ - spec/spec_helper.rb
69
+ - spec/test_key
70
+ - spec/test_key.pub
71
+ has_rdoc: true
72
+ homepage: http://github.org/martinemde/git-ssh-wrapper
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Generate a permissive GIT_SSH wrapper script on the fly
105
+ test_files:
106
+ - spec/git_ssh_wrapper_spec.rb
107
+ - spec/spec.opts
108
+ - spec/spec_helper.rb
109
+ - spec/test_key
110
+ - spec/test_key.pub