net-ssh 6.1.0 → 6.3.0.beta1

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.
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", "", ""))