git-ssh-wrapper 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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