Class: HrrRbSsh::Connection
- Inherits:
-
Object
- Object
- HrrRbSsh::Connection
- 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
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#username ⇒ Object
readonly
Returns the value of attribute username.
-
#variables ⇒ Object
readonly
Returns the value of attribute variables.
Instance Method Summary collapse
- #assign_channel ⇒ Object
- #channel_close(payload) ⇒ Object
- #channel_data(payload) ⇒ Object
- #channel_eof(payload) ⇒ Object
- #channel_extended_data(payload) ⇒ Object
- #channel_open(payload) ⇒ Object
- #channel_open_confirmation(payload) ⇒ Object
- #channel_open_start(address, port, socket) ⇒ Object
- #channel_request(payload) ⇒ Object
- #channel_window_adjust(payload) ⇒ Object
- #close ⇒ Object
- #closed? ⇒ Boolean
- #connection_loop_thread ⇒ Object
- #global_request(payload) ⇒ Object
-
#initialize(authentication, mode, options = {}) ⇒ Connection
constructor
A new instance of Connection.
- #loop ⇒ Object
- #request_channel_open(channel_type, channel_specific_message = {}, wait_response = true) ⇒ Object
- #send(payload) ⇒ Object
- #send_channel_open(message) ⇒ Object
- #send_channel_open_confirmation(channel) ⇒ Object
- #send_channel_open_failure(recipient_channel, reason_code, description) ⇒ Object
- #send_request_failure ⇒ Object
- #send_request_success ⇒ Object
- #start(foreground: true) ⇒ Object
Constructor Details
#initialize(authentication, mode, options = {}) ⇒ Connection
Returns a new instance of Connection.
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/hrr_rb_ssh/connection.rb', line 17 def initialize authentication, mode, ={} @logger = Logger.new self.class.name @authentication = authentication @mode = mode @options = @global_request_handler = GlobalRequestHandler.new self @channels = Hash.new @username = nil @variables = nil @closed = nil end |
Instance Attribute Details
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
11 12 13 |
# File 'lib/hrr_rb_ssh/connection.rb', line 11 def mode @mode end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
11 12 13 |
# File 'lib/hrr_rb_ssh/connection.rb', line 11 def @options end |
#username ⇒ Object (readonly)
Returns the value of attribute username.
11 12 13 |
# File 'lib/hrr_rb_ssh/connection.rb', line 11 def username @username end |
#variables ⇒ Object (readonly)
Returns the value of attribute variables.
11 12 13 |
# File 'lib/hrr_rb_ssh/connection.rb', line 11 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 @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_CLOSE::ID } = Message::SSH_MSG_CHANNEL_CLOSE.decode payload local_channel = [:'recipient channel'] channel = @channels[local_channel] channel.close @logger.info { "wait until threads closed in channel" } channel.wait_until_closed @logger.info { "channel closed" } @logger.info { "deleting channel" } @channels.delete local_channel @logger.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 @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_DATA::ID } = Message::SSH_MSG_CHANNEL_DATA.decode payload local_channel = [:'recipient channel'] @channels[local_channel]..enq end |
#channel_eof(payload) ⇒ Object
245 246 247 248 249 250 |
# File 'lib/hrr_rb_ssh/connection.rb', line 245 def channel_eof payload @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_EOF::ID } = Message::SSH_MSG_CHANNEL_EOF.decode payload local_channel = [:'recipient channel'] @channels[local_channel]..enq end |
#channel_extended_data(payload) ⇒ Object
238 239 240 241 242 243 |
# File 'lib/hrr_rb_ssh/connection.rb', line 238 def channel_extended_data payload @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_EXTENDED_DATA::ID } = Message::SSH_MSG_CHANNEL_EXTENDED_DATA.decode payload local_channel = [:'recipient channel'] @channels[local_channel]..enq end |
#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 @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN::ID } = Message::SSH_MSG_CHANNEL_OPEN.decode payload begin channel = Channel.new self, @channels[channel.local_channel] = channel channel.start send_channel_open_confirmation channel rescue => e @logger.error { [e.backtrace[0], ": ", e., " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join } recipient_channel = [:'sender channel'] send_channel_open_failure recipient_channel, Message::SSH_MSG_CHANNEL_OPEN_FAILURE::ReasonCode::SSH_OPEN_CONNECT_FAILED, e. end end |
#channel_open_confirmation(payload) ⇒ Object
209 210 211 212 213 214 215 |
# File 'lib/hrr_rb_ssh/connection.rb', line 209 def channel_open_confirmation payload @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::ID } = Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION.decode payload channel = @channels[[:'recipient channel']] channel.set_remote_parameters channel.start end |
#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 @logger.info { 'channel open start' } channel = Channel.new self, {:'channel type' => "forwarded-tcpip"}, socket @channels[channel.local_channel] = channel @logger.info { 'channel opened' } = { :'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 end |
#channel_request(payload) ⇒ Object
217 218 219 220 221 222 |
# File 'lib/hrr_rb_ssh/connection.rb', line 217 def channel_request payload @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_REQUEST::ID } = Message::SSH_MSG_CHANNEL_REQUEST.decode payload local_channel = [:'recipient channel'] @channels[local_channel]..enq end |
#channel_window_adjust(payload) ⇒ Object
224 225 226 227 228 229 |
# File 'lib/hrr_rb_ssh/connection.rb', line 224 def channel_window_adjust payload @logger.info { 'received ' + Message::SSH_MSG_CHANNEL_WINDOW_ADJUST::ID } = Message::SSH_MSG_CHANNEL_WINDOW_ADJUST.decode payload local_channel = [:'recipient channel'] @channels[local_channel]..enq end |
#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 @logger.info { "closing connection" } @closed = true @authentication.close @channels.values.each do |channel| begin channel.close rescue => e @logger.error { [e.backtrace[0], ": ", e., " (", 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 @logger.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
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/hrr_rb_ssh/connection.rb', line 85 def connection_loop_thread @logger.info { "start connection loop" } Thread.new do begin while true begin payload = @authentication.receive rescue Error::ClosedAuthentication => e @logger.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 @logger.warn { "received unsupported message: id: #{payload[0,1].unpack("C")[0]}" } end end rescue => e @logger.error { [e.backtrace[0], ": ", e., " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join } ensure @logger.info { "closing connection loop" } close @logger.info { "connection loop closed" } end end end |
#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 @logger.info { 'received ' + Message::SSH_MSG_GLOBAL_REQUEST::ID } = Message::SSH_MSG_GLOBAL_REQUEST.decode payload begin @global_request_handler.request rescue if [:'want reply'] send_request_failure end else if [:'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, ={}, wait_response=true @logger.info { 'request channel open' } case channel_type when "session" channel = Channel.new self, {:'channel type' => channel_type} @channels[channel.local_channel] = channel end = { :'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 .merge() @logger.info { 'sent channel open' } if wait_response @logger.info { 'wait response' } channel.wait_until_started end unless channel.closed? @logger.info { 'channel opened' } channel else raise "Faild opening channel" end end |
#send(payload) ⇒ Object
31 32 33 34 35 36 37 38 |
# 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) ⇒ Object
282 283 284 285 |
# File 'lib/hrr_rb_ssh/connection.rb', line 282 def send_channel_open payload = Message::SSH_MSG_CHANNEL_OPEN.encode @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 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.encode @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 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.encode @authentication.send payload end |
#send_request_failure ⇒ Object
274 275 276 277 278 279 280 |
# File 'lib/hrr_rb_ssh/connection.rb', line 274 def send_request_failure = { :'message number' => Message::SSH_MSG_REQUEST_FAILURE::VALUE, } payload = Message::SSH_MSG_REQUEST_FAILURE.encode @authentication.send payload end |
#send_request_success ⇒ Object
266 267 268 269 270 271 272 |
# File 'lib/hrr_rb_ssh/connection.rb', line 266 def send_request_success = { :'message number' => Message::SSH_MSG_REQUEST_SUCCESS::VALUE, } payload = Message::SSH_MSG_REQUEST_SUCCESS.encode @authentication.send payload end |
#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 @logger.info { "start connection" } @authentication.start @closed = false @connection_loop_thread = connection_loop_thread if foreground @connection_loop_thread.join end end |