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.
- data/doc/LICENSE-BSD +27 -0
- data/doc/LICENSE-GPL +280 -0
- data/doc/LICENSE-RUBY +56 -0
- data/doc/README +13 -0
- data/doc/manual-html/chapter-1.html +333 -0
- data/doc/manual-html/chapter-2.html +455 -0
- data/doc/manual-html/chapter-3.html +413 -0
- data/doc/manual-html/chapter-4.html +353 -0
- data/doc/manual-html/chapter-5.html +393 -0
- data/doc/manual-html/chapter-6.html +296 -0
- data/doc/manual-html/index.html +217 -0
- data/doc/manual-html/manual.css +192 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/example.erb +18 -0
- data/doc/manual/index.erb +29 -0
- data/doc/manual/manual.css +192 -0
- data/doc/manual/manual.rb +240 -0
- data/doc/manual/manual.yml +67 -0
- data/doc/manual/page.erb +87 -0
- data/doc/manual/parts/channels_callbacks.txt +32 -0
- data/doc/manual/parts/channels_loop.txt +14 -0
- data/doc/manual/parts/channels_open.txt +20 -0
- data/doc/manual/parts/channels_operations.txt +15 -0
- data/doc/manual/parts/channels_types.txt +3 -0
- data/doc/manual/parts/channels_what_are.txt +7 -0
- data/doc/manual/parts/exec_channels.txt +28 -0
- data/doc/manual/parts/exec_open.txt +51 -0
- data/doc/manual/parts/exec_popen3.txt +35 -0
- data/doc/manual/parts/forward_direct.txt +37 -0
- data/doc/manual/parts/forward_handlers.txt +16 -0
- data/doc/manual/parts/forward_intro.txt +18 -0
- data/doc/manual/parts/forward_local.txt +18 -0
- data/doc/manual/parts/forward_remote.txt +14 -0
- data/doc/manual/parts/intro_author.txt +1 -0
- data/doc/manual/parts/intro_getting.txt +39 -0
- data/doc/manual/parts/intro_license.txt +6 -0
- data/doc/manual/parts/intro_support.txt +7 -0
- data/doc/manual/parts/intro_what_is.txt +7 -0
- data/doc/manual/parts/intro_what_is_not.txt +3 -0
- data/doc/manual/parts/proxy_http.txt +52 -0
- data/doc/manual/parts/proxy_intro.txt +1 -0
- data/doc/manual/parts/proxy_socks.txt +23 -0
- data/doc/manual/parts/session_key.txt +66 -0
- data/doc/manual/parts/session_options.txt +42 -0
- data/doc/manual/parts/session_session.txt +14 -0
- data/doc/manual/parts/session_start.txt +49 -0
- data/doc/manual/tutorial.erb +30 -0
- data/examples/channel-demo.rb +81 -0
- data/examples/port-forward.rb +51 -0
- data/examples/process-demo.rb +91 -0
- data/examples/remote-net-port-forward.rb +45 -0
- data/examples/remote-port-forward.rb +80 -0
- data/examples/tail-demo.rb +49 -0
- data/lib/net/ssh.rb +52 -0
- data/lib/net/ssh/connection/channel.rb +411 -0
- data/lib/net/ssh/connection/constants.rb +47 -0
- data/lib/net/ssh/connection/driver.rb +343 -0
- data/lib/net/ssh/connection/services.rb +72 -0
- data/lib/net/ssh/connection/term.rb +90 -0
- data/lib/net/ssh/errors.rb +27 -0
- data/lib/net/ssh/proxy/errors.rb +34 -0
- data/lib/net/ssh/proxy/http.rb +126 -0
- data/lib/net/ssh/proxy/socks4.rb +83 -0
- data/lib/net/ssh/proxy/socks5.rb +160 -0
- data/lib/net/ssh/service/forward/driver.rb +319 -0
- data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
- data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
- data/lib/net/ssh/service/forward/services.rb +76 -0
- data/lib/net/ssh/service/process/driver.rb +153 -0
- data/lib/net/ssh/service/process/open.rb +193 -0
- data/lib/net/ssh/service/process/popen3.rb +160 -0
- data/lib/net/ssh/service/process/services.rb +66 -0
- data/lib/net/ssh/service/services.rb +44 -0
- data/lib/net/ssh/session.rb +242 -0
- data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
- data/lib/net/ssh/transport/compress/compressor.rb +53 -0
- data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
- data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
- data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
- data/lib/net/ssh/transport/compress/services.rb +68 -0
- data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
- data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
- data/lib/net/ssh/transport/constants.rb +66 -0
- data/lib/net/ssh/transport/errors.rb +47 -0
- data/lib/net/ssh/transport/identity-cipher.rb +61 -0
- data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
- data/lib/net/ssh/transport/kex/dh.rb +231 -0
- data/lib/net/ssh/transport/kex/services.rb +60 -0
- data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
- data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
- data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
- data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
- data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
- data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
- data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
- data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
- data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
- data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
- data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
- data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
- data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
- data/lib/net/ssh/transport/ossl/services.rb +149 -0
- data/lib/net/ssh/transport/packet-stream.rb +210 -0
- data/lib/net/ssh/transport/services.rb +146 -0
- data/lib/net/ssh/transport/session.rb +296 -0
- data/lib/net/ssh/transport/version-negotiator.rb +73 -0
- data/lib/net/ssh/userauth/agent.rb +218 -0
- data/lib/net/ssh/userauth/constants.rb +35 -0
- data/lib/net/ssh/userauth/driver.rb +176 -0
- data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
- data/lib/net/ssh/userauth/methods/password.rb +70 -0
- data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
- data/lib/net/ssh/userauth/methods/services.rb +63 -0
- data/lib/net/ssh/userauth/services.rb +126 -0
- data/lib/net/ssh/userauth/userkeys.rb +258 -0
- data/lib/net/ssh/util/buffer.rb +274 -0
- data/lib/net/ssh/util/openssl.rb +146 -0
- data/lib/net/ssh/util/prompter.rb +73 -0
- data/lib/net/ssh/version.rb +29 -0
- data/test/ALL-TESTS.rb +21 -0
- data/test/connection/tc_channel.rb +136 -0
- data/test/connection/tc_driver.rb +287 -0
- data/test/connection/tc_integration.rb +85 -0
- data/test/proxy/tc_http.rb +209 -0
- data/test/proxy/tc_socks4.rb +148 -0
- data/test/proxy/tc_socks5.rb +214 -0
- data/test/service/forward/tc_driver.rb +289 -0
- data/test/service/forward/tc_local_network_handler.rb +123 -0
- data/test/service/forward/tc_remote_network_handler.rb +108 -0
- data/test/service/process/tc_driver.rb +79 -0
- data/test/service/process/tc_integration.rb +117 -0
- data/test/service/process/tc_open.rb +179 -0
- data/test/service/process/tc_popen3.rb +164 -0
- data/test/tc_integration.rb +79 -0
- data/test/transport/compress/tc_none_compress.rb +41 -0
- data/test/transport/compress/tc_none_decompress.rb +45 -0
- data/test/transport/compress/tc_zlib_compress.rb +61 -0
- data/test/transport/compress/tc_zlib_decompress.rb +48 -0
- data/test/transport/kex/tc_dh.rb +304 -0
- data/test/transport/kex/tc_dh_gex.rb +70 -0
- data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
- data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
- data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
- data/test/transport/ossl/fixtures/not-a-private-key +4 -0
- data/test/transport/ossl/fixtures/not-supported +2 -0
- data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
- data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
- data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
- data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
- data/test/transport/ossl/hmac/tc_md5.rb +50 -0
- data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
- data/test/transport/ossl/hmac/tc_none.rb +50 -0
- data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
- data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
- data/test/transport/ossl/tc_buffer.rb +97 -0
- data/test/transport/ossl/tc_buffer_factory.rb +67 -0
- data/test/transport/ossl/tc_cipher_factory.rb +84 -0
- data/test/transport/ossl/tc_digest_factory.rb +39 -0
- data/test/transport/ossl/tc_hmac_factory.rb +72 -0
- data/test/transport/ossl/tc_key_factory.rb +199 -0
- data/test/transport/tc_algorithm_negotiator.rb +169 -0
- data/test/transport/tc_identity_cipher.rb +52 -0
- data/test/transport/tc_integration.rb +110 -0
- data/test/transport/tc_packet_stream.rb +183 -0
- data/test/transport/tc_session.rb +283 -0
- data/test/transport/tc_version_negotiator.rb +86 -0
- data/test/userauth/methods/tc_hostbased.rb +136 -0
- data/test/userauth/methods/tc_password.rb +89 -0
- data/test/userauth/methods/tc_publickey.rb +167 -0
- data/test/userauth/tc_agent.rb +223 -0
- data/test/userauth/tc_driver.rb +190 -0
- data/test/userauth/tc_integration.rb +81 -0
- data/test/userauth/tc_userkeys.rb +265 -0
- data/test/util/tc_buffer.rb +217 -0
- metadata +256 -0
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
module Connection
|
|
20
|
+
|
|
21
|
+
module Constants
|
|
22
|
+
|
|
23
|
+
# Connection protocol generic messages
|
|
24
|
+
|
|
25
|
+
GLOBAL_REQUEST = 80
|
|
26
|
+
REQUEST_SUCCESS = 81
|
|
27
|
+
REQUEST_FAILURE = 82
|
|
28
|
+
|
|
29
|
+
# Channel related messages
|
|
30
|
+
|
|
31
|
+
CHANNEL_OPEN = 90
|
|
32
|
+
CHANNEL_OPEN_CONFIRMATION = 91
|
|
33
|
+
CHANNEL_OPEN_FAILURE = 92
|
|
34
|
+
CHANNEL_WINDOW_ADJUST = 93
|
|
35
|
+
CHANNEL_DATA = 94
|
|
36
|
+
CHANNEL_EXTENDED_DATA = 95
|
|
37
|
+
CHANNEL_EOF = 96
|
|
38
|
+
CHANNEL_CLOSE = 97
|
|
39
|
+
CHANNEL_REQUEST = 98
|
|
40
|
+
CHANNEL_SUCCESS = 99
|
|
41
|
+
CHANNEL_FAILURE = 100
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,343 @@
|
|
|
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 'thread'
|
|
18
|
+
require 'net/ssh/connection/constants'
|
|
19
|
+
require 'net/ssh/errors'
|
|
20
|
+
|
|
21
|
+
module Net
|
|
22
|
+
module SSH
|
|
23
|
+
module Connection
|
|
24
|
+
|
|
25
|
+
class Driver
|
|
26
|
+
include Constants
|
|
27
|
+
|
|
28
|
+
# A structure for representing global requests, as registered by the
|
|
29
|
+
# #global_request method.
|
|
30
|
+
Request = Struct.new( :type, :data, :callback )
|
|
31
|
+
|
|
32
|
+
#--
|
|
33
|
+
# ====================================================================
|
|
34
|
+
# CONSTRUCTOR
|
|
35
|
+
# ====================================================================
|
|
36
|
+
#++
|
|
37
|
+
|
|
38
|
+
# Create a new connection driver that communicates over the given
|
|
39
|
+
# transport session. +log+ is the logger instance to write log messages
|
|
40
|
+
# to, buffers is a buffer factory, and channels is a factory that can
|
|
41
|
+
# return new channel instances.
|
|
42
|
+
def initialize( session, log, buffers, factories )
|
|
43
|
+
@session = session
|
|
44
|
+
@log = log
|
|
45
|
+
@buffers = buffers
|
|
46
|
+
@factories = factories
|
|
47
|
+
|
|
48
|
+
@channel_id_mutex = Mutex.new
|
|
49
|
+
@next_channel_id = 0
|
|
50
|
+
|
|
51
|
+
@channel_map = Hash.new
|
|
52
|
+
@request_queue = Array.new
|
|
53
|
+
@channel_open_handlers = Hash.new
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#--
|
|
57
|
+
# ====================================================================
|
|
58
|
+
# CHANNEL MANAGEMENT
|
|
59
|
+
# ====================================================================
|
|
60
|
+
#++
|
|
61
|
+
|
|
62
|
+
# Open and return a new channel. This returns immediately, before the
|
|
63
|
+
# server confirms that the channel was opened. When the server sends
|
|
64
|
+
# the confirmation, the +on_confirm+ callback will be invoked.
|
|
65
|
+
def open_channel( type, extra_data=nil, &on_confirm )
|
|
66
|
+
channel = @factories[:open].call( type, extra_data )
|
|
67
|
+
channel.on_confirm_open &on_confirm
|
|
68
|
+
@channel_map[ channel.local_id ] = channel
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Remove the given channel from the connection.
|
|
72
|
+
def remove_channel( channel )
|
|
73
|
+
@channel_map.delete channel.local_id
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Returns an array of active channels.
|
|
77
|
+
def channels
|
|
78
|
+
@channel_map.values
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Add a callback to be invoked when a channel-open request is recieved
|
|
82
|
+
# for a channel of the given type. The handler-id is returned.
|
|
83
|
+
def add_channel_open_handler( type, &block )
|
|
84
|
+
( @channel_open_handlers[ type ] ||= Array.new ).push block
|
|
85
|
+
@channel_open_handlers.length
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Remove a callback with the given id for channel-open requests of the
|
|
89
|
+
# given type.
|
|
90
|
+
def remove_channel_open_handler( type, id )
|
|
91
|
+
@channel_open_handlers[ type ][ id-1 ] = nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Return the next available channel id for this connection. This
|
|
95
|
+
# method is thread-safe.
|
|
96
|
+
def allocate_channel_id
|
|
97
|
+
@channel_id_mutex.synchronize do
|
|
98
|
+
@next_channel_id += 1
|
|
99
|
+
return @next_channel_id
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
#--
|
|
104
|
+
# ====================================================================
|
|
105
|
+
# CONNECTION PROCESSING
|
|
106
|
+
# ====================================================================
|
|
107
|
+
#++
|
|
108
|
+
|
|
109
|
+
# Repeated call #process for as long as the given block returns
|
|
110
|
+
# +true+. If no block is given, then the loop continues until there
|
|
111
|
+
# are no more open channels on this connection.
|
|
112
|
+
def loop( &block )
|
|
113
|
+
block ||= proc { not @channel_map.empty? }
|
|
114
|
+
process while block.call
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Wait for and dispatch a single event.
|
|
118
|
+
def process
|
|
119
|
+
type, response = @session.wait_for_message
|
|
120
|
+
|
|
121
|
+
unless ( dispatcher = MESSAGES[ type ] )
|
|
122
|
+
raise Net::SSH::Exception,
|
|
123
|
+
"Unexpected response type '#{type}', (#{response.inspect})"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
dispatcher[:method].bind( self ).call( response )
|
|
127
|
+
self
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
#--
|
|
131
|
+
# ====================================================================
|
|
132
|
+
# COMMUNICATION
|
|
133
|
+
# ====================================================================
|
|
134
|
+
#++
|
|
135
|
+
|
|
136
|
+
# Send a global request packet to the server. This returns immediately.
|
|
137
|
+
# The given block will be invoked when the server responds.
|
|
138
|
+
def global_request( type, data=nil, &block )
|
|
139
|
+
writer = @buffers.writer
|
|
140
|
+
writer.write_byte GLOBAL_REQUEST
|
|
141
|
+
writer.write_string type.to_s
|
|
142
|
+
writer.write_bool true
|
|
143
|
+
writer.write data.to_s if data
|
|
144
|
+
@session.send_message writer
|
|
145
|
+
|
|
146
|
+
@request_queue.push Request.new( type, data, block )
|
|
147
|
+
self
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# A convenience method for sending messages.
|
|
151
|
+
def send_message( msg )
|
|
152
|
+
@session.send_message msg
|
|
153
|
+
self
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
#--
|
|
157
|
+
# ====================================================================
|
|
158
|
+
# MESSAGE HANDLERS
|
|
159
|
+
# ====================================================================
|
|
160
|
+
#++
|
|
161
|
+
|
|
162
|
+
def do_request_success( response )
|
|
163
|
+
@log.debug "REQUEST_SUCCESS received" if @log.debug?
|
|
164
|
+
process_request response, true
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def do_request_failure( response )
|
|
168
|
+
@log.debug "REQUEST_FAILURE received" if @log.debug?
|
|
169
|
+
process_request response, false
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def do_channel_open( response )
|
|
173
|
+
ch_type = response.read_string
|
|
174
|
+
@log.debug "CHANNEL_OPEN recieved (#{ch_type})" if @log.debug?
|
|
175
|
+
handled = false
|
|
176
|
+
|
|
177
|
+
sender_channel = response.read_long
|
|
178
|
+
window_size = response.read_long
|
|
179
|
+
packet_size = response.read_long
|
|
180
|
+
|
|
181
|
+
channel = @factories[:create].call( ch_type, sender_channel,
|
|
182
|
+
window_size, packet_size )
|
|
183
|
+
|
|
184
|
+
( @channel_open_handlers[ ch_type ] || [] ).each do |handler|
|
|
185
|
+
next unless handler
|
|
186
|
+
handled = true
|
|
187
|
+
handler.call( self, channel, response )
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
unless handled
|
|
191
|
+
raise Net::SSH::Exception,
|
|
192
|
+
"cannot handle request to open a channel of type '#{ch_type}'"
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
@channel_map[channel.local_id] = channel
|
|
196
|
+
|
|
197
|
+
writer = @buffers.writer
|
|
198
|
+
writer.write_byte CHANNEL_OPEN_CONFIRMATION
|
|
199
|
+
writer.write_long channel.remote_id
|
|
200
|
+
writer.write_long channel.local_id
|
|
201
|
+
writer.write_long 0x7FFFFFFF
|
|
202
|
+
writer.write_long 0x7FFFFFFF
|
|
203
|
+
@session.send_message writer
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def do_channel_open_failure( response )
|
|
207
|
+
local_id = response.read_long
|
|
208
|
+
reason_code = response.read_long
|
|
209
|
+
reason = response.read_string
|
|
210
|
+
language = response.read_string
|
|
211
|
+
|
|
212
|
+
@log.debug "CHANNEL_OPEN_FAILURE recieved (#{reason})" if @log.debug?
|
|
213
|
+
|
|
214
|
+
channel = @channel_map[ local_id ]
|
|
215
|
+
@channel_map.delete local_id
|
|
216
|
+
channel.do_confirm_failed reason_code, reason, language
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def do_channel_open_confirmation( response )
|
|
220
|
+
local_id = response.read_long
|
|
221
|
+
remote_id = response.read_long
|
|
222
|
+
window_size = response.read_long
|
|
223
|
+
packet_size = response.read_long
|
|
224
|
+
|
|
225
|
+
if @log.debug?
|
|
226
|
+
@log.debug "CHANNEL_OPEN_CONFIRMATION recieved (#{local_id})"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
channel = @channel_map[ local_id ]
|
|
230
|
+
channel.do_confirm_open remote_id, window_size, packet_size
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def do_channel_window_adjust( response )
|
|
234
|
+
local_id = response.read_long
|
|
235
|
+
bytes_to_add = response.read_long
|
|
236
|
+
|
|
237
|
+
if @log.debug?
|
|
238
|
+
@log.debug "CHANNEL_WINDOW_ADJUST recieved " +
|
|
239
|
+
"(#{local_id}:#{bytes_to_add})"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
@channel_map[ local_id ].do_window_adjust( bytes_to_add )
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def do_channel_data( response )
|
|
246
|
+
local_id = response.read_long
|
|
247
|
+
data = response.read_string
|
|
248
|
+
|
|
249
|
+
if @log.debug?
|
|
250
|
+
@log.debug "CHANNEL_DATA recieved (#{local_id}:#{data.inspect})"
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
@channel_map[ local_id ].do_data data
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def do_channel_extended_data( response )
|
|
257
|
+
local_id = response.read_long
|
|
258
|
+
data_type = response.read_long
|
|
259
|
+
data = response.read_string
|
|
260
|
+
|
|
261
|
+
if @log.debug?
|
|
262
|
+
@log.debug "CHANNEL_EXTENDED_DATA recieved " +
|
|
263
|
+
"(#{local_id}:#{data_type}:#{data.inspect})"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
@channel_map[ local_id ].do_extended_data data_type, data
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def do_channel_eof( response )
|
|
270
|
+
local_id = response.read_long
|
|
271
|
+
@log.debug "CHANNEL_EOF recieved (#{local_id})" if @log.debug?
|
|
272
|
+
@channel_map[ local_id ].do_eof
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def do_channel_close( response )
|
|
276
|
+
local_id = response.read_long
|
|
277
|
+
@log.debug "CHANNEL_CLOSE recieved (#{local_id})" if @log.debug?
|
|
278
|
+
@channel_map[ local_id ].close false
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def do_channel_request( response )
|
|
282
|
+
local_id = response.read_long
|
|
283
|
+
request = response.read_string
|
|
284
|
+
want_reply = response.read_bool
|
|
285
|
+
request_data = response.remainder_as_buffer
|
|
286
|
+
|
|
287
|
+
if @log.debug?
|
|
288
|
+
@log.debug "CHANNEL_REQUEST recieved (#{local_id}:#{request})"
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
@channel_map[ local_id ].do_request request, want_reply, request_data
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def do_channel_success( response )
|
|
295
|
+
local_id = response.read_long
|
|
296
|
+
@log.debug "CHANNEL_SUCCESS recieved (#{local_id})" if @log.debug?
|
|
297
|
+
@channel_map[ local_id ].do_success
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def do_channel_failure( response )
|
|
301
|
+
local_id = response.read_long
|
|
302
|
+
@log.debug "CHANNEL_FAILURE recieved (#{local_id})" if @log.debug?
|
|
303
|
+
@channel_map[ local_id ].do_failure
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
#--
|
|
307
|
+
# ====================================================================
|
|
308
|
+
# INTERNAL STATE MANAGEMENT
|
|
309
|
+
# ====================================================================
|
|
310
|
+
private
|
|
311
|
+
#++
|
|
312
|
+
|
|
313
|
+
# Process a response recived from a "global_request".
|
|
314
|
+
def process_request( response, success )
|
|
315
|
+
request = @request_queue.shift
|
|
316
|
+
request.callback.call( success, response ) if request.callback
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
#--
|
|
320
|
+
# ====================================================================
|
|
321
|
+
# MESSAGE DISPATCHER SETUP
|
|
322
|
+
# ====================================================================
|
|
323
|
+
#++
|
|
324
|
+
|
|
325
|
+
MESSAGES = {}
|
|
326
|
+
[ :request_success, :request_failure, :channel_open,
|
|
327
|
+
:channel_open_failure, :channel_open_confirmation,
|
|
328
|
+
:channel_window_adjust, :channel_data, :channel_extended_data,
|
|
329
|
+
:channel_eof, :channel_close, :channel_request, :channel_success,
|
|
330
|
+
:channel_failure
|
|
331
|
+
].each do |event|
|
|
332
|
+
constant = Constants.const_get event.to_s.upcase.to_sym
|
|
333
|
+
MESSAGES[ constant ] = {
|
|
334
|
+
:name => event,
|
|
335
|
+
:method => instance_method( "do_#{event}".to_sym )
|
|
336
|
+
}
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
module Connection
|
|
20
|
+
|
|
21
|
+
# Register the services that define the "connection" layer of the SSH
|
|
22
|
+
# protocol.
|
|
23
|
+
def register_services( container )
|
|
24
|
+
|
|
25
|
+
# The :connection namespace contains all of the services in the
|
|
26
|
+
# connection layer of the SSH protocol.
|
|
27
|
+
container.namespace_define :connection do |ns|
|
|
28
|
+
|
|
29
|
+
# The :channel namespace contains the channel-specific services.
|
|
30
|
+
ns.namespace_define :channel do |ch|
|
|
31
|
+
|
|
32
|
+
# The :open service provides a proc object that may be used to
|
|
33
|
+
# request that a new channel be opened.
|
|
34
|
+
ch.open do |c,p|
|
|
35
|
+
require 'net/ssh/connection/channel'
|
|
36
|
+
lambda do |type, data|
|
|
37
|
+
Channel.open( c[:driver],
|
|
38
|
+
c[:log_for, p],
|
|
39
|
+
c[:transport][:buffers],
|
|
40
|
+
type, data )
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# The :create service provides a proc object that may be used to
|
|
45
|
+
# create new channels, without sending a request to the server.
|
|
46
|
+
ch.create do |c,p|
|
|
47
|
+
require 'net/ssh/connection/channel'
|
|
48
|
+
lambda do |type,rid,wsize,psize|
|
|
49
|
+
Channel.create( c[:driver],
|
|
50
|
+
c[:log_for, p],
|
|
51
|
+
c[:transport][:buffers],
|
|
52
|
+
type, rid, wsize, psize )
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The :driver service manages the connection layer.
|
|
58
|
+
ns.driver do |c,p|
|
|
59
|
+
require 'net/ssh/connection/driver'
|
|
60
|
+
Driver.new( c[:transport][:session],
|
|
61
|
+
c[:log_for, p],
|
|
62
|
+
c[:transport][:buffers],
|
|
63
|
+
:open => c[:channel][:open],
|
|
64
|
+
:create => c[:channel][:create] )
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
module_function :register_services
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|