net-ssh 3.3.0.beta1 → 4.0.0.alpha1
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 +2 -1
- data/CHANGES.txt +3 -16
- data/Gemfile +17 -0
- data/README.rdoc +1 -1
- data/Rakefile +16 -9
- data/lib/net/ssh.rb +1 -5
- data/lib/net/ssh/authentication/agent/java_pageant.rb +1 -1
- data/lib/net/ssh/authentication/agent/socket.rb +5 -5
- data/lib/net/ssh/authentication/ed25519.rb +140 -0
- data/lib/net/ssh/authentication/key_manager.rb +2 -2
- data/lib/net/ssh/authentication/pageant.rb +1 -1
- data/lib/net/ssh/buffer.rb +5 -23
- data/lib/net/ssh/connection/session.rb +3 -20
- data/lib/net/ssh/key_factory.rb +14 -4
- data/lib/net/ssh/proxy/http.rb +2 -2
- data/lib/net/ssh/service/forward.rb +1 -1
- data/lib/net/ssh/test/socket.rb +1 -1
- data/lib/net/ssh/transport/algorithms.rb +2 -16
- data/lib/net/ssh/transport/cipher_factory.rb +16 -22
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +1 -1
- data/lib/net/ssh/transport/key_expander.rb +1 -0
- data/lib/net/ssh/transport/openssl.rb +1 -1
- data/lib/net/ssh/transport/session.rb +0 -1
- data/lib/net/ssh/version.rb +3 -3
- data/net-ssh.gemspec +28 -9
- data/test/authentication/test_agent.rb +1 -9
- data/test/authentication/test_ed25519.rb +77 -0
- data/test/common.rb +0 -16
- data/test/connection/test_channel.rb +3 -3
- data/test/connection/test_session.rb +0 -1
- data/test/integration/{README.txt → README.md} +2 -1
- data/test/integration/common.rb +8 -6
- data/test/integration/playbook.yml +8 -7
- data/test/integration/test_ed25519_pkeys.rb +70 -0
- data/test/integration/test_forward.rb +15 -120
- data/test/integration/test_id_rsa_keys.rb +11 -11
- data/test/integration/test_proxy.rb +2 -2
- data/test/test_buffer.rb +1 -29
- data/test/transport/kex/test_ecdh_sha2_nistp384.rb +1 -1
- data/test/transport/test_algorithms.rb +6 -6
- data/test/transport/test_cipher_factory.rb +0 -119
- data/test/transport/test_packet_stream.rb +0 -576
- data/test/transport/test_session.rb +1 -1
- metadata +79 -6
- metadata.gz.sig +0 -0
- data/test/integration/test_encoding.rb +0 -23
data/lib/net/ssh/key_factory.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'net/ssh/transport/openssl'
|
2
2
|
require 'net/ssh/prompt'
|
3
|
+
require 'net/ssh/authentication/ed25519'
|
3
4
|
|
4
5
|
module Net; module SSH
|
5
6
|
|
@@ -21,6 +22,7 @@ module Net; module SSH
|
|
21
22
|
}
|
22
23
|
if defined?(OpenSSL::PKey::EC)
|
23
24
|
MAP["ecdsa"] = OpenSSL::PKey::EC
|
25
|
+
MAP["ed25519"] = ED25519::PrivKey
|
24
26
|
end
|
25
27
|
|
26
28
|
class <<self
|
@@ -62,6 +64,9 @@ module Net; module SSH
|
|
62
64
|
elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC)
|
63
65
|
key_type = OpenSSL::PKey::EC
|
64
66
|
error_class = OpenSSL::PKey::ECError
|
67
|
+
elsif data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/)
|
68
|
+
openssh_key = true
|
69
|
+
key_type = ED25519::PrivKey
|
65
70
|
elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/)
|
66
71
|
raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'"
|
67
72
|
else
|
@@ -70,13 +75,18 @@ module Net; module SSH
|
|
70
75
|
end
|
71
76
|
|
72
77
|
encrypted_key = data.match(/ENCRYPTED/)
|
78
|
+
openssh_key = data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/)
|
73
79
|
tries = 0
|
74
80
|
|
75
81
|
begin
|
76
|
-
if
|
77
|
-
|
82
|
+
if openssh_key
|
83
|
+
ED25519::PrivKey.read(data, passphrase || 'invalid')
|
78
84
|
else
|
79
|
-
|
85
|
+
if pkey_read
|
86
|
+
return OpenSSL::PKey.read(data, passphrase || 'invalid')
|
87
|
+
else
|
88
|
+
return key_type.new(data, passphrase || 'invalid')
|
89
|
+
end
|
80
90
|
end
|
81
91
|
rescue error_class
|
82
92
|
if encrypted_key && ask_passphrase
|
@@ -110,7 +120,7 @@ module Net; module SSH
|
|
110
120
|
blob = nil
|
111
121
|
begin
|
112
122
|
blob = fields.shift
|
113
|
-
end while !blob.nil? && !/^(ssh-(rsa|dss)|ecdsa-sha2-nistp\d+)$/.match(blob)
|
123
|
+
end while !blob.nil? && !/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)$/.match(blob)
|
114
124
|
blob = fields.shift
|
115
125
|
|
116
126
|
raise Net::SSH::Exception, "public key at #{filename} is not valid" if blob.nil?
|
data/lib/net/ssh/proxy/http.rb
CHANGED
@@ -8,7 +8,7 @@ module Net; module SSH; module Proxy
|
|
8
8
|
#
|
9
9
|
# require 'net/ssh/proxy/http'
|
10
10
|
#
|
11
|
-
# proxy = Net::SSH::Proxy::HTTP.new('
|
11
|
+
# proxy = Net::SSH::Proxy::HTTP.new('proxy_host', proxy_port)
|
12
12
|
# Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
|
13
13
|
# ...
|
14
14
|
# end
|
@@ -16,7 +16,7 @@ module Net; module SSH; module Proxy
|
|
16
16
|
# If the proxy requires authentication, you can pass :user and :password
|
17
17
|
# to the proxy's constructor:
|
18
18
|
#
|
19
|
-
# proxy = Net::SSH::Proxy::HTTP.new('
|
19
|
+
# proxy = Net::SSH::Proxy::HTTP.new('proxy_host', proxy_port,
|
20
20
|
# :user => "user", :password => "password")
|
21
21
|
#
|
22
22
|
# Note that HTTP digest authentication is not supported; Basic only at
|
@@ -357,7 +357,7 @@ module Net; module SSH; module Service
|
|
357
357
|
channel[:invisible] = true
|
358
358
|
|
359
359
|
begin
|
360
|
-
agent = Authentication::Agent.connect(logger
|
360
|
+
agent = Authentication::Agent.connect(logger)
|
361
361
|
if (agent.socket.is_a? ::IO)
|
362
362
|
prepare_client(agent.socket, channel, :agent)
|
363
363
|
else
|
data/lib/net/ssh/test/socket.rb
CHANGED
@@ -25,8 +25,8 @@ module Net; module SSH; module Test
|
|
25
25
|
|
26
26
|
@script = Script.new
|
27
27
|
|
28
|
-
script.sends(:kexinit)
|
29
28
|
script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false)
|
29
|
+
script.sends(:kexinit)
|
30
30
|
script.sends(:newkeys)
|
31
31
|
script.gets(:newkeys)
|
32
32
|
end
|
@@ -33,14 +33,6 @@ module Net; module SSH; module Transport
|
|
33
33
|
aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
|
34
34
|
idea-cbc none arcfour128 arcfour256 arcfour
|
35
35
|
aes128-ctr aes192-ctr aes256-ctr
|
36
|
-
camellia128-cbc camellia192-cbc camellia256-cbc
|
37
|
-
camellia128-cbc@openssh.org
|
38
|
-
camellia192-cbc@openssh.org
|
39
|
-
camellia256-cbc@openssh.org
|
40
|
-
camellia128-ctr camellia192-ctr camellia256-ctr
|
41
|
-
camellia128-ctr@openssh.org
|
42
|
-
camellia192-ctr@openssh.org
|
43
|
-
camellia256-ctr@openssh.org
|
44
36
|
cast128-ctr blowfish-ctr 3des-ctr
|
45
37
|
),
|
46
38
|
|
@@ -124,12 +116,6 @@ module Net; module SSH; module Transport
|
|
124
116
|
prepare_preferred_algorithms!
|
125
117
|
end
|
126
118
|
|
127
|
-
# Start the algorithm negotation
|
128
|
-
def start
|
129
|
-
raise ArgumentError, "Cannot call start if it's negoitation started or done" if @pending || @initialized
|
130
|
-
send_kexinit
|
131
|
-
end
|
132
|
-
|
133
119
|
# Request a rekey operation. This will return immediately, and does not
|
134
120
|
# actually perform the rekey operation. It does cause the session to change
|
135
121
|
# state, however--until the key exchange finishes, no new packets will be
|
@@ -295,8 +281,8 @@ module Net; module SSH; module Transport
|
|
295
281
|
|
296
282
|
Net::SSH::Buffer.from(:byte, KEXINIT,
|
297
283
|
:long, [rand(0xFFFFFFFF), rand(0xFFFFFFFF), rand(0xFFFFFFFF), rand(0xFFFFFFFF)],
|
298
|
-
:
|
299
|
-
:
|
284
|
+
:string, [kex, host_key, encryption, encryption, hmac, hmac],
|
285
|
+
:string, [compression, compression, language, language],
|
300
286
|
:bool, false, :long, 0)
|
301
287
|
end
|
302
288
|
|
@@ -21,12 +21,6 @@ module Net; module SSH; module Transport
|
|
21
21
|
"arcfour256" => "rc4",
|
22
22
|
"arcfour512" => "rc4",
|
23
23
|
"arcfour" => "rc4",
|
24
|
-
"camellia128-cbc" => "camellia-128-cbc",
|
25
|
-
"camellia192-cbc" => "camellia-192-cbc",
|
26
|
-
"camellia256-cbc" => "camellia-256-cbc",
|
27
|
-
"camellia128-cbc@openssh.org" => "camellia-128-cbc",
|
28
|
-
"camellia192-cbc@openssh.org" => "camellia-192-cbc",
|
29
|
-
"camellia256-cbc@openssh.org" => "camellia-256-cbc",
|
30
24
|
|
31
25
|
"3des-ctr" => "des-ede3",
|
32
26
|
"blowfish-ctr" => "bf-ecb",
|
@@ -34,12 +28,6 @@ module Net; module SSH; module Transport
|
|
34
28
|
"aes192-ctr" => "aes-192-ecb",
|
35
29
|
"aes128-ctr" => "aes-128-ecb",
|
36
30
|
"cast128-ctr" => "cast5-ecb",
|
37
|
-
"camellia128-ctr" => "camellia-128-ecb",
|
38
|
-
"camellia192-ctr" => "camellia-192-ecb",
|
39
|
-
"camellia256-ctr" => "camellia-256-ecb",
|
40
|
-
"camellia128-ctr@openssh.org" => "camellia-128-ecb",
|
41
|
-
"camellia192-ctr@openssh.org" => "camellia-192-ecb",
|
42
|
-
"camellia256-ctr@openssh.org" => "camellia-256-ecb",
|
43
31
|
|
44
32
|
"none" => "none",
|
45
33
|
}
|
@@ -76,11 +64,11 @@ module Net; module SSH; module Transport
|
|
76
64
|
cipher.padding = 0
|
77
65
|
|
78
66
|
cipher.extend(Net::SSH::Transport::CTR) if (name =~ /-ctr(@openssh.org)?$/)
|
79
|
-
cipher.iv
|
67
|
+
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
|
80
68
|
|
81
69
|
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
|
82
70
|
cipher.key_len = key_len
|
83
|
-
cipher.key
|
71
|
+
cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
|
84
72
|
cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
|
85
73
|
|
86
74
|
return cipher
|
@@ -90,15 +78,21 @@ module Net; module SSH; module Transport
|
|
90
78
|
# block-size ] for the named cipher algorithm. If the cipher
|
91
79
|
# algorithm is unknown, or is "none", 0 is returned for both elements
|
92
80
|
# of the tuple.
|
93
|
-
|
81
|
+
# if :iv_len option is supplied the third return value will be ivlen
|
82
|
+
def self.get_lengths(name, options = {})
|
94
83
|
ossl_name = SSH_TO_OSSL[name]
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
84
|
+
if ossl_name.nil? || ossl_name == "none"
|
85
|
+
result = [0, 0]
|
86
|
+
result << 0 if options[:iv_len]
|
87
|
+
else
|
88
|
+
cipher = OpenSSL::Cipher::Cipher.new(ossl_name)
|
89
|
+
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
|
90
|
+
cipher.key_len = key_len
|
91
|
+
|
92
|
+
result = [key_len, ossl_name=="rc4" ? 8 : cipher.block_size]
|
93
|
+
result << cipher.iv_len if options[:iv_len]
|
94
|
+
end
|
95
|
+
result
|
102
96
|
end
|
103
97
|
end
|
104
98
|
|
@@ -57,7 +57,7 @@ module Net; module SSH; module Transport; module Kex
|
|
57
57
|
# send the KEXECDH_INIT message
|
58
58
|
## byte SSH_MSG_KEX_ECDH_INIT
|
59
59
|
## string Q_C, client's ephemeral public key octet string
|
60
|
-
buffer = Net::SSH::Buffer.from(:byte, init, :
|
60
|
+
buffer = Net::SSH::Buffer.from(:byte, init, :string, ecdh.public_key.to_bn.to_s(2))
|
61
61
|
connection.send_message(buffer)
|
62
62
|
|
63
63
|
# expect the following KEXECDH_REPLY message
|
@@ -185,7 +185,7 @@ module OpenSSL
|
|
185
185
|
def to_blob
|
186
186
|
@blob ||= Net::SSH::Buffer.from(:string, ssh_type,
|
187
187
|
:string, CurveNameAliasInv[self.group.curve_name],
|
188
|
-
:
|
188
|
+
:string, self.public_key.to_bn.to_s(2)).to_s
|
189
189
|
@blob
|
190
190
|
end
|
191
191
|
|
@@ -84,7 +84,6 @@ module Net; module SSH; module Transport
|
|
84
84
|
@server_version = ServerVersion.new(socket, logger, options[:timeout])
|
85
85
|
|
86
86
|
@algorithms = Algorithms.new(self, options)
|
87
|
-
@algorithms.start
|
88
87
|
wait { algorithms.initialized? }
|
89
88
|
rescue Errno::ETIMEDOUT
|
90
89
|
raise Net::SSH::ConnectionTimeout
|
data/lib/net/ssh/version.rb
CHANGED
@@ -45,17 +45,17 @@ module Net; module SSH
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# The major component of this version of the Net::SSH library
|
48
|
-
MAJOR =
|
48
|
+
MAJOR = 4
|
49
49
|
|
50
50
|
# The minor component of this version of the Net::SSH library
|
51
|
-
MINOR =
|
51
|
+
MINOR = 0
|
52
52
|
|
53
53
|
# The tiny component of this version of the Net::SSH library
|
54
54
|
TINY = 0
|
55
55
|
|
56
56
|
# The prerelease component of this version of the Net::SSH library
|
57
57
|
# nil allowed
|
58
|
-
PRE =
|
58
|
+
PRE = "alpha1"
|
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.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
|
5
|
+
# stub: net-ssh 4.0.0.alpha1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "net-ssh"
|
9
|
-
s.version = "
|
9
|
+
s.version = "4.0.0.alpha1"
|
10
10
|
|
11
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 = "2016-
|
15
|
+
s.date = "2016-03-19"
|
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 = [
|
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.files = [
|
23
23
|
".travis.yml",
|
24
24
|
"CHANGES.txt",
|
25
|
+
"Gemfile",
|
25
26
|
"LICENSE.txt",
|
26
27
|
"Manifest",
|
27
28
|
"README.rdoc",
|
@@ -32,6 +33,7 @@ Gem::Specification.new do |s|
|
|
32
33
|
"lib/net/ssh/authentication/agent/java_pageant.rb",
|
33
34
|
"lib/net/ssh/authentication/agent/socket.rb",
|
34
35
|
"lib/net/ssh/authentication/constants.rb",
|
36
|
+
"lib/net/ssh/authentication/ed25519.rb",
|
35
37
|
"lib/net/ssh/authentication/key_manager.rb",
|
36
38
|
"lib/net/ssh/authentication/methods/abstract.rb",
|
37
39
|
"lib/net/ssh/authentication/methods/hostbased.rb",
|
@@ -121,6 +123,7 @@ Gem::Specification.new do |s|
|
|
121
123
|
"test/authentication/methods/test_password.rb",
|
122
124
|
"test/authentication/methods/test_publickey.rb",
|
123
125
|
"test/authentication/test_agent.rb",
|
126
|
+
"test/authentication/test_ed25519.rb",
|
124
127
|
"test/authentication/test_key_manager.rb",
|
125
128
|
"test/authentication/test_session.rb",
|
126
129
|
"test/common.rb",
|
@@ -140,11 +143,11 @@ Gem::Specification.new do |s|
|
|
140
143
|
"test/configs/wild_cards",
|
141
144
|
"test/connection/test_channel.rb",
|
142
145
|
"test/connection/test_session.rb",
|
143
|
-
"test/integration/README.
|
146
|
+
"test/integration/README.md",
|
144
147
|
"test/integration/Vagrantfile",
|
145
148
|
"test/integration/common.rb",
|
146
149
|
"test/integration/playbook.yml",
|
147
|
-
"test/integration/
|
150
|
+
"test/integration/test_ed25519_pkeys.rb",
|
148
151
|
"test/integration/test_forward.rb",
|
149
152
|
"test/integration/test_id_rsa_keys.rb",
|
150
153
|
"test/integration/test_proxy.rb",
|
@@ -192,7 +195,7 @@ Gem::Specification.new do |s|
|
|
192
195
|
s.licenses = ["MIT"]
|
193
196
|
s.required_ruby_version = Gem::Requirement.new(">= 2.0")
|
194
197
|
s.rubyforge_project = "net-ssh"
|
195
|
-
s.rubygems_version = "2.
|
198
|
+
s.rubygems_version = "2.4.6"
|
196
199
|
s.signing_key = "/mnt/gem/net-ssh-private_key.pem"
|
197
200
|
s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
|
198
201
|
|
@@ -200,15 +203,31 @@ Gem::Specification.new do |s|
|
|
200
203
|
s.specification_version = 4
|
201
204
|
|
202
205
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
203
|
-
s.
|
206
|
+
s.add_runtime_dependency(%q<rbnacl-libsodium>, [">= 1.0.2"])
|
207
|
+
s.add_runtime_dependency(%q<rbnacl>, [">= 3.1.2"])
|
208
|
+
s.add_runtime_dependency(%q<bcrypt_pbkdf>, ["= 1.0.0.alpha1"]) unless RUBY_PLATFORM == "java"
|
209
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
210
|
+
s.add_development_dependency(%q<test-unit>, [">= 0.8.5"])
|
204
211
|
s.add_development_dependency(%q<mocha>, [">= 0"])
|
212
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
205
213
|
else
|
206
|
-
s.add_dependency(%q<
|
214
|
+
s.add_dependency(%q<rbnacl-libsodium>, [">= 1.0.2"])
|
215
|
+
s.add_dependency(%q<rbnacl>, [">= 3.1.2"])
|
216
|
+
s.add_dependency(%q<bcrypt_pbkdf>, ["= 1.0.0.alpha1"]) unless RUBY_PLATFORM == "java"
|
217
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
218
|
+
s.add_dependency(%q<test-unit>, [">= 0.8.5"])
|
207
219
|
s.add_dependency(%q<mocha>, [">= 0"])
|
220
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
208
221
|
end
|
209
222
|
else
|
210
|
-
s.add_dependency(%q<
|
223
|
+
s.add_dependency(%q<rbnacl-libsodium>, [">= 1.0.2"])
|
224
|
+
s.add_dependency(%q<rbnacl>, [">= 3.1.2"])
|
225
|
+
s.add_dependency(%q<bcrypt_pbkdf>, ["= 1.0.0.alpha1"]) unless RUBY_PLATFORM == "java"
|
226
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
227
|
+
s.add_dependency(%q<test-unit>, [">= 0.8.5"])
|
211
228
|
s.add_dependency(%q<mocha>, [">= 0"])
|
229
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
212
230
|
end
|
231
|
+
s.add_dependency('jruby-pageant', ['>= 1.1.1']) if RUBY_PLATFORM == 'jruby'
|
213
232
|
end
|
214
233
|
|
@@ -32,11 +32,6 @@ module Authentication
|
|
32
32
|
agent(false).connect!
|
33
33
|
end
|
34
34
|
|
35
|
-
def test_connect_should_use_agent_socket_factory_instead_of_factory
|
36
|
-
assert_equal agent.connect!, socket
|
37
|
-
assert_equal agent.connect!(agent_socket_factory), "/foo/bar.sock"
|
38
|
-
end
|
39
|
-
|
40
35
|
def test_connect_should_raise_error_if_connection_could_not_be_established
|
41
36
|
factory.expects(:open).raises(SocketError)
|
42
37
|
assert_raises(Net::SSH::Authentication::AgentNotAvailable) { agent(false).connect! }
|
@@ -218,15 +213,12 @@ module Authentication
|
|
218
213
|
def agent(auto=:connect)
|
219
214
|
@agent ||= begin
|
220
215
|
agent = Net::SSH::Authentication::Agent.new
|
221
|
-
agent.stubs(:
|
216
|
+
agent.stubs(:agent_socket_factory).returns(factory)
|
222
217
|
agent.connect! if auto == :connect
|
223
218
|
agent
|
224
219
|
end
|
225
220
|
end
|
226
221
|
|
227
|
-
def agent_socket_factory
|
228
|
-
@agent_socket_factory ||= ->{"/foo/bar.sock"}
|
229
|
-
end
|
230
222
|
end
|
231
223
|
|
232
224
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'common'
|
2
|
+
require 'net/ssh/authentication/ed25519'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module Authentication
|
6
|
+
|
7
|
+
class TestED25519 < Test::Unit::TestCase
|
8
|
+
def test_no_pwd_key
|
9
|
+
pub = Net::SSH::Buffer.new(Base64.decode64(public_key_no_pwd.split(' ')[1]))
|
10
|
+
_type = pub.read_string
|
11
|
+
pub_data = pub.read_string
|
12
|
+
priv = private_key_no_pwd
|
13
|
+
|
14
|
+
pub_key = ED25519::PubKey.new(pub_data)
|
15
|
+
priv_key = ED25519::PrivKey.new(priv,nil)
|
16
|
+
|
17
|
+
shared_secret = "Hello"
|
18
|
+
signed = priv_key.ssh_do_sign(shared_secret)
|
19
|
+
self.assert_equal(true,pub_key.ssh_do_verify(signed,shared_secret))
|
20
|
+
self.assert_equal(priv_key.public_key.fingerprint, pub_key.fingerprint)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_pwd_key
|
24
|
+
if defined?(JRUBY_VERSION)
|
25
|
+
puts "Skipping password protected ED25519 for JRuby"
|
26
|
+
return
|
27
|
+
end
|
28
|
+
pub = Net::SSH::Buffer.new(Base64.decode64(public_key_pwd.split(' ')[1]))
|
29
|
+
_type = pub.read_string
|
30
|
+
pub_data = pub.read_string
|
31
|
+
priv = private_key_pwd
|
32
|
+
|
33
|
+
pub_key = ED25519::PubKey.new(pub_data)
|
34
|
+
priv_key = ED25519::PrivKey.new(priv,'pwd')
|
35
|
+
|
36
|
+
shared_secret = "Hello"
|
37
|
+
signed = priv_key.ssh_do_sign(shared_secret)
|
38
|
+
self.assert_equal(true,pub_key.ssh_do_verify(signed,shared_secret))
|
39
|
+
self.assert_equal(priv_key.public_key.fingerprint, pub_key.fingerprint)
|
40
|
+
end
|
41
|
+
|
42
|
+
def private_key_pwd
|
43
|
+
@pwd_key = <<-EOF
|
44
|
+
-----BEGIN OPENSSH PRIVATE KEY-----
|
45
|
+
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBxwCvr3V
|
46
|
+
/8pWhC/xvTnGJhAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAICaHkFaGXqYhUVFc
|
47
|
+
aZ10TPUbkIvmaFXwYRoOS5qE8MciAAAAsNUAhbNQKwNcOr0eNq3nhtjoyeVyH8hRrpWsiY
|
48
|
+
46vPiECi6R6OdYGSd7W3fdzUDeyOYCY9ZVIjAzENG+9FsygYzMi6XCuw00OuDFLUp4fL4K
|
49
|
+
i/coUIVqouB4TPQAmsCVXiIRVTWQtRG0kWfFaV3qRt/bc22ZCvCT6ZZ1UmtulqqfUhSlKM
|
50
|
+
oPcTikV1iWH5Xc+GxRFRRGTN/6HvBf0AKDB1kMXlDhGnBnHGeNH1pk44xG
|
51
|
+
-----END OPENSSH PRIVATE KEY-----
|
52
|
+
EOF
|
53
|
+
end
|
54
|
+
|
55
|
+
def public_key_pwd
|
56
|
+
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICaHkFaGXqYhUVFcaZ10TPUbkIvmaFXwYRoOS5qE8Mci vagrant@vagrant-ubuntu-trusty-64'
|
57
|
+
end
|
58
|
+
|
59
|
+
def private_key_no_pwd
|
60
|
+
@anonymous_key = <<-EOF
|
61
|
+
-----BEGIN OPENSSH PRIVATE KEY-----
|
62
|
+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
63
|
+
QyNTUxOQAAACAwdjQYeBiTz1DdZFzzLvG+t913L+eVqCgtzpAYxQG8yQAAAKjlHzLo5R8y
|
64
|
+
6AAAAAtzc2gtZWQyNTUxOQAAACAwdjQYeBiTz1DdZFzzLvG+t913L+eVqCgtzpAYxQG8yQ
|
65
|
+
AAAEBPrD+n4901Y+NYJ2sry+EWRdltGFhMISvp91TywJ//mTB2NBh4GJPPUN1kXPMu8b63
|
66
|
+
3Xcv55WoKC3OkBjFAbzJAAAAIHZhZ3JhbnRAdmFncmFudC11YnVudHUtdHJ1c3R5LTY0AQ
|
67
|
+
IDBAU=
|
68
|
+
-----END OPENSSH PRIVATE KEY-----
|
69
|
+
EOF
|
70
|
+
end
|
71
|
+
|
72
|
+
def public_key_no_pwd
|
73
|
+
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDB2NBh4GJPPUN1kXPMu8b633Xcv55WoKC3OkBjFAbzJ vagrant@vagrant-ubuntu-trusty-64'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|