mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
fixed up the ol' http server
git-svn-id: file:///home/svn/incoming/trunk@2843 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
d99e5b4f89
commit
2b82d4c4c4
@ -40,6 +40,131 @@ module StreamServer
|
||||
super
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Default server monitoring and client management implementation follows
|
||||
# below.
|
||||
#
|
||||
##
|
||||
|
||||
def on_client_connect(client)
|
||||
if (on_client_connect_proc)
|
||||
on_client_connect_proc.call(client)
|
||||
end
|
||||
end
|
||||
|
||||
def on_client_data(client)
|
||||
if (on_client_data_proc)
|
||||
on_client_data_proc.call(client)
|
||||
end
|
||||
end
|
||||
|
||||
def on_client_close(client)
|
||||
if (on_client_close_proc)
|
||||
on_client_close_proc.call(client)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Start monitoring the listener socket for connections and keep track of
|
||||
# all client connections.
|
||||
#
|
||||
def start
|
||||
self.clients = []
|
||||
self.clifds = []
|
||||
self.fd2cli = {}
|
||||
|
||||
self.listener_thread = Thread.new {
|
||||
monitor_listener
|
||||
}
|
||||
self.clients_thread = Thread.new {
|
||||
monitor_clients
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Terminates the listener monitoring threads and closes all active clients.
|
||||
#
|
||||
def stop
|
||||
self.listener_thread.kill
|
||||
self.clients_thread.kill
|
||||
|
||||
self.clients.each { |cli|
|
||||
close_client(cli)
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Closes a client connection.
|
||||
#
|
||||
def close_client(client)
|
||||
if (client)
|
||||
fd2cli.delete(client.sock)
|
||||
clifds.delete(client.sock)
|
||||
clients.delete(client)
|
||||
|
||||
client.close
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Callback procedures.
|
||||
#
|
||||
attr_accessor :on_client_connect_proc
|
||||
attr_accessor :on_client_data_proc
|
||||
attr_accessor :on_client_close_proc
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :clients, :clifds, :fd2cli
|
||||
attr_accessor :listener_thread, :clients_thread
|
||||
|
||||
#
|
||||
# Monitors the listener socket for new connections
|
||||
#
|
||||
def monitor_listener
|
||||
begin
|
||||
sd = Rex::ThreadSafe.select([ poll_fd ])
|
||||
|
||||
# Accept the new client connection
|
||||
if (sd[0].length > 0)
|
||||
cli = accept
|
||||
|
||||
next if (!cli)
|
||||
|
||||
# Insert it into some lists
|
||||
self.clients << cli
|
||||
self.clifds << cli.sock
|
||||
self.fd2cli[cli.sock] = cli
|
||||
|
||||
on_client_connect(cli)
|
||||
end
|
||||
rescue
|
||||
elog("Error in stream server listener monitor: #{$!}")
|
||||
end while true
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Monitors clients for data.
|
||||
#
|
||||
def monitor_clients
|
||||
begin
|
||||
if (clients.length == 0)
|
||||
Rex::ThreadSafe::sleep(0.2)
|
||||
next
|
||||
end
|
||||
|
||||
sd = Rex::ThreadSafe.select(clifds)
|
||||
|
||||
sd[0].each { |fd|
|
||||
on_client_data(self.fd2cli[fd])
|
||||
}
|
||||
rescue
|
||||
elog("Error in stream server client monitor: #{$!}")
|
||||
end while true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -78,9 +78,6 @@ class Server
|
||||
self.listen_port = port
|
||||
self.listen_host = listen_host
|
||||
self.listener = nil
|
||||
self.clients = []
|
||||
self.clifds = []
|
||||
self.fd2cli = {}
|
||||
self.resources = {}
|
||||
end
|
||||
|
||||
@ -91,40 +88,31 @@ class Server
|
||||
self.listener = Rex::Socket::TcpServer.create(
|
||||
'LocalHost' => self.listen_host,
|
||||
'LocalPort' => self.listen_port)
|
||||
|
||||
# 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.listener_thread = Thread.new {
|
||||
monitor_listener
|
||||
}
|
||||
self.clients_thread = Thread.new {
|
||||
monitor_clients
|
||||
}
|
||||
self.listener.start
|
||||
end
|
||||
|
||||
#
|
||||
# Terminates the monitor thread and turns off the listener.
|
||||
#
|
||||
def stop
|
||||
self.listener_thread.kill
|
||||
self.clients_thread.kill
|
||||
|
||||
self.clients.each { |cli|
|
||||
close_client(cli)
|
||||
}
|
||||
|
||||
self.listener.stop
|
||||
self.listener.close
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the supplied client connection and removes it from the internal
|
||||
# hashes and lists.
|
||||
# Closes the supplied client, if valid.
|
||||
#
|
||||
def close_client(cli)
|
||||
if (cli)
|
||||
self.fd2cli.delete(cli.sock)
|
||||
self.clifds.delete(cli.sock)
|
||||
self.clients.delete(cli)
|
||||
cli.close
|
||||
end
|
||||
listener.close_client(cli)
|
||||
end
|
||||
|
||||
#
|
||||
@ -153,7 +141,7 @@ class Server
|
||||
end
|
||||
|
||||
#
|
||||
# Adds Server headers and stuff
|
||||
# Adds Server headers and stuff.
|
||||
#
|
||||
def add_response_headers(resp)
|
||||
resp['Server'] = DefaultServer
|
||||
@ -163,63 +151,21 @@ class Server
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :listener
|
||||
attr_accessor :listener_thread, :clients_thread
|
||||
attr_accessor :clients, :clifds, :fd2cli
|
||||
attr_accessor :resources
|
||||
attr_accessor :listener, :resources
|
||||
|
||||
#
|
||||
# Monitors the listener for new connections
|
||||
# Extends new clients with the ServerClient module and initializes them.
|
||||
#
|
||||
def monitor_listener
|
||||
begin
|
||||
sd = Rex::ThreadSafe.select([ listener.sock ])
|
||||
def on_client_connect(cli)
|
||||
cli.extend(ServerClient)
|
||||
|
||||
# Accept the new client connection
|
||||
if (sd[0].length > 0)
|
||||
cli = listener.accept
|
||||
|
||||
next if (!cli)
|
||||
|
||||
cli.extend(ServerClient)
|
||||
|
||||
# Initialize the server client extension
|
||||
cli.init_cli(self)
|
||||
|
||||
# Insert it into some lists
|
||||
self.clients << cli
|
||||
self.clifds << cli.sock
|
||||
self.fd2cli[cli.sock] = cli
|
||||
end
|
||||
rescue
|
||||
elog("Exception caught in HTTP server listener monitor: #{$!}")
|
||||
end while true
|
||||
cli.init_cli(self)
|
||||
end
|
||||
|
||||
#
|
||||
# Monitors client connections for data
|
||||
# Processes data coming in from a client.
|
||||
#
|
||||
def monitor_clients
|
||||
begin
|
||||
if (clients.length == 0)
|
||||
Rex::ThreadSafe::sleep(0.2)
|
||||
next
|
||||
end
|
||||
|
||||
sd = Rex::ThreadSafe.select(clifds)
|
||||
|
||||
sd[0].each { |fd|
|
||||
process_client(self.fd2cli[fd])
|
||||
}
|
||||
rescue
|
||||
elog("Exception caught in HTTP server clients monitor: #{$!}")
|
||||
end while true
|
||||
end
|
||||
|
||||
#
|
||||
# Processes data coming in from a client
|
||||
#
|
||||
def process_client(cli)
|
||||
def on_client_data(cli)
|
||||
begin
|
||||
case cli.request.parse(cli.get)
|
||||
when Packet::ParseCode::Completed
|
||||
|
@ -80,7 +80,7 @@ class Rex::Socket::Parameters
|
||||
self.server = hash['Server'] || false
|
||||
|
||||
# The communication subsystem to use to create the socket
|
||||
self.comm = hash['Comm'] || Rex::Socket::Comm::Local;
|
||||
self.comm = hash['Comm'] || Rex::Socket::Comm::Local
|
||||
|
||||
# The number of connection retries to make (client only)
|
||||
self.retries = hash['Retries'] || 0
|
||||
|
Loading…
Reference in New Issue
Block a user