net-ssh 5.1.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +1 -3
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +8 -2
  5. data/.rubocop_todo.yml +392 -379
  6. data/.travis.yml +16 -17
  7. data/CHANGES.txt +52 -1
  8. data/Manifest +0 -1
  9. data/README.md +287 -0
  10. data/Rakefile +1 -2
  11. data/appveyor.yml +4 -2
  12. data/lib/net/ssh/authentication/certificate.rb +10 -1
  13. data/lib/net/ssh/authentication/ed25519.rb +14 -2
  14. data/lib/net/ssh/authentication/ed25519_loader.rb +1 -1
  15. data/lib/net/ssh/authentication/key_manager.rb +34 -5
  16. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +3 -1
  17. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +0 -1
  18. data/lib/net/ssh/authentication/session.rb +9 -6
  19. data/lib/net/ssh/buffer.rb +1 -10
  20. data/lib/net/ssh/buffered_io.rb +0 -1
  21. data/lib/net/ssh/config.rb +52 -31
  22. data/lib/net/ssh/connection/channel.rb +17 -5
  23. data/lib/net/ssh/connection/event_loop.rb +0 -1
  24. data/lib/net/ssh/connection/session.rb +7 -4
  25. data/lib/net/ssh/key_factory.rb +104 -17
  26. data/lib/net/ssh/known_hosts.rb +41 -26
  27. data/lib/net/ssh/loggable.rb +2 -2
  28. data/lib/net/ssh/proxy/command.rb +0 -1
  29. data/lib/net/ssh/proxy/socks5.rb +0 -1
  30. data/lib/net/ssh/service/forward.rb +2 -1
  31. data/lib/net/ssh/test.rb +3 -2
  32. data/lib/net/ssh/transport/algorithms.rb +84 -45
  33. data/lib/net/ssh/transport/cipher_factory.rb +11 -27
  34. data/lib/net/ssh/transport/constants.rb +10 -6
  35. data/lib/net/ssh/transport/ctr.rb +1 -7
  36. data/lib/net/ssh/transport/hmac/abstract.rb +16 -0
  37. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  38. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  39. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  40. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  41. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  42. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  43. data/lib/net/ssh/transport/hmac.rb +15 -13
  44. data/lib/net/ssh/transport/kex/abstract.rb +123 -0
  45. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  46. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +38 -0
  47. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  48. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +1 -15
  49. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +9 -118
  50. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -6
  51. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  52. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +18 -79
  53. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
  54. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
  55. data/lib/net/ssh/transport/kex.rb +14 -11
  56. data/lib/net/ssh/transport/openssl.rb +104 -107
  57. data/lib/net/ssh/transport/packet_stream.rb +48 -13
  58. data/lib/net/ssh/transport/session.rb +1 -1
  59. data/lib/net/ssh/transport/state.rb +1 -1
  60. data/lib/net/ssh/version.rb +1 -1
  61. data/lib/net/ssh.rb +13 -4
  62. data/net-ssh-public_cert.pem +18 -19
  63. data/net-ssh.gemspec +9 -7
  64. data.tar.gz.sig +0 -0
  65. metadata +56 -40
  66. metadata.gz.sig +0 -0
  67. data/Gemfile.noed25519.lock +0 -41
  68. data/README.rdoc +0 -194
  69. data/lib/net/ssh/ruby_compat.rb +0 -13
  70. data/support/arcfour_check.rb +0 -20
data/.travis.yml CHANGED
@@ -7,12 +7,12 @@ addon:
7
7
  gateway.netssh
8
8
 
9
9
  rvm:
10
- - 2.2.10
11
- - 2.3.7
12
- - 2.4.5
13
- - 2.5.3
14
- - 2.6.0-rc2
15
- - jruby-9.2.5.0
10
+ - 2.3.8
11
+ - 2.4.8
12
+ - 2.5.7
13
+ - 2.6.5
14
+ - 2.7.0
15
+ - jruby-9.2.11.1
16
16
  - rbx-3.107
17
17
  - ruby-head
18
18
  env:
@@ -21,33 +21,32 @@ env:
21
21
  matrix:
22
22
  exclude:
23
23
  - rvm: rbx-3.107
24
- - rvm: jruby-9.2.5.0
25
24
  include:
26
25
  - rvm: rbx-3.107
27
26
  env: NET_SSH_RUN_INTEGRATION_TESTS=
28
- - rvm: jruby-9.2.5.0
27
+ - rvm: jruby-9.2.11.1
29
28
  env: JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false' NET_SSH_RUN_INTEGRATION_TESTS=
30
29
  fast_finish: true
31
30
  allow_failures:
32
31
  - rvm: rbx-3.107
33
- - rvm: jruby-9.2.5.0
32
+ - rvm: jruby-9.2.11.1
34
33
  - rvm: ruby-head
35
34
 
36
35
  install:
37
36
  - export JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false'
38
37
  - sudo pip install ansible urllib3 pyOpenSSL ndg-httpsclient pyasn1
39
- - gem install bundler -v "= 1.16"
38
+ - gem install bundler -v "= 1.17"
40
39
  - gem list bundler
41
- - bundle _1.16_ install
42
- - bundle _1.16_ -v
43
- - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ install
40
+ - bundle _1.17_ install
41
+ - bundle _1.17_ -v
42
+ - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.17_ install
44
43
  - sudo ansible-galaxy install rvm.ruby
45
44
  - sudo chown -R travis:travis /home/travis/.ansible
46
45
  - 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'
47
46
 
48
47
  script:
49
48
  - ssh -V
50
- - bundle _1.16_ exec rake test
51
- - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ exec rake test
52
- - bundle _1.16_ exec rake test_test
53
- - bundle _1.16_ exec rubocop
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
data/CHANGES.txt CHANGED
@@ -1,8 +1,59 @@
1
+ === 6.1.0
2
+
3
+ * adapt to ssh's default bahaviors when no username is provided.
4
+ When Net::SSH.start user is nil and config has no entry
5
+ we default to Etc.getpwuid.name() instead of Etc.getlogin(). [#749]
6
+
7
+ === 6.1.0.rc1
8
+
9
+ * Make sha2-{256,512}-etm@openssh.com MAC default again [#761]
10
+ * Support algorithm subtraction syntax from ssh_config [#751]
11
+
12
+ === 6.0.2
13
+
14
+ * Fix corrupted hmac issue in etm hmac [#759]
15
+
16
+ === 6.0.1
17
+
18
+ * Make sha2-{256,512}-etm@openssh.com MAC opt-in as they seems to have issues [#757]
19
+
20
+ === 6.0.0
21
+
22
+ * Support empty lines and comments in known_hosts [donoghuc, #742]
23
+ * Add sha2-{256,512}-etm@openssh.com MAC algorithms [graaff, #714]
24
+
25
+ === 6.0.0 beta2
26
+
27
+ * Support :certkeys and CertificateFile configuration option [Anders Carling, #722]
28
+
29
+ === 6.0.0 beta1
30
+
31
+ * curve25519sha256 support [Florian Wininger ,#690]
32
+ * disabled insecure algs [Florian Wininger , #709]
33
+
34
+ === 5.2.0
35
+
36
+ === 5.2.0.rc3
37
+
38
+ * Fix check_host_ip read from config
39
+ * Support ssh-ed25519 in kown hosts
40
+
41
+ === 5.2.0.rc2
42
+
43
+ * Read check_host_ip from ssh config files
44
+
45
+ === 5.2.0.rc1
46
+
47
+ * Interpret * and ? in know_hosts file [Romain Tartière, #660]
48
+ * New :check_host_ip so ip checking can be disabled in known hosts [Romain Tartière, #656]
49
+
50
+ === 5.1.0
51
+
1
52
  === 5.1.0.rc1
2
53
 
3
54
  * Support new OpenSSH private key format for rsa - bcrypt for rsa (ed25519 already supported) [#646]
4
55
  * Support IdentityAgent is ssh config [Frank Groeneveld, #645]
5
- * Improve Match processin in ssh config [Aleksandrs Ļedovskis, #642]
56
+ * Improve Match processing in ssh config [Aleksandrs Ļedovskis, #642]
6
57
  * Ignore signature verification when verify_host_key is never [Piotr Kliczewski, #641]
7
58
  * Alg preference was changed to prefer stronger encryptions [Tray, #637]
8
59
 
data/Manifest CHANGED
@@ -33,7 +33,6 @@ lib/net/ssh/proxy/errors.rb
33
33
  lib/net/ssh/proxy/http.rb
34
34
  lib/net/ssh/proxy/socks4.rb
35
35
  lib/net/ssh/proxy/socks5.rb
36
- lib/net/ssh/ruby_compat.rb
37
36
  lib/net/ssh/service/forward.rb
38
37
  lib/net/ssh/test.rb
39
38
  lib/net/ssh/test/channel.rb
data/README.md ADDED
@@ -0,0 +1,287 @@
1
+ [![Gem Version](https://badge.fury.io/rb/net-ssh.svg)](https://badge.fury.io/rb/net-ssh)
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)
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
+ [![Backers on Open Collective](https://opencollective.com/net-ssh/backers/badge.svg)](#backers])
6
+ [![Sponsors on Open Collective](https://opencollective.com/net-ssh/sponsors/badge.svg)](#sponsors)
7
+
8
+ # Net::SSH 6.x
9
+
10
+ * Docs: http://net-ssh.github.com/net-ssh
11
+ * Issues: https://github.com/net-ssh/net-ssh/issues
12
+ * Codes: https://github.com/net-ssh/net-ssh
13
+ * Email: net-ssh@solutious.com
14
+
15
+ *As of v2.6.4, all gem releases are signed. See [INSTALL](#install).*
16
+
17
+ ## DESCRIPTION:
18
+
19
+ Net::SSH is a pure-Ruby implementation of the SSH2 client protocol.
20
+ It allows you to write programs that invoke and interact with processes on remote servers, via SSH2.
21
+
22
+ ## FEATURES:
23
+
24
+ * Execute processes on remote servers and capture their output
25
+ * Run multiple processes in parallel over a single SSH connection
26
+ * Support for SSH subsystems
27
+ * Forward local and remote ports via an SSH connection
28
+
29
+ ## Supported Algorithms
30
+
31
+ Net::SSH 6.0 disables by default the usage of weak algorithms.
32
+ We strongly recommend that you install a servers's version that supports the latest algorithms.
33
+
34
+ It is possible to return to the previous behavior by adding the option : `append_all_supported_algorithms: true`
35
+
36
+ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
37
+
38
+ ### Host Keys
39
+
40
+ | Name | Support | Details |
41
+ |----------------------|-----------------------|----------|
42
+ | ssh-rsa | OK | |
43
+ | ssh-ed25519 | OK | Require the gem `ed25519` |
44
+ | ecdsa-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
45
+ | ecdsa-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
46
+ | ecdsa-sha2-nistp256 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
47
+ | ssh-dss | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
48
+
49
+ ### Key Exchange
50
+
51
+ | Name | Support | Details |
52
+ |--------------------------------------|-----------------------|----------|
53
+ | curve25519-sha256 | OK | Require the gem `x25519` |
54
+ | ecdh-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
55
+ | ecdh-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
56
+ | ecdh-sha2-nistp256 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
57
+ | diffie-hellman-group1-sha1 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
58
+ | diffie-hellman-group14-sha1 | OK | |
59
+ | diffie-hellman-group-exchange-sha1 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
60
+ | diffie-hellman-group-exchange-sha256 | OK | |
61
+
62
+ ### Encryption algorithms (ciphers)
63
+
64
+ | Name | Support | Details |
65
+ |--------------------------------------|-----------------------|----------|
66
+ | aes256-ctr / aes192-ctr / aes128-ctr | OK | |
67
+ | aes256-cbc / aes192-cbc / aes128-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
68
+ | rijndael-cbc@lysator.liu.se | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
69
+ | blowfish-ctr blowfish-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
70
+ | cast128-ctr cast128-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
71
+ | 3des-ctr 3des-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
72
+ | idea-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
73
+ | none | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
74
+
75
+ ### Message Authentication Code algorithms
76
+
77
+ | Name | Support | Details |
78
+ |----------------------|-----------------------|----------|
79
+ | hmac-sha2-512-etm | OK | |
80
+ | hmac-sha2-256-etm | OK | |
81
+ | hmac-sha2-512 | OK | |
82
+ | hmac-sha2-256 | OK | |
83
+ | hmac-sha2-512-96 | Deprecated in 6.0 | removed from the specification, will be removed in 7.0 |
84
+ | hmac-sha2-256-96 | Deprecated in 6.0 | removed from the specification, will be removed in 7.0 |
85
+ | hmac-sha1 | OK | for backward compatibility |
86
+ | hmac-sha1-96 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
87
+ | hmac-ripemd160 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
88
+ | hmac-md5 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
89
+ | hmac-md5-96 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
90
+ | none | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
91
+
92
+ ## SYNOPSIS:
93
+
94
+ In a nutshell:
95
+
96
+ ```ruby
97
+ require 'net/ssh'
98
+
99
+ Net::SSH.start('host', 'user', password: "password") do |ssh|
100
+
101
+ # capture all stderr and stdout output from a remote process
102
+ output = ssh.exec!("hostname")
103
+ puts output
104
+
105
+ # capture only stdout matching a particular pattern
106
+ stdout = ""
107
+ ssh.exec!("ls -l /home/jamis") do |channel, stream, data|
108
+ stdout << data if stream == :stdout && /foo/.match(data)
109
+ end
110
+ puts stdout
111
+
112
+ # run multiple processes in parallel to completion
113
+ ssh.exec "sed ..."
114
+ ssh.exec "awk ..."
115
+ ssh.exec "rm -rf ..."
116
+ ssh.loop
117
+
118
+ # open a new channel and configure a minimal set of callbacks, then run
119
+ # the event loop until the channel finishes (closes)
120
+ channel = ssh.open_channel do |ch|
121
+ ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
122
+ raise "could not execute command" unless success
123
+
124
+ # "on_data" is called when the process writes something to stdout
125
+ ch.on_data do |c, data|
126
+ $stdout.print data
127
+ end
128
+
129
+ # "on_extended_data" is called when the process writes something to stderr
130
+ ch.on_extended_data do |c, type, data|
131
+ $stderr.print data
132
+ end
133
+
134
+ ch.on_close { puts "done!" }
135
+ end
136
+ end
137
+
138
+ channel.wait
139
+
140
+ # forward connections on local port 1234 to port 80 of www.capify.org
141
+ ssh.forward.local(1234, "www.capify.org", 80)
142
+ ssh.loop { true }
143
+ end
144
+ ```
145
+
146
+ See Net::SSH for more documentation, and links to further information.
147
+
148
+ ## REQUIREMENTS:
149
+
150
+ The only requirement you might be missing is the OpenSSL bindings for Ruby with a version greather than `1.0.1`.
151
+ These are built by default on most platforms, but you can verify that they're built and installed on your system by running the following command line:
152
+
153
+ ```sh
154
+ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
155
+ ```
156
+
157
+ If that spits out something like `OpenSSL 1.0.1 14 Mar 2012`, then you're set.
158
+ If you get an error, then you'll need to see about rebuilding ruby with OpenSSL support,
159
+ or (if your platform supports it) installing the OpenSSL bindings separately.
160
+
161
+ ## INSTALL:
162
+
163
+ ```sh
164
+ gem install net-ssh # might need sudo privileges
165
+ ```
166
+
167
+ NOTE: If you are running on jruby on windows you need to install `jruby-pageant` manually
168
+ (gemspec doesn't allow for platform specific dependencies at gem installation time).
169
+
170
+ However, in order to be sure the code you're installing hasn't been tampered with,
171
+ it's recommended that you verify the [signature](http://docs.rubygems.org/read/chapter/21).
172
+ To do this, you need to add my public key as a trusted certificate (you only need to do this once):
173
+
174
+ ```sh
175
+ # Add the public key as a trusted certificate
176
+ # (You only need to do this once)
177
+ curl -O https://raw.githubusercontent.com/net-ssh/net-ssh/master/net-ssh-public_cert.pem
178
+ gem cert --add net-ssh-public_cert.pem
179
+ ```
180
+
181
+ Then, when install the gem, do so with high security:
182
+
183
+ ```sh
184
+ gem install net-ssh -P HighSecurity
185
+ ```
186
+
187
+ If you don't add the public key, you'll see an error like "Couldn't verify data signature".
188
+ If you're still having trouble let me know and I'll give you a hand.
189
+
190
+ For ed25519 public key auth support your bundle file should contain `ed25519`, `bcrypt_pbkdf` dependencies.
191
+
192
+ ```sh
193
+ gem install ed25519
194
+ gem install bcrypt_pbkdf
195
+ ```
196
+
197
+ For curve25519-sha256 kex exchange support your bundle file should contain `x25519` dependency.
198
+
199
+ ## RUBY SUPPORT
200
+
201
+ * See [net-ssh.gemspec](https://github.com/net-ssh/net-ssh/blob/master/net-ssh.gemspec) for current versions ruby requirements
202
+
203
+ ## RUNNING TESTS
204
+
205
+ If you want to run the tests or use any of the Rake tasks, you'll need Mocha and
206
+ other dependencies listed in Gemfile
207
+
208
+ Run the test suite from the net-ssh directory with the following command:
209
+
210
+ ```sh
211
+ bundle exec rake test
212
+ ```
213
+
214
+ Run a single test file like this:
215
+
216
+ ```sh
217
+ ruby -Ilib -Itest test/transport/test_server_version.rb
218
+ ```
219
+
220
+ To run integration tests see test/integration/README.txt
221
+
222
+ ### BUILDING GEM
223
+
224
+ ```sh
225
+ rake build
226
+ ```
227
+
228
+ ### GEM SIGNING (for maintainers)
229
+
230
+ If you have the net-ssh private signing key, you will be able to create signed release builds. Make sure the private key path matches the `signing_key` path set in `net-ssh.gemspec` and tell rake to sign the gem by setting the `NET_SSH_BUILDGEM_SIGNED` flag:
231
+
232
+ ```sh
233
+ NET_SSH_BUILDGEM_SIGNED=true rake build
234
+ ```
235
+
236
+ For time to time, the public certificate associated to the private key needs to be renewed. You can do this with the following command:
237
+
238
+ ```sh
239
+ gem cert --build netssh@solutious.com --private-key path/2/net-ssh-private_key.pem
240
+ mv gem-public_cert.pem net-ssh-public_cert.pem
241
+ gem cert --add net-ssh-public_cert.pem
242
+ ```
243
+
244
+ ## CREDITS
245
+
246
+ ### Contributors
247
+
248
+ This project exists thanks to all the people who contribute.
249
+
250
+ [![contributors](https://opencollective.com/net-ssh/contributors.svg?width=890&button=false)](graphs/contributors)
251
+
252
+ ### Backers
253
+
254
+ Thank you to all our backers! 🙏 [Become a backer](https://opencollective.com/net-ssh#backer)
255
+
256
+ [![backers](https://opencollective.com/net-ssh/backers.svg?width=890)](https://opencollective.com/net-ssh#backers)
257
+
258
+ ### Sponsors
259
+
260
+ Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor](https://opencollective.com/net-ssh#sponsor)
261
+
262
+ [![Sponsor](https://opencollective.com/net-ssh/sponsor/0/avatar.svg)](https://opencollective.com/net-ssh/sponsor/0/website)
263
+
264
+ ## LICENSE:
265
+
266
+ (The MIT License)
267
+
268
+ Copyright (c) 2008 Jamis Buck
269
+
270
+ Permission is hereby granted, free of charge, to any person obtaining
271
+ a copy of this software and associated documentation files (the
272
+ 'Software'), to deal in the Software without restriction, including
273
+ without limitation the rights to use, copy, modify, merge, publish,
274
+ distribute, sublicense, and/or sell copies of the Software, and to
275
+ permit persons to whom the Software is furnished to do so, subject to
276
+ the following conditions:
277
+
278
+ The above copyright notice and this permission notice shall be
279
+ included in all copies or substantial portions of the Software.
280
+
281
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
282
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
283
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
284
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
285
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
286
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
287
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  #
3
2
  # Also in your terminal environment run:
4
3
  # $ export LANG=en_US.UTF-8
@@ -32,7 +31,7 @@ RDoc::Task.new do |rdoc|
32
31
  rdoc.rdoc_dir = "rdoc"
33
32
  rdoc.title = "#{name} #{version}"
34
33
  rdoc.generator = 'hanna' # gem install hanna-nouveau
35
- rdoc.main = 'README.rdoc'
34
+ rdoc.main = 'README.md'
36
35
  rdoc.rdoc_files.include("README*")
37
36
  rdoc.rdoc_files.include("bin/*.rb")
38
37
  rdoc.rdoc_files.include("lib/**/*.rb")
data/appveyor.yml CHANGED
@@ -5,9 +5,11 @@ skip_tags: true
5
5
  environment:
6
6
  matrix:
7
7
  - ruby_version: "jruby-9.1.2.0"
8
+ - ruby_version: "26-x64"
9
+ - ruby_version: "25-x64"
10
+ - ruby_version: "24-x64"
8
11
  - ruby_version: "23"
9
12
  - ruby_version: "23-x64"
10
- - ruby_version: "22-x64"
11
13
 
12
14
  matrix:
13
15
  allow_failures:
@@ -29,7 +31,7 @@ install:
29
31
  - if "%ruby_version%" == "jruby-9.1.2.0" ( cinst jruby --version 9.1.2.0 -i --allow-empty-checksums )
30
32
  - if "%ruby_version%" == "jruby-9.1.2.0" ( SET "PATH=C:\jruby-9.1.2.0\bin\;%PATH%" )
31
33
  - ruby --version
32
- - gem install bundler --no-document --user-install -v 1.16
34
+ - gem install bundler --no-document --user-install -v 1.17
33
35
  - SET BUNDLE_GEMFILE=Gemfile.noed25519
34
36
  - bundle install --retry=3
35
37
  - cinst freesshd
@@ -31,7 +31,16 @@ 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
- cert.valid_before = Time.at(buffer.read_int64)
34
+
35
+ cert.valid_before = if RUBY_PLATFORM == "java"
36
+ # 0x20c49ba5e353f7 = 0x7fffffffffffffff/1000, the largest value possible for JRuby
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)
40
+ else
41
+ Time.at(buffer.read_int64)
42
+ end
43
+
35
44
  cert.critical_options = read_options(buffer)
36
45
  cert.extensions = read_options(buffer)
37
46
  cert.reserved = buffer.read_string
@@ -26,10 +26,22 @@ module Net
26
26
  CipherFactory = Net::SSH::Transport::CipherFactory
27
27
 
28
28
  MBEGIN = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
29
- MEND = "-----END OPENSSH PRIVATE KEY-----\n"
29
+ MEND = "-----END OPENSSH PRIVATE KEY-----"
30
30
  MAGIC = "openssh-key-v1"
31
31
 
32
+ class DecryptError < ArgumentError
33
+ def initialize(message, encrypted_key: false)
34
+ super(message)
35
+ @encrypted_key = encrypted_key
36
+ end
37
+
38
+ def encrypted_key?
39
+ return @encrypted_key
40
+ end
41
+ end
42
+
32
43
  def self.read(datafull, password)
44
+ datafull = datafull.strip
33
45
  raise ArgumentError.new("Expected #{MBEGIN} at start of private key") unless datafull.start_with?(MBEGIN)
34
46
  raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
35
47
  datab64 = datafull[MBEGIN.size...-MEND.size]
@@ -74,7 +86,7 @@ module Net
74
86
  check1 = decoded.read_long
75
87
  check2 = decoded.read_long
76
88
 
77
- raise ArgumentError, "Decrypt failed on private key" if (check1 != check2)
89
+ raise DecryptError.new("Decrypt failed on private key", encrypted_key: kdfname == 'bcrypt') if (check1 != check2)
78
90
 
79
91
  type_name = decoded.read_string
80
92
  case type_name
@@ -3,7 +3,7 @@ module Net
3
3
  module Authentication
4
4
 
5
5
  # Loads ED25519 support which requires optinal dependecies like
6
- # rbnacl, bcrypt_pbkdf
6
+ # ed25519, bcrypt_pbkdf
7
7
  module ED25519Loader
8
8
 
9
9
  begin
@@ -30,6 +30,9 @@ module Net
30
30
  # The list of user key data that will be examined
31
31
  attr_reader :key_data
32
32
 
33
+ # The list of user key certificate files that will be examined
34
+ attr_reader :keycert_files
35
+
33
36
  # The map of loaded identities
34
37
  attr_reader :known_identities
35
38
 
@@ -43,6 +46,7 @@ module Net
43
46
  self.logger = logger
44
47
  @key_files = []
45
48
  @key_data = []
49
+ @keycert_files = []
46
50
  @use_agent = options[:use_agent] != false
47
51
  @known_identities = {}
48
52
  @agent = nil
@@ -66,6 +70,12 @@ module Net
66
70
  self
67
71
  end
68
72
 
73
+ # Add the given keycert_file to the list of keycert files that will be used.
74
+ def add_keycert(keycert_file)
75
+ keycert_files.push(File.expand_path(keycert_file)).uniq!
76
+ self
77
+ end
78
+
69
79
  # Add the given key_file to the list of keys that will be used.
70
80
  def add_key_data(key_data_)
71
81
  key_data.push(key_data_).uniq!
@@ -108,7 +118,7 @@ module Net
108
118
  user_identities.delete(corresponding_user_identity) if corresponding_user_identity
109
119
 
110
120
  if !options[:keys_only] || corresponding_user_identity
111
- known_identities[key] = { from: :agent }
121
+ known_identities[key] = { from: :agent, identity: key }
112
122
  yield key
113
123
  end
114
124
  end
@@ -122,6 +132,21 @@ module Net
122
132
  yield key
123
133
  end
124
134
 
135
+ known_identity_blobs = known_identities.keys.map(&:to_blob)
136
+ keycert_files.each do |keycert_file|
137
+ keycert = KeyFactory.load_public_key(keycert_file)
138
+ next if known_identity_blobs.include?(keycert.to_blob)
139
+
140
+ (_, corresponding_identity) = known_identities.detect { |public_key, _|
141
+ public_key.to_pem == keycert.to_pem
142
+ }
143
+
144
+ if corresponding_identity
145
+ known_identities[keycert] = corresponding_identity
146
+ yield keycert
147
+ end
148
+ end
149
+
125
150
  self
126
151
  end
127
152
 
@@ -139,7 +164,7 @@ module Net
139
164
 
140
165
  if info[:key].nil? && info[:from] == :file
141
166
  begin
142
- info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive])
167
+ info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive], options[:password_prompt])
143
168
  rescue OpenSSL::OpenSSLError, Exception => e
144
169
  raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
145
170
  end
@@ -152,7 +177,7 @@ module Net
152
177
 
153
178
  if info[:from] == :agent
154
179
  raise KeyManagerError, "the agent is no longer available" unless agent
155
- return agent.sign(identity, data.to_s)
180
+ return agent.sign(info[:identity], data.to_s)
156
181
  end
157
182
 
158
183
  raise KeyManagerError, "[BUG] can't determine identity origin (#{info.inspect})"
@@ -229,11 +254,15 @@ module Net
229
254
  key = KeyFactory.load_public_key(identity[:pubkey_file])
230
255
  { public_key: key, from: :file, file: identity[:privkey_file] }
231
256
  when :privkey_file
232
- private_key = KeyFactory.load_private_key(identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt])
257
+ private_key = KeyFactory.load_private_key(
258
+ identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt]
259
+ )
233
260
  key = private_key.send(:public_key)
234
261
  { public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
235
262
  when :data
236
- private_key = KeyFactory.load_data_private_key(identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt])
263
+ private_key = KeyFactory.load_data_private_key(
264
+ identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt]
265
+ )
237
266
  key = private_key.send(:public_key)
238
267
  { public_key: key, from: :key_data, data: identity[:data], key: private_key }
239
268
  else
@@ -40,7 +40,9 @@ module Net
40
40
  instruction = message.read_string
41
41
  debug { "keyboard-interactive info request" }
42
42
 
43
- prompter = prompt.start(type: 'keyboard-interactive', name: name, instruction: instruction) if password.nil? && interactive? && prompter.nil?
43
+ if password.nil? && interactive? && prompter.nil?
44
+ prompter = prompt.start(type: 'keyboard-interactive', name: name, instruction: instruction)
45
+ end
44
46
 
45
47
  _ = message.read_string # lang_tag
46
48
  responses = []
@@ -1,4 +1,3 @@
1
-
2
1
  require 'openssl'
3
2
 
4
3
  module Net
@@ -63,6 +63,7 @@ module Net
63
63
 
64
64
  key_manager = KeyManager.new(logger, options)
65
65
  keys.each { |key| key_manager.add(key) } unless keys.empty?
66
+ keycerts.each { |keycert| key_manager.add_keycert(keycert) } unless keycerts.empty?
66
67
  key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty?
67
68
  default_keys.each { |key| key_manager.add(key) } unless options.key?(:keys) || options.key?(:key_data)
68
69
 
@@ -136,12 +137,8 @@ module Net
136
137
  # Returns an array of paths to the key files usually defined
137
138
  # by system default.
138
139
  def default_keys
139
- if defined?(OpenSSL::PKey::EC)
140
- %w[~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa
141
- ~/.ssh2/id_ed25519 ~/.ssh2/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_ecdsa]
142
- else
143
- %w[~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa]
144
- end
140
+ %w[~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa
141
+ ~/.ssh2/id_ed25519 ~/.ssh2/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_ecdsa]
145
142
  end
146
143
 
147
144
  # Returns an array of paths to the key files that should be used when
@@ -150,6 +147,12 @@ module Net
150
147
  Array(options[:keys])
151
148
  end
152
149
 
150
+ # Returns an array of paths to the keycert files that should be used when
151
+ # attempting any key-based authentication mechanism.
152
+ def keycerts
153
+ Array(options[:keycerts])
154
+ end
155
+
153
156
  # Returns an array of the key data that should be used when
154
157
  # attempting any key-based authentication mechanism.
155
158
  def key_data