Class: Rex::Proto::Ssh::Server
- Inherits:
-
Object
- Object
- Rex::Proto::Ssh::Server
- Includes:
- Rex::Proto
- Defined in:
- lib/rex/proto/ssh/server.rb
Overview
Acts as an SSH server, accepting clients and extending them with Connections
Instance Attribute Summary collapse
-
#clients ⇒ Object
Returns the value of attribute clients.
-
#comm ⇒ Object
Returns the value of attribute comm.
-
#context ⇒ Object
Returns the value of attribute context.
-
#listen_host ⇒ Object
Returns the value of attribute listen_host.
-
#listen_port ⇒ Object
Returns the value of attribute listen_port.
-
#listener ⇒ Object
Returns the value of attribute listener.
-
#monitor_thread ⇒ Object
Returns the value of attribute monitor_thread.
-
#on_client_connect_proc ⇒ Object
Returns the value of attribute on_client_connect_proc.
-
#on_client_data_proc ⇒ Object
Returns the value of attribute on_client_data_proc.
-
#server_options ⇒ Object
Returns the value of attribute server_options.
Class Method Summary collapse
-
.hardcore_alias(*args) ⇒ Object
Returns the hardcore alias for the SSH service.
Instance Method Summary collapse
-
#alias ⇒ Object
SSH server.
-
#close_client(cli) ⇒ Object
Closes the supplied client, if valid.
-
#enqueue_client(cli) ⇒ Object
protected
Waits for SSH client to “grow a pair” of FDs and adds a ChannelFD object derived from the client’s Connection Channel’s FDs to the Ssh::Server’s clients array.
-
#initialize(port = 22, listen_host = '0.0.0.0', context = {}, comm = nil, ssh_opts = default_options, cc_cb = nil, cd_cb = nil) ⇒ Server
constructor
Initializes an SSH server as listening on the provided port and hostname.
-
#inspect ⇒ String
More readable inspect that only shows the url and resources.
-
#monitor_clients ⇒ Object
protected
Watches FD channel abstractions, removes closed instances, checks for read data on clients if client data callback is defined, invokes the callback if possible, sleeps otherwise.
-
#on_client_connect(cli) ⇒ Object
protected
Extends new clients with the ServerClient module and initializes them.
-
#start(srvsock = nil) ⇒ Object
Listens on the defined port and host and starts monitoring for clients.
-
#stop ⇒ Object
Terminates the monitor thread and turns off the listener.
-
#wait ⇒ Object
Waits for the SSH service to terminate.
Constructor Details
#initialize(port = 22, listen_host = '0.0.0.0', context = {}, comm = nil, ssh_opts = default_options, cc_cb = nil, cd_cb = nil) ⇒ Server
Initializes an SSH server as listening on the provided port and hostname.
52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rex/proto/ssh/server.rb', line 52 def initialize(port = 22, listen_host = '0.0.0.0', context = {}, comm = nil, ssh_opts = , cc_cb = nil, cd_cb = nil) self.listen_host = listen_host self.listen_port = port self.context = context self.comm = comm self.listener = nil self. = ssh_opts self.on_client_connect_proc = cc_cb self.on_client_data_proc = cd_cb end |
Instance Attribute Details
#clients ⇒ Object
Returns the value of attribute clients.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def clients @clients end |
#comm ⇒ Object
Returns the value of attribute comm.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def comm @comm end |
#context ⇒ Object
Returns the value of attribute context.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def context @context end |
#listen_host ⇒ Object
Returns the value of attribute listen_host.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def listen_host @listen_host end |
#listen_port ⇒ Object
Returns the value of attribute listen_port.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def listen_port @listen_port end |
#listener ⇒ Object
Returns the value of attribute listener.
139 140 141 |
# File 'lib/rex/proto/ssh/server.rb', line 139 def listener @listener end |
#monitor_thread ⇒ Object
Returns the value of attribute monitor_thread.
138 139 140 |
# File 'lib/rex/proto/ssh/server.rb', line 138 def monitor_thread @monitor_thread end |
#on_client_connect_proc ⇒ Object
Returns the value of attribute on_client_connect_proc.
139 140 141 |
# File 'lib/rex/proto/ssh/server.rb', line 139 def on_client_connect_proc @on_client_connect_proc end |
#on_client_data_proc ⇒ Object
Returns the value of attribute on_client_data_proc.
139 140 141 |
# File 'lib/rex/proto/ssh/server.rb', line 139 def on_client_data_proc @on_client_data_proc end |
#server_options ⇒ Object
Returns the value of attribute server_options.
139 140 141 |
# File 'lib/rex/proto/ssh/server.rb', line 139 def @server_options end |
Class Method Details
.hardcore_alias(*args) ⇒ Object
Returns the hardcore alias for the SSH service
74 75 76 |
# File 'lib/rex/proto/ssh/server.rb', line 74 def self.hardcore_alias(*args) "#{(args[0])}-#{(args[1])}-#{args[4] || ''}" end |
Instance Method Details
#alias ⇒ Object
SSH server.
81 82 83 |
# File 'lib/rex/proto/ssh/server.rb', line 81 def alias super || "SSH Server" end |
#close_client(cli) ⇒ Object
Closes the supplied client, if valid.
132 133 134 135 |
# File 'lib/rex/proto/ssh/server.rb', line 132 def close_client(cli) clients.delete(cli) listener.close_client(cli.parent) end |
#enqueue_client(cli) ⇒ Object (protected)
Waits for SSH client to “grow a pair” of FDs and adds a ChannelFD object derived from the client’s Connection Channel’s FDs to the Ssh::Server’s clients array
187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rex/proto/ssh/server.rb', line 187 def enqueue_client(cli) Rex::ThreadFactory.spawn("ChannelFDWaiter", false) do begin Timeout::timeout(15) do while cli.connection.open_channel_keys.empty? do sleep 0.02 end self.clients.push(Ssh::ChannelFD.new(cli)) end rescue Timeout::Error elog("Unable to find channel FDs for client #{cli}") end end end |
#inspect ⇒ String
More readable inspect that only shows the url and resources
67 68 69 |
# File 'lib/rex/proto/ssh/server.rb', line 67 def inspect "#<#{self.class} ssh://#{listen_host}:#{listen_port}>" end |
#monitor_clients ⇒ Object (protected)
Watches FD channel abstractions, removes closed instances, checks for read data on clients if client data callback is defined, invokes the callback if possible, sleeps otherwise.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/rex/proto/ssh/server.rb', line 162 def monitor_clients loop do self.clients.delete_if {|c| c.closed? } if self.on_client_data_proc if clients.any? { |cli| cli.has_read_data? and self.on_client_data_proc.call(cli)} next else sleep 0.05 end else sleep 0.5 end end rescue => e wlog(e) end |
#on_client_connect(cli) ⇒ Object (protected)
Extends new clients with the ServerClient module and initializes them.
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rex/proto/ssh/server.rb', line 146 def on_client_connect(cli) cli.extend(ServerClient) cli.init_cli(self) if self.on_client_connect_proc self.on_client_connect_proc.call(cli) else enqueue_client(cli) end end |
#start(srvsock = nil) ⇒ Object
Listens on the defined port and host and starts monitoring for clients.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rex/proto/ssh/server.rb', line 89 def start(srvsock = nil) self.listener = srvsock.is_a?(Rex::Socket::TcpServer) ? srvsock : Rex::Socket::TcpServer.create( 'LocalHost' => self.listen_host, 'LocalPort' => self.listen_port, 'Context' => self.context, 'Comm' => self.comm ) # Register callbacks self.listener.on_client_connect_proc = Proc.new { |cli| on_client_connect(cli) } # self.listener.on_client_data_proc = Proc.new { |cli| # on_client_data(cli) # } self.clients = [] self.monitor_thread = Rex::ThreadFactory.spawn("SshServerClientMonitor", false) { monitor_clients } self.listener.start end |
#stop ⇒ Object
Terminates the monitor thread and turns off the listener.
115 116 117 118 119 |
# File 'lib/rex/proto/ssh/server.rb', line 115 def stop self.listener.stop self.listener.close self.clients = [] end |
#wait ⇒ Object
Waits for the SSH service to terminate
125 126 127 |
# File 'lib/rex/proto/ssh/server.rb', line 125 def wait self.listener.wait if self.listener end |