net-ssh 2.9.4 → 2.10.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +11 -4
- data/CHANGES.txt +15 -5
- data/README.rdoc +1 -1
- data/Rakefile +12 -5
- data/lib/net/ssh.rb +16 -1
- data/lib/net/ssh/authentication/key_manager.rb +20 -11
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +11 -4
- data/lib/net/ssh/authentication/methods/password.rb +3 -1
- data/lib/net/ssh/authentication/pageant.rb +32 -12
- data/lib/net/ssh/connection/channel.rb +7 -26
- data/lib/net/ssh/connection/session.rb +2 -11
- data/lib/net/ssh/proxy/command.rb +14 -3
- data/lib/net/ssh/ruby_compat.rb +0 -5
- data/lib/net/ssh/transport/algorithms.rb +3 -4
- data/lib/net/ssh/transport/cipher_factory.rb +0 -1
- data/lib/net/ssh/transport/session.rb +8 -7
- data/lib/net/ssh/version.rb +4 -4
- data/net-ssh-public_cert.pem +15 -15
- data/net-ssh.gemspec +9 -5
- data/setup.rb +1 -1
- data/test/README.txt +6 -13
- data/test/authentication/methods/test_keyboard_interactive.rb +21 -0
- data/test/authentication/test_key_manager.rb +5 -1
- data/test/connection/test_channel.rb +0 -3
- data/test/connection/test_session.rb +8 -17
- data/test/integration/README.txt +19 -0
- data/test/integration/Vagrantfile +12 -0
- data/test/integration/common.rb +57 -0
- data/test/integration/playbook.yml +46 -0
- data/test/integration/test_id_rsa_keys.rb +78 -0
- data/test/start/test_options.rb +8 -1
- data/test/test_all.rb +1 -0
- data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +5 -1
- data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +5 -1
- data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +2 -17
- data/test/transport/test_algorithms.rb +21 -17
- data/test/transport/test_session.rb +1 -1
- metadata +24 -20
- metadata.gz.sig +0 -0
- data/Rudyfile +0 -96
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'rubygems'
|
2
3
|
require 'net/ssh/proxy/errors'
|
3
4
|
require 'net/ssh/ruby_compat'
|
4
5
|
|
@@ -66,12 +67,22 @@ module Net; module SSH; module Proxy
|
|
66
67
|
raise ConnectError, "#{e}: #{command_line}"
|
67
68
|
end
|
68
69
|
@command_line = command_line
|
69
|
-
|
70
|
-
|
70
|
+
if Gem.win_platform?
|
71
|
+
# read_nonblock and write_nonblock are not available on Windows
|
72
|
+
# pipe. Use sysread and syswrite as a replacement works.
|
73
|
+
def io.send(data, flag)
|
74
|
+
syswrite(data)
|
75
|
+
end
|
76
|
+
|
77
|
+
def io.recv(size)
|
78
|
+
sysread(size)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
def io.send(data, flag)
|
71
82
|
write_nonblock(data)
|
72
83
|
end
|
73
84
|
|
74
|
-
def recv(size)
|
85
|
+
def io.recv(size)
|
75
86
|
read_nonblock(size)
|
76
87
|
end
|
77
88
|
end
|
data/lib/net/ssh/ruby_compat.rb
CHANGED
@@ -224,10 +224,9 @@ module Net; module SSH; module Transport
|
|
224
224
|
end
|
225
225
|
lwarn { "unsupported #{algorithm} algorithm: `#{unsupported}'" } unless unsupported.empty?
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
list.each { |name| algorithms[algorithm] << name unless algorithms[algorithm].include?(name) }
|
227
|
+
if options[:append_all_supported_algorithms]
|
228
|
+
list.each { |name| algorithms[algorithm] << name unless algorithms[algorithm].include?(name) }
|
229
|
+
end
|
231
230
|
end
|
232
231
|
end
|
233
232
|
|
@@ -76,7 +76,6 @@ module Net; module SSH; module Transport
|
|
76
76
|
cipher.padding = 0
|
77
77
|
|
78
78
|
cipher.extend(Net::SSH::Transport::CTR) if (name =~ /-ctr(@openssh.org)?$/)
|
79
|
-
|
80
79
|
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
|
81
80
|
|
82
81
|
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
|
@@ -63,14 +63,15 @@ module Net; module SSH; module Transport
|
|
63
63
|
@options = options
|
64
64
|
|
65
65
|
debug { "establishing connection to #{@host}:#{@port}" }
|
66
|
-
|
67
|
-
@socket = timeout(options[:timeout] || 0)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
|
67
|
+
@socket = timeout(options[:timeout] || 0) do
|
68
|
+
if (factory = options[:proxy])
|
69
|
+
factory.open(@host, @port, options)
|
70
|
+
else
|
71
|
+
TCPSocket.open(@host, @port, @bind_address)
|
72
72
|
end
|
73
|
-
|
73
|
+
end
|
74
|
+
|
74
75
|
@socket.extend(PacketStream)
|
75
76
|
@socket.logger = @logger
|
76
77
|
|
data/lib/net/ssh/version.rb
CHANGED
@@ -48,14 +48,14 @@ module Net; module SSH
|
|
48
48
|
MAJOR = 2
|
49
49
|
|
50
50
|
# The minor component of this version of the Net::SSH library
|
51
|
-
MINOR =
|
51
|
+
MINOR = 10
|
52
52
|
|
53
53
|
# The tiny component of this version of the Net::SSH library
|
54
|
-
TINY =
|
54
|
+
TINY = 0
|
55
55
|
|
56
|
-
# The prerelease component of this version of the Net::SSH library
|
56
|
+
# The prerelease component of this version of the Net::SSH library
|
57
57
|
# nil allowed
|
58
|
-
PRE =
|
58
|
+
PRE = 'beta1'
|
59
59
|
|
60
60
|
# The current version of the Net::SSH library as a Version instance
|
61
61
|
CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
|
data/net-ssh-public_cert.pem
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
2
|
MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMRAwDgYDVQQDDAduZXQt
|
3
3
|
c3NoMRkwFwYKCZImiZPyLGQBGRYJc29sdXRpb3VzMRMwEQYKCZImiZPyLGQBGRYD
|
4
|
-
|
4
|
+
Y29tMB4XDTE0MTIwMjE3MzkyMFoXDTE1MTIwMjE3MzkyMFowQjEQMA4GA1UEAwwH
|
5
5
|
bmV0LXNzaDEZMBcGCgmSJomT8ixkARkWCXNvbHV0aW91czETMBEGCgmSJomT8ixk
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0qnw4JV5JN
|
7
|
+
MWelqu7pnW2z6GZJ7+zLFYJQNETJyF0U5zo7aCRK08OeUxnpu/TCCXK8iQVkNLfz
|
8
|
+
9pVIhF+X8pMEIruAkYGwBt1aWfuSNeyodyMk0vpZdxBHbOTJ4qBRUc6qOtNOeOzv
|
9
|
+
8ObYUX52P/EMMaeXTRU+e7MGkB9pb6FvPPNx5akxwIaoRvtcMsc/hJnQuP5r96w6
|
10
|
+
t06MgKbXhWAX6gev0RVlrQqzxXst6iuvsrgZGjFqzob5wbTiX9M0+bFAB0EI7tJC
|
11
|
+
sv5keEbtNRaU7p3ZbMm4wTHHJLOtD+BpUCSzwv4ToNj9mZtJBMYw2Eeo7z1DklEG
|
12
|
+
mr95zbe+zNMCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQU1bTfpzmitXwv
|
13
|
+
LmTXi0IO5vd8NGYwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQA0Aps8
|
14
|
+
UPINGa8XUUtrZtzrgX0/iyXNkKY1ld85g1N3WKEAVLfQI7TlGr0Qv2Ekx6RqlxbR
|
15
|
+
Vyq08pytSnghW2otR3bIGMGQzqxAeRLb25cjEwH7YIJ32n7ZC1fpMnBZOBDmueWA
|
16
|
+
B9EonmoO3ne7AJSgIvBbZzBPhzM4HrQGRW8LsPFsuj+dcJI43HOQwkmv2TRz0+t6
|
17
|
+
mGZldmqLcK0abv4JepLfB9XTue3kuyA29NGBibqyvRwlKckLpvKfHZX6Jxad8xxm
|
18
|
+
MbvRpzgROzyfw1qYi4dnIyMwTtXFFcZ0a2jpxHPkcTYFK6TzvFgDLAP0Y/u9jqUQ
|
19
|
+
eZ7/3CdSi/isZHEw
|
20
20
|
-----END CERTIFICATE-----
|
data/net-ssh.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: net-ssh 2.
|
5
|
+
# stub: net-ssh 2.10.0.beta1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "net-ssh"
|
9
|
-
s.version = "2.
|
9
|
+
s.version = "2.10.0.beta1"
|
10
10
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Jamis Buck", "Delano Mandelbaum", "Mikl\u{f3}s Fazekas"]
|
14
14
|
s.cert_chain = ["net-ssh-public_cert.pem"]
|
15
|
-
s.date = "
|
15
|
+
s.date = "2015-05-21"
|
16
16
|
s.description = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2."
|
17
17
|
s.email = "net-ssh@solutious.com"
|
18
18
|
s.extra_rdoc_files = [
|
@@ -26,7 +26,6 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Manifest",
|
27
27
|
"README.rdoc",
|
28
28
|
"Rakefile",
|
29
|
-
"Rudyfile",
|
30
29
|
"THANKS.txt",
|
31
30
|
"lib/net/ssh.rb",
|
32
31
|
"lib/net/ssh/authentication/agent.rb",
|
@@ -140,6 +139,11 @@ Gem::Specification.new do |s|
|
|
140
139
|
"test/configs/wild_cards",
|
141
140
|
"test/connection/test_channel.rb",
|
142
141
|
"test/connection/test_session.rb",
|
142
|
+
"test/integration/README.txt",
|
143
|
+
"test/integration/Vagrantfile",
|
144
|
+
"test/integration/common.rb",
|
145
|
+
"test/integration/playbook.yml",
|
146
|
+
"test/integration/test_id_rsa_keys.rb",
|
143
147
|
"test/known_hosts/github",
|
144
148
|
"test/manual/test_forward.rb",
|
145
149
|
"test/manual/test_pageant.rb",
|
data/setup.rb
CHANGED
@@ -1460,7 +1460,7 @@ class Installer
|
|
1460
1460
|
begin
|
1461
1461
|
require 'test/unit'
|
1462
1462
|
rescue LoadError
|
1463
|
-
setup_rb_error 'test/unit cannot loaded. You need Ruby 1.
|
1463
|
+
setup_rb_error 'test/unit cannot loaded. You need Ruby 1.9 or later to invoke this task.'
|
1464
1464
|
end
|
1465
1465
|
runner = Test::Unit::AutoRunner.new(true)
|
1466
1466
|
runner.to_run << TESTDIR
|
data/test/README.txt
CHANGED
@@ -1,28 +1,21 @@
|
|
1
|
-
2011-01-19
|
2
|
-
|
3
1
|
RUNNING TESTS
|
4
2
|
|
5
3
|
Run the test suite from the net-ssh directory with the following command:
|
6
4
|
|
7
|
-
ruby -Ilib -Itest
|
5
|
+
ruby -Ilib -Itest test/test_all.rb
|
8
6
|
|
9
7
|
Run a single test file like this:
|
10
8
|
|
11
|
-
ruby -Ilib -Itest
|
12
|
-
|
9
|
+
ruby -Ilib -Itest test/transport/test_server_version.rb
|
13
10
|
|
14
11
|
EXPECTED RESULTS
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
* Ruby 1.8: all tests pass (up until version 2.5)
|
19
|
-
|
20
|
-
* JRuby 1.7: 98% test pass (510 tests, 1914 assertions, 2 failures, 9 errors)
|
21
|
-
|
22
|
-
* JRuby 1.6: 98% test pass (510 tests, 1914 assertions, 4 failures, 5 errors)
|
13
|
+
https://travis-ci.org/net-ssh/net-ssh/
|
23
14
|
|
24
|
-
|
15
|
+
INTEGRATION TESTS
|
25
16
|
|
17
|
+
brew install ansible ; ansible-galaxy install rvm_io.rvm1-ruby ; vagrant up ; vagrant ssh
|
18
|
+
cd /net-ssh ; rake integration-test
|
26
19
|
|
27
20
|
PORT FORWARDING TESTS
|
28
21
|
|
@@ -71,6 +71,27 @@ module Authentication; module Methods
|
|
71
71
|
assert subject.authenticate("ssh-connection", "jamis", "the-password")
|
72
72
|
end
|
73
73
|
|
74
|
+
def test_authenticate_should_not_prompt_for_input_when_in_non_interactive_mode
|
75
|
+
|
76
|
+
def transport.options
|
77
|
+
{non_interactive: true}
|
78
|
+
end
|
79
|
+
transport.expect do |t,packet|
|
80
|
+
assert_equal USERAUTH_REQUEST, packet.type
|
81
|
+
t.return(USERAUTH_INFO_REQUEST, :string, "", :string, "", :string, "", :long, 2, :string, "Name:", :bool, true, :string, "Password:", :bool, false)
|
82
|
+
t.expect do |t2,packet2|
|
83
|
+
assert_equal USERAUTH_INFO_RESPONSE, packet2.type
|
84
|
+
assert_equal 2, packet2.read_long
|
85
|
+
assert_equal "", packet2.read_string
|
86
|
+
assert_equal "", packet2.read_string
|
87
|
+
t2.return(USERAUTH_SUCCESS)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
assert subject.authenticate("ssh-connection", "jamis", nil)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
74
95
|
def test_authenticate_should_prompt_for_input_when_password_is_not_given
|
75
96
|
subject.expects(:prompt).with("Name:", true).returns("name")
|
76
97
|
subject.expects(:prompt).with("Password:", false).returns("password")
|
@@ -156,7 +156,9 @@ module Authentication
|
|
156
156
|
|
157
157
|
def stub_file_private_key(name, key, options = {})
|
158
158
|
manager.add(name)
|
159
|
+
File.stubs(:file?).with(name).returns(true)
|
159
160
|
File.stubs(:readable?).with(name).returns(true)
|
161
|
+
File.stubs(:file?).with(name + ".pub").returns(true)
|
160
162
|
File.stubs(:readable?).with(name + ".pub").returns(false)
|
161
163
|
|
162
164
|
case options.fetch(:passphrase, :indifferently)
|
@@ -179,7 +181,9 @@ module Authentication
|
|
179
181
|
|
180
182
|
def stub_file_public_key(name, key)
|
181
183
|
manager.add(name)
|
182
|
-
File.stubs(:
|
184
|
+
File.stubs(:file?).with(name).returns(true)
|
185
|
+
File.stubs(:readable?).with(name).returns(true)
|
186
|
+
File.stubs(:file?).with(name + ".pub").returns(true)
|
183
187
|
File.stubs(:readable?).with(name + ".pub").returns(true)
|
184
188
|
|
185
189
|
Net::SSH::KeyFactory.expects(:load_public_key).with(name + ".pub").returns(key).at_least_once
|
@@ -74,11 +74,8 @@ module Connection
|
|
74
74
|
assert !channel.closing?
|
75
75
|
|
76
76
|
connection.expect { |t,packet| assert_equal CHANNEL_CLOSE, packet.type }
|
77
|
-
connection.expects(:cleanup_channel).with(channel)
|
78
77
|
channel.close
|
79
78
|
|
80
|
-
channel.process
|
81
|
-
|
82
79
|
assert channel.closing?
|
83
80
|
end
|
84
81
|
|
@@ -117,14 +117,14 @@ module Connection
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def test_process_should_exit_after_processing_if_block_is_true_then_false
|
120
|
-
session.channels[0] = stub("channel", :
|
120
|
+
session.channels[0] = stub("channel", :closing? => false)
|
121
121
|
session.channels[0].expects(:process)
|
122
122
|
IO.expects(:select).never
|
123
123
|
process_times(2)
|
124
124
|
end
|
125
125
|
|
126
126
|
def test_process_should_not_process_channels_that_are_closing
|
127
|
-
session.channels[0] = stub("channel", :
|
127
|
+
session.channels[0] = stub("channel", :closing? => true)
|
128
128
|
session.channels[0].expects(:process).never
|
129
129
|
IO.expects(:select).never
|
130
130
|
process_times(2)
|
@@ -299,17 +299,8 @@ module Connection
|
|
299
299
|
end
|
300
300
|
|
301
301
|
def test_channel_close_packet_should_be_routed_to_corresponding_channel_and_channel_should_be_closed_and_removed
|
302
|
-
|
303
|
-
|
304
|
-
# CHANNEL_CLOSE to server and are waiting for server's response.
|
305
|
-
expects(:local_closed?).returns(true)
|
306
|
-
expects(:do_close)
|
307
|
-
expects(:close).with()
|
308
|
-
expects(:remote_closed!).with()
|
309
|
-
expects(:remote_closed?).with().returns(true)
|
310
|
-
expects(:local_id).returns(14)
|
311
|
-
end
|
312
|
-
|
302
|
+
channel_at(14).expects(:do_close).with()
|
303
|
+
session.channels[14].expects(:close).with()
|
313
304
|
transport.return(CHANNEL_CLOSE, :long, 14)
|
314
305
|
process_times(2)
|
315
306
|
assert session.channels.empty?
|
@@ -386,13 +377,13 @@ module Connection
|
|
386
377
|
options = { :keepalive => true, :keepalive_interval => 300, :keepalive_maxcount => 3 }
|
387
378
|
expected_packet = P(:byte, Net::SSH::Packet::GLOBAL_REQUEST, :string, "keepalive@openssh.com", :bool, true)
|
388
379
|
[1,2,3].each do |i|
|
389
|
-
Time.stubs(:now).returns(i*300)
|
380
|
+
Time.stubs(:now).returns(Time.at(i*300))
|
390
381
|
IO.stubs(:select).with([socket],[],nil,timeout).returns(nil)
|
391
|
-
transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content
|
382
|
+
transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
|
392
383
|
session(options).process
|
393
384
|
end
|
394
385
|
|
395
|
-
Time.stubs(:now).returns(4*300)
|
386
|
+
Time.stubs(:now).returns(Time.at(4*300))
|
396
387
|
IO.stubs(:select).with([socket],[],nil,timeout).returns(nil)
|
397
388
|
transport.expects(:enqueue_message).with{ |msg| msg.content == expected_packet.content }
|
398
389
|
assert_raises(Net::SSH::Timeout) { session(options).process }
|
@@ -532,7 +523,7 @@ module Connection
|
|
532
523
|
end
|
533
524
|
|
534
525
|
def channel_at(local_id)
|
535
|
-
session.channels[local_id] = stub("channel", :process => true, :
|
526
|
+
session.channels[local_id] = stub("channel", :process => true, :closing? => false)
|
536
527
|
end
|
537
528
|
|
538
529
|
def transport(options={})
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Integration tests with vagrant
|
2
|
+
|
3
|
+
Requirements:
|
4
|
+
|
5
|
+
* Vagrant (https://www.vagrantup.com/)
|
6
|
+
* Ansible (http://docs.ansible.com/intro_installation.html)
|
7
|
+
|
8
|
+
Setup:
|
9
|
+
|
10
|
+
ansible-galaxy install rvm_io.rvm1-ruby
|
11
|
+
vagrant up
|
12
|
+
vagrant ssh
|
13
|
+
cd /net-ssh
|
14
|
+
rake integration-test
|
15
|
+
|
16
|
+
# TODO
|
17
|
+
|
18
|
+
* get it running on ci (probalby needs docker)
|
19
|
+
* could not get gem install jeweler to work
|
@@ -0,0 +1,12 @@
|
|
1
|
+
VAGRANTFILE_API_VERSION = "2"
|
2
|
+
|
3
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
4
|
+
config.vm.box = "ubuntu/trusty64"
|
5
|
+
config.vm.provision "ansible" do |ansible|
|
6
|
+
ansible.playbook = "./playbook.yml"
|
7
|
+
ansible.sudo = true
|
8
|
+
ansible.verbose ='vvvv'
|
9
|
+
end
|
10
|
+
|
11
|
+
config.vm.synced_folder "../..", "/net-ssh"
|
12
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
|
2
|
+
gem "test-unit" # http://rubyforge.org/pipermail/test-unit-tracker/2009-July/000075.html
|
3
|
+
gem 'mocha'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha/setup'
|
6
|
+
require 'pty'
|
7
|
+
require 'expect'
|
8
|
+
|
9
|
+
module IntegrationTestHelpers
|
10
|
+
def sh command
|
11
|
+
puts "$ #{command}"
|
12
|
+
res = system(command)
|
13
|
+
status = $?
|
14
|
+
raise "Command: #{command} failed:#{status.exitstatus}" unless res
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_authorized_key(user,pubkey)
|
18
|
+
authorized_key = "/home/#{user}/.ssh/authorized_keys"
|
19
|
+
sh "sudo cp #{pubkey} #{authorized_key}"
|
20
|
+
sh "sudo chown #{user} #{authorized_key}"
|
21
|
+
sh "sudo chmod 0744 #{authorized_key}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def with_agent(&block)
|
25
|
+
puts "/usr/bin/ssh-agent -c"
|
26
|
+
agent_out = `/usr/bin/ssh-agent -c`
|
27
|
+
agent_out.split("\n").each do |line|
|
28
|
+
if line =~ /setenv (\S+) (\S+);/
|
29
|
+
ENV[$1] = $2
|
30
|
+
puts "ENV[#{$1}]=#{$2}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
begin
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
sh "/usr/bin/ssh-agent -k"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def ssh_add(key,password)
|
41
|
+
command = "ssh-add #{key}"
|
42
|
+
status = nil
|
43
|
+
PTY.spawn(command) do |reader, writer, pid|
|
44
|
+
begin
|
45
|
+
reader.expect(/Enter passphrase for .*:/) { |data| puts data }
|
46
|
+
writer.puts(password)
|
47
|
+
until reader.eof? do
|
48
|
+
puts reader.readline
|
49
|
+
end
|
50
|
+
rescue Errno::EIO => e
|
51
|
+
end
|
52
|
+
pid, status = Process.wait2 pid
|
53
|
+
end
|
54
|
+
raise "Command: #{command} failed:#{status.exitstatus}" unless status
|
55
|
+
status.exitstatus
|
56
|
+
end
|
57
|
+
end
|