net-ssh 1.0.10 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/bin/rb-keygen +210 -0
  2. data/doc/manual-html/chapter-1.html +2 -2
  3. data/doc/manual-html/chapter-2.html +13 -2
  4. data/doc/manual-html/chapter-3.html +2 -2
  5. data/doc/manual-html/chapter-4.html +2 -2
  6. data/doc/manual-html/chapter-5.html +2 -2
  7. data/doc/manual-html/chapter-6.html +2 -2
  8. data/doc/manual-html/chapter-7.html +2 -2
  9. data/doc/manual-html/index.html +5 -5
  10. data/doc/manual/manual.yml +3 -3
  11. data/doc/manual/parts/0007.txt +2 -0
  12. data/doc/manual/parts/0008.txt +2 -0
  13. data/examples/auth-forward.rb +41 -0
  14. data/lib/net/ssh/connection/driver.rb +15 -1
  15. data/lib/net/ssh/errors.rb +36 -0
  16. data/lib/net/ssh/host-key-verifier.rb +108 -0
  17. data/lib/net/ssh/lenient-host-key-verifier.rb +25 -0
  18. data/lib/net/ssh/null-host-key-verifier.rb +14 -0
  19. data/lib/net/ssh/service/agentforward/driver.rb +78 -0
  20. data/lib/net/ssh/service/agentforward/services.rb +41 -0
  21. data/lib/net/ssh/service/services.rb +2 -0
  22. data/lib/net/ssh/session.rb +47 -1
  23. data/lib/net/ssh/transport/kex/dh.rb +20 -2
  24. data/lib/net/ssh/transport/kex/services.rb +2 -0
  25. data/lib/net/ssh/transport/session.rb +10 -0
  26. data/lib/net/ssh/userauth/agent.rb +11 -0
  27. data/lib/net/ssh/version.rb +2 -2
  28. data/test/connection/tc_integration.rb +4 -2
  29. data/test/service/agentforward/tc_driver.rb +138 -0
  30. data/test/service/process/tc_integration.rb +2 -0
  31. data/test/tc_integration.rb +4 -3
  32. data/test/transport/kex/tc_dh.rb +6 -0
  33. data/test/transport/kex/tc_dh_gex.rb +1 -0
  34. data/test/transport/tc_integration.rb +6 -1
  35. data/test/userauth/tc_integration.rb +2 -0
  36. metadata +70 -60
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env ruby
2
+ # =======================================================================
3
+ # Net::SSH -- A Ruby module implementing the SSH2 client protocol
4
+ # Copyright (C) 2004-2007 Jamis Buck (jamis@37signals.com)
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ # =======================================================================
20
+
21
+ require 'base64'
22
+ require 'optparse'
23
+ require 'net/ssh'
24
+ require 'net/ssh/util/openssl'
25
+ require 'net/ssh/util/buffer'
26
+
27
+ begin
28
+ require 'password'
29
+ $use_password = true
30
+ rescue LoadError
31
+ $use_password = false
32
+ end
33
+
34
+ # This class represents the "keygen" application for the Net::SSH suite.
35
+ # It implements a subset of the functionality of ssh-keygen, and tries to
36
+ # be reasonably commandline-compatible.
37
+ class KeyGenerator
38
+
39
+ # Create a new KeyGenerator. By default the script's commandline will be
40
+ # used to initialize the generator, but you can specify a different array
41
+ # of options manually.
42
+ #
43
+ # If there is an error parsing the arguments, the application will halt
44
+ # after displaying the error and a description of available options.
45
+ def initialize( args=ARGV )
46
+ begin
47
+ parse_args( args )
48
+ rescue OptionParser::ParseError => e
49
+ puts "Error: #{e.message}"
50
+ puts @parser
51
+ exit
52
+ end
53
+ end
54
+
55
+ # The driver for the application. Currently, it just calls +generate_key+,
56
+ # but eventually other functionality may be added. This method would do
57
+ # the logic to determine which methods should be invoked.
58
+ def run
59
+ generate_key
60
+ end
61
+
62
+ KEYS = {
63
+ "rsa" => OpenSSL::PKey::RSA,
64
+ "dsa" => OpenSSL::PKey::DSA
65
+ }
66
+
67
+ # Generate and export public and private key files according to the settings
68
+ # given by the options array when the object was instantiated. For values that
69
+ # may not have been specified (like filename, and passphrase), the user will
70
+ # be prompted. If the 'ruby-password' module is installed, it will be used for
71
+ # prompting for the passphrase, otherwise a simple +gets+ will be used.
72
+ def generate_key
73
+ key_class = KEYS[ @options[:type] ] or
74
+ raise NotImplementedError, "unsupported key type `#{@options[:type]}'"
75
+
76
+ if_chatty "generating key..."
77
+ key = key_class.new( @options[ :bits ] )
78
+
79
+ unless ( filename = @options[ :filename ] )
80
+ default = "#{ENV['HOME']}/.ssh/id_#{@options[:type]}"
81
+ print "Enter file in which to save the key (#{default}): "
82
+ answer = gets.strip
83
+ filename = ( answer.length == 0 ? default : answer )
84
+ end
85
+
86
+ unless ( passphrase = @options[ :new_passphrase ] )
87
+ loop do
88
+ passphrase = get_password "Enter passphrase (empty for no passphrase): "
89
+ verify_phrase = get_password "Enter same passphrase again: "
90
+ break if passphrase == verify_phrase
91
+ end
92
+
93
+ passphrase = nil if passphrase.length == 0
94
+ end
95
+
96
+ if passphrase
97
+ private_pem = key.export( OpenSSL::Cipher::Cipher.new( "des-ede3-cbc" ), passphrase )
98
+ else
99
+ private_pem = key.export
100
+ end
101
+
102
+ public_pem = export_ssh_pubkey( key )
103
+
104
+ File.open( filename, "w" ) { |file| file.write private_pem }
105
+ File.open( filename + ".pub", "w" ) { |file| file.write public_pem }
106
+
107
+ if_chatty "done!"
108
+ end
109
+ private :generate_key
110
+
111
+ # Returns a string representing the SSH-formatted public key, suitable for inserting
112
+ # into (for instance) the authorized_keys file.
113
+ def export_ssh_pubkey( key )
114
+ s = key.ssh_type + " "
115
+
116
+ writer = Net::SSH::Util::WriterBuffer.new
117
+ writer.write_key key
118
+ s << Base64.encode64( writer.to_s ).strip.gsub( /[\n\r\t ]/, "" )
119
+ s << " #{ENV['USER']}@#{ENV['HOSTNAME']}"
120
+
121
+ s
122
+ end
123
+ private :export_ssh_pubkey
124
+
125
+ # A utility method for getting a password. If the 'ruby-password' module is available,
126
+ # it will be used, otherwise a +print+/+gets+ combination will be used. The entered
127
+ # password will be returned.
128
+ def get_password( prompt )
129
+ if $use_password
130
+ return Password.get( prompt )
131
+ else
132
+ print prompt
133
+ return gets.chomp
134
+ end
135
+ end
136
+ private :get_password
137
+
138
+ # Parse the given arguments as if they were commandline arguments.
139
+ def parse_args( args )
140
+ @options = {
141
+ :bits => 1024
142
+ }
143
+
144
+ @parser = OptionParser.new do |parser|
145
+ parser.banner = "Usage: rb-keygen [options]"
146
+
147
+ parser.separator ""
148
+ parser.separator "Options:"
149
+
150
+ parser.on( "-b", "--bits BITS",
151
+ "Number of bits in the key to create." ) do |bits|
152
+ @options[ :bits ] = bits.to_i
153
+ end
154
+
155
+ parser.on( "-f", "--filename FILENAME",
156
+ "Filename of the keyfile." ) do |filename|
157
+ @options[ :filename ] = filename
158
+ end
159
+
160
+ parser.on( "-q", "--quiet", "Suppress normal output." ) do
161
+ @options[ :quiet ] = true
162
+ end
163
+
164
+ parser.on( "-t", "--type TYPE",
165
+ "Specify the TYPE of key to create (`rsa' or `dsa')" ) do |type|
166
+ unless [ "rsa", "dsa" ].include? type
167
+ raise OptionParser::ParseError, "`#{type}' is not a valid key type, must be `rsa' or `dsa'"
168
+ end
169
+ @options[ :type ] = type
170
+ end
171
+
172
+ parser.on( "-N", "--new-passphrase PHRASE",
173
+ "Provide new passphrase" ) do |phrase|
174
+ @options[ :new_passphrase ] = phrase
175
+ end
176
+
177
+ parser.separator ""
178
+ parser.separator "Other options:"
179
+
180
+ parser.on_tail( "-h", "--help", "Show this message" ) do
181
+ puts parser
182
+ exit
183
+ end
184
+ end
185
+
186
+ @parser.parse! args
187
+
188
+ unless @options[ :type ]
189
+ raise OptionParser::ParseError, "You must specify a key type (-t)"
190
+ end
191
+
192
+ unless [ "rsa", "dsa" ].include? @options[ :type ]
193
+ raise OptionParser::ParseError, "You must specify a key type (-t)"
194
+ end
195
+ end
196
+ private :parse_args
197
+
198
+ # Used for logging optional messages. If the application was told to be
199
+ # quiet (with the -q option), this method does nothing; otherwise, it
200
+ # prints the messages to +stderr+.
201
+ def if_chatty( *args )
202
+ unless @options[ :quiet ]
203
+ $stderr.puts *args
204
+ end
205
+ end
206
+ private :if_chatty
207
+
208
+ end
209
+
210
+ KeyGenerator.new.run
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -378,6 +378,9 @@
378
378
 
379
379
 
380
380
  <p>A future version of Net::SSH may include it&#8217;s own agent implementation as well, to make using an agent on a variety of platforms simpler.</p>
381
+
382
+
383
+ <p>Agent forwarding is available, and may be requested with the :forward_agent option to Net::SSH.start. Agents are not forwarded by default.</p>
381
384
  </div>
382
385
 
383
386
 
@@ -428,6 +431,10 @@
428
431
  <td style="vertical-align:top;text-align:center;"><code>:encryption</code> </td>
429
432
  <td> This is the cipher algorithm to use when sending/receiving data to/from the remote server. It defaults to <code>3des-cbc</code>. Other valid algorithms supported by Net::SSH are <code>aes128-cbc</code>, <code>blowfish-cbc</code>, <code>aes256-cbc</code>, <code>aes192-cbc</code>, <code>idea-cbc</code>, and <code>none</code>. Note that the values you specify here are only <em>suggestions</em>, and if the server you are contacting cannot use your recommended algorithm, a fallback algorithm will be used (typically chosen in the order the algorithms were listed, above). This option may take an array, if you want to specify the order of the fallback algorithms to try, as well. </td>
430
433
  </tr>
434
+ <tr>
435
+ <td style="vertical-align:top;text-align:center;"><code>:forward_agent</code> </td>
436
+ <td> Set to a true value to request that the local authentication agent be forwarded to the remote host. By default the agent will not be forwarded. </td>
437
+ </tr>
431
438
  <tr>
432
439
  <td style="vertical-align:top;text-align:center;"><code>:hmac</code> </td>
433
440
  <td> This specifies the &#8220;message authentication code&#8221; (MAC) algorithm to use to ensure that each packet transmitted and recieved is authentic. This defaults to <code>hmac-md5</code>. Other valid algorithms supported by Net::SSH are <code>hmac-sha1</code>, <code>hmac-md5-96</code>, <code>hmac-md5-sha1</code>, and <code>none</code>. Note that the values you specify here are only <em>suggestions</em>, and if the server you are contacting cannot use your recommended algorithm, a fallback algorithm will be used (typically chosen in the order the algorithms were listed, above). This option may take an array, if you want to specify the order of the fallback algorithms to try, as well. </td>
@@ -456,6 +463,10 @@
456
463
  <td style="vertical-align:top;text-align:center;"><code>:log</code> </td>
457
464
  <td> Specifies either a string or an IO object. If it is a string, it names the file that all log messages should be written to. Otherwise, the messages will be written to the IO object directly. Defaults to <span class="caps">STDERR</span>.</td>
458
465
  </tr>
466
+ <tr>
467
+ <td style="vertical-align:top;text-align:center;"><code>:paranoid</code> </td>
468
+ <td> Controls how Net::SSH responds to a server key that it does not recognize. The default, <code>true</code>, will result in all keys being accepted the first time they are seen for a particular host, and then an exception being raised if the key ever changes. However, no host key verification will be done if the connection appears to be tunneled over a locally forwarded port. If set to <code>false</code>, no server key verification is done. You can also set this to <code>:very</code>, in which case errors are raised even if the connection appears to be tunneled.</td>
469
+ </tr>
459
470
  <tr>
460
471
  <td style="vertical-align:top;text-align:center;"><code>:port</code> </td>
461
472
  <td> This is the port number that should be used to connect to the remote machine. If you wish to specify the port, you are generally better off specifying it as the second parameter to <code>start</code>, rather than as an option, but you <em>can</em> specify it this way, if you prefer.</td>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
16
  <div class="info">
17
- Net::SSH Version: <strong>1.0.10</strong><br />
18
- Manual Last Updated: <strong>2006-09-09 23:59 UTC</strong>
17
+ Net::SSH Version: <strong>1.1.0</strong><br />
18
+ Manual Last Updated: <strong>2007-05-01 04:05 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -212,16 +212,16 @@
212
212
  <table border='0' cellpadding='0' cellspacing='0' align='center'><tr><td>
213
213
  <ul>
214
214
 
215
- <li>Removed documentation indicating that ruby-password will be used if present (it won't)</li>
215
+ <li>Added information on ssh-agent forwarding.</li>
216
216
 
217
- <li>Removed links to the wiki (which wasn't being used) and the faq (which never existed)</li>
217
+ <li>Added information about the :paranoid setting.</li>
218
218
 
219
219
  </ul>
220
220
  </table>
221
221
 
222
222
 
223
223
  <p class="copyright">
224
- Copyright &copy; 2004-2006
224
+ Copyright &copy; 2004-2007
225
225
  Jamis Buck
226
226
  (<a href="mailto:jamis@jamisbuck.org">jamis@jamisbuck.org</a>)
227
227
  </p>
@@ -6,7 +6,7 @@
6
6
  # http://creativecommons.org/licenses/by-sa/2.0/
7
7
 
8
8
  meta: !^meta
9
- copyright: 2004-2006
9
+ copyright: 2004-2007
10
10
  author: Jamis Buck
11
11
  email: jamis@jamisbuck.org
12
12
 
@@ -21,8 +21,8 @@ product: !^product
21
21
  - API Documentation: http://net-ssh.rubyforge.org/api
22
22
 
23
23
  recent_updates:
24
- - "Removed documentation indicating that ruby-password will be used if present (it won't)"
25
- - "Removed links to the wiki (which wasn't being used) and the faq (which never existed)"
24
+ - "Added information on ssh-agent forwarding."
25
+ - "Added information about the :paranoid setting."
26
26
 
27
27
  chapters:
28
28
 
@@ -63,3 +63,5 @@ On Unixish systems, you allow your Net::SSH programs to interface with a running
63
63
  On Windows, the pageant process will be detected automatically, if it is running.
64
64
 
65
65
  A future version of Net::SSH may include it's own agent implementation as well, to make using an agent on a variety of platforms simpler.
66
+
67
+ Agent forwarding is available, and may be requested with the :forward_agent option to Net::SSH.start. Agents are not forwarded by default.
@@ -12,6 +12,7 @@ table(list).
12
12
  |^=. @:container@ | This is the dependency injection container to use when registering all of the services that Net::SSH uses internally. If unspecified (the default) a new container will be created. This option allows you to reuse a single container for multiple application components.|
13
13
  |^=. @:crypto_backend@ | This is the cryptography backend to use. It defaults to @:ossl@, which specifies the OpenSSL cryptography engine. Currently, this is the only supported backend, but in the future others may be provided, and this is how they would be selected.|
14
14
  |^=. @:encryption@ | This is the cipher algorithm to use when sending/receiving data to/from the remote server. It defaults to @3des-cbc@. Other valid algorithms supported by Net::SSH are @aes128-cbc@, @blowfish-cbc@, @aes256-cbc@, @aes192-cbc@, @idea-cbc@, and @none@. Note that the values you specify here are only _suggestions_, and if the server you are contacting cannot use your recommended algorithm, a fallback algorithm will be used (typically chosen in the order the algorithms were listed, above). This option may take an array, if you want to specify the order of the fallback algorithms to try, as well. |
15
+ |^=. @:forward_agent@ | Set to a true value to request that the local authentication agent be forwarded to the remote host. By default the agent will not be forwarded. |
15
16
  |^=. @:hmac@ | This specifies the "message authentication code" (MAC) algorithm to use to ensure that each packet transmitted and recieved is authentic. This defaults to @hmac-md5@. Other valid algorithms supported by Net::SSH are @hmac-sha1@, @hmac-md5-96@, @hmac-md5-sha1@, and @none@. Note that the values you specify here are only _suggestions_, and if the server you are contacting cannot use your recommended algorithm, a fallback algorithm will be used (typically chosen in the order the algorithms were listed, above). This option may take an array, if you want to specify the order of the fallback algorithms to try, as well. |
16
17
  |^=. @:host_key@ | This specifies the host key type that should be used when negotiating keys with the server. This defaults to @ssh-dss@, but may also be @ssh-rsa@. As with some other option types, the value you specify is only a recommendation, not a commandment, and if the server cannot honor the key type you specified, a fallback will be chosen from among the other supported types. If you wish to specify the fallback algorithms to try, you may pass an array as the value of this option, which contains (in order) the key types to try. |
17
18
  |^=. @:host_keys@ | This is an array of file names that contain the private keys which identify the host your script is running on. These default to @/etc/ssh/ssh_host_dsa_key@ and @/etc/ssh/ssh_host_rsa_key@ (which are both typically only readable by root). These keys are only used in hostbased authentication.|
@@ -19,6 +20,7 @@ table(list).
19
20
  |^=. @:keys@ | This specifies the list of private key files to use _instead_ of the defaults (@$HOME/.ssh/id_dsa@, @$HOME/.ssh2/id_dsa@, @$HOME/.ssh/id_rsa@, and @$HOME/.ssh2/id_rsa@). The value of this option should be an array of strings.|
20
21
  |^=. @:languages@ | This option specifies the preferred language (or languages) that should be used when communicating error messages. It has no effect on Net::SSH, but may cause the server (if it supports your suggested language) to send errors in the language you request. The default is empty.|
21
22
  |^=. @:log@ | Specifies either a string or an IO object. If it is a string, it names the file that all log messages should be written to. Otherwise, the messages will be written to the IO object directly. Defaults to STDERR.|
23
+ |^=. @:paranoid@ | Controls how Net::SSH responds to a server key that it does not recognize. The default, @true@, will result in all keys being accepted the first time they are seen for a particular host, and then an exception being raised if the key ever changes. However, no host key verification will be done if the connection appears to be tunneled over a locally forwarded port. If set to @false@, no server key verification is done. You can also set this to @:very@, in which case errors are raised even if the connection appears to be tunneled.|
22
24
  |^=. @:port@ | This is the port number that should be used to connect to the remote machine. If you wish to specify the port, you are generally better off specifying it as the second parameter to @start@, rather than as an option, but you _can_ specify it this way, if you prefer.|
23
25
  |^=. @:registry_options@ | If the @:container@ option is not specified, a new container will be created. This option specifies a hash of additional options that may be used to configure the new container (registry). By default, it is empty.|
24
26
  |^=. @:verbose@ | Specifies how verbose the logging should be. Valid values are @:fatal@, @:error@, @:warn@, @:info@, and @:debug@. Defaults to @:warn@. WARNING: selecting @:debug@ will result in LOTS of output! (Further customization of verbosity can be accomplished by specifying which Net::SSH components should have which logging levels, via the @:registry_options@ option.)|
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+
3
+ $:.unshift "../lib"
4
+ require 'net/ssh'
5
+
6
+
7
+
8
+ Net::SSH.start( 'localhost', { :verbose => :debug, :forward_agent => true } ) do |session|
9
+ #Net::SSH.start( 'localhost' ) do |session|
10
+
11
+ def exec( command )
12
+ lambda do |channel|
13
+ channel.exec command
14
+ channel.on_data do |ch,data|
15
+ ch[:data] ||= ""
16
+ ch[:data] << data
17
+ end
18
+ channel.on_extended_data do |ch,type,data|
19
+ ch[:extended_data] ||= []
20
+ ch[:extended_data][type] ||= ""
21
+ ch[:extended_data][type] << data
22
+ end
23
+ end
24
+ end
25
+
26
+ c = session.open_channel( &exec( "ssh -A munkyii.nodnol.org ssh-add -l" ) )
27
+
28
+ session.loop
29
+
30
+ puts "----------------------------------"
31
+ if c.valid?
32
+ puts c[:data]
33
+ if c[:extended_data] && c[:extended_data][1]
34
+ puts "-- stderr: --"
35
+ puts c[:extended_data][1]
36
+ end
37
+ else
38
+ puts "channel was not opened: #{c.reason} (#{c.reason_code})"
39
+ end
40
+
41
+ end
@@ -134,7 +134,10 @@ module Net
134
134
  # +true+. If no block is given, then the loop continues until there
135
135
  # are no more open channels on this connection.
136
136
  def loop( &block )
137
- block ||= proc { not @channel_map.empty? }
137
+ block ||= proc do
138
+ channels = @channel_map.reject {|k,v| v.type == 'auth-agent@openssh.com' }
139
+ not channels.empty?
140
+ end
138
141
  process while block.call
139
142
  end
140
143
 
@@ -178,6 +181,17 @@ module Net
178
181
  self
179
182
  end
180
183
 
184
+ # Send a channel request packet to the server.
185
+ def channel_request( type )
186
+ writer = @buffers.writer
187
+ writer.write_byte CHANNEL_REQUEST
188
+ writer.write_long 0 # channel id
189
+ writer.write_string type
190
+ writer.write_byte 0 # want_confirm
191
+
192
+ @session.send_message writer
193
+ end
194
+
181
195
  # A convenience method for sending messages.
182
196
  def send_message( msg )
183
197
  @session.send_message msg