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
252
253
254
255
256
257
258
259
260
261
262
263
264
|
# File 'lib/hrr_rb_ssh/connection.rb', line 252
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
231
232
233
234
235
236
|
# File 'lib/hrr_rb_ssh/connection.rb', line 231
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
end
|
#channel_eof(payload) ⇒ Object
245
246
247
248
249
250
|
# File 'lib/hrr_rb_ssh/connection.rb', line 245
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
end
|
#channel_extended_data(payload) ⇒ Object
#channel_open(payload) ⇒ Object
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# File 'lib/hrr_rb_ssh/connection.rb', line 166
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# File 'lib/hrr_rb_ssh/connection.rb', line 147
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
217
218
219
220
221
222
|
# File 'lib/hrr_rb_ssh/connection.rb', line 217
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
end
|
#channel_window_adjust(payload) ⇒ Object
#close ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/hrr_rb_ssh/connection.rb', line 64
def close
log_info { "closing 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 unless @connection_loop_thread == Thread.current
log_info { "connection closed" }
end
|
#closed? ⇒ Boolean
81
82
83
|
# File 'lib/hrr_rb_ssh/connection.rb', line 81
def closed?
@closed
end
|
#connection_loop_thread ⇒ Object
#global_request(payload) ⇒ Object
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/hrr_rb_ssh/connection.rb', line 131
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
60
61
62
|
# File 'lib/hrr_rb_ssh/connection.rb', line 60
def loop
@connection_loop_thread.join
end
|
#request_channel_open(channel_type, channel_specific_message = {}, wait_response = true) ⇒ Object
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
# File 'lib/hrr_rb_ssh/connection.rb', line 181
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
282
283
284
285
|
# File 'lib/hrr_rb_ssh/connection.rb', line 282
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
287
288
289
290
291
292
293
294
295
296
297
298
|
# File 'lib/hrr_rb_ssh/connection.rb', line 287
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
300
301
302
303
304
305
306
307
308
309
310
|
# File 'lib/hrr_rb_ssh/connection.rb', line 300
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
|
# File 'lib/hrr_rb_ssh/connection.rb', line 50
def start foreground: true
log_info { "start connection" }
@authentication.start
@closed = false
@connection_loop_thread = connection_loop_thread
if foreground
@connection_loop_thread.join
end
end
|