net-ssh 6.1.0 → 6.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -1
  3. data.tar.gz.sig +0 -0
  4. data/.github/workflows/ci.yml +93 -0
  5. data/.gitignore +2 -0
  6. data/.rubocop.yml +11 -1
  7. data/.rubocop_todo.yml +383 -291
  8. data/.travis.yml +10 -11
  9. data/CHANGES.txt +16 -3
  10. data/Gemfile +2 -0
  11. data/Gemfile.noed25519 +2 -0
  12. data/README.md +2 -2
  13. data/Rakefile +1 -0
  14. data/lib/net/ssh.rb +1 -2
  15. data/lib/net/ssh/authentication/agent.rb +16 -0
  16. data/lib/net/ssh/authentication/certificate.rb +8 -5
  17. data/lib/net/ssh/authentication/constants.rb +0 -1
  18. data/lib/net/ssh/authentication/ed25519.rb +7 -3
  19. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  20. data/lib/net/ssh/authentication/key_manager.rb +28 -29
  21. data/lib/net/ssh/authentication/methods/abstract.rb +0 -1
  22. data/lib/net/ssh/authentication/methods/hostbased.rb +0 -2
  23. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +1 -1
  24. data/lib/net/ssh/authentication/methods/none.rb +5 -8
  25. data/lib/net/ssh/authentication/methods/password.rb +1 -2
  26. data/lib/net/ssh/authentication/methods/publickey.rb +0 -2
  27. data/lib/net/ssh/authentication/pageant.rb +89 -89
  28. data/lib/net/ssh/authentication/session.rb +14 -15
  29. data/lib/net/ssh/buffer.rb +10 -5
  30. data/lib/net/ssh/buffered_io.rb +18 -19
  31. data/lib/net/ssh/config.rb +29 -16
  32. data/lib/net/ssh/connection/channel.rb +72 -69
  33. data/lib/net/ssh/connection/constants.rb +0 -4
  34. data/lib/net/ssh/connection/event_loop.rb +22 -16
  35. data/lib/net/ssh/connection/keepalive.rb +12 -12
  36. data/lib/net/ssh/connection/session.rb +95 -94
  37. data/lib/net/ssh/connection/term.rb +56 -58
  38. data/lib/net/ssh/errors.rb +10 -10
  39. data/lib/net/ssh/key_factory.rb +0 -1
  40. data/lib/net/ssh/known_hosts.rb +79 -11
  41. data/lib/net/ssh/loggable.rb +8 -9
  42. data/lib/net/ssh/packet.rb +1 -1
  43. data/lib/net/ssh/prompt.rb +8 -10
  44. data/lib/net/ssh/proxy/command.rb +1 -1
  45. data/lib/net/ssh/proxy/errors.rb +2 -4
  46. data/lib/net/ssh/proxy/http.rb +17 -19
  47. data/lib/net/ssh/proxy/https.rb +6 -8
  48. data/lib/net/ssh/proxy/jump.rb +8 -10
  49. data/lib/net/ssh/proxy/socks4.rb +1 -3
  50. data/lib/net/ssh/proxy/socks5.rb +2 -4
  51. data/lib/net/ssh/service/forward.rb +3 -3
  52. data/lib/net/ssh/test.rb +1 -2
  53. data/lib/net/ssh/test/channel.rb +21 -23
  54. data/lib/net/ssh/test/extensions.rb +29 -29
  55. data/lib/net/ssh/test/kex.rb +6 -8
  56. data/lib/net/ssh/test/local_packet.rb +0 -2
  57. data/lib/net/ssh/test/packet.rb +2 -2
  58. data/lib/net/ssh/test/remote_packet.rb +6 -8
  59. data/lib/net/ssh/test/script.rb +22 -24
  60. data/lib/net/ssh/test/socket.rb +11 -14
  61. data/lib/net/ssh/transport/algorithms.rb +5 -2
  62. data/lib/net/ssh/transport/cipher_factory.rb +16 -16
  63. data/lib/net/ssh/transport/constants.rb +3 -3
  64. data/lib/net/ssh/transport/ctr.rb +4 -4
  65. data/lib/net/ssh/transport/hmac/abstract.rb +0 -1
  66. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  67. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  68. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  69. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  70. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  71. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  72. data/lib/net/ssh/transport/identity_cipher.rb +10 -12
  73. data/lib/net/ssh/transport/kex.rb +2 -0
  74. data/lib/net/ssh/transport/kex/abstract.rb +9 -2
  75. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +1 -0
  76. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  77. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  78. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -1
  79. data/lib/net/ssh/transport/key_expander.rb +6 -7
  80. data/lib/net/ssh/transport/openssl.rb +19 -15
  81. data/lib/net/ssh/transport/packet_stream.rb +1 -2
  82. data/lib/net/ssh/transport/server_version.rb +17 -16
  83. data/lib/net/ssh/transport/session.rb +3 -1
  84. data/lib/net/ssh/transport/state.rb +42 -42
  85. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  86. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  87. data/lib/net/ssh/verifiers/always.rb +6 -4
  88. data/lib/net/ssh/verifiers/never.rb +0 -2
  89. data/lib/net/ssh/version.rb +2 -2
  90. data/net-ssh-public_cert.pem +8 -8
  91. data/net-ssh.gemspec +2 -2
  92. data/support/ssh_tunnel_bug.rb +3 -3
  93. metadata +17 -15
  94. metadata.gz.sig +0 -0
data/.travis.yml CHANGED
@@ -1,17 +1,16 @@
1
1
  language: ruby
2
2
  sudo: true
3
- dist: trusty
3
+ dist: focal
4
4
 
5
5
  addon:
6
6
  hosts:
7
7
  gateway.netssh
8
8
 
9
9
  rvm:
10
- - 2.3.8
11
- - 2.4.8
12
10
  - 2.5.7
13
11
  - 2.6.5
14
12
  - 2.7.0
13
+ - 3.0.0
15
14
  - jruby-9.2.11.1
16
15
  - rbx-3.107
17
16
  - ruby-head
@@ -35,18 +34,18 @@ matrix:
35
34
  install:
36
35
  - export JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false'
37
36
  - sudo pip install ansible urllib3 pyOpenSSL ndg-httpsclient pyasn1
38
- - gem install bundler -v "= 1.17"
37
+ - gem install bundler
39
38
  - gem list bundler
40
- - bundle _1.17_ install
41
- - bundle _1.17_ -v
42
- - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.17_ install
39
+ - bundle install
40
+ - bundle -v
41
+ - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle install
43
42
  - sudo ansible-galaxy install rvm.ruby
44
43
  - sudo chown -R travis:travis /home/travis/.ansible
45
44
  - ansible-playbook ./test/integration/playbook.yml -i "localhost," --become -c local -e 'no_rvm=true' -e 'myuser=travis' -e 'mygroup=travis' -e 'homedir=/home/travis'
46
45
 
47
46
  script:
48
47
  - ssh -V
49
- - bundle _1.17_ exec rake test
50
- - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.17_ exec rake test
51
- - bundle _1.17_ exec rake test_test
52
- - bundle _1.17_ exec rubocop
48
+ - bundle exec rake test
49
+ - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle exec rake test
50
+ - bundle exec rake test_test
51
+ - bundle exec rubocop
data/CHANGES.txt CHANGED
@@ -1,6 +1,19 @@
1
+ === 6.3.0 beta1
2
+
3
+ * Support cert based host key auth, fix asterisk in known_hosts [#833]
4
+ * Support kex dh-group14-sha256 [#795]
5
+ * Fix StrictHostKeyChecking ssh config parameter translation [#765]
6
+
7
+ === 6.2.0 rc1
8
+
9
+ === 6.2.0 beta1
10
+
11
+ * rsa-sha2-512, rsa-sha2-256 host_key algs [#771]
12
+ * JRuby aes*-ctr suppport [#767]
13
+
1
14
  === 6.1.0
2
15
 
3
- * adapt to ssh's default bahaviors when no username is provided.
16
+ * Adapt to ssh's default behaviors when no username is provided.
4
17
  When Net::SSH.start user is nil and config has no entry
5
18
  we default to Etc.getpwuid.name() instead of Etc.getlogin(). [#749]
6
19
 
@@ -36,7 +49,7 @@
36
49
  === 5.2.0.rc3
37
50
 
38
51
  * Fix check_host_ip read from config
39
- * Support ssh-ed25519 in kown hosts
52
+ * Support ssh-ed25519 in known hosts
40
53
 
41
54
  === 5.2.0.rc2
42
55
 
@@ -59,7 +72,7 @@
59
72
 
60
73
  === 5.0.2
61
74
 
62
- * fix ctr for jruby [#612]
75
+ * Fix ctr for jruby [#612]
63
76
 
64
77
  === 5.0.1
65
78
 
data/Gemfile CHANGED
@@ -9,3 +9,5 @@ if ENV["CI"]
9
9
  gem 'codecov', require: false, group: :test
10
10
  gem 'simplecov', require: false, group: :test
11
11
  end
12
+
13
+ gem 'webrick', group: %i[development test] if RUBY_VERSION.split(".")[0].to_i >= 3
data/Gemfile.noed25519 CHANGED
@@ -8,3 +8,5 @@ if ENV["CI"] && !Gem.win_platform?
8
8
  gem 'simplecov', require: false, group: :test
9
9
  gem 'codecov', require: false, group: :test
10
10
  end
11
+
12
+ gem 'webrick', group: %i[development test] if RUBY_VERSION.split(".")[0].to_i >= 3
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/net-ssh.svg)](https://badge.fury.io/rb/net-ssh)
2
2
  [![Join the chat at https://gitter.im/net-ssh/net-ssh](https://badges.gitter.im/net-ssh/net-ssh.svg)](https://gitter.im/net-ssh/net-ssh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
- [![Build Status](https://travis-ci.org/net-ssh/net-ssh.svg?branch=master)](https://travis-ci.org/net-ssh/net-ssh)
3
+ [![Build status](https://github.com/net-ssh/net-ssh/actions/workflows/ci.yml/badge.svg)](https://github.com/net-ssh/net-ssh/actions/workflows/ci.yml)
4
4
  [![Coverage status](https://codecov.io/gh/net-ssh/net-ssh/branch/master/graph/badge.svg)](https://codecov.io/gh/net-ssh/net-ssh)
5
5
  [![Backers on Open Collective](https://opencollective.com/net-ssh/backers/badge.svg)](#backers])
6
6
  [![Sponsors on Open Collective](https://opencollective.com/net-ssh/sponsors/badge.svg)](#sponsors)
7
7
 
8
8
  # Net::SSH 6.x
9
9
 
10
- * Docs: http://net-ssh.github.com/net-ssh
10
+ * Docs: http://net-ssh.github.io/net-ssh
11
11
  * Issues: https://github.com/net-ssh/net-ssh/issues
12
12
  * Codes: https://github.com/net-ssh/net-ssh
13
13
  * Email: net-ssh@solutious.com
data/Rakefile CHANGED
@@ -48,6 +48,7 @@ namespace :cert do
48
48
  raw = File.read "net-ssh-public_cert.pem"
49
49
  certificate = OpenSSL::X509::Certificate.new raw
50
50
  raise Exception, "Not yet expired: #{certificate.not_after}" unless certificate.not_after < Time.now
51
+
51
52
  sh "gem cert --build netssh@solutious.com --days 365*5 --private-key /mnt/gem/net-ssh-private_key.pem"
52
53
  sh "mv gem-public_cert.pem net-ssh-public_cert.pem"
53
54
  sh "gem cert --add net-ssh-public_cert.pem"
data/lib/net/ssh.rb CHANGED
@@ -15,7 +15,6 @@ require 'net/ssh/connection/session'
15
15
  require 'net/ssh/prompt'
16
16
 
17
17
  module Net
18
-
19
18
  # Net::SSH is a library for interacting, programmatically, with remote
20
19
  # processes via the SSH2 protocol. Sessions are always initiated via
21
20
  # Net::SSH.start. From there, a program interacts with the new SSH session
@@ -122,7 +121,7 @@ module Net
122
121
  # * :forward_agent => set to true if you want the SSH agent connection to
123
122
  # be forwarded
124
123
  # * :known_hosts => a custom object holding known hosts records.
125
- # It must implement #search_for and add in a similiar manner as KnownHosts.
124
+ # It must implement #search_for and `add` in a similiar manner as KnownHosts.
126
125
  # * :global_known_hosts_file => the location of the global known hosts
127
126
  # file. Set to an array if you want to specify multiple global known
128
127
  # hosts files. Defaults to %w(/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2).
@@ -13,6 +13,7 @@ module Net
13
13
  module Authentication
14
14
  # Class for representing agent-specific errors.
15
15
  class AgentError < Net::SSH::Exception; end
16
+
16
17
  # An exception for indicating that the SSH agent is not available.
17
18
  class AgentNotAvailable < AgentError; end
18
19
 
@@ -39,6 +40,8 @@ module Net
39
40
  SSH2_AGENT_ADD_IDENTITY = 17
40
41
  SSH2_AGENT_REMOVE_IDENTITY = 18
41
42
  SSH2_AGENT_REMOVE_ALL_IDENTITIES = 19
43
+ SSH2_AGENT_LOCK = 22
44
+ SSH2_AGENT_UNLOCK = 23
42
45
  SSH2_AGENT_ADD_ID_CONSTRAINED = 25
43
46
  SSH2_AGENT_FAILURE = 30
44
47
  SSH2_AGENT_VERSION_RESPONSE = 103
@@ -105,6 +108,7 @@ module Net
105
108
  type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION)
106
109
 
107
110
  raise AgentNotAvailable, "SSH2 agents are not yet supported" if type == SSH2_AGENT_VERSION_RESPONSE
111
+
108
112
  if type == SSH2_AGENT_FAILURE
109
113
  debug { "Unexpected response type==#{type}, this will be ignored" }
110
114
  elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
@@ -189,6 +193,18 @@ module Net
189
193
  raise AgentError, "could not remove all identity from agent" if type != SSH_AGENT_SUCCESS
190
194
  end
191
195
 
196
+ # lock the ssh agent with password
197
+ def lock(password)
198
+ type, = send_and_wait(SSH2_AGENT_LOCK, :string, password)
199
+ raise AgentError, "could not lock agent" if type != SSH_AGENT_SUCCESS
200
+ end
201
+
202
+ # unlock the ssh agent with password
203
+ def unlock(password)
204
+ type, = send_and_wait(SSH2_AGENT_UNLOCK, :string, password)
205
+ raise AgentError, "could not unlock agent" if type != SSH_AGENT_SUCCESS
206
+ end
207
+
192
208
  private
193
209
 
194
210
  def unix_socket_class
@@ -31,12 +31,13 @@ module Net
31
31
  cert.key_id = buffer.read_string
32
32
  cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
33
33
  cert.valid_after = Time.at(buffer.read_int64)
34
-
34
+
35
35
  cert.valid_before = if RUBY_PLATFORM == "java"
36
36
  # 0x20c49ba5e353f7 = 0x7fffffffffffffff/1000, the largest value possible for JRuby
37
37
  # JRuby Time.at multiplies the arg by 1000, and then stores it in a signed long.
38
- # 0x20c49ba5e353f7 = 292278994-08-17 01:12:55 -0600
39
- Time.at([0x20c49ba5e353f7, buffer.read_int64].min)
38
+ # 0x20c49ba2d52500 = 292278993-01-01 00:00:00 +0000
39
+ # JRuby 9.1 does not accept the year 292278994 because of edge cases (https://github.com/JodaOrg/joda-time/issues/190)
40
+ Time.at([0x20c49ba2d52500, buffer.read_int64].min)
40
41
  else
41
42
  Time.at(buffer.read_int64)
42
43
  end
@@ -69,8 +70,8 @@ module Net
69
70
  key.ssh_do_sign(data)
70
71
  end
71
72
 
72
- def ssh_do_verify(sig, data)
73
- key.ssh_do_verify(sig, data)
73
+ def ssh_do_verify(sig, data, options = {})
74
+ key.ssh_do_verify(sig, data, options)
74
75
  end
75
76
 
76
77
  def to_pem
@@ -124,6 +125,7 @@ module Net
124
125
  def self.type_symbol(type)
125
126
  types = { 1 => :user, 2 => :host }
126
127
  raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
128
+
127
129
  types.fetch(type)
128
130
  end
129
131
  private_class_method :type_symbol
@@ -133,6 +135,7 @@ module Net
133
135
  def type_value(type)
134
136
  types = { user: 1, host: 2 }
135
137
  raise ArgumentError("unsupported type: #{type}") unless types.include?(type)
138
+
136
139
  types.fetch(type)
137
140
  end
138
141
 
@@ -1,7 +1,6 @@
1
1
  module Net
2
2
  module SSH
3
3
  module Authentication
4
-
5
4
  # Describes the constants used by the Net::SSH::Authentication components
6
5
  # of the Net::SSH library. Individual authentication method implemenations
7
6
  # may define yet more constants that are specific to their implementation.
@@ -44,9 +44,11 @@ module Net
44
44
  datafull = datafull.strip
45
45
  raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
46
46
  raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
47
+
47
48
  datab64 = datafull[MBEGIN.size...-MEND.size]
48
49
  data = Base64.decode64(datab64)
49
50
  raise ArgumentError.new("Expected #{MAGIC} at start of decoded private key") unless data.start_with?(MAGIC)
51
+
50
52
  buffer = Net::SSH::Buffer.new(data[MAGIC.size + 1..-1])
51
53
 
52
54
  ciphername = buffer.read_string
@@ -59,6 +61,7 @@ module Net
59
61
  kdfopts = Net::SSH::Buffer.new(buffer.read_string)
60
62
  num_keys = buffer.read_long
61
63
  raise ArgumentError.new("Only 1 key is supported in ssh keys #{num_keys} was in private key") unless num_keys == 1
64
+
62
65
  _pubkey = buffer.read_string
63
66
 
64
67
  len = buffer.read_long
@@ -72,12 +75,13 @@ module Net
72
75
  rounds = kdfopts.read_long
73
76
 
74
77
  raise "BCryptPbkdf is not implemented for jruby" if RUBY_PLATFORM == "java"
78
+
75
79
  key = BCryptPbkdf::key(password, salt, keylen + ivlen, rounds)
76
80
  else
77
81
  key = '\x00' * (keylen + ivlen)
78
82
  end
79
83
 
80
- cipher = CipherFactory.get(ciphername, key: key[0...keylen], iv:key[keylen...keylen + ivlen], decrypt: true)
84
+ cipher = CipherFactory.get(ciphername, key: key[0...keylen], iv: key[keylen...keylen + ivlen], decrypt: true)
81
85
 
82
86
  decoded = cipher.update(buffer.remainder_as_buffer.to_s)
83
87
  decoded << cipher.final
@@ -112,7 +116,7 @@ module Net
112
116
  end
113
117
 
114
118
  def to_blob
115
- Net::SSH::Buffer.from(:mstring,"ssh-ed25519",:string,@verify_key.to_bytes).to_s
119
+ Net::SSH::Buffer.from(:mstring,"ssh-ed25519".dup,:string,@verify_key.to_bytes).to_s
116
120
  end
117
121
 
118
122
  def ssh_type
@@ -123,7 +127,7 @@ module Net
123
127
  ssh_type
124
128
  end
125
129
 
126
- def ssh_do_verify(sig,data)
130
+ def ssh_do_verify(sig, data, options = {})
127
131
  @verify_key.verify(sig,data)
128
132
  end
129
133
 
@@ -1,11 +1,9 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Authentication
4
-
5
4
  # Loads ED25519 support which requires optinal dependecies like
6
5
  # ed25519, bcrypt_pbkdf
7
6
  module ED25519Loader
8
-
9
7
  begin
10
8
  require 'net/ssh/authentication/ed25519'
11
9
  LOADED = true
@@ -14,20 +12,19 @@ module Net
14
12
  ERROR = e
15
13
  LOADED = false
16
14
  end
17
-
15
+
18
16
  def self.raiseUnlessLoaded(message)
19
17
  description = ERROR.is_a?(LoadError) ? dependenciesRequiredForED25519 : ''
20
18
  description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
21
19
  raise NotImplementedError, "#{message}\n#{description}" unless LOADED
22
20
  end
23
-
21
+
24
22
  def self.dependenciesRequiredForED25519
25
23
  result = "net-ssh requires the following gems for ed25519 support:\n"
26
24
  result << " * ed25519 (>= 1.2, < 2.0)\n"
27
25
  result << " * bcrypt_pbkdf (>= 1.0, < 2.0)\n" unless RUBY_PLATFORM == "java"
28
26
  result << "See https://github.com/net-ssh/net-ssh/issues/565 for more information\n"
29
27
  end
30
-
31
28
  end
32
29
  end
33
30
  end
@@ -6,7 +6,6 @@ require 'net/ssh/authentication/agent'
6
6
  module Net
7
7
  module SSH
8
8
  module Authentication
9
-
10
9
  # A trivial exception class used to report errors in the key manager.
11
10
  class KeyManagerError < Net::SSH::Exception; end
12
11
 
@@ -177,6 +176,7 @@ module Net
177
176
 
178
177
  if info[:from] == :agent
179
178
  raise KeyManagerError, "the agent is no longer available" unless agent
179
+
180
180
  return agent.sign(info[:identity], data.to_s)
181
181
  end
182
182
 
@@ -201,6 +201,7 @@ module Net
201
201
  # or if the agent is otherwise not available.
202
202
  def agent
203
203
  return unless use_agent?
204
+
204
205
  @agent ||= Agent.connect(logger, options[:agent_socket_factory], options[:identity_agent])
205
206
  rescue AgentNotAvailable
206
207
  @use_agent = false
@@ -248,37 +249,35 @@ module Net
248
249
  # Load prepared identities. Private key decryption errors ignored if ignore_decryption_errors
249
250
  def load_identities(identities, ask_passphrase, ignore_decryption_errors)
250
251
  identities.map do |identity|
251
- begin
252
- case identity[:load_from]
253
- when :pubkey_file
254
- key = KeyFactory.load_public_key(identity[:pubkey_file])
255
- { public_key: key, from: :file, file: identity[:privkey_file] }
256
- when :privkey_file
257
- private_key = KeyFactory.load_private_key(
258
- identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt]
259
- )
260
- key = private_key.send(:public_key)
261
- { public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
262
- when :data
263
- private_key = KeyFactory.load_data_private_key(
264
- identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt]
265
- )
266
- key = private_key.send(:public_key)
267
- { public_key: key, from: :key_data, data: identity[:data], key: private_key }
268
- else
269
- identity
270
- end
271
- rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, OpenSSL::PKey::PKeyError, ArgumentError => e
272
- if ignore_decryption_errors
273
- identity
274
- else
275
- process_identity_loading_error(identity, e)
276
- nil
277
- end
278
- rescue Exception => e
252
+ case identity[:load_from]
253
+ when :pubkey_file
254
+ key = KeyFactory.load_public_key(identity[:pubkey_file])
255
+ { public_key: key, from: :file, file: identity[:privkey_file] }
256
+ when :privkey_file
257
+ private_key = KeyFactory.load_private_key(
258
+ identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt]
259
+ )
260
+ key = private_key.send(:public_key)
261
+ { public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
262
+ when :data
263
+ private_key = KeyFactory.load_data_private_key(
264
+ identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt]
265
+ )
266
+ key = private_key.send(:public_key)
267
+ { public_key: key, from: :key_data, data: identity[:data], key: private_key }
268
+ else
269
+ identity
270
+ end
271
+ rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, OpenSSL::PKey::PKeyError, ArgumentError => e
272
+ if ignore_decryption_errors
273
+ identity
274
+ else
279
275
  process_identity_loading_error(identity, e)
280
276
  nil
281
277
  end
278
+ rescue Exception => e
279
+ process_identity_loading_error(identity, e)
280
+ nil
282
281
  end.compact
283
282
  end
284
283
 
@@ -7,7 +7,6 @@ module Net
7
7
  module SSH
8
8
  module Authentication
9
9
  module Methods
10
-
11
10
  # The base class of all user authentication methods. It provides a few
12
11
  # bits of common functionality.
13
12
  class Abstract
@@ -4,7 +4,6 @@ module Net
4
4
  module SSH
5
5
  module Authentication
6
6
  module Methods
7
-
8
7
  # Implements the host-based SSH authentication method.
9
8
  class Hostbased < Abstract
10
9
  include Constants
@@ -67,7 +66,6 @@ module Net
67
66
  Buffer.from(:key, identity).to_s, hostname, client_username).to_s
68
67
  end
69
68
  end
70
-
71
69
  end
72
70
  end
73
71
  end
@@ -5,7 +5,6 @@ module Net
5
5
  module SSH
6
6
  module Authentication
7
7
  module Methods
8
-
9
8
  # Implements the "keyboard-interactive" SSH authentication method.
10
9
  class KeyboardInteractive < Abstract
11
10
  USERAUTH_INFO_REQUEST = 60
@@ -32,6 +31,7 @@ module Net
32
31
  message[:authentications].split(/,/).include? 'keyboard-interactive'
33
32
 
34
33
  return false unless interactive?
34
+
35
35
  password = nil
36
36
  debug { "retrying keyboard-interactive" }
37
37
  send_message(userauth_request(username, next_service, "keyboard-interactive", "", ""))