net-ssh 6.1.0 → 7.3.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.dockerignore +6 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/config/rubocop_linter_action.yml +4 -0
- data/.github/workflows/ci-with-docker.yml +44 -0
- data/.github/workflows/ci.yml +94 -0
- data/.github/workflows/rubocop.yml +16 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +12 -1
- data/.rubocop_todo.yml +475 -376
- data/CHANGES.txt +64 -3
- data/DEVELOPMENT.md +23 -0
- data/Dockerfile +29 -0
- data/Dockerfile.openssl3 +17 -0
- data/Gemfile +2 -0
- data/Gemfile.noed25519 +2 -0
- data/Gemfile.norbnacl +12 -0
- data/README.md +38 -22
- data/Rakefile +92 -0
- data/SECURITY.md +4 -0
- data/docker-compose.yml +25 -0
- data/lib/net/ssh/authentication/agent.rb +29 -13
- data/lib/net/ssh/authentication/certificate.rb +14 -11
- data/lib/net/ssh/authentication/constants.rb +0 -1
- data/lib/net/ssh/authentication/ed25519.rb +14 -11
- data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
- data/lib/net/ssh/authentication/key_manager.rb +65 -36
- data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
- data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
- data/lib/net/ssh/authentication/methods/none.rb +6 -9
- data/lib/net/ssh/authentication/methods/password.rb +2 -3
- data/lib/net/ssh/authentication/methods/publickey.rb +57 -17
- data/lib/net/ssh/authentication/pageant.rb +97 -97
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +3 -3
- data/lib/net/ssh/authentication/session.rb +25 -17
- data/lib/net/ssh/buffer.rb +71 -51
- data/lib/net/ssh/buffered_io.rb +25 -26
- data/lib/net/ssh/config.rb +33 -20
- data/lib/net/ssh/connection/channel.rb +84 -82
- data/lib/net/ssh/connection/constants.rb +0 -4
- data/lib/net/ssh/connection/event_loop.rb +30 -24
- data/lib/net/ssh/connection/keepalive.rb +12 -12
- data/lib/net/ssh/connection/session.rb +109 -108
- data/lib/net/ssh/connection/term.rb +56 -58
- data/lib/net/ssh/errors.rb +12 -12
- data/lib/net/ssh/key_factory.rb +7 -8
- data/lib/net/ssh/known_hosts.rb +86 -18
- data/lib/net/ssh/loggable.rb +8 -9
- data/lib/net/ssh/packet.rb +1 -1
- data/lib/net/ssh/prompt.rb +9 -11
- data/lib/net/ssh/proxy/command.rb +1 -1
- data/lib/net/ssh/proxy/errors.rb +2 -4
- data/lib/net/ssh/proxy/http.rb +18 -20
- data/lib/net/ssh/proxy/https.rb +8 -10
- data/lib/net/ssh/proxy/jump.rb +8 -10
- data/lib/net/ssh/proxy/socks4.rb +2 -4
- data/lib/net/ssh/proxy/socks5.rb +3 -5
- data/lib/net/ssh/service/forward.rb +7 -7
- data/lib/net/ssh/test/channel.rb +24 -26
- data/lib/net/ssh/test/extensions.rb +35 -35
- data/lib/net/ssh/test/kex.rb +6 -8
- data/lib/net/ssh/test/local_packet.rb +0 -2
- data/lib/net/ssh/test/packet.rb +3 -3
- data/lib/net/ssh/test/remote_packet.rb +6 -8
- data/lib/net/ssh/test/script.rb +25 -27
- data/lib/net/ssh/test/socket.rb +12 -15
- data/lib/net/ssh/test.rb +4 -5
- data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
- data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
- data/lib/net/ssh/transport/algorithms.rb +51 -19
- data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
- data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
- data/lib/net/ssh/transport/cipher_factory.rb +56 -29
- data/lib/net/ssh/transport/constants.rb +3 -3
- data/lib/net/ssh/transport/ctr.rb +7 -7
- data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
- data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
- data/lib/net/ssh/transport/hmac/md5.rb +0 -2
- data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/none.rb +0 -2
- data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
- data/lib/net/ssh/transport/hmac.rb +12 -12
- data/lib/net/ssh/transport/identity_cipher.rb +19 -13
- data/lib/net/ssh/transport/kex/abstract.rb +12 -5
- data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +21 -21
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
- data/lib/net/ssh/transport/kex.rb +8 -6
- data/lib/net/ssh/transport/key_expander.rb +7 -8
- data/lib/net/ssh/transport/openssl.rb +51 -26
- data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
- data/lib/net/ssh/transport/packet_stream.rb +46 -26
- data/lib/net/ssh/transport/server_version.rb +17 -16
- data/lib/net/ssh/transport/session.rb +9 -7
- data/lib/net/ssh/transport/state.rb +44 -44
- data/lib/net/ssh/verifiers/accept_new.rb +0 -2
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
- data/lib/net/ssh/verifiers/always.rb +6 -4
- data/lib/net/ssh/verifiers/never.rb +0 -2
- data/lib/net/ssh/version.rb +2 -2
- data/lib/net/ssh.rb +15 -8
- data/net-ssh-public_cert.pem +19 -18
- data/net-ssh.gemspec +7 -4
- data/support/ssh_tunnel_bug.rb +3 -3
- data.tar.gz.sig +0 -0
- metadata +76 -29
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -52
data/CHANGES.txt
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
|
+
=== 7.3.0 rc0
|
|
2
|
+
|
|
3
|
+
* aes(128|256)gcm [#946]
|
|
4
|
+
|
|
5
|
+
=== 7.2.2
|
|
6
|
+
|
|
7
|
+
* ruby 3.3.0: base64 fix
|
|
8
|
+
|
|
9
|
+
=== 7.2.1 rc1
|
|
10
|
+
|
|
11
|
+
* feat: allow load of certkey from string [#926]
|
|
12
|
+
* fix: fix for Socket#recv returning nil on ruby 3.3.0 [#928]
|
|
13
|
+
|
|
14
|
+
=== 7.2.0
|
|
15
|
+
|
|
16
|
+
* Add debugging information for algorithm of pubkey in use [#918]
|
|
17
|
+
|
|
18
|
+
=== 7.2.0 rc1
|
|
19
|
+
|
|
20
|
+
* Allow IdentityAgent as option to Net::SSH.start [#912]
|
|
21
|
+
|
|
22
|
+
=== 7.2.0 beta1
|
|
23
|
+
|
|
24
|
+
* Support `chacha20-poly1305@opnessh.com` cypher if `RbNaCl` gem is installed [#908]
|
|
25
|
+
|
|
26
|
+
=== 7.1.0
|
|
27
|
+
|
|
28
|
+
* Accept pubkey_algorithms option when starting a new connection [#891]
|
|
29
|
+
|
|
30
|
+
=== 7.1.0 beta1
|
|
31
|
+
|
|
32
|
+
* Don't use the deprecated set_XXX methods on RSA keys. [#875]
|
|
33
|
+
* Raise error when BCryptPbkdf fails [#876]
|
|
34
|
+
|
|
35
|
+
=== 7.0.1
|
|
36
|
+
|
|
37
|
+
* Drop leftover debug statement [#866]
|
|
38
|
+
|
|
39
|
+
=== 7.0.0
|
|
40
|
+
|
|
41
|
+
* BREAKING: Drop support for Ruby 2.5
|
|
42
|
+
* Fix decoding of ecdsa-sha2-nistp256 private keys [#657, #854]
|
|
43
|
+
* Fix missing require [#855]
|
|
44
|
+
* Support `~` in the path to the SSH agent's unix socket [#850]
|
|
45
|
+
* Add support for RSA client authentication with SHA-2 [a45f54]
|
|
46
|
+
* openssl: DSA: don't hardcode expected signature size, see ruby/openssl#483 [23a15c]
|
|
47
|
+
* Internal housekeeping (rubocop, codecov, remove travis, adding/improving tests)
|
|
48
|
+
|
|
49
|
+
=== 6.3.0 beta1
|
|
50
|
+
|
|
51
|
+
* Support cert based host key auth, fix asterisk in known_hosts [#833]
|
|
52
|
+
* Support kex dh-group14-sha256 [#795]
|
|
53
|
+
* Fix StrictHostKeyChecking ssh config parameter translation [#765]
|
|
54
|
+
|
|
55
|
+
=== 6.2.0 rc1
|
|
56
|
+
|
|
57
|
+
=== 6.2.0 beta1
|
|
58
|
+
|
|
59
|
+
* rsa-sha2-512, rsa-sha2-256 host_key algs [#771]
|
|
60
|
+
* JRuby aes*-ctr suppport [#767]
|
|
61
|
+
|
|
1
62
|
=== 6.1.0
|
|
2
63
|
|
|
3
|
-
*
|
|
64
|
+
* Adapt to ssh's default behaviors when no username is provided.
|
|
4
65
|
When Net::SSH.start user is nil and config has no entry
|
|
5
66
|
we default to Etc.getpwuid.name() instead of Etc.getlogin(). [#749]
|
|
6
67
|
|
|
@@ -36,7 +97,7 @@
|
|
|
36
97
|
=== 5.2.0.rc3
|
|
37
98
|
|
|
38
99
|
* Fix check_host_ip read from config
|
|
39
|
-
* Support ssh-ed25519 in
|
|
100
|
+
* Support ssh-ed25519 in known hosts
|
|
40
101
|
|
|
41
102
|
=== 5.2.0.rc2
|
|
42
103
|
|
|
@@ -59,7 +120,7 @@
|
|
|
59
120
|
|
|
60
121
|
=== 5.0.2
|
|
61
122
|
|
|
62
|
-
*
|
|
123
|
+
* Fix ctr for jruby [#612]
|
|
63
124
|
|
|
64
125
|
=== 5.0.1
|
|
65
126
|
|
data/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
### Development notes
|
|
2
|
+
|
|
3
|
+
## Building/running ssh server in debug mode
|
|
4
|
+
|
|
5
|
+
clone the openssh server from `https://github.com/openssh/openssh-portable`
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
brew install openssl
|
|
9
|
+
/usr/local/Cellar/openssl@3/3.1.0/bin/openssl
|
|
10
|
+
|
|
11
|
+
autoreconf
|
|
12
|
+
./configure --with-ssl-dir=/usr/local/Cellar/openssl@3/3.1.0/ --with-audit=debug --enable-debug CPPFLAGS="-DDEBUG -DPACKET_DEBUG" CFLAGS="-g -O0"
|
|
13
|
+
make
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
To run server in debug mode:
|
|
17
|
+
```sh
|
|
18
|
+
echo '#' > /tmp/sshd_config
|
|
19
|
+
ssh-keygen -t rsa -f /tmp/ssh_host_rsa_key
|
|
20
|
+
# /Users/boga/Work/OSS/NetSSH/openssh-portable/sshd -p 2222 -D -d -d -d -e -f /tmp/sshd_config
|
|
21
|
+
/Users/boga/Work/OSS/NetSSH/openssh-portable/sshd -p 2222 -D -d -d -d -e -f /tmp/sshd_config -h /tmp/ssh_host_rsa_key
|
|
22
|
+
|
|
23
|
+
```
|
data/Dockerfile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
ARG RUBY_VERSION=3.1
|
|
2
|
+
FROM ruby:${RUBY_VERSION}
|
|
3
|
+
|
|
4
|
+
ARG BUNDLERV=
|
|
5
|
+
|
|
6
|
+
RUN apt update && apt install -y openssh-server sudo netcat-openbsd \
|
|
7
|
+
&& useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_1' \
|
|
8
|
+
&& useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_2' \
|
|
9
|
+
&& echo net_ssh_1:foopwd | chpasswd \
|
|
10
|
+
&& echo net_ssh_2:foo2pwd | chpasswd \
|
|
11
|
+
&& mkdir -p /home/net_ssh_1/.ssh \
|
|
12
|
+
&& mkdir -p /home/net_ssh_2/.ssh \
|
|
13
|
+
&& echo "net_ssh_1 ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
|
|
14
|
+
&& echo "net_ssh_2 ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
|
|
15
|
+
&& ssh-keygen -f /etc/ssh/users_ca -N ''
|
|
16
|
+
|
|
17
|
+
ENV INSTALL_PATH="/netssh"
|
|
18
|
+
|
|
19
|
+
WORKDIR $INSTALL_PATH
|
|
20
|
+
|
|
21
|
+
COPY Gemfile net-ssh.gemspec $INSTALL_PATH/
|
|
22
|
+
|
|
23
|
+
COPY lib/net/ssh/version.rb $INSTALL_PATH/lib/net/ssh/version.rb
|
|
24
|
+
|
|
25
|
+
RUN gem install bundler ${BUNDLERV} && bundle install
|
|
26
|
+
|
|
27
|
+
COPY . $INSTALL_PATH/
|
|
28
|
+
|
|
29
|
+
CMD service ssh start && rake test && NET_SSH_NO_ED25519=1 rake test
|
data/Dockerfile.openssl3
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
FROM ubuntu:22.04
|
|
2
|
+
|
|
3
|
+
ENV INSTALL_PATH="/netssh"
|
|
4
|
+
|
|
5
|
+
RUN apt update && apt install -y openssl ruby ruby-dev git build-essential
|
|
6
|
+
|
|
7
|
+
WORKDIR $INSTALL_PATH
|
|
8
|
+
|
|
9
|
+
COPY Gemfile net-ssh.gemspec $INSTALL_PATH/
|
|
10
|
+
|
|
11
|
+
COPY lib/net/ssh/version.rb $INSTALL_PATH/lib/net/ssh/version.rb
|
|
12
|
+
|
|
13
|
+
RUN ls -l && gem install bundler && bundle install
|
|
14
|
+
|
|
15
|
+
COPY . $INSTALL_PATH/
|
|
16
|
+
|
|
17
|
+
CMD openssl version && ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' && rake test
|
data/Gemfile
CHANGED
data/Gemfile.noed25519
CHANGED
data/Gemfile.norbnacl
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
ENV['NET_SSH_NO_RBNACL'] = 'true'
|
|
4
|
+
# Specify your gem's dependencies in mygem.gemspec
|
|
5
|
+
gemspec
|
|
6
|
+
|
|
7
|
+
if ENV["CI"] && !Gem.win_platform?
|
|
8
|
+
gem 'simplecov', require: false, group: :test
|
|
9
|
+
gem 'codecov', require: false, group: :test
|
|
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
|
[](https://badge.fury.io/rb/net-ssh)
|
|
2
2
|
[](https://gitter.im/net-ssh/net-ssh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
3
|
-
[](https://github.com/net-ssh/net-ssh/actions/workflows/ci.yml)
|
|
4
4
|
[](https://codecov.io/gh/net-ssh/net-ssh)
|
|
5
5
|
[](#backers])
|
|
6
6
|
[](#sponsors)
|
|
7
7
|
|
|
8
|
-
# Net::SSH
|
|
8
|
+
# Net::SSH 7.x
|
|
9
9
|
|
|
10
|
-
* Docs: http://net-ssh.github.
|
|
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
|
|
@@ -33,7 +33,7 @@ We strongly recommend that you install a servers's version that supports the lat
|
|
|
33
33
|
|
|
34
34
|
It is possible to return to the previous behavior by adding the option : `append_all_supported_algorithms: true`
|
|
35
35
|
|
|
36
|
-
Unsecure algoritms will definitely be removed in Net::SSH
|
|
36
|
+
Unsecure algoritms will definitely be removed in Net::SSH 8.*.
|
|
37
37
|
|
|
38
38
|
### Host Keys
|
|
39
39
|
|
|
@@ -44,7 +44,7 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
|
|
|
44
44
|
| ecdsa-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
|
|
45
45
|
| ecdsa-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
|
|
46
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
|
|
47
|
+
| ssh-dss | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
48
48
|
|
|
49
49
|
### Key Exchange
|
|
50
50
|
|
|
@@ -54,9 +54,9 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
|
|
|
54
54
|
| ecdh-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
|
|
55
55
|
| ecdh-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
|
|
56
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
|
|
57
|
+
| diffie-hellman-group1-sha1 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
58
58
|
| diffie-hellman-group14-sha1 | OK | |
|
|
59
|
-
| diffie-hellman-group-exchange-sha1 | Deprecated in 6.0 | unsecure, will be removed in
|
|
59
|
+
| diffie-hellman-group-exchange-sha1 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
60
60
|
| diffie-hellman-group-exchange-sha256 | OK | |
|
|
61
61
|
|
|
62
62
|
### Encryption algorithms (ciphers)
|
|
@@ -64,13 +64,14 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
|
|
|
64
64
|
| Name | Support | Details |
|
|
65
65
|
|--------------------------------------|-----------------------|----------|
|
|
66
66
|
| aes256-ctr / aes192-ctr / aes128-ctr | OK | |
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
67
|
+
| chacha20-poly1305@openssh.com | OK. | Requires the gem `rbnacl` |
|
|
68
|
+
| aes256-cbc / aes192-cbc / aes128-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
69
|
+
| rijndael-cbc@lysator.liu.se | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
70
|
+
| blowfish-ctr blowfish-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
71
|
+
| cast128-ctr cast128-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
72
|
+
| 3des-ctr 3des-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
73
|
+
| idea-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
74
|
+
| none | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
74
75
|
|
|
75
76
|
### Message Authentication Code algorithms
|
|
76
77
|
|
|
@@ -80,14 +81,14 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
|
|
|
80
81
|
| hmac-sha2-256-etm | OK | |
|
|
81
82
|
| hmac-sha2-512 | OK | |
|
|
82
83
|
| hmac-sha2-256 | OK | |
|
|
83
|
-
| hmac-sha2-512-96 | Deprecated in 6.0 | removed from the specification, will be removed in
|
|
84
|
-
| hmac-sha2-256-96 | Deprecated in 6.0 | removed from the specification, will be removed in
|
|
84
|
+
| hmac-sha2-512-96 | Deprecated in 6.0 | removed from the specification, will be removed in 8.0 |
|
|
85
|
+
| hmac-sha2-256-96 | Deprecated in 6.0 | removed from the specification, will be removed in 8.0 |
|
|
85
86
|
| hmac-sha1 | OK | for backward compatibility |
|
|
86
|
-
| hmac-sha1-96 | Deprecated in 6.0 | unsecure, will be removed in
|
|
87
|
-
| hmac-ripemd160 | Deprecated in 6.0 | unsecure, will be removed in
|
|
88
|
-
| hmac-md5 | Deprecated in 6.0 | unsecure, will be removed in
|
|
89
|
-
| hmac-md5-96 | Deprecated in 6.0 | unsecure, will be removed in
|
|
90
|
-
| none | Deprecated in 6.0 | unsecure, will be removed in
|
|
87
|
+
| hmac-sha1-96 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
88
|
+
| hmac-ripemd160 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
89
|
+
| hmac-md5 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
90
|
+
| hmac-md5-96 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
91
|
+
| none | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
|
|
91
92
|
|
|
92
93
|
## SYNOPSIS:
|
|
93
94
|
|
|
@@ -211,13 +212,19 @@ Run the test suite from the net-ssh directory with the following command:
|
|
|
211
212
|
bundle exec rake test
|
|
212
213
|
```
|
|
213
214
|
|
|
215
|
+
NOTE : you can run test on all ruby versions with docker :
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
docker-compose up --build
|
|
219
|
+
```
|
|
220
|
+
|
|
214
221
|
Run a single test file like this:
|
|
215
222
|
|
|
216
223
|
```sh
|
|
217
224
|
ruby -Ilib -Itest test/transport/test_server_version.rb
|
|
218
225
|
```
|
|
219
226
|
|
|
220
|
-
To run integration tests see test/integration/README.
|
|
227
|
+
To run integration tests see [here](test/integration/README.md)
|
|
221
228
|
|
|
222
229
|
### BUILDING GEM
|
|
223
230
|
|
|
@@ -241,6 +248,12 @@ mv gem-public_cert.pem net-ssh-public_cert.pem
|
|
|
241
248
|
gem cert --add net-ssh-public_cert.pem
|
|
242
249
|
```
|
|
243
250
|
|
|
251
|
+
or `rake cert:update_public_when_expired`
|
|
252
|
+
|
|
253
|
+
## Security contact information
|
|
254
|
+
|
|
255
|
+
See [SECURITY.md](SECURITY.md)
|
|
256
|
+
|
|
244
257
|
## CREDITS
|
|
245
258
|
|
|
246
259
|
### Contributors
|
|
@@ -261,6 +274,9 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
|
|
261
274
|
|
|
262
275
|
[](https://opencollective.com/net-ssh/sponsor/0/website)
|
|
263
276
|
|
|
277
|
+
[<img src="https://github.com/net-ssh/net-ssh/assets/52435/9690bf3e-34ea-4c52-8aea-1cc4cb5bcb6d" width="320">](https://ubicloud.com)
|
|
278
|
+
|
|
279
|
+
|
|
264
280
|
## LICENSE:
|
|
265
281
|
|
|
266
282
|
(The MIT License)
|
data/Rakefile
CHANGED
|
@@ -48,12 +48,100 @@ 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"
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
58
|
+
def change_version(&block)
|
|
59
|
+
version_file = 'lib/net/ssh/version.rb'
|
|
60
|
+
require_relative version_file
|
|
61
|
+
pre = Net::SSH::Version::PRE
|
|
62
|
+
tiny = Net::SSH::Version::TINY
|
|
63
|
+
result = block[pre: pre, tiny: Net::SSH::Version::TINY]
|
|
64
|
+
raise ArgumentError, "Version change logic should always return a pre" unless result.key?(:pre)
|
|
65
|
+
|
|
66
|
+
new_pre = result[:pre]
|
|
67
|
+
new_tiny = result[:tiny] || tiny
|
|
68
|
+
found = { pre: false, tiny: false }
|
|
69
|
+
File.open("#{version_file}.new", "w") do |f|
|
|
70
|
+
File.readlines(version_file).each do |line|
|
|
71
|
+
match =
|
|
72
|
+
if pre.nil?
|
|
73
|
+
/^(\s+PRE\s+=\s+)nil(\s*)$/.match(line)
|
|
74
|
+
else
|
|
75
|
+
/^(\s+PRE\s+=\s+")#{pre}("\s*)$/.match(line)
|
|
76
|
+
end
|
|
77
|
+
if match
|
|
78
|
+
prefix = match[1]
|
|
79
|
+
postfix = match[2]
|
|
80
|
+
prefix.delete_suffix!('"')
|
|
81
|
+
postfix.delete_prefix!('"')
|
|
82
|
+
new_line = "#{prefix}#{new_pre.inspect}#{postfix}"
|
|
83
|
+
puts "Changing:\n - #{line} + #{new_line}"
|
|
84
|
+
line = new_line
|
|
85
|
+
found[:pre] = true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if new_tiny != tiny
|
|
89
|
+
match = /^(\s+TINY\s+=\s+)#{tiny}(\s*)$/.match(line)
|
|
90
|
+
if match
|
|
91
|
+
prefix = match[1]
|
|
92
|
+
postfix = match[2]
|
|
93
|
+
new_line = "#{prefix}#{new_tiny}#{postfix}"
|
|
94
|
+
puts "Changing:\n - #{line} + #{new_line}"
|
|
95
|
+
line = new_line
|
|
96
|
+
found[:tiny] = true
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
f.write(line)
|
|
101
|
+
end
|
|
102
|
+
raise ArgumentError, "Cound not find line: PRE = \"#{pre}\" in #{version_file}" unless found[:pre]
|
|
103
|
+
raise ArgumentError, "Cound not find line: TINY = \"#{tiny}\" in #{version_file}" unless found[:tiny] || new_tiny == tiny
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
FileUtils.mv version_file, "#{version_file}.old"
|
|
107
|
+
FileUtils.mv "#{version_file}.new", version_file
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
namespace :vbump do
|
|
111
|
+
desc "Final release"
|
|
112
|
+
task :final do
|
|
113
|
+
change_version do |pre:, tiny:|
|
|
114
|
+
_ = tiny
|
|
115
|
+
if pre.nil?
|
|
116
|
+
{ tiny: tiny + 1, pre: nil }
|
|
117
|
+
else
|
|
118
|
+
raise ArgumentError, "Unexpected pre: #{pre}" if pre.nil?
|
|
119
|
+
|
|
120
|
+
{ pre: nil }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
desc "Increment prerelease"
|
|
126
|
+
task :pre, [:type] do |_t, args|
|
|
127
|
+
change_version do |pre:, tiny:|
|
|
128
|
+
puts " PRE => #{pre.inspect}"
|
|
129
|
+
match = /^([a-z]+)(\d+)/.match(pre)
|
|
130
|
+
raise ArgumentError, "Unexpected pre: #{pre}" if match.nil? && args[:type].nil?
|
|
131
|
+
|
|
132
|
+
if match.nil? || (!args[:type].nil? && args[:type] != match[1])
|
|
133
|
+
if pre.nil?
|
|
134
|
+
{ pre: "#{args[:type]}1", tiny: tiny + 1 }
|
|
135
|
+
else
|
|
136
|
+
{ pre: "#{args[:type]}1" }
|
|
137
|
+
end
|
|
138
|
+
else
|
|
139
|
+
{ pre: "#{match[1]}#{match[2].to_i + 1}" }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
57
145
|
namespace :rdoc do
|
|
58
146
|
desc "Update gh-pages branch"
|
|
59
147
|
task :publish do
|
|
@@ -94,6 +182,10 @@ Rake::TestTask.new do |t|
|
|
|
94
182
|
t.test_files = test_files
|
|
95
183
|
end
|
|
96
184
|
|
|
185
|
+
# We need to enable the OpenSSL 3.0 legacy providers for our test suite
|
|
186
|
+
require 'openssl'
|
|
187
|
+
ENV['OPENSSL_CONF'] = 'test/openssl3.conf' if OpenSSL::OPENSSL_LIBRARY_VERSION.start_with? "OpenSSL 3"
|
|
188
|
+
|
|
97
189
|
desc "Run tests of Net::SSH:Test"
|
|
98
190
|
Rake::TestTask.new do |t|
|
|
99
191
|
t.name = "test_test"
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
## Security contact information
|
|
2
|
+
|
|
3
|
+
To report a security vulnerability, please use the
|
|
4
|
+
[GitHub private vulnerability reporting feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability).
|
data/docker-compose.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
ruby-3.1:
|
|
5
|
+
build:
|
|
6
|
+
context: .
|
|
7
|
+
args:
|
|
8
|
+
RUBY_VERSION: 3.1
|
|
9
|
+
ruby-3.0:
|
|
10
|
+
build:
|
|
11
|
+
context: .
|
|
12
|
+
args:
|
|
13
|
+
RUBY_VERSION: 3.0
|
|
14
|
+
ruby-2.7:
|
|
15
|
+
build:
|
|
16
|
+
context: .
|
|
17
|
+
args:
|
|
18
|
+
RUBY_VERSION: 2.7
|
|
19
|
+
BUNDLERV: "-v 2.2.28"
|
|
20
|
+
ruby-2.6:
|
|
21
|
+
build:
|
|
22
|
+
context: .
|
|
23
|
+
args:
|
|
24
|
+
RUBY_VERSION: 2.6
|
|
25
|
+
BUNDLERV: "-v 2.4.22"
|
|
@@ -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
|
|
@@ -62,7 +65,7 @@ module Net
|
|
|
62
65
|
|
|
63
66
|
# Instantiates a new agent object, connects to a running SSH agent,
|
|
64
67
|
# negotiates the agent protocol version, and returns the agent object.
|
|
65
|
-
def self.connect(logger=nil, agent_socket_factory = nil, identity_agent = nil)
|
|
68
|
+
def self.connect(logger = nil, agent_socket_factory = nil, identity_agent = nil)
|
|
66
69
|
agent = new(logger)
|
|
67
70
|
agent.connect!(agent_socket_factory, identity_agent)
|
|
68
71
|
agent.negotiate!
|
|
@@ -71,7 +74,7 @@ module Net
|
|
|
71
74
|
|
|
72
75
|
# Creates a new Agent object, using the optional logger instance to
|
|
73
76
|
# report status.
|
|
74
|
-
def initialize(logger=nil)
|
|
77
|
+
def initialize(logger = nil)
|
|
75
78
|
self.logger = logger
|
|
76
79
|
end
|
|
77
80
|
|
|
@@ -85,9 +88,9 @@ module Net
|
|
|
85
88
|
if agent_socket_factory
|
|
86
89
|
agent_socket_factory.call
|
|
87
90
|
elsif identity_agent
|
|
88
|
-
unix_socket_class.open(identity_agent)
|
|
91
|
+
unix_socket_class.open(File.expand_path(identity_agent))
|
|
89
92
|
elsif ENV['SSH_AUTH_SOCK'] && unix_socket_class
|
|
90
|
-
unix_socket_class.open(ENV['SSH_AUTH_SOCK'])
|
|
93
|
+
unix_socket_class.open(File.expand_path(ENV['SSH_AUTH_SOCK']))
|
|
91
94
|
elsif Gem.win_platform? && RUBY_ENGINE != "jruby"
|
|
92
95
|
Pageant::Socket.open
|
|
93
96
|
else
|
|
@@ -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
|
|
@@ -173,7 +177,7 @@ module Net
|
|
|
173
177
|
|
|
174
178
|
req_type = constraints.empty? ? SSH2_AGENT_ADD_IDENTITY : SSH2_AGENT_ADD_ID_CONSTRAINED
|
|
175
179
|
type, = send_and_wait(req_type, :string, priv_key.ssh_type, :raw, blob_for_add(priv_key),
|
|
176
|
-
|
|
180
|
+
:string, comment, :raw, constraints)
|
|
177
181
|
raise AgentError, "could not add identity to agent" if type != SSH_AGENT_SUCCESS
|
|
178
182
|
end
|
|
179
183
|
|
|
@@ -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
|
|
@@ -235,31 +251,31 @@ module Net
|
|
|
235
251
|
case priv_key.ssh_type
|
|
236
252
|
when /^ssh-dss$/
|
|
237
253
|
Net::SSH::Buffer.from(:bignum, priv_key.p, :bignum, priv_key.q, :bignum, priv_key.g,
|
|
238
|
-
|
|
254
|
+
:bignum, priv_key.pub_key, :bignum, priv_key.priv_key).to_s
|
|
239
255
|
when /^ssh-dss-cert-v01@openssh\.com$/
|
|
240
256
|
Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.priv_key).to_s
|
|
241
257
|
when /^ecdsa\-sha2\-(\w*)$/
|
|
242
258
|
curve_name = OpenSSL::PKey::EC::CurveNameAliasInv[priv_key.group.curve_name]
|
|
243
259
|
Net::SSH::Buffer.from(:string, curve_name, :mstring, priv_key.public_key.to_bn.to_s(2),
|
|
244
|
-
|
|
260
|
+
:bignum, priv_key.private_key).to_s
|
|
245
261
|
when /^ecdsa\-sha2\-(\w*)-cert-v01@openssh\.com$/
|
|
246
262
|
Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.private_key).to_s
|
|
247
263
|
when /^ssh-ed25519$/
|
|
248
264
|
Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes,
|
|
249
|
-
|
|
265
|
+
:string, priv_key.sign_key.keypair).to_s
|
|
250
266
|
when /^ssh-ed25519-cert-v01@openssh\.com$/
|
|
251
267
|
# Unlike the other certificate types, the public key is included after the certifiate.
|
|
252
268
|
Net::SSH::Buffer.from(:string, priv_key.to_blob,
|
|
253
|
-
|
|
254
|
-
|
|
269
|
+
:string, priv_key.key.public_key.verify_key.to_bytes,
|
|
270
|
+
:string, priv_key.key.sign_key.keypair).to_s
|
|
255
271
|
when /^ssh-rsa$/
|
|
256
272
|
# `n` and `e` are reversed compared to the ordering in `OpenSSL::PKey::RSA#to_blob`.
|
|
257
273
|
Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, :bignum, priv_key.d,
|
|
258
|
-
|
|
274
|
+
:bignum, priv_key.iqmp, :bignum, priv_key.p, :bignum, priv_key.q).to_s
|
|
259
275
|
when /^ssh-rsa-cert-v01@openssh\.com$/
|
|
260
276
|
Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.d,
|
|
261
|
-
|
|
262
|
-
|
|
277
|
+
:bignum, priv_key.key.iqmp, :bignum, priv_key.key.p,
|
|
278
|
+
:bignum, priv_key.key.q).to_s
|
|
263
279
|
end
|
|
264
280
|
end
|
|
265
281
|
end
|
|
@@ -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
|
-
#
|
|
39
|
-
|
|
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
|
|
@@ -65,12 +66,12 @@ module Net
|
|
|
65
66
|
).to_s
|
|
66
67
|
end
|
|
67
68
|
|
|
68
|
-
def ssh_do_sign(data)
|
|
69
|
-
key.ssh_do_sign(data)
|
|
69
|
+
def ssh_do_sign(data, sig_alg = nil)
|
|
70
|
+
key.ssh_do_sign(data, sig_alg)
|
|
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
|
|
@@ -82,7 +83,7 @@ module Net
|
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
# Signs the certificate with key.
|
|
85
|
-
def sign!(key, sign_nonce=nil)
|
|
86
|
+
def sign!(key, sign_nonce = nil)
|
|
86
87
|
# ssh-keygen uses 32 bytes of nonce.
|
|
87
88
|
self.nonce = sign_nonce || SecureRandom.random_bytes(32)
|
|
88
89
|
self.signature_key = key
|
|
@@ -93,7 +94,7 @@ module Net
|
|
|
93
94
|
self
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
def sign(key, sign_nonce=nil)
|
|
97
|
+
def sign(key, sign_nonce = nil)
|
|
97
98
|
cert = clone
|
|
98
99
|
cert.sign!(key, sign_nonce)
|
|
99
100
|
end
|
|
@@ -101,8 +102,8 @@ module Net
|
|
|
101
102
|
# Checks whether the certificate's signature was signed by signature key.
|
|
102
103
|
def signature_valid?
|
|
103
104
|
buffer = Buffer.new(signature)
|
|
104
|
-
buffer.read_string
|
|
105
|
-
signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature)
|
|
105
|
+
sig_format = buffer.read_string
|
|
106
|
+
signature_key.ssh_do_verify(buffer.read_string, to_blob_without_signature, host_key: sig_format)
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
def self.read_options(buffer)
|
|
@@ -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.
|