Class: HrrRbSsh::Connection
- Inherits:
-
Object
- Object
- HrrRbSsh::Connection
show all
- Includes:
- Loggable
- Defined in:
- lib/hrr_rb_ssh/connection.rb,
lib/hrr_rb_ssh/connection/channel.rb,
lib/hrr_rb_ssh/connection/request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type.rb,
lib/hrr_rb_ssh/connection/global_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb,
lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb,
lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb,
lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb,
lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb,
lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb,
lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb
Defined Under Namespace
Classes: Channel, GlobalRequestHandler, RequestHandler
Instance Attribute Summary collapse
Attributes included from Loggable
#log_key, #logger
Instance Method Summary
collapse
Methods included from Loggable
#log_debug, #log_error, #log_fatal, #log_info, #log_warn
Constructor Details
#initialize(authentication, mode, options = {}, logger: nil) ⇒ Connection
Returns a new instance of Connection.
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/hrr_rb_ssh/connection.rb', line 19
def initialize authentication, mode, options={}, logger: nil
self.logger = logger
@authentication = authentication
@mode = mode
@options = options
@global_request_handler = GlobalRequestHandler.new self, logger: logger
@channels = Hash.new
@username = nil
@variables = nil
@closed = nil
end
|
Instance Attribute Details
#mode ⇒ Object
Returns the value of attribute mode.
13
14
15
|
# File 'lib/hrr_rb_ssh/connection.rb', line 13
def mode
@mode
end
|
#options ⇒ Object
Returns the value of attribute options.
13
14
15
|
# File 'lib/hrr_rb_ssh/connection.rb', line 13
def options
@options
end
|
#username ⇒ Object
Returns the value of attribute username.
13
14
15
|
# File 'lib/hrr_rb_ssh/connection.rb', line 13
def username
@username
end
|
#variables ⇒ Object
Returns the value of attribute variables.
13
14
15
|
# File 'lib/hrr_rb_ssh/connection.rb', line 13
def variables
@variables
end
|
Instance Method Details
#assign_channel ⇒ Object
40
41
42
43
44
45
46
47
48
|
# File 'lib/hrr_rb_ssh/connection.rb', line 40
def assign_channel
i = 0
res = nil
while true
break unless @channels.keys.include?(i)
i += 1
end
i
end
|
#channel_close(payload) ⇒ Object
258
259
260
261
262
263
264
265
266
267
268
269
270
|
# File 'lib/hrr_rb_ssh/connection.rb', line 258
def channel_close payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_CLOSE::ID }
message = Message::SSH_MSG_CHANNEL_CLOSE.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
channel = @channels[local_channel]
channel.close
log_info { "wait until threads closed in channel" }
channel.wait_until_closed
log_info { "channel closed" }
log_info { "deleting channel" }
@channels.delete local_channel
log_info { "channel deleted" }
end
|
#channel_data(payload) ⇒ Object
237
238
239
240
241
242
|
# File 'lib/hrr_rb_ssh/connection.rb', line 237
def channel_data payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_DATA::ID }
message = Message::SSH_MSG_CHANNEL_DATA.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
@channels[local_channel].receive_message_queue.enq message if @channels.has_key? local_channel
end
|
#channel_eof(payload) ⇒ Object
251
252
253
254
255
256
|
# File 'lib/hrr_rb_ssh/connection.rb', line 251
def channel_eof payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_EOF::ID }
message = Message::SSH_MSG_CHANNEL_EOF.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
@channels[local_channel].receive_message_queue.enq message if @channels.has_key? local_channel
end
|
#channel_extended_data(payload) ⇒ Object
244
245
246
247
248
249
|
# File 'lib/hrr_rb_ssh/connection.rb', line 244
def channel_extended_data payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_EXTENDED_DATA::ID }
message = Message::SSH_MSG_CHANNEL_EXTENDED_DATA.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
@channels[local_channel].receive_message_queue.enq message if @channels.has_key? local_channel
end
|
#channel_open(payload) ⇒ Object
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
# File 'lib/hrr_rb_ssh/connection.rb', line 172
def channel_open payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN::ID }
message = Message::SSH_MSG_CHANNEL_OPEN.new(logger: logger).decode payload
begin
channel = Channel.new self, message, logger: logger
@channels[channel.local_channel] = channel
channel.start
send_channel_open_confirmation channel
rescue => e
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
recipient_channel = message[:'sender channel']
send_channel_open_failure recipient_channel, Message::SSH_MSG_CHANNEL_OPEN_FAILURE::ReasonCode::SSH_OPEN_CONNECT_FAILED, e.message
end
end
|
#channel_open_confirmation(payload) ⇒ Object
#channel_open_start(address, port, socket) ⇒ Object
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
# File 'lib/hrr_rb_ssh/connection.rb', line 153
def channel_open_start address, port, socket
log_info { 'channel open start' }
channel = Channel.new self, {:'channel type' => "forwarded-tcpip"}, socket, logger: logger
@channels[channel.local_channel] = channel
log_info { 'channel opened' }
message = {
:'message number' => Message::SSH_MSG_CHANNEL_OPEN::VALUE,
:'channel type' => "forwarded-tcpip",
:'sender channel' => channel.local_channel,
:'initial window size' => channel.local_window_size,
:'maximum packet size' => channel.local_maximum_packet_size,
:'address that was connected' => address,
:'port that was connected' => port,
:'originator IP address' => socket.remote_address.ip_address,
:'originator port' => socket.remote_address.ip_port,
}
send_channel_open message
end
|
#channel_request(payload) ⇒ Object
223
224
225
226
227
228
|
# File 'lib/hrr_rb_ssh/connection.rb', line 223
def channel_request payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_REQUEST::ID }
message = Message::SSH_MSG_CHANNEL_REQUEST.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
@channels[local_channel].receive_message_queue.enq message if @channels.has_key? local_channel
end
|
#channel_window_adjust(payload) ⇒ Object
230
231
232
233
234
235
|
# File 'lib/hrr_rb_ssh/connection.rb', line 230
def channel_window_adjust payload
log_info { 'received ' + Message::SSH_MSG_CHANNEL_WINDOW_ADJUST::ID }
message = Message::SSH_MSG_CHANNEL_WINDOW_ADJUST.new(logger: logger).decode payload
local_channel = message[:'recipient channel']
@channels[local_channel].receive_message_queue.enq message if @channels.has_key? local_channel
end
|
#close ⇒ Object
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/hrr_rb_ssh/connection.rb', line 69
def close
return if @closed
log_info { "close connection" }
@closed = true
@authentication.close
@channels.values.each do |channel|
begin
channel.close
rescue => e
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
end
end
@channels.clear
@global_request_handler.close
@connection_loop_thread.join if @connection_loop_thread && @connection_loop_thread != Thread.current
log_info { "connection closed" }
end
|
#closed? ⇒ Boolean
87
88
89
|
# File 'lib/hrr_rb_ssh/connection.rb', line 87
def closed?
@closed
end
|
#connection_loop_thread ⇒ Object
#global_request(payload) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# File 'lib/hrr_rb_ssh/connection.rb', line 137
def global_request payload
log_info { 'received ' + Message::SSH_MSG_GLOBAL_REQUEST::ID }
message = Message::SSH_MSG_GLOBAL_REQUEST.new(logger: logger).decode payload
begin
@global_request_handler.request message
rescue
if message[:'want reply']
send_request_failure
end
else
if message[:'want reply']
send_request_success
end
end
end
|
#loop ⇒ Object
65
66
67
|
# File 'lib/hrr_rb_ssh/connection.rb', line 65
def loop
@connection_loop_thread.join
end
|
#request_channel_open(channel_type, channel_specific_message = {}, wait_response = true) ⇒ Object
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
# File 'lib/hrr_rb_ssh/connection.rb', line 187
def request_channel_open channel_type, channel_specific_message={}, wait_response=true
log_info { 'request channel open' }
case channel_type
when "session"
channel = Channel.new self, {:'channel type' => channel_type}, logger: logger
@channels[channel.local_channel] = channel
end
message = {
:'message number' => Message::SSH_MSG_CHANNEL_OPEN::VALUE,
:'channel type' => channel_type,
:'sender channel' => channel.local_channel,
:'initial window size' => channel.local_window_size,
:'maximum packet size' => channel.local_maximum_packet_size,
}
send_channel_open message.merge(channel_specific_message)
log_info { 'sent channel open' }
if wait_response
log_info { 'wait response' }
channel.wait_until_started
end
unless channel.closed?
log_info { 'channel opened' }
channel
else
raise "Faild opening channel"
end
end
|
#send_channel_open(message) ⇒ Object
288
289
290
291
|
# File 'lib/hrr_rb_ssh/connection.rb', line 288
def send_channel_open message
payload = Message::SSH_MSG_CHANNEL_OPEN.new(logger: logger).encode message
@authentication.send payload
end
|
#send_channel_open_confirmation(channel) ⇒ Object
293
294
295
296
297
298
299
300
301
302
303
304
|
# File 'lib/hrr_rb_ssh/connection.rb', line 293
def send_channel_open_confirmation channel
message = {
:'message number' => Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::VALUE,
:'channel type' => channel.channel_type,
:'recipient channel' => channel.remote_channel,
:'sender channel' => channel.local_channel,
:'initial window size' => channel.local_window_size,
:'maximum packet size' => channel.local_maximum_packet_size,
}
payload = Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION.new(logger: logger).encode message
@authentication.send payload
end
|
#send_channel_open_failure(recipient_channel, reason_code, description) ⇒ Object
306
307
308
309
310
311
312
313
314
315
316
|
# File 'lib/hrr_rb_ssh/connection.rb', line 306
def send_channel_open_failure recipient_channel, reason_code, description
message = {
:'message number' => Message::SSH_MSG_CHANNEL_OPEN_FAILURE::VALUE,
:'recipient channel' => recipient_channel,
:'reason code' => reason_code,
:'description' => description,
:'language tag' => "",
}
payload = Message::SSH_MSG_CHANNEL_OPEN_FAILURE.new(logger: logger).encode message
@authentication.send payload
end
|
#send_request_failure ⇒ Object
#send_request_success ⇒ Object
#start(foreground: true) ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/hrr_rb_ssh/connection.rb', line 50
def start foreground: true
log_info { "start connection" }
begin
@authentication.start
rescue Error::ClosedAuthentication
close
raise Error::ClosedConnection
end
@closed = false
@connection_loop_thread = connection_loop_thread
if foreground
@connection_loop_thread.join
end
end
|