net-ssh 0.5.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 (179) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/doc/README +13 -0
  5. data/doc/manual-html/chapter-1.html +333 -0
  6. data/doc/manual-html/chapter-2.html +455 -0
  7. data/doc/manual-html/chapter-3.html +413 -0
  8. data/doc/manual-html/chapter-4.html +353 -0
  9. data/doc/manual-html/chapter-5.html +393 -0
  10. data/doc/manual-html/chapter-6.html +296 -0
  11. data/doc/manual-html/index.html +217 -0
  12. data/doc/manual-html/manual.css +192 -0
  13. data/doc/manual/chapter.erb +18 -0
  14. data/doc/manual/example.erb +18 -0
  15. data/doc/manual/index.erb +29 -0
  16. data/doc/manual/manual.css +192 -0
  17. data/doc/manual/manual.rb +240 -0
  18. data/doc/manual/manual.yml +67 -0
  19. data/doc/manual/page.erb +87 -0
  20. data/doc/manual/parts/channels_callbacks.txt +32 -0
  21. data/doc/manual/parts/channels_loop.txt +14 -0
  22. data/doc/manual/parts/channels_open.txt +20 -0
  23. data/doc/manual/parts/channels_operations.txt +15 -0
  24. data/doc/manual/parts/channels_types.txt +3 -0
  25. data/doc/manual/parts/channels_what_are.txt +7 -0
  26. data/doc/manual/parts/exec_channels.txt +28 -0
  27. data/doc/manual/parts/exec_open.txt +51 -0
  28. data/doc/manual/parts/exec_popen3.txt +35 -0
  29. data/doc/manual/parts/forward_direct.txt +37 -0
  30. data/doc/manual/parts/forward_handlers.txt +16 -0
  31. data/doc/manual/parts/forward_intro.txt +18 -0
  32. data/doc/manual/parts/forward_local.txt +18 -0
  33. data/doc/manual/parts/forward_remote.txt +14 -0
  34. data/doc/manual/parts/intro_author.txt +1 -0
  35. data/doc/manual/parts/intro_getting.txt +39 -0
  36. data/doc/manual/parts/intro_license.txt +6 -0
  37. data/doc/manual/parts/intro_support.txt +7 -0
  38. data/doc/manual/parts/intro_what_is.txt +7 -0
  39. data/doc/manual/parts/intro_what_is_not.txt +3 -0
  40. data/doc/manual/parts/proxy_http.txt +52 -0
  41. data/doc/manual/parts/proxy_intro.txt +1 -0
  42. data/doc/manual/parts/proxy_socks.txt +23 -0
  43. data/doc/manual/parts/session_key.txt +66 -0
  44. data/doc/manual/parts/session_options.txt +42 -0
  45. data/doc/manual/parts/session_session.txt +14 -0
  46. data/doc/manual/parts/session_start.txt +49 -0
  47. data/doc/manual/tutorial.erb +30 -0
  48. data/examples/channel-demo.rb +81 -0
  49. data/examples/port-forward.rb +51 -0
  50. data/examples/process-demo.rb +91 -0
  51. data/examples/remote-net-port-forward.rb +45 -0
  52. data/examples/remote-port-forward.rb +80 -0
  53. data/examples/tail-demo.rb +49 -0
  54. data/lib/net/ssh.rb +52 -0
  55. data/lib/net/ssh/connection/channel.rb +411 -0
  56. data/lib/net/ssh/connection/constants.rb +47 -0
  57. data/lib/net/ssh/connection/driver.rb +343 -0
  58. data/lib/net/ssh/connection/services.rb +72 -0
  59. data/lib/net/ssh/connection/term.rb +90 -0
  60. data/lib/net/ssh/errors.rb +27 -0
  61. data/lib/net/ssh/proxy/errors.rb +34 -0
  62. data/lib/net/ssh/proxy/http.rb +126 -0
  63. data/lib/net/ssh/proxy/socks4.rb +83 -0
  64. data/lib/net/ssh/proxy/socks5.rb +160 -0
  65. data/lib/net/ssh/service/forward/driver.rb +319 -0
  66. data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
  67. data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
  68. data/lib/net/ssh/service/forward/services.rb +76 -0
  69. data/lib/net/ssh/service/process/driver.rb +153 -0
  70. data/lib/net/ssh/service/process/open.rb +193 -0
  71. data/lib/net/ssh/service/process/popen3.rb +160 -0
  72. data/lib/net/ssh/service/process/services.rb +66 -0
  73. data/lib/net/ssh/service/services.rb +44 -0
  74. data/lib/net/ssh/session.rb +242 -0
  75. data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
  76. data/lib/net/ssh/transport/compress/compressor.rb +53 -0
  77. data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
  78. data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
  79. data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
  80. data/lib/net/ssh/transport/compress/services.rb +68 -0
  81. data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
  82. data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
  83. data/lib/net/ssh/transport/constants.rb +66 -0
  84. data/lib/net/ssh/transport/errors.rb +47 -0
  85. data/lib/net/ssh/transport/identity-cipher.rb +61 -0
  86. data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
  87. data/lib/net/ssh/transport/kex/dh.rb +231 -0
  88. data/lib/net/ssh/transport/kex/services.rb +60 -0
  89. data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
  90. data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
  91. data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
  92. data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
  93. data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
  94. data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
  95. data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
  96. data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
  97. data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
  98. data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
  99. data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
  100. data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
  101. data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
  102. data/lib/net/ssh/transport/ossl/services.rb +149 -0
  103. data/lib/net/ssh/transport/packet-stream.rb +210 -0
  104. data/lib/net/ssh/transport/services.rb +146 -0
  105. data/lib/net/ssh/transport/session.rb +296 -0
  106. data/lib/net/ssh/transport/version-negotiator.rb +73 -0
  107. data/lib/net/ssh/userauth/agent.rb +218 -0
  108. data/lib/net/ssh/userauth/constants.rb +35 -0
  109. data/lib/net/ssh/userauth/driver.rb +176 -0
  110. data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
  111. data/lib/net/ssh/userauth/methods/password.rb +70 -0
  112. data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
  113. data/lib/net/ssh/userauth/methods/services.rb +63 -0
  114. data/lib/net/ssh/userauth/services.rb +126 -0
  115. data/lib/net/ssh/userauth/userkeys.rb +258 -0
  116. data/lib/net/ssh/util/buffer.rb +274 -0
  117. data/lib/net/ssh/util/openssl.rb +146 -0
  118. data/lib/net/ssh/util/prompter.rb +73 -0
  119. data/lib/net/ssh/version.rb +29 -0
  120. data/test/ALL-TESTS.rb +21 -0
  121. data/test/connection/tc_channel.rb +136 -0
  122. data/test/connection/tc_driver.rb +287 -0
  123. data/test/connection/tc_integration.rb +85 -0
  124. data/test/proxy/tc_http.rb +209 -0
  125. data/test/proxy/tc_socks4.rb +148 -0
  126. data/test/proxy/tc_socks5.rb +214 -0
  127. data/test/service/forward/tc_driver.rb +289 -0
  128. data/test/service/forward/tc_local_network_handler.rb +123 -0
  129. data/test/service/forward/tc_remote_network_handler.rb +108 -0
  130. data/test/service/process/tc_driver.rb +79 -0
  131. data/test/service/process/tc_integration.rb +117 -0
  132. data/test/service/process/tc_open.rb +179 -0
  133. data/test/service/process/tc_popen3.rb +164 -0
  134. data/test/tc_integration.rb +79 -0
  135. data/test/transport/compress/tc_none_compress.rb +41 -0
  136. data/test/transport/compress/tc_none_decompress.rb +45 -0
  137. data/test/transport/compress/tc_zlib_compress.rb +61 -0
  138. data/test/transport/compress/tc_zlib_decompress.rb +48 -0
  139. data/test/transport/kex/tc_dh.rb +304 -0
  140. data/test/transport/kex/tc_dh_gex.rb +70 -0
  141. data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
  142. data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
  143. data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
  144. data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
  145. data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
  146. data/test/transport/ossl/fixtures/not-a-private-key +4 -0
  147. data/test/transport/ossl/fixtures/not-supported +2 -0
  148. data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
  149. data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
  150. data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
  151. data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
  152. data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
  153. data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
  154. data/test/transport/ossl/hmac/tc_md5.rb +50 -0
  155. data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
  156. data/test/transport/ossl/hmac/tc_none.rb +50 -0
  157. data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
  158. data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
  159. data/test/transport/ossl/tc_buffer.rb +97 -0
  160. data/test/transport/ossl/tc_buffer_factory.rb +67 -0
  161. data/test/transport/ossl/tc_cipher_factory.rb +84 -0
  162. data/test/transport/ossl/tc_digest_factory.rb +39 -0
  163. data/test/transport/ossl/tc_hmac_factory.rb +72 -0
  164. data/test/transport/ossl/tc_key_factory.rb +199 -0
  165. data/test/transport/tc_algorithm_negotiator.rb +169 -0
  166. data/test/transport/tc_identity_cipher.rb +52 -0
  167. data/test/transport/tc_integration.rb +110 -0
  168. data/test/transport/tc_packet_stream.rb +183 -0
  169. data/test/transport/tc_session.rb +283 -0
  170. data/test/transport/tc_version_negotiator.rb +86 -0
  171. data/test/userauth/methods/tc_hostbased.rb +136 -0
  172. data/test/userauth/methods/tc_password.rb +89 -0
  173. data/test/userauth/methods/tc_publickey.rb +167 -0
  174. data/test/userauth/tc_agent.rb +223 -0
  175. data/test/userauth/tc_driver.rb +190 -0
  176. data/test/userauth/tc_integration.rb +81 -0
  177. data/test/userauth/tc_userkeys.rb +265 -0
  178. data/test/util/tc_buffer.rb +217 -0
  179. metadata +256 -0
@@ -0,0 +1,61 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ module Net
18
+ module SSH
19
+
20
+ module Transport
21
+
22
+ # A cipher that does nothing but pass the data through, unchanged. This
23
+ # keeps things in the code nice and clean when a cipher has not yet been
24
+ # determined (i.e., during key exchange).
25
+ class IdentityCipher
26
+
27
+ # A default block size of 8 is required by the SSH2 protocol.
28
+ def block_size
29
+ 8
30
+ end
31
+
32
+ # Does nothing. Returns self.
33
+ def encrypt
34
+ self
35
+ end
36
+
37
+ # Does nothing. Returns self.
38
+ def decrypt
39
+ self
40
+ end
41
+
42
+ # Passes its single argument through unchanged.
43
+ def update( text )
44
+ text
45
+ end
46
+
47
+ # Returns the empty string.
48
+ def final
49
+ ""
50
+ end
51
+
52
+ # The name of this cipher, which is "identity".
53
+ def name
54
+ "identity"
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,106 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'net/ssh/errors'
18
+ require 'net/ssh/transport/constants'
19
+ require 'net/ssh/transport/kex/dh.rb'
20
+
21
+ module Net
22
+ module SSH
23
+ module Transport
24
+ module Kex
25
+
26
+ # A key-exchange service implementing the
27
+ # "diffie-hellman-group-exchange-sha1" key-exchange algorithm.
28
+ class DiffieHellmanGroupExchangeSHA1 < DiffieHellmanGroup1SHA1
29
+
30
+ MINIMUM_BITS = 1024
31
+ MAXIMUM_BITS = 8192
32
+
33
+ KEXDH_GEX_GROUP = 31
34
+ KEXDH_GEX_INIT = 32
35
+ KEXDH_GEX_REPLY = 33
36
+ KEXDH_GEX_REQUEST = 34
37
+
38
+ # Compute the number of bits needed for the given number of bytes.
39
+ def compute_need_bits( data )
40
+ need_bits = data[:need_bytes] * 8
41
+ if need_bits < MINIMUM_BITS
42
+ need_bits = MINIMUM_BITS
43
+ elsif need_bits > MAXIMUM_BITS
44
+ need_bits = MAXIMUM_BITS
45
+ end
46
+
47
+ data[:need_bits] = need_bits
48
+ data[:need_bytes] = need_bits / 8
49
+ end
50
+ private :compute_need_bits
51
+
52
+ # Returns the DH key parameters for the given session.
53
+ def get_parms( session, data )
54
+ compute_need_bits( data )
55
+
56
+ # request the DH key parameters for the given number of bits.
57
+ buffer = @buffers.writer
58
+ buffer.write_byte KEXDH_GEX_REQUEST
59
+ buffer.write_long MINIMUM_BITS
60
+ buffer.write_long data[:need_bits]
61
+ buffer.write_long MAXIMUM_BITS
62
+ session.send_message buffer
63
+
64
+ type, buffer = session.wait_for_message
65
+ unless type == KEXDH_GEX_GROUP
66
+ raise Net::SSH::Exception, "expected KEXDH_GEX_GROUP, got #{type}"
67
+ end
68
+
69
+ p = buffer.read_bignum
70
+ g = buffer.read_bignum
71
+
72
+ [ p, g ]
73
+ end
74
+ private :get_parms
75
+
76
+ # Returns the INIT/REPLY constants used by this algorithm.
77
+ def get_init_reply
78
+ [ KEXDH_GEX_INIT, KEXDH_GEX_REPLY ]
79
+ end
80
+ private :get_init_reply
81
+
82
+ # Build the signature buffer to use when verifying a signature from
83
+ # the server.
84
+ def build_signature_buffer( dh, data, result )
85
+ response = @buffers.writer
86
+ response.write_string data[:client_version_string],
87
+ data[:server_version_string],
88
+ data[:client_algorithm_packet],
89
+ data[:server_algorithm_packet],
90
+ result[:key_blob]
91
+ response.write_long MINIMUM_BITS,
92
+ data[:need_bits],
93
+ MAXIMUM_BITS
94
+ response.write_bignum dh.p, dh.g, dh.pub_key,
95
+ result[:server_dh_pubkey],
96
+ result[:shared_secret]
97
+ response
98
+ end
99
+ private :build_signature_buffer
100
+
101
+ end
102
+
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,231 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'net/ssh/errors'
18
+ require 'net/ssh/transport/constants'
19
+
20
+ module Net
21
+ module SSH
22
+ module Transport
23
+ module Kex
24
+
25
+ # A key-exchange service implementing the "diffie-hellman-group1-sha1"
26
+ # key-exchange algorithm.
27
+ class DiffieHellmanGroup1SHA1
28
+ include Constants
29
+
30
+ # The value of 'P', as a string, in hexadecimal
31
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
32
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
33
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
34
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
35
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
36
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
37
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
38
+ "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"
39
+
40
+ # The radix in which P_s represents the value of P
41
+ P_r = 16
42
+
43
+ # The group constant
44
+ G = 2
45
+
46
+ # The reference to the key factory to use.
47
+ attr_writer :keys
48
+
49
+ # The reference to the buffer factory to use.
50
+ attr_writer :buffers
51
+
52
+ # Create a new instance of the DiffieHellmanGroup1SHA1 algorithm.
53
+ # The parameters are, respectively, a factory for creating new
54
+ # Bignum instances, and a factory for obtaining digester objects.
55
+ def initialize( bn, digests )
56
+ @bn = bn
57
+
58
+ @p = @bn.new( P_s, P_r )
59
+ @g = G
60
+
61
+ @digester = digests.get( "sha1" )
62
+ end
63
+
64
+ # Returns the DH key parameters for the given session.
65
+ def get_parms( session, data )
66
+ [ @p, @g ]
67
+ end
68
+ private :get_parms
69
+
70
+ # Returns the INIT/REPLY constants used by this algorithm.
71
+ def get_init_reply
72
+ [ KEXDH_INIT, KEXDH_REPLY ]
73
+ end
74
+ private :get_init_reply
75
+
76
+ # Build the signature buffer to use when verifying a signature from
77
+ # the server.
78
+ def build_signature_buffer( dh, data, result )
79
+ response = @buffers.writer
80
+ response.write_string data[:client_version_string],
81
+ data[:server_version_string],
82
+ data[:client_algorithm_packet],
83
+ data[:server_algorithm_packet],
84
+ result[:key_blob]
85
+ response.write_bignum dh.pub_key,
86
+ result[:server_dh_pubkey],
87
+ result[:shared_secret]
88
+ response
89
+ end
90
+ private :build_signature_buffer
91
+
92
+ # Generate a DH key with a private key consisting of the given
93
+ # number of bytes.
94
+ def generate_key( session, data ) #:nodoc:
95
+ dh = @keys.get( "dh" )
96
+ dh.p, dh.g = get_parms( session, data )
97
+
98
+ dh.priv_key = @bn.rand( data[:need_bytes] * 8 )
99
+
100
+ loop do
101
+ dh.generate_key!
102
+ break if dh.valid?
103
+ end
104
+
105
+ dh
106
+ end
107
+
108
+ # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
109
+ # resulting buffer.
110
+ def send_kexinit( dh, session ) #:nodoc:
111
+ init, reply = get_init_reply
112
+
113
+ # send the KEXINIT message
114
+ buffer = @buffers.writer
115
+ buffer.write_byte init
116
+ buffer.write_bignum dh.pub_key
117
+ session.send_message buffer
118
+
119
+ # expect the KEXDH_REPLY message
120
+ type, buffer = session.wait_for_message
121
+ raise Net::SSH::Exception,
122
+ "expected REPLY" unless type == reply
123
+
124
+ return buffer
125
+ end
126
+
127
+ # Parse the buffer from a KEXDH_REPLY message, returning a hash of
128
+ # the extracted values.
129
+ def parse_kex_reply( dh, buffer, session ) #:nodoc:
130
+ result = Hash.new
131
+
132
+ result[:key_blob] = buffer.read_string
133
+ result[:server_key] = @buffers.reader( result[:key_blob] ).read_key
134
+ result[:server_dh_pubkey] = buffer.read_bignum
135
+ result[:shared_secret] =
136
+ @bn.new( dh.compute_key( result[:server_dh_pubkey] ), 2 )
137
+
138
+ sig_buffer = @buffers.reader( buffer.read_string )
139
+ sig_type = sig_buffer.read_string
140
+ if sig_type != session.algorithms.host_key
141
+ raise Net::SSH::Exception,
142
+ "host key algorithm mismatch for signature " +
143
+ "'#{sig_type}' != '#{session.algorithms.host_key}'"
144
+ end
145
+ result[:server_sig] = sig_buffer.read_string
146
+
147
+ return result
148
+ end
149
+
150
+ # Verify that the given key is of the expected type, and that it
151
+ # really is the key for the session's host. Raise Net::SSH::Exception
152
+ # if it is not.
153
+ def verify_server_key( key, session ) #:nodoc:
154
+ if key.ssh_type != session.algorithms.host_key
155
+ raise Net::SSH::Exception,
156
+ "host key algorithm mismatch " +
157
+ "'#{key.ssh_type}' != '#{session.algorithms.host_key}'"
158
+ end
159
+
160
+ # TODO: verify that the server key is really the key for the given
161
+ # host, probably by having a service that can verify server keys.
162
+ end
163
+
164
+ # Verify the signature that was received. Raise Net::SSH::Exception
165
+ # if the signature could not be verified. Otherwise, return the new
166
+ # session-id.
167
+ def verify_signature( dh, data, result ) #:nodoc:
168
+ response = build_signature_buffer( dh, data, result )
169
+
170
+ hash = @digester.digest( response.to_s )
171
+
172
+ unless result[:server_key].ssh_do_verify(
173
+ result[:server_sig], hash )
174
+ raise Net::SSH::Exception, "could not verify server signature"
175
+ end
176
+
177
+ return hash
178
+ end
179
+
180
+ # Send the NEWKEYS message, and expect the NEWKEYS message in
181
+ # reply.
182
+ def confirm_newkeys( session ) #:nodoc:
183
+ # expect the server's NEWKEYS message
184
+ type, buffer = session.wait_for_message
185
+ raise Net::SSH::Exception, "expected NEWKEYS" unless type == NEWKEYS
186
+
187
+ # reply with our own NEWKEYS message
188
+ response = @buffers.writer
189
+ response.write_byte NEWKEYS
190
+ session.send_message response
191
+ end
192
+
193
+ # Perform the key-exchange for the given session, with the given
194
+ # data. The data is a Hash of symbols representing information
195
+ # required by this algorithm, which was acquired during earlier
196
+ # processing. This method will return an object consisting of the
197
+ # following fields:
198
+ #
199
+ # * :session_id
200
+ # * :server_key
201
+ # * :shared_secret
202
+ # * :hashing_algorithm
203
+ #
204
+ # The caller is expected to be able to understand how to use these
205
+ # deliverables.
206
+ def exchange_keys( session, data )
207
+ data = data.dup
208
+ dh = generate_key( session, data )
209
+
210
+ buffer = send_kexinit( dh, session )
211
+
212
+ result = parse_kex_reply( dh, buffer, session )
213
+
214
+ verify_server_key( result[:server_key], session )
215
+
216
+ session_id = verify_signature( dh, data, result )
217
+
218
+ confirm_newkeys( session )
219
+
220
+ return Struct.new( :session_id,
221
+ :server_key, :shared_secret, :hashing_algorithm ).new(
222
+ session_id, result[:server_key], result[:shared_secret],
223
+ @digester )
224
+ end
225
+
226
+ end
227
+
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,60 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # This source file is distributed as part of the Net::SSH Secure Shell Client
7
+ # library for Ruby. This file (and the library as a whole) may be used only as
8
+ # allowed by either the BSD license, or the Ruby license (or, by association
9
+ # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SSH
10
+ # distribution for the texts of these licenses.
11
+ # -----------------------------------------------------------------------------
12
+ # net-ssh website : http://net-ssh.rubyforge.org
13
+ # project website: http://rubyforge.org/projects/net-ssh
14
+ # =============================================================================
15
+ #++
16
+
17
+ require 'openssl'
18
+
19
+ module Net
20
+ module SSH
21
+ module Transport
22
+ module Kex
23
+
24
+ # Register the services that perform key-exchanges.
25
+ def register_services( container )
26
+ container.namespace_define :kex do |b|
27
+
28
+ # The :dh service is a standard Diffie-Hellman key exchange
29
+ # algorithm using Group-1 and SHA-1.
30
+ b.dh :model => :singleton_deferred do
31
+ require 'net/ssh/transport/kex/dh'
32
+ dh = DiffieHellmanGroup1SHA1.new( b.bns, b.digesters )
33
+ dh.keys = b.keys
34
+ dh.buffers = b.buffers
35
+ dh
36
+ end
37
+
38
+ # The :dh_gex service is a standard Diffie-Hellman key exchange
39
+ # algorithm using SHA-1 and a negotiated group.
40
+ b.dh_gex :model => :singleton_deferred do
41
+ require 'net/ssh/transport/kex/dh-gex'
42
+ dh = DiffieHellmanGroupExchangeSHA1.new( b.bns, b.digesters )
43
+ dh.keys = b.keys
44
+ dh.buffers = b.buffers
45
+ dh
46
+ end
47
+
48
+ # Add these services to the hash of available kex algorithms.
49
+ b.kex_names.update(
50
+ "diffie-hellman-group-exchange-sha1" => b.dh_gex,
51
+ "diffie-hellman-group1-sha1" => b.dh
52
+ )
53
+ end
54
+ end
55
+ module_function :register_services
56
+
57
+ end
58
+ end
59
+ end
60
+ end