net-ssh 7.2.3 → 8.0.4

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 (78) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +3 -0
  4. data/.github/pull_request_template.md +1 -0
  5. data/.github/workflows/changelog.yml +18 -0
  6. data/.github/workflows/ci-with-docker.yml +20 -9
  7. data/.github/workflows/ci.yml +10 -20
  8. data/.github/workflows/rubocop.yml +3 -1
  9. data/.rubocop.yml +5 -1
  10. data/.rubocop_todo.yml +4 -8
  11. data/CHANGES.txt +122 -0
  12. data/CONTRIBUTING.md +34 -0
  13. data/Dockerfile +4 -1
  14. data/Dockerfile.openssl3 +1 -1
  15. data/Dockerfile.zlib_ng +29 -0
  16. data/Gemfile +2 -0
  17. data/README.md +74 -57
  18. data/Rakefile +30 -12
  19. data/appveyor.yml +4 -16
  20. data/changelog.d/README.md +1 -0
  21. data/docker-compose.yml +1 -9
  22. data/lib/net/ssh/authentication/agent.rb +35 -11
  23. data/lib/net/ssh/authentication/ed25519.rb +140 -37
  24. data/lib/net/ssh/authentication/ed25519_loader.rb +14 -9
  25. data/lib/net/ssh/authentication/key_manager.rb +42 -16
  26. data/lib/net/ssh/authentication/methods/abstract.rb +2 -8
  27. data/lib/net/ssh/authentication/methods/publickey.rb +3 -1
  28. data/lib/net/ssh/authentication/security_key.rb +71 -0
  29. data/lib/net/ssh/authentication/session.rb +29 -17
  30. data/lib/net/ssh/buffer.rb +6 -1
  31. data/lib/net/ssh/buffered_io.rb +40 -3
  32. data/lib/net/ssh/config.rb +30 -13
  33. data/lib/net/ssh/connection/channel.rb +49 -2
  34. data/lib/net/ssh/connection/session.rb +151 -13
  35. data/lib/net/ssh/errors.rb +24 -6
  36. data/lib/net/ssh/key_factory.rb +11 -4
  37. data/lib/net/ssh/known_hosts.rb +62 -8
  38. data/lib/net/ssh/multiplex/client.rb +162 -0
  39. data/lib/net/ssh/multiplex/control_path.rb +120 -0
  40. data/lib/net/ssh/multiplex/proxy_transport.rb +218 -0
  41. data/lib/net/ssh/multiplex.rb +126 -0
  42. data/lib/net/ssh/prompt.rb +3 -3
  43. data/lib/net/ssh/proxy/command.rb +28 -3
  44. data/lib/net/ssh/proxy/jump.rb +71 -8
  45. data/lib/net/ssh/service/forward.rb +44 -27
  46. data/lib/net/ssh/test/extensions.rb +3 -2
  47. data/lib/net/ssh/test/socket.rb +1 -1
  48. data/lib/net/ssh/test.rb +2 -1
  49. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  50. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  51. data/lib/net/ssh/transport/algorithms.rb +96 -34
  52. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +89 -16
  53. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +20 -1
  54. data/lib/net/ssh/transport/cipher_factory.rb +32 -8
  55. data/lib/net/ssh/transport/constants.rb +1 -0
  56. data/lib/net/ssh/transport/gcm_cipher.rb +228 -0
  57. data/lib/net/ssh/transport/hmac/abstract.rb +16 -0
  58. data/lib/net/ssh/transport/hmac/sha1_etm.rb +12 -0
  59. data/lib/net/ssh/transport/hmac.rb +2 -0
  60. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +41 -9
  61. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +14 -6
  62. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +8 -0
  63. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +45 -15
  64. data/lib/net/ssh/transport/openssl.rb +2 -1
  65. data/lib/net/ssh/transport/packet_stream.rb +19 -3
  66. data/lib/net/ssh/transport/server_version.rb +33 -13
  67. data/lib/net/ssh/transport/session.rb +61 -46
  68. data/lib/net/ssh/transport/state.rb +1 -1
  69. data/lib/net/ssh/verifiers/always.rb +43 -8
  70. data/lib/net/ssh/version.rb +3 -3
  71. data/lib/net/ssh.rb +148 -63
  72. data/net-ssh-public_cert.pem +7 -7
  73. data/net-ssh.gemspec +6 -8
  74. data.tar.gz.sig +0 -0
  75. metadata +64 -46
  76. metadata.gz.sig +0 -0
  77. data/Gemfile.noed25519 +0 -12
  78. data/Gemfile.norbnacl +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 524dafc8f2460b2e19662e19cb1916dc6b7f57b78b9cdc6ceadf486bc4fc1945
4
- data.tar.gz: 1f400ebf2e8622ab81b348c6db7d45d88dfd3c3bd04e61bc60ea8678482f5f11
3
+ metadata.gz: 110d479784d8cc56b52a5a3e9b14e5f23dbf556873b64a8e1563df31b1205911
4
+ data.tar.gz: e0f0d31f6476b896ddc6354906cc1b861f99687365a0783527b738e69f4d4e15
5
5
  SHA512:
6
- metadata.gz: 00c33f37023f2cb493b231ee924db6be810fb8d3505d085160c6d790bcd928856081321b5743c2829e773ba506fee8aa3e5a5e9c94ec705199fa77458ad8c17f
7
- data.tar.gz: 195425e6e604b3dbe56cfabd2567b292cd40caa8affbd3f624901a2ddbcb024bacc052093722407a62070bfd3bacdce4c60aee6693a29ac20ad140ba2683fcc3
6
+ metadata.gz: 985c71acd2df6c9e5a287c8e64c6e960cd80bd47c5d18837e1381a7c38f09ee2bbad51e3946f8d26d5f467c4999fca322e3ce4b48aa16115c2d434f675cf52cd
7
+ data.tar.gz: 81a1286e7e73a6c6b17a4a64e5c5004844a734bfa0118d39041ff291eb0e364c9fa4d3777cd7c745fb0ba038bd1aed2cef191b9c001cfb47937b7154a0506813
checksums.yaml.gz.sig CHANGED
Binary file
data/.dockerignore CHANGED
@@ -2,5 +2,8 @@
2
2
  .git/
3
3
  .gitignore
4
4
 
5
+ # Vagrant
6
+ test/integration/.vagrant
7
+
5
8
  docker-compose.yml
6
9
  README.md
@@ -0,0 +1 @@
1
+ <!-- After opening the PR, add a changelog.d/<PR number>.<type>.txt fragment (none, change, security, breaking or breaking-security) instead of editing CHANGES.txt; see CONTRIBUTING.md#changelog. -->
@@ -0,0 +1,18 @@
1
+ name: Changelog
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, labeled, unlabeled]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ changelog:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ # HEAD is the PR merged into the base branch; HEAD^1 is the base it was merged into.
17
+ fetch-depth: 2
18
+ - uses: net-ssh/changelogd@v1
@@ -12,22 +12,19 @@ jobs:
12
12
 
13
13
  steps:
14
14
  - name: Checkout code
15
- uses: actions/checkout@v3
15
+ uses: actions/checkout@v4
16
16
 
17
17
  - name: Build docker images
18
- run: docker-compose build
19
-
20
- - name: Run ruby 2.6
21
- run: docker-compose run ruby-2.6
18
+ run: docker compose build
22
19
 
23
20
  - name: Run ruby 2.7
24
- run: docker-compose run ruby-2.7
21
+ run: docker compose run ruby-2.7
25
22
 
26
23
  - name: Run ruby 3.0
27
- run: docker-compose run ruby-3.0
24
+ run: docker compose run ruby-3.0
28
25
 
29
26
  - name: Run ruby 3.1
30
- run: docker-compose run ruby-3.1
27
+ run: docker compose run ruby-3.1
31
28
 
32
29
  test_openssl3:
33
30
  name: Run test suite with docker and openssl 3.0
@@ -35,10 +32,24 @@ jobs:
35
32
 
36
33
  steps:
37
34
  - name: Checkout code
38
- uses: actions/checkout@v3
35
+ uses: actions/checkout@v4
39
36
 
40
37
  - name: Build docker images
41
38
  run: docker build -t netssh_openssl3 -f Dockerfile.openssl3 .
42
39
 
43
40
  - name: Run ruby 3.0 with openssl3
44
41
  run: docker run --rm netssh_openssl3
42
+
43
+ test_zlib_ng:
44
+ name: Run test suite with docker and zlib-ng
45
+ runs-on: ubuntu-latest
46
+
47
+ steps:
48
+ - name: Checkout code
49
+ uses: actions/checkout@v4
50
+
51
+ - name: Build docker images
52
+ run: docker build -t netssh_zlib_ng -f Dockerfile.zlib_ng .
53
+
54
+ - name: Run ruby with zlib-ng
55
+ run: docker run --rm netssh_zlib_ng
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-22.04
8
8
  strategy:
9
9
  matrix:
10
- ruby-version: [2.6.10, 2.7.7, 3.0.6, 3.1.3, 3.2.1, 3.3.0]
10
+ ruby-version: [2.7.8, 3.0.6, 3.1.3, 3.2.1, 3.3, 3.4, '4.0']
11
11
  steps:
12
12
  - uses: actions/checkout@v3
13
13
 
@@ -21,16 +21,16 @@ jobs:
21
21
  python-version: 3.8
22
22
 
23
23
  - name: Cache bundler
24
- uses: actions/cache@v1
24
+ uses: actions/cache@v4
25
25
  id: bundler-cache
26
26
  with:
27
27
  path: vendor/bundle
28
28
  key: ${{ runner.os }}-${{ matrix.ruby-version }}-gem-v3-${{ hashFiles('**/Gemfile') }}-${{ hashFiles('**/net-ssh.gemspec') }}
29
29
  restore-keys: |
30
30
  ${{ runner.os }}-${{ matrix.ruby-version }}-gem-v3-
31
-
31
+
32
32
  - name: Cache pip
33
- uses: actions/cache@v1
33
+ uses: actions/cache@v4
34
34
  id: pip-cache
35
35
  with:
36
36
  path: ~/.cache/pip
@@ -39,15 +39,14 @@ jobs:
39
39
  ${{ runner.os }}-pip-v1
40
40
  - name: Bundle install
41
41
  run: |
42
- gem install bundler ${{ (startsWith(matrix.ruby-version, '2.6.') || startsWith(matrix.ruby-version, '2.7.')) && '-v 2.4.22' || '' }}
42
+ gem install bundler ${{ startsWith(matrix.ruby-version, '2.7.') && '-v 2.4.22' || '' }}
43
43
  bundle config set path 'vendor/bundle'
44
44
  bundle config set --local path 'vendor/bundle'
45
- bundle install --jobs 4 --retry 3 --path vendor/bundle
46
- BUNDLE_GEMFILE=./Gemfile.noed25519 bundle install --jobs 4 --retry 3 --path vendor/bundle
45
+ bundle install --jobs 4 --retry 3
47
46
  env:
48
47
  BUNDLE_PATH: vendor/bundle
49
48
 
50
-
49
+
51
50
  - name: Add to etc/hosts
52
51
  run: |
53
52
  sudo echo "127.0.0.1 gateway.netssh" | sudo tee -a /etc/hosts
@@ -78,17 +77,8 @@ jobs:
78
77
  env:
79
78
  NET_SSH_RUN_INTEGRATION_TESTS: 1
80
79
  CI: 1
81
- - name: Run tests (without rbnacl)
82
- run: bundle exec rake test
83
- env:
84
- BUNDLE_GEMFILE: ./Gemfile.norbnacl
85
- NET_SSH_RUN_INTEGRATION_TESTS: 1
86
- CI: 1
87
- - name: Run Tests (without ed25519)
88
- run: bundle exec rake test
89
- env:
90
- BUNDLE_GEMFILE: ./Gemfile.noed25519
91
- NET_SSH_RUN_INTEGRATION_TESTS: 1
92
- CI: 1
80
+ RUBYOPT: '--enable=frozen-string-literal'
93
81
  - name: Run test helper test
94
82
  run: bundle exec rake test_test
83
+ env:
84
+ RUBYOPT: '--enable=frozen-string-literal'
@@ -1,6 +1,8 @@
1
1
  name: Rubocop
2
2
 
3
- on: [push]
3
+ on:
4
+ pull_request:
5
+ push: { branches: master }
4
6
 
5
7
  jobs:
6
8
  build:
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ AllCops:
4
4
  - "vendor/**/.*"
5
5
  - "vendor/**/*"
6
6
  NewCops: enable
7
- TargetRubyVersion: 2.6
7
+ TargetRubyVersion: 2.7
8
8
 
9
9
  inherit_from: .rubocop_todo.yml
10
10
 
@@ -20,3 +20,7 @@ Layout/LineLength:
20
20
 
21
21
  Style/EmptyLiteral:
22
22
  Enabled: false
23
+
24
+ # CI runs the suite with RUBYOPT=--enable=frozen-string-literal instead of a magic comment in every file.
25
+ Style/FrozenStringLiteralComment:
26
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -235,7 +235,7 @@ Lint/UselessTimes:
235
235
  # Offense count: 205
236
236
  # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
237
237
  Metrics/AbcSize:
238
- Max: 74
238
+ Max: 76
239
239
 
240
240
  # Offense count: 16
241
241
  # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
@@ -335,6 +335,7 @@ Naming/MemoizedInstanceVariableName:
335
335
  Naming/MethodName:
336
336
  Exclude:
337
337
  - 'lib/net/ssh/authentication/ed25519_loader.rb'
338
+ - 'lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb'
338
339
  - 'lib/net/ssh/transport/kex/curve25519_sha256_loader.rb'
339
340
  - 'test/authentication/test_agent.rb'
340
341
  - 'test/authentication/test_session.rb'
@@ -586,13 +587,6 @@ Style/FormatString:
586
587
  - 'lib/net/ssh/authentication/pageant.rb'
587
588
  - 'lib/net/ssh/loggable.rb'
588
589
 
589
- # Offense count: 174
590
- # This cop supports safe auto-correction (--auto-correct).
591
- # Configuration parameters: EnforcedStyle.
592
- # SupportedStyles: always, always_true, never
593
- Style/FrozenStringLiteralComment:
594
- Enabled: false
595
-
596
590
  # Offense count: 1
597
591
  # This cop supports safe auto-correction (--auto-correct).
598
592
  Style/GlobalStdStream:
@@ -758,10 +752,12 @@ Style/OpenStructUse:
758
752
  Exclude:
759
753
  - 'test/authentication/test_ed25519.rb'
760
754
  - 'test/common.rb'
755
+ - 'test/test_known_hosts.rb'
761
756
  - 'test/transport/kex/test_curve25519_sha256.rb'
762
757
  - 'test/transport/kex/test_diffie_hellman_group1_sha1.rb'
763
758
  - 'test/transport/kex/test_ecdh_sha2_nistp256.rb'
764
759
  - 'test/verifiers/test_always.rb'
760
+ - 'test/verifiers/test_cert_authority_checks.rb'
765
761
 
766
762
  # Offense count: 16
767
763
  # Configuration parameters: AllowedMethods.
data/CHANGES.txt CHANGED
@@ -1,3 +1,125 @@
1
+ === 8.0.4
2
+
3
+ * Security: validate every ProxyJump hop, not only the first, as [user@]host[:port] (refusing a path, query, fragment or password) and shell-escape the hops passed to ssh -J; a hop such as `evil/x&$(cmd)` ran `cmd` through the shell [GHSA-g2r2-x3p2-5677]
4
+
5
+ === 8.0.3
6
+
7
+ * Add `preopen_channels` option: keep a spare session channel open so each command saves a round trip [#1071]
8
+
9
+ === 8.0.2
10
+
11
+ * Fixed `Session#close` raising `EOFError: cannot send data if channel has declared eof` when a forwarded connection still had unread data from its local client; data net-ssh had already read is still sent before the EOF and, as in OpenSSH, the rest is dropped; a regression in 8.0.0 [#1066, #1067]
12
+
13
+ === 8.0.1
14
+
15
+ * Fixed `unexpected packet type 94 during initial key exchange` (or 93) when channel data arrives during a client-initiated re-key, which broke bulk transfers at the first re-key (e.g. with `rekey_limit`, or after about 1 GB); a regression in 7.3.5 and 8.0.0 [#1063]
16
+ * `control_master: :auto` now ignores `forward_agent` (logged at info level) instead of raising ArgumentError, and logs the ignored connection options at info instead of warn level, so it works with sshkit (Kamal, Capistrano), which always passes `forward_agent: true`, `keys`, `known_hosts` and `keepalive` [#1062]
17
+
18
+ === 8.0.0
19
+
20
+ * No changes since 8.0.0 rc5.
21
+
22
+ === 8.0.0 rc5
23
+
24
+ * BREAKING: Security: a custom `verify_host_key` verifier must now implement `verify_signature` (deprecated since 5.1.0) or ArgumentError is raised; such verifiers were previously wrapped so the server's host key signature was never checked [#1050]
25
+ * BREAKING: Unsupported key types now raise `Net::SSH::UnsupportedKeyType` (a `Net::SSH::Exception`) instead of `NotImplementedError`; code that rescued `NotImplementedError` around key loading or connecting should rescue the new class [#945, #1060]
26
+ * BREAKING: `Net::SSH.start` raises ArgumentError for option values that are `nil` or arrays containing `nil` (deprecated since 4.0.0); omit the option to use the default or ssh_config value, the error names a value that turns it off where one exists (e.g. `proxy: false`, `keys: []`, `config: false`). `password: nil` and `passphrase: nil` are still accepted [#458, #1053]
27
+ * BREAKING: removed the `:paranoid` option (deprecated since 4.2.0); use `:verify_host_key` with the same values. Passing `:paranoid` raises ArgumentError [#1050]
28
+ * BREAKING: removed the `verify_host_key` values `false`, `true`, `:very` and `:secure` (deprecated since 5.0.0); use `:never`, `:accept_new_or_local_tunnel`, `:accept_new` and `:always` respectively. The old values raise ArgumentError naming the replacement [#1050]
29
+ * BREAKING: `Net::SSH::HostKeyEntries::PubKey` (the known_hosts entries returned by `KnownHosts.search_for`) no longer forwards methods to the wrapped key (deprecated since 7.0.0); use `ssh_type`, `to_blob` or `matches_key?`, or the new `key` reader for the wrapped public key [#1050]
30
+ * Security: `append_all_supported_algorithms: true` no longer enables the `none` cipher and MAC; name them explicitly (`encryption: '+none'`, `hmac: '+none'`) to use them [#1051]
31
+ * Security: `diffie-hellman-group-exchange-sha1/sha256` now requires groups of at least 2048 bits and requests sizes from the negotiated ciphers, as OpenSSH since 7.2, and rejects invalid server groups and DH public values; like OpenSSH, the requested group size is capped at 4096 bits for Cisco servers. Pass `minimum_dh_bits: 1024` to connect to legacy servers that only offer 1024-bit groups. `minimum_dh_bits` values other than 1024 no longer fail key exchange with "could not verify server signature" [#1049]
32
+ * Security: `diffie-hellman-group14-sha1` is no longer offered by default for key exchange, as in OpenSSH since 8.2; add `KexAlgorithms +diffie-hellman-group14-sha1` in ssh_config (or `kex: '+diffie-hellman-group14-sha1'`) or pass `append_all_supported_algorithms: true` to re-enable [#705, #1042]
33
+ * Changelog entries are now added as `changelog.d/<PR number>.<type>.txt` fragment files instead of editing CHANGES.txt, and CI requires one per PR; see CONTRIBUTING.md [#1058]
34
+ * `Net::SSH.start(host, user, control_master: :auto)` reuses an already running OpenSSH ControlMaster found via `:control_path` or ssh_config `ControlPath`, falling back to a normal connection when there is none [#443, #1057]
35
+ * Default `max_win_size` is now 2 MB as in OpenSSH (was 128 KB), which avoids truncated output from some devices (e.g. Mikrotik); pass `max_win_size: 0x20000` for the old behaviour [#726, #1055]
36
+ * Added `hmac-sha1-etm@openssh.com`, offered by default after the SHA2 etm MACs as in OpenSSH [#985, #1056]
37
+ * `Net::SSH::Proxy::Jump` `options:` values may be an Array for ssh_config options that can be given more than once (`IdentityFile`, `CertificateFile`, `SendEnv`); each element is passed as its own `-o Key=value`, an empty Array passes nothing, and a `nil` value (alone or in an Array) raises ArgumentError as in `Net::SSH.start` [#1052]
38
+ * `ssh-rsa-cert-v00@openssh.com` host keys are deprecated and warn when named in `host_key`/`HostKeyAlgorithms` or negotiated; net-ssh cannot parse v00 certificates, use `ssh-rsa-cert-v01@openssh.com` or a modern key type [#1051]
39
+ * README: weak algorithms (CBC/3DES/Blowfish ciphers, `ssh-dss`, `diffie-hellman-group1-sha1`, old MACs, ...) stay available as opt-ins for legacy servers rather than being removed in 8.0 [#1051]
40
+ * An ssh-agent that fails while listing keys (e.g. closes the connection) is now skipped and key files are still tried, as in OpenSSH, instead of aborting authentication [#867, #1048]
41
+ * `%r` in a ProxyCommand now defaults to the connection's user, as in OpenSSH, instead of raising unless `:remote_user` is set [#881, #787, #1047]
42
+ * `Net::SSH.start` no longer modifies the options hash passed to it [#989, #1046]
43
+ * `Session#exec!` with a block now returns an empty string with `exitstatus` (like the non-block form) instead of `nil` [#848, #1045]
44
+ * ssh_config `KexAlgorithms` is now honoured and maps to `:kex`, including `+`, `-` and `^`; it was previously ignored [#1042]
45
+ * `Net::SSH::Proxy::Jump.new` accepts `options:`, a Hash of ssh_config options passed to the jump host's ssh command as escaped `-o Key=value` arguments, e.g. `options: { 'StrictHostKeyChecking' => 'no' }` [#915, #1041]
46
+ * `Net::SSH::Proxy::Jump` no longer fails with "unknown key" or substitutes the target host when the `config:` path contains `%` [#1041]
47
+
48
+ === 8.0.0 rc4
49
+
50
+ * Security: RSA signatures using SHA-1 (`ssh-rsa`, `ssh-rsa-cert-v01@openssh.com`) are no longer offered by default for host keys or public key authentication, as in OpenSSH since 8.8; RSA keys keep working via rsa-sha2-256/512. For servers that only support SHA-1 add `HostKeyAlgorithms +ssh-rsa` / `PubkeyAcceptedAlgorithms +ssh-rsa` in ssh_config (or `host_key: '+ssh-rsa'` / `pubkey_algorithms: %w[+ssh-rsa]`), or pass `append_all_supported_algorithms: true` [#1039]
51
+ * Security: ssh_config `PubkeyAcceptedAlgorithms` (and its old name `PubkeyAcceptedKeyTypes`) is now honoured, including `+`, `-` and `^`, and `pubkey_algorithms` now applies to all key types instead of only RSA, adding `rsa-sha2-512`; DSA (`ssh-dss`) keys are no longer offered by default, as in OpenSSH since 7.0 — add `+ssh-dss` or pass `append_all_supported_algorithms: true` to re-enable [#923]
52
+ * Security: ssh_config `Ciphers`, `MACs`, `KexAlgorithms` and `HostKeyAlgorithms` lists starting with `+`, `-` or `^` now append to, remove from or prepend to the default list, as in OpenSSH, instead of silently enabling every supported algorithm including weak ones that are off by default; every listed item is honoured and `-` accepts wildcards. Pass `append_all_supported_algorithms: true` to also get the full supported list [#925]
53
+ * Support agent-backed FIDO/U2F security keys (sk-ecdsa-sha2-nistp256@openssh.com, sk-ssh-ed25519@openssh.com) for publickey auth [#1007]
54
+ * Port forwarding no longer buffers a whole stream in memory when one side reads slowly: like OpenSSH, window is granted only as data is written to the local socket, and the local socket is read only while the remote window has room. An application that writes everything to a forwarded port before reading anything now blocks once the window fills, as it would with `ssh -L` or a direct TCP connection; the old unbounded buffering hid this [#1037, #1003]
55
+ * Data forwarded to a local socket just before the remote end sends EOF or closes the channel is no longer truncated or dropped: it is written out before the socket is shut down or closed, without blocking the event loop until the local application reads [#1037]
56
+ * Multi-factor authentication works when the server's AuthenticationMethods order differs from net-ssh's: after each partial success the allowed methods are tried again, as OpenSSH does [#873, #872]
57
+ * `HostKeyError#host`, `#port` and `#ip` now return the connected host, port and IP (`ip` is nil through a ProxyCommand) instead of always nil [#963]
58
+ * OpenSSH-format private keys with Windows (CRLF) line endings now load [#922, #921]
59
+ * Send CHANNEL_EOF before CHANNEL_CLOSE when closing a session's remaining channels, as OpenSSH does; fixes hangs at close with servers that wait for EOF, such as some SFTP servers [#672]
60
+ * ssh_config: trailing `# comments` are now ignored, as in OpenSSH; a `#` inside quotes or in the middle of a word is kept [#990]
61
+
62
+ === 8.0.0 rc3
63
+
64
+ * Fix "Calling Net::SSH::Buffer methods on HostKeyEntries PubKey is deprecated" warnings printed on every connection to a host in known_hosts [#1026, #1027]
65
+ * `ProxyJump none` now means no proxy instead of jumping through a host named "none", and `ProxyCommand none` is matched case-insensitively, as in OpenSSH [#893, #972, #1030]
66
+ * Send SIGHUP to the ProxyCommand process on close, as OpenSSH does, so tunnels such as EC2 Instance Connect Endpoint no longer hang at exit [#947]
67
+ * Reconnect when the ssh-agent closes the connection on the legacy version request (e.g. older Proton Pass) instead of raising FrozenError [#1008]
68
+ * ssh_config: parse `Key = value` lines like OpenSSH (the value no longer keeps the leading space, and the keyword ends at the first `=`), and honor ProxyJump/ProxyCommand before the first Host [#1034]
69
+
70
+ === 8.0.0 rc2
71
+
72
+ * Security: refuse agent channels opened by the server unless agent forwarding was requested (`forward_agent`, ForwardAgent, or `Forward#agent`); any use of port forwarding let a malicious server use the local ssh-agent [GHSA-qpg5-fx6p-8cq3]
73
+ * Security: reject host and user names containing shell metacharacters, and non-numeric ports, before substituting them into ProxyCommand/ProxyJump commands, as OpenSSH does since 9.6 [GHSA-3x7f-q7wf-fp73]
74
+ * Security: reject OpenSSH private keys claiming more than 2**20 bcrypt rounds, and only run the KDF once a passphrase is given [GHSA-rpq3-v334-f5pm]
75
+ * Security: bound the server's identification banner like OpenSSH (8192-byte lines, 1024 lines), and apply `:timeout` to the whole version exchange instead of only its first byte [GHSA-r75w-7fhp-84w8]
76
+ * Security: reject packet lengths below 5 or above 256 KB, as OpenSSH does [GHSA-pfqh-p9vh-wx4p]
77
+ * Security: treat unexpected packets during the initial key exchange as a protocol error, and bound packets queued during a re-key [GHSA-ggxh-cfwq-5xqc]
78
+
79
+ === 8.0.0 rc1
80
+
81
+ * BREAKING: TCP_NODELAY is now set on the connection socket by default, as OpenSSH does; pass `no_delay: false` to keep Nagle's algorithm on [#1017]
82
+ * Ruby 4.0 support: add `logger` as a runtime dependency; Windows Pageant users on Ruby 4.0 need `fiddle` in their Gemfile [#984, #1012]
83
+ * Close the socket when connection setup fails, e.g. on a server version timeout [#1013]
84
+ * Ignore SSH_MSG_EXT_INFO from servers that send it unrequested [#1020]
85
+ * Fix `undefined method 'to_pem'` for ECDSA key_data when an agent is running [#982]
86
+ * Agent forwarding connects to the agent set by `identity_agent`/IdentityAgent [#974]
87
+ * Keyboard-interactive prompts show input when the server asks for it to be echoed [#1014]
88
+ * Raise Net::SSH::Exception on a truncated KEXINIT [#1016]
89
+ * Remote forwarding no longer prints diagnostics to stdout [#953]
90
+
91
+ === 8.0.0 beta3
92
+
93
+ * Verify @cert-authority host certificate constraints — principals (shell-glob, matching OpenSSH), validity window, host type, and critical options — instead of trusting any CA-signed certificate for any host [#1009]
94
+
95
+ === 8.0.0 beta1
96
+
97
+ * BREAKING: require Ruby 2.7 and the openssl gem >= 3.2 [#1001]
98
+ * Use OpenSSL for Ed25519, X25519 and ChaCha20-Poly1305; the ed25519, x25519 and rbnacl gems are no longer needed [#1001]
99
+ * Support AEAD-encrypted OpenSSH private keys [#1001]
100
+
101
+ === 7.3.3
102
+
103
+ * Support .pub file as IdentityFile to filter/prioritize agent keys (1Password SSH agent use case) [#942]
104
+ * Fix cert signing regression when using a .pub companion file without an agent [#1006]
105
+ * Fix unreadable .pub IdentityFile silently skipped instead of raising [#1006]
106
+ * Allow multiple UserKnownHostsFile entries (space-separated, matching ssh_config(5)) [#979]
107
+ * Stop mutating ENV['HOME'] at require time [#997]
108
+ * Fix ED25519 loader with frozen string literals [#995]
109
+
110
+ === 7.3.2 rc2
111
+
112
+ * Fix Ruby 2.6 compat: use public_to_der fallback for EC public keys [#993]
113
+ * Fix test framework hang: preserve StringIO position in idle!
114
+
115
+ === 7.3.2 rc1
116
+
117
+ * Support frozen strings [#958]
118
+
119
+ === 7.3.0 rc0
120
+
121
+ * aes(128|256)gcm [#946]
122
+
1
123
  === 7.2.2
2
124
 
3
125
  * ruby 3.3.0: base64 fix
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,34 @@
1
+ # Contributing to net-ssh
2
+
3
+ Run the unit tests with `bundle exec rake test` and the linter with `bundle exec rubocop`; see [README.md](README.md) and [DEVELOPMENT.md](DEVELOPMENT.md) for integration tests and debugging tips.
4
+
5
+ ## Changelog
6
+
7
+ Don't edit `CHANGES.txt`. Instead, add a fragment file to `changelog.d/` in your PR; the release's version bump (`rake vbump:*`) moves all fragments into a new `=== <version>` section at the top of `CHANGES.txt` and deletes them.
8
+
9
+ A fragment is named `<number>.<type>.txt`, where `<number>` is the PR number (so open the PR first, then add the fragment), and contains a single UTF-8 paragraph: the entry as it should read in `CHANGES.txt`, without the bullet or prefix. Lines are joined, so it can be wrapped. If it doesn't end with a reference list such as `[#985, #1056]` or `[GHSA-xxxx-xxxx-xxxx]`, ` [#<number>]` is appended.
10
+
11
+ | Type | Written as | Use for |
12
+ | ------------------- | ------------------------------ | ------------------------------------------------------------ |
13
+ | `breaking-security` | `* BREAKING: Security: <text>` | an incompatible change made for security |
14
+ | `breaking` | `* BREAKING: <text>` | an incompatible change |
15
+ | `security` | `* Security: <text>` | a security fix or hardening |
16
+ | `change` | `* <text>` | any other user-visible fix or feature |
17
+ | `none` | nothing | PRs with no user-visible change (tests, CI, docs, refactors) |
18
+
19
+ Examples:
20
+
21
+ ```sh
22
+ rake "changelog:new[1058,change,Session#exec! now returns the exit status]"
23
+ # changelog.d/1058.change.txt -> * Session#exec! now returns the exit status [#1058]
24
+
25
+ echo 'Removed the `:paranoid` option; use `:verify_host_key` [#1050]' > changelog.d/1050.breaking.txt
26
+ echo 'Reject packet lengths above 256 KB, as OpenSSH does [GHSA-pfqh-p9vh-wx4p]' > changelog.d/1060.security.txt
27
+ touch changelog.d/1061.none.txt
28
+ ```
29
+
30
+ For several entries from one PR add a suffix: `1050.breaking.txt`, `1050.breaking.2.txt` (`changelog:new` picks the next free one).
31
+
32
+ `rake changelog:check` validates the fragments and `rake changelog:preview` prints the section the next release would add. CI fails a PR that edits `CHANGES.txt` or doesn't add or modify a `changelog.d/<PR number>.<type>.txt` fragment, unless it only touches `changelog.d/` or a maintainer adds the `skip-changelog` label; Dependabot PRs are skipped.
33
+
34
+ The full rules, including how a release orders the entries, are in the [changelogd README](https://github.com/net-ssh/changelogd#readme).
data/Dockerfile CHANGED
@@ -3,6 +3,9 @@ FROM ruby:${RUBY_VERSION}
3
3
 
4
4
  ARG BUNDLERV=
5
5
 
6
+ # Ruby 2.7 and 3.0 images are built on Debian bullseye, which only archive.debian.org still serves.
7
+ RUN if grep -q bullseye /etc/os-release; then sed -i 's|deb.debian.org|archive.debian.org|' /etc/apt/sources.list; fi
8
+
6
9
  RUN apt update && apt install -y openssh-server sudo netcat-openbsd \
7
10
  && useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_1' \
8
11
  && useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_2' \
@@ -26,4 +29,4 @@ RUN gem install bundler ${BUNDLERV} && bundle install
26
29
 
27
30
  COPY . $INSTALL_PATH/
28
31
 
29
- CMD service ssh start && rake test && NET_SSH_NO_ED25519=1 rake test
32
+ CMD service ssh start && rake test
data/Dockerfile.openssl3 CHANGED
@@ -2,7 +2,7 @@ FROM ubuntu:22.04
2
2
 
3
3
  ENV INSTALL_PATH="/netssh"
4
4
 
5
- RUN apt update && apt install -y openssl ruby ruby-dev git build-essential
5
+ RUN apt update && apt install -y openssl libssl-dev ruby ruby-dev git build-essential
6
6
 
7
7
  WORKDIR $INSTALL_PATH
8
8
 
@@ -0,0 +1,29 @@
1
+ FROM fedora:latest
2
+
3
+ ENV INSTALL_PATH="/netssh"
4
+
5
+ # Fedora's OpenSSL 3.x blocks SHA-1 for RSA/DSA signing by default.
6
+ # - LEGACY crypto policy relaxes the system-wide restrictions.
7
+ # - OPENSSL_CONF points to our config which activates the legacy provider,
8
+ # sets SECLEVEL=0, and sets rh-allow-sha1-signatures=yes (Fedora/RHEL
9
+ # OpenSSL patch that gates SHA-1 signing independently of the policy level).
10
+ # OPENSSL_CONF must be set as a Docker ENV so it is in the environment before
11
+ # Ruby/OpenSSL initialises — setting it in the Rakefile is too late.
12
+ ENV OPENSSL_CONF="/netssh/test/openssl3.conf"
13
+
14
+ RUN dnf install -y openssl openssl-devel ruby ruby-devel git make gcc redhat-rpm-config zlib-ng crypto-policies-scripts && \
15
+ update-crypto-policies --set LEGACY
16
+
17
+ WORKDIR $INSTALL_PATH
18
+
19
+ COPY Gemfile net-ssh.gemspec $INSTALL_PATH/
20
+
21
+ COPY lib/net/ssh/version.rb $INSTALL_PATH/lib/net/ssh/version.rb
22
+
23
+ RUN ls -l && gem install bundler && bundle install
24
+
25
+ COPY . $INSTALL_PATH/
26
+
27
+ CMD openssl version && ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' && \
28
+ rpm -q zlib-ng && ruby -rzlib -e 'puts Zlib.zlib_version' && \
29
+ rake test
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in mygem.gemspec
4
4
  gemspec
5
5
 
6
+ gem "changelogd", git: "https://github.com/net-ssh/changelogd.git", tag: "v1", group: :development
7
+
6
8
  gem 'byebug', group: %i[development test] if !Gem.win_platform? && RUBY_ENGINE == "ruby"
7
9
 
8
10
  if ENV["CI"]