net-ssh 1.1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. data/CHANGELOG.rdoc +37 -0
  2. data/Manifest +101 -0
  3. data/README.rdoc +110 -0
  4. data/Rakefile +26 -0
  5. data/{THANKS → THANKS.rdoc} +2 -5
  6. data/lib/net/ssh.rb +189 -57
  7. data/lib/net/ssh/authentication/agent.rb +175 -0
  8. data/lib/net/ssh/authentication/constants.rb +18 -0
  9. data/lib/net/ssh/authentication/key_manager.rb +166 -0
  10. data/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  11. data/lib/net/ssh/authentication/methods/hostbased.rb +71 -0
  12. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +66 -0
  13. data/lib/net/ssh/authentication/methods/password.rb +39 -0
  14. data/lib/net/ssh/authentication/methods/publickey.rb +92 -0
  15. data/lib/net/ssh/authentication/pageant.rb +176 -0
  16. data/lib/net/ssh/authentication/session.rb +116 -0
  17. data/lib/net/ssh/buffer.rb +339 -0
  18. data/lib/net/ssh/buffered_io.rb +149 -0
  19. data/lib/net/ssh/config.rb +173 -0
  20. data/lib/net/ssh/connection/channel.rb +575 -454
  21. data/lib/net/ssh/connection/constants.rb +31 -45
  22. data/lib/net/ssh/connection/session.rb +569 -0
  23. data/lib/net/ssh/connection/term.rb +176 -88
  24. data/lib/net/ssh/errors.rb +83 -61
  25. data/lib/net/ssh/key_factory.rb +85 -0
  26. data/lib/net/ssh/known_hosts.rb +129 -0
  27. data/lib/net/ssh/loggable.rb +61 -0
  28. data/lib/net/ssh/packet.rb +102 -0
  29. data/lib/net/ssh/prompt.rb +93 -0
  30. data/lib/net/ssh/proxy/errors.rb +8 -28
  31. data/lib/net/ssh/proxy/http.rb +75 -107
  32. data/lib/net/ssh/proxy/socks4.rb +35 -48
  33. data/lib/net/ssh/proxy/socks5.rb +76 -108
  34. data/lib/net/ssh/service/forward.rb +267 -0
  35. data/lib/net/ssh/test.rb +89 -0
  36. data/lib/net/ssh/test/channel.rb +129 -0
  37. data/lib/net/ssh/test/extensions.rb +152 -0
  38. data/lib/net/ssh/test/kex.rb +44 -0
  39. data/lib/net/ssh/test/local_packet.rb +51 -0
  40. data/lib/net/ssh/test/packet.rb +81 -0
  41. data/lib/net/ssh/test/remote_packet.rb +38 -0
  42. data/lib/net/ssh/test/script.rb +157 -0
  43. data/lib/net/ssh/test/socket.rb +59 -0
  44. data/lib/net/ssh/transport/algorithms.rb +384 -0
  45. data/lib/net/ssh/transport/cipher_factory.rb +72 -0
  46. data/lib/net/ssh/transport/constants.rb +22 -58
  47. data/lib/net/ssh/transport/hmac.rb +31 -0
  48. data/lib/net/ssh/transport/hmac/abstract.rb +48 -0
  49. data/lib/net/ssh/transport/hmac/md5.rb +12 -0
  50. data/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  51. data/lib/net/ssh/transport/hmac/none.rb +15 -0
  52. data/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  53. data/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  54. data/lib/net/ssh/transport/identity_cipher.rb +40 -0
  55. data/lib/net/ssh/transport/kex.rb +13 -0
  56. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  57. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  58. data/lib/net/ssh/{util → transport}/openssl.rb +22 -40
  59. data/lib/net/ssh/transport/packet_stream.rb +230 -0
  60. data/lib/net/ssh/transport/server_version.rb +61 -0
  61. data/lib/net/ssh/transport/session.rb +225 -303
  62. data/lib/net/ssh/transport/state.rb +170 -0
  63. data/lib/net/ssh/verifiers/lenient.rb +30 -0
  64. data/lib/net/ssh/verifiers/null.rb +12 -0
  65. data/lib/net/ssh/verifiers/strict.rb +53 -0
  66. data/lib/net/ssh/version.rb +57 -26
  67. data/net-ssh.gemspec +54 -0
  68. data/setup.rb +1585 -0
  69. data/test/authentication/methods/common.rb +28 -0
  70. data/test/authentication/methods/test_abstract.rb +51 -0
  71. data/test/authentication/methods/test_hostbased.rb +108 -0
  72. data/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  73. data/test/authentication/methods/test_password.rb +50 -0
  74. data/test/authentication/methods/test_publickey.rb +123 -0
  75. data/test/authentication/test_agent.rb +205 -0
  76. data/test/authentication/test_key_manager.rb +100 -0
  77. data/test/authentication/test_session.rb +93 -0
  78. data/test/common.rb +106 -0
  79. data/test/configs/exact_match +8 -0
  80. data/test/configs/wild_cards +14 -0
  81. data/test/connection/test_channel.rb +452 -0
  82. data/test/connection/test_session.rb +483 -0
  83. data/test/test_all.rb +6 -0
  84. data/test/test_buffer.rb +336 -0
  85. data/test/test_buffered_io.rb +63 -0
  86. data/test/test_config.rb +78 -0
  87. data/test/test_key_factory.rb +67 -0
  88. data/test/transport/hmac/test_md5.rb +34 -0
  89. data/test/transport/hmac/test_md5_96.rb +25 -0
  90. data/test/transport/hmac/test_none.rb +34 -0
  91. data/test/transport/hmac/test_sha1.rb +34 -0
  92. data/test/transport/hmac/test_sha1_96.rb +25 -0
  93. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  94. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  95. data/test/transport/test_algorithms.rb +302 -0
  96. data/test/transport/test_cipher_factory.rb +163 -0
  97. data/test/transport/test_hmac.rb +34 -0
  98. data/test/transport/test_identity_cipher.rb +40 -0
  99. data/test/transport/test_packet_stream.rb +433 -0
  100. data/test/transport/test_server_version.rb +55 -0
  101. data/test/transport/test_session.rb +312 -0
  102. data/test/transport/test_state.rb +173 -0
  103. metadata +102 -253
  104. data/ChangeLog +0 -560
  105. data/LICENSE +0 -7
  106. data/NEWS +0 -152
  107. data/README +0 -14
  108. data/bin/rb-keygen +0 -210
  109. data/doc/LICENSE-BSD +0 -27
  110. data/doc/LICENSE-GPL +0 -280
  111. data/doc/LICENSE-RUBY +0 -56
  112. data/doc/manual-html/chapter-1.html +0 -388
  113. data/doc/manual-html/chapter-2.html +0 -552
  114. data/doc/manual-html/chapter-3.html +0 -470
  115. data/doc/manual-html/chapter-4.html +0 -413
  116. data/doc/manual-html/chapter-5.html +0 -525
  117. data/doc/manual-html/chapter-6.html +0 -456
  118. data/doc/manual-html/chapter-7.html +0 -343
  119. data/doc/manual-html/index.html +0 -235
  120. data/doc/manual-html/stylesheets/manual.css +0 -270
  121. data/doc/manual-html/stylesheets/ruby.css +0 -17
  122. data/doc/manual/chapter.erb +0 -38
  123. data/doc/manual/example.erb +0 -18
  124. data/doc/manual/index.erb +0 -29
  125. data/doc/manual/manual.rb +0 -311
  126. data/doc/manual/manual.yml +0 -73
  127. data/doc/manual/page.erb +0 -87
  128. data/doc/manual/parts/0000.txt +0 -5
  129. data/doc/manual/parts/0001.txt +0 -3
  130. data/doc/manual/parts/0002.txt +0 -40
  131. data/doc/manual/parts/0003.txt +0 -6
  132. data/doc/manual/parts/0004.txt +0 -7
  133. data/doc/manual/parts/0005.txt +0 -1
  134. data/doc/manual/parts/0006.txt +0 -49
  135. data/doc/manual/parts/0007.txt +0 -67
  136. data/doc/manual/parts/0008.txt +0 -43
  137. data/doc/manual/parts/0009.txt +0 -14
  138. data/doc/manual/parts/0010.txt +0 -7
  139. data/doc/manual/parts/0011.txt +0 -14
  140. data/doc/manual/parts/0012.txt +0 -3
  141. data/doc/manual/parts/0013.txt +0 -20
  142. data/doc/manual/parts/0014.txt +0 -32
  143. data/doc/manual/parts/0015.txt +0 -14
  144. data/doc/manual/parts/0016.txt +0 -28
  145. data/doc/manual/parts/0017.txt +0 -50
  146. data/doc/manual/parts/0018.txt +0 -35
  147. data/doc/manual/parts/0019.txt +0 -7
  148. data/doc/manual/parts/0020.txt +0 -72
  149. data/doc/manual/parts/0021.txt +0 -50
  150. data/doc/manual/parts/0022.txt +0 -42
  151. data/doc/manual/parts/0023.txt +0 -51
  152. data/doc/manual/parts/0024.txt +0 -18
  153. data/doc/manual/parts/0025.txt +0 -18
  154. data/doc/manual/parts/0026.txt +0 -15
  155. data/doc/manual/parts/0027.txt +0 -37
  156. data/doc/manual/parts/0028.txt +0 -16
  157. data/doc/manual/parts/0029.txt +0 -1
  158. data/doc/manual/parts/0030.txt +0 -52
  159. data/doc/manual/parts/0031.txt +0 -25
  160. data/doc/manual/stylesheets/manual.css +0 -270
  161. data/doc/manual/stylesheets/ruby.css +0 -17
  162. data/doc/manual/tutorial.erb +0 -30
  163. data/examples/auth-forward.rb +0 -41
  164. data/examples/channel-demo.rb +0 -81
  165. data/examples/port-forward.rb +0 -51
  166. data/examples/process-demo.rb +0 -91
  167. data/examples/remote-net-port-forward.rb +0 -45
  168. data/examples/remote-port-forward.rb +0 -80
  169. data/examples/shell-demo.rb +0 -46
  170. data/examples/ssh-client.rb +0 -67
  171. data/examples/sync-shell-demo.rb +0 -69
  172. data/examples/tail-demo.rb +0 -49
  173. data/lib/net/ssh/connection/driver.rb +0 -446
  174. data/lib/net/ssh/connection/services.rb +0 -72
  175. data/lib/net/ssh/host-key-verifier.rb +0 -52
  176. data/lib/net/ssh/known-hosts.rb +0 -96
  177. data/lib/net/ssh/lenient-host-key-verifier.rb +0 -25
  178. data/lib/net/ssh/null-host-key-verifier.rb +0 -14
  179. data/lib/net/ssh/service/agentforward/driver.rb +0 -78
  180. data/lib/net/ssh/service/agentforward/services.rb +0 -41
  181. data/lib/net/ssh/service/forward/driver.rb +0 -319
  182. data/lib/net/ssh/service/forward/local-network-handler.rb +0 -71
  183. data/lib/net/ssh/service/forward/remote-network-handler.rb +0 -83
  184. data/lib/net/ssh/service/forward/services.rb +0 -76
  185. data/lib/net/ssh/service/process/driver.rb +0 -153
  186. data/lib/net/ssh/service/process/open.rb +0 -193
  187. data/lib/net/ssh/service/process/popen3.rb +0 -178
  188. data/lib/net/ssh/service/process/services.rb +0 -66
  189. data/lib/net/ssh/service/services.rb +0 -60
  190. data/lib/net/ssh/service/shell/driver.rb +0 -86
  191. data/lib/net/ssh/service/shell/services.rb +0 -54
  192. data/lib/net/ssh/service/shell/shell.rb +0 -222
  193. data/lib/net/ssh/service/shell/sync.rb +0 -114
  194. data/lib/net/ssh/session.rb +0 -305
  195. data/lib/net/ssh/transport/algorithm-negotiator.rb +0 -275
  196. data/lib/net/ssh/transport/compress/compressor.rb +0 -53
  197. data/lib/net/ssh/transport/compress/decompressor.rb +0 -53
  198. data/lib/net/ssh/transport/compress/none-compressor.rb +0 -39
  199. data/lib/net/ssh/transport/compress/none-decompressor.rb +0 -39
  200. data/lib/net/ssh/transport/compress/services.rb +0 -68
  201. data/lib/net/ssh/transport/compress/zlib-compressor.rb +0 -60
  202. data/lib/net/ssh/transport/compress/zlib-decompressor.rb +0 -52
  203. data/lib/net/ssh/transport/errors.rb +0 -47
  204. data/lib/net/ssh/transport/identity-cipher.rb +0 -61
  205. data/lib/net/ssh/transport/kex/dh-gex.rb +0 -106
  206. data/lib/net/ssh/transport/kex/dh.rb +0 -249
  207. data/lib/net/ssh/transport/kex/services.rb +0 -62
  208. data/lib/net/ssh/transport/ossl/buffer-factory.rb +0 -52
  209. data/lib/net/ssh/transport/ossl/buffer.rb +0 -87
  210. data/lib/net/ssh/transport/ossl/cipher-factory.rb +0 -98
  211. data/lib/net/ssh/transport/ossl/digest-factory.rb +0 -51
  212. data/lib/net/ssh/transport/ossl/hmac-factory.rb +0 -71
  213. data/lib/net/ssh/transport/ossl/hmac/hmac.rb +0 -62
  214. data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +0 -44
  215. data/lib/net/ssh/transport/ossl/hmac/md5.rb +0 -46
  216. data/lib/net/ssh/transport/ossl/hmac/none.rb +0 -46
  217. data/lib/net/ssh/transport/ossl/hmac/services.rb +0 -68
  218. data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +0 -44
  219. data/lib/net/ssh/transport/ossl/hmac/sha1.rb +0 -45
  220. data/lib/net/ssh/transport/ossl/key-factory.rb +0 -116
  221. data/lib/net/ssh/transport/ossl/services.rb +0 -149
  222. data/lib/net/ssh/transport/packet-stream.rb +0 -236
  223. data/lib/net/ssh/transport/services.rb +0 -146
  224. data/lib/net/ssh/transport/version-negotiator.rb +0 -73
  225. data/lib/net/ssh/userauth/agent.rb +0 -222
  226. data/lib/net/ssh/userauth/constants.rb +0 -35
  227. data/lib/net/ssh/userauth/driver.rb +0 -183
  228. data/lib/net/ssh/userauth/methods/hostbased.rb +0 -119
  229. data/lib/net/ssh/userauth/methods/keyboard-interactive.rb +0 -104
  230. data/lib/net/ssh/userauth/methods/password.rb +0 -70
  231. data/lib/net/ssh/userauth/methods/publickey.rb +0 -137
  232. data/lib/net/ssh/userauth/methods/services.rb +0 -90
  233. data/lib/net/ssh/userauth/pageant.rb +0 -197
  234. data/lib/net/ssh/userauth/services.rb +0 -141
  235. data/lib/net/ssh/userauth/userkeys.rb +0 -258
  236. data/lib/net/ssh/util/buffer.rb +0 -274
  237. data/lib/net/ssh/util/prompter.rb +0 -73
  238. data/test/ALL-TESTS.rb +0 -18
  239. data/test/connection/tc_channel.rb +0 -136
  240. data/test/connection/tc_driver.rb +0 -287
  241. data/test/connection/tc_integration.rb +0 -87
  242. data/test/proxy/tc_http.rb +0 -209
  243. data/test/proxy/tc_socks4.rb +0 -148
  244. data/test/proxy/tc_socks5.rb +0 -214
  245. data/test/service/agentforward/tc_driver.rb +0 -138
  246. data/test/service/forward/tc_driver.rb +0 -289
  247. data/test/service/forward/tc_local_network_handler.rb +0 -123
  248. data/test/service/forward/tc_remote_network_handler.rb +0 -111
  249. data/test/service/process/tc_driver.rb +0 -79
  250. data/test/service/process/tc_integration.rb +0 -119
  251. data/test/service/process/tc_open.rb +0 -179
  252. data/test/service/process/tc_popen3.rb +0 -164
  253. data/test/tc_integration.rb +0 -80
  254. data/test/transport/compress/tc_none_compress.rb +0 -41
  255. data/test/transport/compress/tc_none_decompress.rb +0 -45
  256. data/test/transport/compress/tc_zlib_compress.rb +0 -61
  257. data/test/transport/compress/tc_zlib_decompress.rb +0 -48
  258. data/test/transport/kex/tc_dh.rb +0 -312
  259. data/test/transport/kex/tc_dh_gex.rb +0 -71
  260. data/test/transport/ossl/fixtures/dsa-encrypted +0 -15
  261. data/test/transport/ossl/fixtures/dsa-encrypted-bad +0 -15
  262. data/test/transport/ossl/fixtures/dsa-unencrypted +0 -12
  263. data/test/transport/ossl/fixtures/dsa-unencrypted-bad +0 -12
  264. data/test/transport/ossl/fixtures/dsa-unencrypted.pub +0 -1
  265. data/test/transport/ossl/fixtures/not-a-private-key +0 -4
  266. data/test/transport/ossl/fixtures/not-supported +0 -2
  267. data/test/transport/ossl/fixtures/rsa-encrypted +0 -18
  268. data/test/transport/ossl/fixtures/rsa-encrypted-bad +0 -18
  269. data/test/transport/ossl/fixtures/rsa-unencrypted +0 -15
  270. data/test/transport/ossl/fixtures/rsa-unencrypted-bad +0 -15
  271. data/test/transport/ossl/fixtures/rsa-unencrypted.pub +0 -1
  272. data/test/transport/ossl/hmac/tc_hmac.rb +0 -58
  273. data/test/transport/ossl/hmac/tc_md5.rb +0 -50
  274. data/test/transport/ossl/hmac/tc_md5_96.rb +0 -50
  275. data/test/transport/ossl/hmac/tc_none.rb +0 -50
  276. data/test/transport/ossl/hmac/tc_sha1.rb +0 -50
  277. data/test/transport/ossl/hmac/tc_sha1_96.rb +0 -50
  278. data/test/transport/ossl/tc_buffer.rb +0 -97
  279. data/test/transport/ossl/tc_buffer_factory.rb +0 -67
  280. data/test/transport/ossl/tc_cipher_factory.rb +0 -84
  281. data/test/transport/ossl/tc_digest_factory.rb +0 -39
  282. data/test/transport/ossl/tc_hmac_factory.rb +0 -72
  283. data/test/transport/ossl/tc_key_factory.rb +0 -199
  284. data/test/transport/tc_algorithm_negotiator.rb +0 -170
  285. data/test/transport/tc_identity_cipher.rb +0 -52
  286. data/test/transport/tc_integration.rb +0 -115
  287. data/test/transport/tc_packet_stream.rb +0 -184
  288. data/test/transport/tc_session.rb +0 -296
  289. data/test/transport/tc_version_negotiator.rb +0 -86
  290. data/test/userauth/methods/tc_hostbased.rb +0 -136
  291. data/test/userauth/methods/tc_password.rb +0 -89
  292. data/test/userauth/methods/tc_publickey.rb +0 -167
  293. data/test/userauth/tc_agent.rb +0 -223
  294. data/test/userauth/tc_driver.rb +0 -190
  295. data/test/userauth/tc_integration.rb +0 -97
  296. data/test/userauth/tc_userkeys.rb +0 -265
  297. data/test/util/tc_buffer.rb +0 -217
@@ -1,32 +0,0 @@
1
- There are various callbacks that may be registered on a channel. Registering a callback is as simple as invoking the corresponding method on the channel and giving it a block that should be invoked when the named action occurs. The following table describes each callback and how it is used.
2
-
3
- table(list).
4
- |_. Name |_. Description |
5
- |=^. @on_close@ | This callback should accept a single parameter: the channel being closed. It is called immediately after the channel is removed from the connection. The callback should not send any data through the channel, since at this point the channel is no longer connected to the remote host.|
6
- |=^. @on_confirm_failed@ | This callback should accept four parameters: the channel instance, the reason code, a description of why the confirm failed, and the language code for the message. It is called immediately after the server has indicated that a channel could not be opened.|
7
- |=^. @on_confirm_open@ | This callback should accept a single parameter: the channel being opened. It is called immediately after the server has confirmed that the channel has been opened. This callback is typically set by a block passed to an @#open_channel@ call.|
8
- |=^. @on_data@ | This callback is invoked when data is received over the channel from the remote server. This data typically corresponds to the remote process's @stdout@ stream. The channel should accept two parameters: the channel itself, and the data being received.|
9
- |=^. @on_eof@ | This callback is called when the server indicates that no more data will be sent _from the server_ over this channel. Your program is still welcome to send data to the server, but you are guaranteed at this point that your @on_data@ and @on_extended_data@ callbacks will no longer be called for this channel. The callback should accept a single parameter, the channel itself.|
10
- |=^. @on_extended_data@ | This callback is called when _extended data_ is received from the server. There are (potentially) many _types_ of extended data. The callback should accept three parameters: the channel, an integer indicating the type of the data, and the data itself. Right now, you can pretty much count on the data type being a "1", which corresponds to the remote process's @stderr@ stream. Other data types are not defined in the SSH specification, but that does not mean some SSH servers won't try to invent their own.|
11
- |=^. @on_failure@ | When a request is sent over a channel (via the @send_request@ or @send_request_string@ methods), it may either succeed or fail. If it fails, this callback will be invoked. It should take a single parameter: the channel itself.|
12
- |=^. @on_request@ | When the server sends a "channel request" to the client, this callback will be invoked. Channel requests from the server typically indicate things like the exit status of a process. This callback should take four parameters: the channel, the type of request (as a string, like "exit-status"), a boolean (indicating whether or not the server wants an explicit reply to this request), and the data from the request, which will be a buffer object (see the API documentation for @Net::SSH::Util::ReaderBufferImpl@).|
13
- |=^. @on_success@ | When a request is sent over a channel (via the @send_request@ or @send_request_string@ methods), it may either succeed or fail. If it succeeds, this callback will be invoked. It should take a single parameter: the channel itself.|
14
- |=^. @on_window_adjust@ | When the server asks the client to adjust this channel's window size, this callback will be invoked. It should accept two parameters: the channel, and the number of bytes to add the channel's window size.|
15
-
16
- In general, you will never need to register callbacks for @on_failure@, @on_request@, @on_success@, or @on_window_adjust@, unless you are needing to implement support for some subservice or piggy-backed protocol (like SFTP).
17
-
18
- Following is an example of registering callbacks on a channel:
19
-
20
- {{{lang=ruby,caption=Registering callbacks on a channel,number=true
21
- Net::SSH.start( 'host' ) do |session|
22
- session.open_channel do |channel|
23
- channel.on_close do |ch|
24
- puts "channel closed successfully."
25
- end
26
- puts "closing channel..."
27
- channel.close
28
- end
29
-
30
- session.loop
31
- end
32
- }}}
@@ -1,14 +0,0 @@
1
- There are a variety of operations that may be performed on a channel. Some we've already mentioned, like registering callbacks, or closing the channel. Some of the other more common operations are listed (and described) in the following table.
2
-
3
- table(list).
4
- |_. Operation |_. Description |
5
- | @#exec@ | Executes a command asynchronously on this channel.|
6
- | @#request_pty@ | Requests that a pseudo-terminal (pty) be opened for this channel.|
7
- | @#send_data@ | Sends the given data string to the server via this channel. This is useful for sending data to a remote process, or sending an SFTP packet to the SFTP subsystem.|
8
- | @#send_eof@ | Tells the server that no further data will be sent from the client to the server. The client must honor this by not sending any more data (either normal or extended) to the server over this channel.|
9
- | @#send_extended_data@ | Sends a data string to the server, along with an integer describing its type. This is typically used to send @stderr@ data.|
10
- | @#send_request@ | Sends a named request to the server for this channel. This is primarily used by implementations of protocols and subsystems that run on top of SSH.|
11
- | @#send_signal@ | Indicates that the server should send the given signal to the process on the other end of the channel.|
12
- | @#subsystem@ | Requests that the server start the given subsystem on this channel. This is how (for instance) the SFTP subsystem is invoked. |
13
-
14
- See the API documentation for an exhaustive reference of all available channel operations.
@@ -1,28 +0,0 @@
1
- To run multiple processes in parallel, you can access the channel API directly, setting up multiple channels and callbacks in order to process the output from the channel.
2
-
3
- Suppose, for example, that you wanted to run multiple "tail" commands on various logs on the remote machine, combining them all into the output on the client. Something like the following would suffice:
4
-
5
- {{{lang=ruby,number=true,caption=Running "tail" on multiple remote files
6
- def do_tail( session, file )
7
- session.open_channel do |channel|
8
- channel.on_data do |ch, data|
9
- puts "[#{file}] -> #{data}"
10
- end
11
- channel.exec "tail -f #{file}"
12
- end
13
- end
14
-
15
- Net::SSH.start( 'host' ) do |session|
16
- do_tail session, "/var/log/messages"
17
- do_tail session, "/var/log/XFree86.0.log"
18
- do_tail session, "/var/log/tomcat/catalina.log"
19
- do_tail session, "/var/log/mysql/mysql.err"
20
- session.loop
21
- end
22
- }}}
23
-
24
- As you can see, four different logs are tailed on four separate channels. Each channel registers an @on_data@ callback (which simply displays the data it recieves, together with the name of the log file it came from). The @exec@ method of the channel is then invoked, which simply sends the request to execute the process to the server, and then returns.
25
-
26
- The @loop@ method then blocks while packets and processed and callbacks are invoked, completing the program.
27
-
28
- This approach works fine for processing data coming from the server, and with a little work and coordination can work well for sending data _to_ the server as well, by calling the @send_data@ method of the channel at the appropriate times. However, it requires a bit of forethought, since you have to come up with a simple state machine to manage most interactive sessions, and many times that's more effort than it is worth.
@@ -1,50 +0,0 @@
1
- The @#process.open@ interface provides a simpler way to manage interactive sessions. It still works via callbacks, and it still requires a kind of state machine in order to process input, but it does simplify things a little bit.
2
-
3
- Just open an SSH session. The @#process@ service of the session manages access to convenience methods for handling and communicating with remote processes. In particular the @#open@ method of the @#process@ service allows you to constuct callbacks for dealing with remote processes, more conveniently than using channels directly.
4
-
5
- Consider the "bc" command. It is a command-line calculator that accepts expressions on @stdin@ and writes the results to @stdout@. When it encounters the word @quit@ on the input, it exits. Sounds like a great way to demonstrate the @process@ service...
6
-
7
- {{{lang=ruby,number=true,caption=Using #process.open
8
- Net::SSH.start( 'host' ) do |session|
9
-
10
- session.process.open( "bc" ) do |bc|
11
- dialog = [ "5+5", "7*12", "sqrt(2.000000)", "quit" ]
12
-
13
- bc.on_success do |p|
14
- puts "requesting result of #{dialog.first}"
15
- p.puts dialog.shift
16
- end
17
-
18
- bc.on_stdout do |p,data|
19
- puts "--> #{data}"
20
- unless dialog.empty?
21
- puts "requesting result of #{dialog.first}"
22
- p.puts dialog.shift
23
- end
24
- end
25
-
26
- bc.on_exit do |p, status|
27
- puts "process finished with exit status: #{status}"
28
- end
29
- end
30
-
31
- end
32
- }}}
33
-
34
- Notice the progression. First, the session itself is started. Then, while the session is active, the process is invoked (via @#process.open@). After we have a handle to the process (which is yielded to the block, in this case), we set up the callbacks on the process. These are reminiscent of, but different from, the callbacks that we set up on the channel itself in the previous section.
35
-
36
- The following callbacks are defined for a process handle:
37
-
38
- table(list).
39
- |_. Name |_. Description |
40
- |=^. @on_exit@ | This callback is invoked when the process terminates normally. The block should accept two parameters: the process handle itself, and the exit status of the process.|
41
- |=^. @on_failure@ | This callback is invoked when the process could not be invoked. It should take two parameters: the process handle itself, and a status string (which currently always @nil@).|
42
- |=^. @on_success@ | This callback is invoked after the process has been successfully started. The callback should take a single parameter: the process handle itself.|
43
- |=^. @on_stderr@ | This callback is invoked when data is received from the process's @stderr@ stream. The callback should have two parameters: the process handle, and the data.|
44
- |=^. @on_stdout@ | This callback is invoked when data is received from the process's @stdout@ stream. The callback should have two parameters: the process handle, and the data.|
45
-
46
- Sending data to the process is as simple as calling @puts@ on the process handle. If you don't want a newline appended to your data, use @write@ instead.
47
-
48
- Notice that, when sending a block to @#process.open@, you do not have to explicitly invoke @session.loop@. It is implicitly called at the end of the block. If you ever want to set up multiple processes to run in parallel, simply use @#process.open@ without a block. The process handle will be returned, and you will be required to execute @session.loop@ manually.
49
-
50
- For more information on the @#process.open@ service, see the API documentation for @Net::SSH::Service::Process::Open@.
@@ -1,35 +0,0 @@
1
- The last approach to interacting with remote processes is the @#popen3@ method of @#process@ service. It is a _synchronous_ approach, meaning that each method call _may_ (potentially) block until data is received; you can't be using other features of the Net::SSH package while using it, but you don't have to mess with callbacks.
2
-
3
- If you are familiar with the "popen3" Ruby module, this will seem familiar. It's not a perfect clone of the "popen3" module's functionality, but it's close. What you do is you specify the process to invoke, and then you get three pseudo-IO objects back: the process's input stream, it's output stream, and it's error stream. You can write to the input stream to send data to the process, or read from the output and error streams. Reading from the output or error streams will block until data is available, which makes it very convenient for interacting with a single remote process.
4
-
5
- Here's the previous "bc" example, rewritten to use @#popen3@:
6
-
7
- {{{lang=ruby,number=true,caption=Using #process.popen3
8
- Net::SSH.start( 'host' ) do |session|
9
-
10
- input, output, error = session.process.popen3( "bc" )
11
-
12
- [ "5+5", "7*12", "sqrt(2.000000)" ].each do |formula|
13
- input.puts formula
14
- puts "#{formula}=#{output.read}"
15
- end
16
-
17
- input.puts "quit"
18
-
19
- end
20
- }}}
21
-
22
- Much more concise, isn't it? One caveat, though: there is no way to kill the process (unless the process can terminate itself, such as through the use of issuing bc's "quit" command as used above) without closing the session. To remedy this, there is also a block version of popen3 that provides an explicit scope for the three data streams:
23
-
24
- {{{lang=ruby,number=true,caption=Transactional form of #process.popen3
25
- Net::SSH.start( 'host' ) do |session|
26
- session.process.popen3( "bc" ) do |input, output, error|
27
- [ "5+5", "7*12", "sqrt(2.000000)" ].each do |formula|
28
- input.puts formula
29
- puts "#{formula}=#{output.read}"
30
- end
31
- end
32
- end
33
- }}}
34
-
35
- The three streams will be closed and process explicitly terminated when the block ends.
@@ -1,7 +0,0 @@
1
- A user's _shell_ is the environment in which commands are executed on a remote machine. There are a variety of different shells, including "bash":http://www.gnu.org/software/bash/bash.html, csh, tcsh, "ksh":http://www.kornshell.com/, and many others.
2
-
3
- A shell may be executed like any other program, and when run, it (more-or-less) enters a read-execute-prompt cycle in which the user may interactively run commands.
4
-
5
- SSH has special support for shells, allowing you to start a shell on a channel and have all subsequent data sent to that channel interpreted as the user's input to the shell. Also, SSH supports pty's (_pseudo-tty_'s, or terminals), which allow the shell to act as if it were running locally on the users own machine.
6
-
7
- Because a shell is just a program, you can always start a shell simply by executing it (as described in the previous chapter). However, you can also take advantage of SSH's builtin shell support to execute the user's preferred shell. This chapter will discuss this approach.
@@ -1,72 +0,0 @@
1
- At the lowest level, starting a shell is a matter of sending a "shell" request over a channel.
2
-
3
- {{{lang=ruby,caption=Sending a shell request,number=true
4
- Net::SSH.start( host ) do |session|
5
-
6
- session.open_channel do |channel|
7
-
8
- channel.on_success do
9
- puts "shell was started successfully!"
10
- channel.send_data "exit\n" # tell the shell to exit
11
- end
12
- channel.on_failure do
13
- puts "shell could not be started!"
14
- end
15
- channel.on_data do |ch,data|
16
- puts "recieved #{data} from shell"
17
- end
18
- channel.on_close do
19
- puts "shell terminated"
20
- end
21
-
22
- channel.send_request "shell", nil, true
23
-
24
- end
25
-
26
- session.loop
27
-
28
- end
29
- }}}
30
-
31
- The @#send_request@ method accepts three parameters--the name of the request (in this case, "shell"), any additional data to send with the request (none, in this case), and whether or not you want the server to reply with the success or failure of the request. In general, it is a good idea to ask for the server to reply, so that you know when you can start sending data to the shell.
32
-
33
- If you want to open a pty before starting the shell, you can use the #request_pty method of the channel:
34
-
35
- {{{lang=ruby,number=true,caption=Opening a pty on a channel
36
- Net::SSH.start( host ) do |session|
37
-
38
- session.open_channel do |channel|
39
-
40
- channel.on_success do
41
- puts "pty was requested successfully!"
42
-
43
- channel.on_success do
44
- puts "shell was started successfully!"
45
- channel.send_data "exit\n" # tell the shell to exit
46
- end
47
-
48
- channel.send_request "shell", nil, true
49
- end
50
-
51
- channel.on_failure do
52
- puts "shell could not be started!"
53
- end
54
- channel.on_data do |ch,data|
55
- puts "recieved #{data} from shell"
56
- end
57
- channel.on_close do
58
- puts "shell terminated"
59
- end
60
-
61
- channel.request_pty :want_reply => true
62
-
63
- end
64
-
65
- session.loop
66
-
67
- end
68
- }}}
69
-
70
- First, the pty is requested (with an indicator to the server that it should return a "success" or "failure" notification). When the pty is successfully opened, the "on_success" callback is changed, and the shell is then requested.
71
-
72
- It's a lot of hoops to jump through, but it gives you the finest-grained control over opening a shell. For most things, though, you can live with less control. For those tasks, there are the _shell_ and _sync_ services.
@@ -1,50 +0,0 @@
1
- To make interacting with shells, simpler, version 0.9 of Net::SSH introduced the _shell service_. This allows you to open a shell (with or without a pty), send a series of commands to the shell, and then wait for the output from the shell.
2
-
3
- {{{lang=ruby,number=true,caption=Using the shell service
4
- Net::SSH.start( 'localhost' ) do |session|
5
-
6
- shell = session.shell.open
7
-
8
- # script what we want to do
9
- shell.pwd
10
- shell.cd "/"
11
- shell.pwd
12
- shell.test "-e foo"
13
- shell.cd "/really/bogus/directory"
14
- shell.send_data "/sbin/ifconfig\n"
15
- shell.pwd
16
- shell.ruby "-v"
17
- shell.cd "/usr/lib"
18
- shell.pwd
19
- shell.exit
20
-
21
- # give the above commands sufficient time to terminate
22
- sleep 0.5
23
-
24
- # display the output
25
- $stdout.print shell.stdout while shell.stdout?
26
- $stderr.puts "-- stderr: --"
27
- $stderr.print shell.stderr while shell.stderr?
28
-
29
- end
30
- }}}
31
-
32
- Any unrecognized method that is sent to the shell object is interpreted as a command to send to the server. To explicitly send a command, use the @#send_data@ method (but remember to add a newline!). The @#send_data@ method may also be used to send data to any process running in the shell as that process' @stdin@ stream.
33
-
34
- You can also specify that a pty should be allocated for this shell:
35
-
36
- {{{lang=ruby,number=true,caption=Allocating a pty for the shell
37
- Net::SSH.start( 'localhost' ) do |session|
38
-
39
- shell = session.shell.open( :pty => true )
40
-
41
- # or
42
-
43
- shell = session.shell.open( :pty => { ... } )
44
-
45
- end
46
- }}}
47
-
48
- If you give a hash for the @:pty@ option, it must be a map of the options that describe the new pty. See the API documentation for the @Channel#request_pty@ method for more information.
49
-
50
- Note that this is still an asynchronous approach. You send all the commands through the pipe and then wait for the output. (And be sure to give sufficient time or the processes to terminate!) This is fine for scripts that you just want to throw at the server, but many times you want a more interactive interface, for executing a command and receiving its output before moving on.
@@ -1,42 +0,0 @@
1
- The SyncShell service allows you to execute commands on the shell and block until they finish. It is not fool-proof--it has to use some tricks to accomplish this task, and some commands may foul it up. But for most tasks, it works admirably.
2
-
3
- {{{lang=ruby,number=true,caption=Using the SyncShell service
4
- Net::SSH.start( 'localhost' ) do |session|
5
-
6
- shell = session.shell.sync
7
-
8
- out = shell.pwd
9
- p out.stdout
10
-
11
- out = shell.test "-e foo"
12
- p out.status
13
-
14
- out = shell.cd "/really/bogus/directory"
15
- p out.stderr
16
- p out.status
17
-
18
- out = shell.ruby "-v"
19
- p out.stdout
20
-
21
- out = shell.cd "/usr/lib"
22
-
23
- out = shell.ls "-l"
24
- p out.stdout
25
-
26
- out = shell.send_command( "bc", <<CMD )
27
- 5+5
28
- 10*2
29
- scale=5
30
- 3/4
31
- quit
32
- CMD
33
- p out.stdout
34
-
35
- p shell.exit
36
-
37
- end
38
- }}}
39
-
40
- The result of executing each command is an object that encapsulates the @stdout@ and @stderr@ streams, and the exit status of the command.
41
-
42
- To explicitly execute a command, use the @#send_command@ instead of @#send_data@--otherwise, the command will be executed asynchronously, which is not what you want. Also, if you pass a second parameter to the @#send_command@ method, it is interpreted as the @stdin@ data to send to the new process.
@@ -1,51 +0,0 @@
1
- Using the shell service and pty's, you can now create a simple SSH terminal client. (You'll also want to download and install the "ruby-termios":http://arika.org/ruby/termios library so that your input is not interpreted in a linewise fashion.)
2
-
3
- {{{lang=ruby,number=true,caption=A simple SSH terminal client in Ruby
4
- begin
5
- require 'termios'
6
- rescue LoadError
7
- end
8
-
9
- def stdin_buffer( enable )
10
- return unless defined?( Termios )
11
- attr = Termios::getattr( $stdin )
12
- if enable
13
- attr.c_lflag |= Termios::ICANON | Termios::ECHO
14
- else
15
- attr.c_lflag &= ~(Termios::ICANON|Termios::ECHO)
16
- end
17
- Termios::setattr( $stdin, Termios::TCSANOW, attr )
18
- end
19
-
20
- host = ARGV.shift or abort "You must specify the [user@]host to connect to"
21
- if host =~ /@/
22
- user, host = host.match( /(.*?)@(.*)/ )[1,2]
23
- else
24
- user = ENV['USER'] || ENV['USER_NAME']
25
- end
26
-
27
- Net::SSH.start( host, user ) do |session|
28
-
29
- begin
30
- stdin_buffer false
31
-
32
- shell = session.shell.open( :pty => true )
33
-
34
- loop do
35
- break unless shell.open?
36
- if IO.select([$stdin],nil,nil,0.01)
37
- data = $stdin.sysread(1)
38
- shell.send_data data
39
- end
40
-
41
- $stdout.print shell.stdout while shell.stdout?
42
- $stdout.flush
43
- end
44
- ensure
45
- stdin_buffer true
46
- end
47
-
48
- end
49
- }}}
50
-
51
- The above code is also available as an example script in the Net::SSH distribution (@examples/ssh-client.rb@).
@@ -1,18 +0,0 @@
1
- Port forwarding is a feature of the SSH protocol that allows you to specify a port on one of the hosts, and have network connections on that port forwarded to a port on a different host, using the SSH connection as a proxy. There are basically two ways to use this forwarding:
2
-
3
- # A port on the local host is forwarded via the remote host to another machine. Any connection to the specified port will cause all subsequent data to be sent over the connection to the remote host, where it will then be forwarded to the requested destination host.
4
- # A port on the remote host is forwarded over the connection to the local host, and from there to (potentially) some other remote destination. Any connection to the specified port on the remote host is forwarded over the connection to the local host, which then makes a connection to the specified remote destination and sends the data there.
5
-
6
- All port forwarding in the Net::SSH library is managed by the @#forward@ service. Just invoke methods on that service to set up any of various port forwarding configurations.
7
-
8
- {{{lang=ruby,number=true,caption=Accessing the #forward service
9
- Net::SSH.start( 'host' ) do |session|
10
- forward = session.forward
11
- ...
12
- session.loop
13
- end
14
- }}}
15
-
16
- You can define any number of forwards before invoking the main loop, in which case all of those forwards will be handled transparently (and silently) in parallel, over the same connection. (Isn't SSH lovely?)
17
-
18
- Naturally, you can also have remote processes, SFTP sessions, and more all working at the same time on the connection.
@@ -1,18 +0,0 @@
1
- Forwarding a local connection to a remote destination is simply a matter of invoking the @#local@ method of the @#forward@ service. The simplest version of the method just takes three parameters: the local port to listen on, and the remote host and port to forward the connection to:
2
-
3
- {{{lang=ruby,number=true,caption=Forwarding a local port
4
- Net::SSH.start( 'host' ) do |session|
5
- session.forward.local( 1234, 'www.google.com', 80 )
6
- session.loop
7
- end
8
- }}}
9
-
10
- In the above example, then, any connection received on port 1234 will be forwarded to port 80 on "www.google.com". This means that if you were to point a browser at "http://localhost:1234", it would pull up "Google":http://www.google.com.
11
-
12
- By default, only connections _from the local host_ are accepted. This is because the default bind address is 127.0.0.1. You can specify any bind address you want (including 0.0.0.0 to allow connections from anywhere) by specifying that address as the first parameter to @#local@, with the local port number immediately following.
13
-
14
- {{{lang=ruby,caption=Specifying the bind address when forwarding a local port
15
- session.forward.local( '0.0.0.0', 1234, 'www.google.com', 80 )
16
- }}}
17
-
18
- In this configuration, anyone from anywhere can connect to your machine on port 1234 and be forwarded to Google.
@@ -1,15 +0,0 @@
1
- Forwarding remote connections to the local host is also straightforward; simply call the @#remote_to@ method of the @#forward@ service. This takes three (or four) parameters: the local port and host to be forwarded to (in that order), and the remote port to listen on. The fourth parameter is optional, and is the bind address on the remote machine; this defaults to "127.0.0.1".
2
-
3
- {{{lang=ruby,number=true,caption=Forwarding a remote port
4
- Net::SSH.start( 'host' ) do |session|
5
- session.forward.remote_to( 80, 'www.google.com', 1234 )
6
- session.loop
7
- end
8
- }}}
9
-
10
- The above example causes any connection on port 1234 of the remote machine (_from_ the remote machine) to be forwarded via the local host to port 80 at www.google.com. To make things a bit more open, you could specify a bind address of 0.0.0.0:
11
-
12
- {{{lang=ruby,caption=Specifying the bind address when forwarding a remote port
13
- session.forward.remote_to( 80, 'www.google.com', 1234, '0.0.0.0' )
14
- }}}
15
-