class HrrRbSsh::Connection
Attributes
mode[R]
options[R]
username[R]
variables[R]
Public Class Methods
new(authentication, mode, options={})
click to toggle source
# 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
Public Instance Methods
assign_channel()
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 215 def channel_open_confirmation payload log_info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::ID } message = Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION.new(logger: logger).decode payload channel = @channels[message[:'recipient channel']] channel.set_remote_parameters message channel.start end
channel_open_start(address, port, socket)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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()
click to toggle source
# 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?()
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 87 def closed? @closed end
connection_loop_thread()
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 91 def connection_loop_thread log_info { "start connection loop" } Thread.new do begin while true begin payload = @authentication.receive rescue Error::ClosedAuthentication => e log_info { "authentication closed" } break end @username ||= @authentication.username @variables ||= @authentication.variables case payload[0,1].unpack("C")[0] when Message::SSH_MSG_GLOBAL_REQUEST::VALUE global_request payload when Message::SSH_MSG_CHANNEL_OPEN::VALUE channel_open payload when Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::VALUE channel_open_confirmation payload when Message::SSH_MSG_CHANNEL_REQUEST::VALUE channel_request payload when Message::SSH_MSG_CHANNEL_WINDOW_ADJUST::VALUE channel_window_adjust payload when Message::SSH_MSG_CHANNEL_DATA::VALUE channel_data payload when Message::SSH_MSG_CHANNEL_EXTENDED_DATA::VALUE channel_extended_data payload when Message::SSH_MSG_CHANNEL_EOF::VALUE channel_eof payload when Message::SSH_MSG_CHANNEL_CLOSE::VALUE channel_close payload else log_warn { "received unsupported message: id: #{payload[0,1].unpack("C")[0]}" } end end rescue => e log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join } ensure log_info { "closing connection loop" } close log_info { "connection loop closed" } end end end
global_request(payload)
click to toggle source
# 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()
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 65 def loop @connection_loop_thread.join end
request_channel_open(channel_type, channel_specific_message={})
click to toggle source
# 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(payload)
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 31 def send payload raise Error::ClosedConnection if @closed begin @authentication.send payload rescue Error::ClosedAuthentication raise Error::ClosedConnection end end
send_channel_open(message)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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()
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 280 def send_request_failure message = { :'message number' => Message::SSH_MSG_REQUEST_FAILURE::VALUE, } payload = Message::SSH_MSG_REQUEST_FAILURE.new(logger: logger).encode message @authentication.send payload end
send_request_success()
click to toggle source
# File lib/hrr_rb_ssh/connection.rb, line 272 def send_request_success message = { :'message number' => Message::SSH_MSG_REQUEST_SUCCESS::VALUE, } payload = Message::SSH_MSG_REQUEST_SUCCESS.new(logger: logger).encode message @authentication.send payload end
start(foreground: true)
click to toggle source
# 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