net-ssh 2.7.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.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +94 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +15 -0
  10. data/.rubocop.yml +22 -0
  11. data/.rubocop_todo.yml +1081 -0
  12. data/CHANGES.txt +387 -0
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +29 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +13 -0
  17. data/Gemfile.noed25519 +12 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/ISSUE_TEMPLATE.md +30 -0
  20. data/Manifest +4 -5
  21. data/README.md +303 -0
  22. data/Rakefile +174 -40
  23. data/SECURITY.md +4 -0
  24. data/THANKS.txt +25 -0
  25. data/appveyor.yml +58 -0
  26. data/docker-compose.yml +25 -0
  27. data/lib/net/ssh/authentication/agent.rb +279 -18
  28. data/lib/net/ssh/authentication/certificate.rb +183 -0
  29. data/lib/net/ssh/authentication/constants.rb +17 -15
  30. data/lib/net/ssh/authentication/ed25519.rb +184 -0
  31. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  32. data/lib/net/ssh/authentication/key_manager.rb +125 -54
  33. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  34. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  35. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +19 -12
  36. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  37. data/lib/net/ssh/authentication/methods/password.rb +56 -19
  38. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  39. data/lib/net/ssh/authentication/pageant.rb +483 -246
  40. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  41. data/lib/net/ssh/authentication/session.rb +138 -120
  42. data/lib/net/ssh/buffer.rb +399 -300
  43. data/lib/net/ssh/buffered_io.rb +154 -150
  44. data/lib/net/ssh/config.rb +361 -166
  45. data/lib/net/ssh/connection/channel.rb +640 -596
  46. data/lib/net/ssh/connection/constants.rb +29 -29
  47. data/lib/net/ssh/connection/event_loop.rb +123 -0
  48. data/lib/net/ssh/connection/keepalive.rb +59 -0
  49. data/lib/net/ssh/connection/session.rb +628 -548
  50. data/lib/net/ssh/connection/term.rb +125 -123
  51. data/lib/net/ssh/errors.rb +101 -95
  52. data/lib/net/ssh/key_factory.rb +198 -100
  53. data/lib/net/ssh/known_hosts.rb +221 -98
  54. data/lib/net/ssh/loggable.rb +50 -49
  55. data/lib/net/ssh/packet.rb +83 -79
  56. data/lib/net/ssh/prompt.rb +50 -81
  57. data/lib/net/ssh/proxy/command.rb +108 -60
  58. data/lib/net/ssh/proxy/errors.rb +12 -10
  59. data/lib/net/ssh/proxy/http.rb +82 -78
  60. data/lib/net/ssh/proxy/https.rb +50 -0
  61. data/lib/net/ssh/proxy/jump.rb +54 -0
  62. data/lib/net/ssh/proxy/socks4.rb +5 -8
  63. data/lib/net/ssh/proxy/socks5.rb +18 -20
  64. data/lib/net/ssh/service/forward.rb +383 -255
  65. data/lib/net/ssh/test/channel.rb +145 -136
  66. data/lib/net/ssh/test/extensions.rb +131 -110
  67. data/lib/net/ssh/test/kex.rb +34 -32
  68. data/lib/net/ssh/test/local_packet.rb +46 -44
  69. data/lib/net/ssh/test/packet.rb +89 -70
  70. data/lib/net/ssh/test/remote_packet.rb +32 -30
  71. data/lib/net/ssh/test/script.rb +156 -142
  72. data/lib/net/ssh/test/socket.rb +49 -48
  73. data/lib/net/ssh/test.rb +82 -77
  74. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  75. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  76. data/lib/net/ssh/transport/algorithms.rb +472 -348
  77. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  78. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  79. data/lib/net/ssh/transport/cipher_factory.rb +124 -100
  80. data/lib/net/ssh/transport/constants.rb +32 -24
  81. data/lib/net/ssh/transport/ctr.rb +42 -22
  82. data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  83. data/lib/net/ssh/transport/hmac/abstract.rb +97 -63
  84. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  87. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  88. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  89. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  90. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  91. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  92. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  93. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  94. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  95. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  96. data/lib/net/ssh/transport/hmac.rb +14 -12
  97. data/lib/net/ssh/transport/identity_cipher.rb +54 -44
  98. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  99. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  100. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  101. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  102. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  103. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  104. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  105. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  106. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  107. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  108. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  109. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  110. data/lib/net/ssh/transport/kex.rb +15 -12
  111. data/lib/net/ssh/transport/key_expander.rb +24 -20
  112. data/lib/net/ssh/transport/openssl.rb +161 -124
  113. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  114. data/lib/net/ssh/transport/packet_stream.rb +246 -183
  115. data/lib/net/ssh/transport/server_version.rb +57 -51
  116. data/lib/net/ssh/transport/session.rb +307 -235
  117. data/lib/net/ssh/transport/state.rb +178 -176
  118. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  119. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  120. data/lib/net/ssh/verifiers/always.rb +58 -0
  121. data/lib/net/ssh/verifiers/never.rb +19 -0
  122. data/lib/net/ssh/version.rb +57 -51
  123. data/lib/net/ssh.rb +140 -40
  124. data/net-ssh-public_cert.pem +21 -0
  125. data/net-ssh.gemspec +39 -184
  126. data/support/ssh_tunnel_bug.rb +5 -5
  127. data.tar.gz.sig +0 -0
  128. metadata +205 -99
  129. metadata.gz.sig +0 -0
  130. data/README.rdoc +0 -219
  131. data/Rudyfile +0 -96
  132. data/gem-public_cert.pem +0 -20
  133. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  134. data/lib/net/ssh/authentication/agent/socket.rb +0 -170
  135. data/lib/net/ssh/ruby_compat.rb +0 -51
  136. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  137. data/lib/net/ssh/verifiers/null.rb +0 -12
  138. data/lib/net/ssh/verifiers/secure.rb +0 -54
  139. data/lib/net/ssh/verifiers/strict.rb +0 -24
  140. data/setup.rb +0 -1585
  141. data/support/arcfour_check.rb +0 -20
  142. data/test/README.txt +0 -47
  143. data/test/authentication/methods/common.rb +0 -28
  144. data/test/authentication/methods/test_abstract.rb +0 -51
  145. data/test/authentication/methods/test_hostbased.rb +0 -114
  146. data/test/authentication/methods/test_keyboard_interactive.rb +0 -100
  147. data/test/authentication/methods/test_none.rb +0 -41
  148. data/test/authentication/methods/test_password.rb +0 -52
  149. data/test/authentication/methods/test_publickey.rb +0 -148
  150. data/test/authentication/test_agent.rb +0 -205
  151. data/test/authentication/test_key_manager.rb +0 -218
  152. data/test/authentication/test_session.rb +0 -108
  153. data/test/common.rb +0 -108
  154. data/test/configs/eqsign +0 -3
  155. data/test/configs/exact_match +0 -8
  156. data/test/configs/host_plus +0 -10
  157. data/test/configs/multihost +0 -4
  158. data/test/configs/nohost +0 -19
  159. data/test/configs/numeric_host +0 -4
  160. data/test/configs/send_env +0 -2
  161. data/test/configs/substitutes +0 -8
  162. data/test/configs/wild_cards +0 -14
  163. data/test/connection/test_channel.rb +0 -467
  164. data/test/connection/test_session.rb +0 -526
  165. data/test/known_hosts/github +0 -1
  166. data/test/manual/test_forward.rb +0 -223
  167. data/test/start/test_options.rb +0 -36
  168. data/test/start/test_transport.rb +0 -28
  169. data/test/test_all.rb +0 -11
  170. data/test/test_buffer.rb +0 -433
  171. data/test/test_buffered_io.rb +0 -63
  172. data/test/test_config.rb +0 -151
  173. data/test/test_key_factory.rb +0 -173
  174. data/test/test_known_hosts.rb +0 -13
  175. data/test/transport/hmac/test_md5.rb +0 -41
  176. data/test/transport/hmac/test_md5_96.rb +0 -27
  177. data/test/transport/hmac/test_none.rb +0 -34
  178. data/test/transport/hmac/test_ripemd160.rb +0 -36
  179. data/test/transport/hmac/test_sha1.rb +0 -36
  180. data/test/transport/hmac/test_sha1_96.rb +0 -27
  181. data/test/transport/hmac/test_sha2_256.rb +0 -37
  182. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  183. data/test/transport/hmac/test_sha2_512.rb +0 -37
  184. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  185. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  186. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
  187. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
  188. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -34
  189. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  190. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  191. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  192. data/test/transport/test_algorithms.rb +0 -330
  193. data/test/transport/test_cipher_factory.rb +0 -443
  194. data/test/transport/test_hmac.rb +0 -34
  195. data/test/transport/test_identity_cipher.rb +0 -40
  196. data/test/transport/test_packet_stream.rb +0 -1755
  197. data/test/transport/test_server_version.rb +0 -78
  198. data/test/transport/test_session.rb +0 -319
  199. data/test/transport/test_state.rb +0 -181
data/Rudyfile DELETED
@@ -1,96 +0,0 @@
1
- # Rudyfile
2
- #
3
- # This configuration is used to test installing
4
- # and running net-ssh on a clean machine.
5
- #
6
- # Usage:
7
- #
8
- # $ rudy -vv startup
9
- # $ rudy -vv testsuite
10
- # $ rudy -vv shutdown
11
- #
12
- # Requires: Rudy 0.9 (http://code.google.com/p/rudy/)
13
- #
14
-
15
- defaults do
16
- color true
17
- environment :test
18
- role :netssh
19
- end
20
-
21
- machines do
22
- region :'us-east-1' do
23
- ami 'ami-e348af8a' # Alestic Debian 5.0, 32-bit (US)
24
- end
25
- env :test do
26
- role :netssh do
27
- user :root
28
- end
29
- end
30
- end
31
-
32
- commands do
33
- allow :apt_get, "apt-get", :y, :q
34
- allow :gem_install, "/usr/bin/gem", "install", :n, '/usr/bin', :y, :V, "--no-rdoc", "--no-ri"
35
- allow :gem_sources, "/usr/bin/gem", "sources"
36
- allow :gem_uninstall, "/usr/bin/gem", "uninstall", :V
37
- allow :update_rubygems
38
- allow :rm
39
- end
40
-
41
- routines do
42
-
43
- testsuite do
44
- before :sysupdate, :installdeps, :install_gem
45
-
46
- remote :root do
47
- directory_upload 'test', '/tmp/'
48
- cd '/tmp'
49
- ruby :I, 'lib/', :I, 'test/', :r, 'rubygems', 'test/test_all.rb'
50
- end
51
-
52
- after :install_rubyforge, :install_github
53
- end
54
-
55
- install_gem do
56
- before :package_gem
57
- remote :root do
58
- disable_safe_mode
59
- file_upload "pkg/net-ssh-*.gem", "/tmp/"
60
- gem_install "/tmp/net-ssh-*.gem"
61
- end
62
- end
63
-
64
- package_gem do
65
- local do
66
- rm :r, :f, 'pkg'
67
- rake 'package'
68
- end
69
- end
70
-
71
- remove do
72
- remote :root do
73
- gem_uninstall 'net-ssh'
74
- end
75
- end
76
-
77
- installdeps do
78
- remote :root do
79
- gem_install "rye", "test-unit", "mocha"
80
- rye 'authorize-local'
81
- end
82
- end
83
-
84
- sysupdate do
85
- remote :root do
86
- apt_get "update"
87
- apt_get "install", "build-essential", "git-core"
88
- apt_get "install", "ruby1.8-dev", "rdoc", "libzlib-ruby", "rubygems"
89
- mkdir :p, "/var/lib/gems/1.8/bin" # Doesn't get created, but causes Rubygems to fail
90
- gem_install "builder", "session"
91
- gem_install 'rubygems-update', "-v=1.3.4" # circular issue with 1.3.5 and hoe
92
- update_rubygems
93
- end
94
- end
95
- end
96
-
data/gem-public_cert.pem DELETED
@@ -1,20 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ8wDQYDVQQDDAZkZWxh
3
- bm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
4
- b20wHhcNMTMwMjA2MTE1NzQ1WhcNMTQwMjA2MTE1NzQ1WjBBMQ8wDQYDVQQDDAZk
5
- ZWxhbm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
6
- FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDg1hMtl0XsMuUK
7
- AKTgYWv3gjj7vuEsE2EjT+vyBg8/LpqVVwZziiaebJT9IZiQ+sCFqbiakj0b53pI
8
- hg1yOaBEmH6/W0L7rwzqaRV9sW1eJs9JxFYQCnd67zUnzj8nnRlOjG+hhIG+Vsij
9
- npsGbt28pefuNZJjO5q2clAlfSniIIHfIsU7/StEYu6FUGOjnwryZ0r5yJlr9RrE
10
- Gs+q0DW8QnZ9UpAfuDFQZuIqeKQFFLE7nMmCGaA+0BN1nLl3fVHNbLHq7Avk8+Z+
11
- ZuuvkdscbHlO/l+3xCNQ5nUnHwq0ADAbMLOlmiYYzqXoWLjmeI6me/clktJCfN2R
12
- oZG3UQvvAgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFMSJOEtHzE4l0azv
13
- M0JK0kKNToK1MAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAtOdE73qx
14
- OH2ydi9oT2hS5f9G0y1Z70Tlwh+VGExyfxzVE9XwC+iPpJxNraiHYgF/9/oky7ZZ
15
- R9q0/tJneuhAenZdiQkX7oi4O3v9wRS6YHoWBxMPFKVRLNTzvVJsbmfpCAlp5/5g
16
- ps4wQFy5mibElGVlOobf/ghqZ25HS9J6kd0/C/ry0AUtTogsL7TxGwT4kbCx63ub
17
- 3vywEEhsJUzfd97GCABmtQfRTldX/j7F1z/5wd8p+hfdox1iibds9ZtfaZA3KzKn
18
- kchWN9B6zg9r1XMQ8BM2Jz0XoPanPe354+lWwjpkRKbFow/ZbQHcCLCq24+N6b6g
19
- dgKfNDzwiDpqCA==
20
- -----END CERTIFICATE-----
@@ -1,85 +0,0 @@
1
- require 'jruby_pageant'
2
-
3
- module Net; module SSH; module Authentication
4
-
5
- # This class implements an agent for JRuby + Pageant.
6
- #
7
- # Written by Artūras Šlajus <arturas.slajus@gmail.com>
8
- class Agent
9
- include Loggable
10
- include JRubyPageant
11
-
12
- # A simple module for extending keys, to allow blobs and comments to be
13
- # specified for them.
14
- module Key
15
- # :blob is used by OpenSSL::PKey::RSA#to_blob
16
- attr_accessor :java_blob
17
- attr_accessor :comment
18
- end
19
-
20
- # Instantiates a new agent object, connects to a running SSH agent,
21
- # negotiates the agent protocol version, and returns the agent object.
22
- def self.connect(logger=nil)
23
- agent = new(logger)
24
- agent.connect!
25
- agent
26
- end
27
-
28
- # Creates a new Agent object, using the optional logger instance to
29
- # report status.
30
- def initialize(logger=nil)
31
- self.logger = logger
32
- end
33
-
34
- # Connect to the agent process using the socket factory and socket name
35
- # given by the attribute writers. If the agent on the other end of the
36
- # socket reports that it is an SSH2-compatible agent, this will fail
37
- # (it only supports the ssh-agent distributed by OpenSSH).
38
- def connect!
39
- debug { "connecting to Pageant ssh-agent (via java connector)" }
40
- @agent_proxy = JRubyPageant.create
41
- unless @agent_proxy.is_running
42
- raise AgentNotAvailable, "Pageant is not running!"
43
- end
44
- debug { "connection to Pageant ssh-agent (via java connector) succeeded" }
45
- rescue AgentProxyException => e
46
- error { "could not connect to Pageant ssh-agent (via java connector)" }
47
- raise AgentNotAvailable, e.message, e.backtrace
48
- end
49
-
50
- # Return an array of all identities (public keys) known to the agent.
51
- # Each key returned is augmented with a +comment+ property which is set
52
- # to the comment returned by the agent for that key.
53
- def identities
54
- debug { "getting identities from Pageant" }
55
- @agent_proxy.get_identities.map do |identity|
56
- blob = identity.get_blob
57
- key = Buffer.new(String.from_java_bytes(blob)).read_key
58
- key.extend(Key)
59
- key.java_blob = blob
60
- key.comment = String.from_java_bytes(identity.get_comment)
61
- key
62
- end
63
- rescue AgentProxyException => e
64
- raise AgentError, "Cannot get identities: #{e.message}", e.backtrace
65
- end
66
-
67
- # Simulate agent close. This agent reference is no longer able to
68
- # query the agent.
69
- def close
70
- @agent_proxy = nil
71
- end
72
-
73
- # Using the agent and the given public key, sign the given data. The
74
- # signature is returned in SSH2 format.
75
- def sign(key, data)
76
- signed = @agent_proxy.sign(key.java_blob, data.to_java_bytes)
77
- String.from_java_bytes(signed)
78
- rescue AgentProxyException => e
79
- raise AgentError,
80
- "agent could not sign data with requested identity: #{e.message}",
81
- e.backtrace
82
- end
83
- end
84
-
85
- end; end; end
@@ -1,170 +0,0 @@
1
- require 'net/ssh/transport/server_version'
2
-
3
- # Only load pageant on Windows
4
- if Net::SSH::Authentication::PLATFORM == :win32
5
- require 'net/ssh/authentication/pageant'
6
- end
7
-
8
- module Net; module SSH; module Authentication
9
-
10
- # This class implements a simple client for the ssh-agent protocol. It
11
- # does not implement any specific protocol, but instead copies the
12
- # behavior of the ssh-agent functions in the OpenSSH library (3.8).
13
- #
14
- # This means that although it behaves like a SSH1 client, it also has
15
- # some SSH2 functionality (like signing data).
16
- class Agent
17
- include Loggable
18
-
19
- # A simple module for extending keys, to allow comments to be specified
20
- # for them.
21
- module Comment
22
- attr_accessor :comment
23
- end
24
-
25
- SSH2_AGENT_REQUEST_VERSION = 1
26
- SSH2_AGENT_REQUEST_IDENTITIES = 11
27
- SSH2_AGENT_IDENTITIES_ANSWER = 12
28
- SSH2_AGENT_SIGN_REQUEST = 13
29
- SSH2_AGENT_SIGN_RESPONSE = 14
30
- SSH2_AGENT_FAILURE = 30
31
- SSH2_AGENT_VERSION_RESPONSE = 103
32
-
33
- SSH_COM_AGENT2_FAILURE = 102
34
-
35
- SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
36
- SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
37
- SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
38
- SSH_AGENT_FAILURE = 5
39
-
40
- # The underlying socket being used to communicate with the SSH agent.
41
- attr_reader :socket
42
-
43
- # Instantiates a new agent object, connects to a running SSH agent,
44
- # negotiates the agent protocol version, and returns the agent object.
45
- def self.connect(logger=nil)
46
- agent = new(logger)
47
- agent.connect!
48
- agent.negotiate!
49
- agent
50
- end
51
-
52
- # Creates a new Agent object, using the optional logger instance to
53
- # report status.
54
- def initialize(logger=nil)
55
- self.logger = logger
56
- end
57
-
58
- # Connect to the agent process using the socket factory and socket name
59
- # given by the attribute writers. If the agent on the other end of the
60
- # socket reports that it is an SSH2-compatible agent, this will fail
61
- # (it only supports the ssh-agent distributed by OpenSSH).
62
- def connect!
63
- begin
64
- debug { "connecting to ssh-agent" }
65
- @socket = agent_socket_factory.open(ENV['SSH_AUTH_SOCK'])
66
- rescue
67
- error { "could not connect to ssh-agent" }
68
- raise AgentNotAvailable, $!.message
69
- end
70
- end
71
-
72
- # Attempts to negotiate the SSH agent protocol version. Raises an error
73
- # if the version could not be negotiated successfully.
74
- def negotiate!
75
- # determine what type of agent we're communicating with
76
- type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION)
77
-
78
- if type == SSH2_AGENT_VERSION_RESPONSE
79
- raise NotImplementedError, "SSH2 agents are not yet supported"
80
- elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
81
- raise AgentError, "unknown response from agent: #{type}, #{body.to_s.inspect}"
82
- end
83
- end
84
-
85
- # Return an array of all identities (public keys) known to the agent.
86
- # Each key returned is augmented with a +comment+ property which is set
87
- # to the comment returned by the agent for that key.
88
- def identities
89
- type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES)
90
- raise AgentError, "could not get identity count" if agent_failed(type)
91
- raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER
92
-
93
- identities = []
94
- body.read_long.times do
95
- key = Buffer.new(body.read_string).read_key
96
- key.extend(Comment)
97
- key.comment = body.read_string
98
- identities.push key
99
- end
100
-
101
- return identities
102
- end
103
-
104
- # Closes this socket. This agent reference is no longer able to
105
- # query the agent.
106
- def close
107
- @socket.close
108
- end
109
-
110
- # Using the agent and the given public key, sign the given data. The
111
- # signature is returned in SSH2 format.
112
- def sign(key, data)
113
- type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, 0)
114
-
115
- if agent_failed(type)
116
- raise AgentError, "agent could not sign data with requested identity"
117
- elsif type != SSH2_AGENT_SIGN_RESPONSE
118
- raise AgentError, "bad authentication response #{type}"
119
- end
120
-
121
- return reply.read_string
122
- end
123
-
124
- private
125
-
126
- # Returns the agent socket factory to use.
127
- def agent_socket_factory
128
- if Net::SSH::Authentication::PLATFORM == :win32
129
- Pageant::socket_factory
130
- else
131
- UNIXSocket
132
- end
133
- end
134
-
135
- # Send a new packet of the given type, with the associated data.
136
- def send_packet(type, *args)
137
- buffer = Buffer.from(*args)
138
- data = [buffer.length + 1, type.to_i, buffer.to_s].pack("NCA*")
139
- debug { "sending agent request #{type} len #{buffer.length}" }
140
- @socket.send data, 0
141
- end
142
-
143
- # Read the next packet from the agent. This will return a two-part
144
- # tuple consisting of the packet type, and the packet's body (which
145
- # is returned as a Net::SSH::Buffer).
146
- def read_packet
147
- buffer = Net::SSH::Buffer.new(@socket.read(4))
148
- buffer.append(@socket.read(buffer.read_long))
149
- type = buffer.read_byte
150
- debug { "received agent packet #{type} len #{buffer.length-4}" }
151
- return type, buffer
152
- end
153
-
154
- # Send the given packet and return the subsequent reply from the agent.
155
- # (See #send_packet and #read_packet).
156
- def send_and_wait(type, *args)
157
- send_packet(type, *args)
158
- read_packet
159
- end
160
-
161
- # Returns +true+ if the parameter indicates a "failure" response from
162
- # the agent, and +false+ otherwise.
163
- def agent_failed(type)
164
- type == SSH_AGENT_FAILURE ||
165
- type == SSH2_AGENT_FAILURE ||
166
- type == SSH_COM_AGENT2_FAILURE
167
- end
168
- end
169
-
170
- end; end; end
@@ -1,51 +0,0 @@
1
- require 'thread'
2
-
3
- class String
4
- if RUBY_VERSION < "1.9"
5
- def getbyte(index)
6
- self[index]
7
- end
8
- def setbyte(index, c)
9
- self[index] = c
10
- end
11
- end
12
- if RUBY_VERSION < "1.8.7"
13
- def bytesize
14
- self.size
15
- end
16
- end
17
- end
18
-
19
- module Net; module SSH
20
-
21
- # This class contains miscellaneous patches and workarounds
22
- # for different ruby implementations.
23
- class Compat
24
-
25
- # A workaround for an IO#select threading bug in certain versions of MRI 1.8.
26
- # See: http://net-ssh.lighthouseapp.com/projects/36253/tickets/1-ioselect-threading-bug-in-ruby-18
27
- # The root issue is documented here: http://redmine.ruby-lang.org/issues/show/1993
28
- if RUBY_VERSION >= '1.9' || RUBY_PLATFORM == 'java'
29
- def self.io_select(*params)
30
- IO.select(*params)
31
- end
32
- else
33
- SELECT_MUTEX = Mutex.new
34
- def self.io_select(*params)
35
- # It should be safe to wrap calls in a mutex when the timeout is 0
36
- # (that is, the call is not supposed to block).
37
- # We leave blocking calls unprotected to avoid causing deadlocks.
38
- # This should still catch the main case for Capistrano users.
39
- if params[3] == 0
40
- SELECT_MUTEX.synchronize do
41
- IO.select(*params)
42
- end
43
- else
44
- IO.select(*params)
45
- end
46
- end
47
- end
48
-
49
- end
50
-
51
- end; end
@@ -1,30 +0,0 @@
1
- require 'net/ssh/verifiers/strict'
2
-
3
- module Net; module SSH; module Verifiers
4
-
5
- # Basically the same as the Strict verifier, but does not try to actually
6
- # verify a connection if the server is the localhost and the port is a
7
- # nonstandard port number. Those two conditions will typically mean the
8
- # connection is being tunnelled through a forwarded port, so the known-hosts
9
- # file will not be helpful (in general).
10
- class Lenient < Strict
11
- # Tries to determine if the connection is being tunnelled, and if so,
12
- # returns true. Otherwise, performs the standard strict verification.
13
- def verify(arguments)
14
- return true if tunnelled?(arguments)
15
- super
16
- end
17
-
18
- private
19
-
20
- # A connection is potentially being tunnelled if the port is not 22,
21
- # and the ip refers to the localhost.
22
- def tunnelled?(args)
23
- return false if args[:session].port == Net::SSH::Transport::Session::DEFAULT_PORT
24
-
25
- ip = args[:session].peer[:ip]
26
- return ip == "127.0.0.1" || ip == "::1"
27
- end
28
- end
29
-
30
- end; end; end
@@ -1,12 +0,0 @@
1
- module Net; module SSH; module Verifiers
2
-
3
- # The Null host key verifier simply allows every key it sees, without
4
- # bothering to verify. This is simple, but is not particularly secure.
5
- class Null
6
- # Returns true.
7
- def verify(arguments)
8
- true
9
- end
10
- end
11
-
12
- end; end; end
@@ -1,54 +0,0 @@
1
- require 'net/ssh/errors'
2
- require 'net/ssh/known_hosts'
3
-
4
- module Net; module SSH; module Verifiers
5
-
6
- # Does a strict host verification, looking the server up in the known
7
- # host files to see if a key has already been seen for this server. If this
8
- # server does not appear in any host file, an exception will be raised
9
- # (HostKeyUnknown). This is in contrast to the "Strict" class, which will
10
- # silently add the key to your known_hosts file. If the server does appear at
11
- # least once, but the key given does not match any known for the server, an
12
- # exception will be raised (HostKeyMismatch).
13
- # Otherwise, this returns true.
14
- class Secure
15
- def verify(arguments)
16
- options = arguments[:session].options
17
- host = options[:host_key_alias] || arguments[:session].host_as_string
18
- matches = Net::SSH::KnownHosts.search_for(host, arguments[:session].options)
19
-
20
- # We've never seen this host before, so raise an exception.
21
- if matches.empty?
22
- process_cache_miss(host, arguments, HostKeyUnknown, "is unknown")
23
- end
24
-
25
- # If we found any matches, check to see that the key type and
26
- # blob also match.
27
- found = matches.any? do |key|
28
- key.ssh_type == arguments[:key].ssh_type &&
29
- key.to_blob == arguments[:key].to_blob
30
- end
31
-
32
- # If a match was found, return true. Otherwise, raise an exception
33
- # indicating that the key was not recognized.
34
- unless found
35
- process_cache_miss(host, arguments, HostKeyMismatch, "does not match")
36
- end
37
-
38
- found
39
- end
40
-
41
- private
42
-
43
- def process_cache_miss(host, args, exc_class, message)
44
- exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
45
- "#{message} for #{host.inspect}")
46
- exception.data = args
47
- exception.callback = Proc.new do
48
- Net::SSH::KnownHosts.add(host, args[:key], args[:session].options)
49
- end
50
- raise exception
51
- end
52
- end
53
-
54
- end; end; end
@@ -1,24 +0,0 @@
1
- require 'net/ssh/errors'
2
- require 'net/ssh/known_hosts'
3
- require 'net/ssh/verifiers/secure'
4
-
5
- module Net; module SSH; module Verifiers
6
-
7
- # Does a strict host verification, looking the server up in the known
8
- # host files to see if a key has already been seen for this server. If this
9
- # server does not appear in any host file, this will silently add the
10
- # server. If the server does appear at least once, but the key given does
11
- # not match any known for the server, an exception will be raised (HostKeyMismatch).
12
- # Otherwise, this returns true.
13
- class Strict < Secure
14
- def verify(arguments)
15
- begin
16
- super
17
- rescue HostKeyUnknown => err
18
- err.remember_host!
19
- return true
20
- end
21
- end
22
- end
23
-
24
- end; end; end