2005-12-17 06:46:23 +00:00
|
|
|
#!/usr/bin/env ruby
|
2005-04-10 02:05:43 +00:00
|
|
|
|
2005-04-10 04:13:08 +00:00
|
|
|
require 'timeout'
|
2009-11-02 18:14:57 +00:00
|
|
|
require 'thread'
|
2005-04-10 04:13:08 +00:00
|
|
|
|
2005-04-10 02:05:43 +00:00
|
|
|
module Rex
|
|
|
|
module Post
|
|
|
|
module Meterpreter
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# This class handles waiting for a response to a given request
|
2005-11-15 05:22:13 +00:00
|
|
|
# and the subsequent response association.
|
2005-04-10 02:05:43 +00:00
|
|
|
#
|
|
|
|
###
|
|
|
|
class PacketResponseWaiter
|
2005-04-12 05:37:11 +00:00
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
2005-04-12 05:37:11 +00:00
|
|
|
# Initializes a response waiter instance for the supplied request
|
2005-11-15 05:22:13 +00:00
|
|
|
# identifier.
|
|
|
|
#
|
2005-04-10 02:05:43 +00:00
|
|
|
def initialize(rid, completion_routine = nil, completion_param = nil)
|
2005-04-15 07:03:33 +00:00
|
|
|
self.rid = rid.dup
|
2005-04-10 02:05:43 +00:00
|
|
|
self.response = nil
|
|
|
|
|
|
|
|
if (completion_routine)
|
|
|
|
self.completion_routine = completion_routine
|
|
|
|
self.completion_param = completion_param
|
|
|
|
else
|
2010-09-13 21:07:02 +00:00
|
|
|
self.done = false
|
2010-09-13 20:57:38 +00:00
|
|
|
self.wthread = initialize_waiter_thread
|
2005-04-10 02:05:43 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-13 20:57:38 +00:00
|
|
|
#
|
|
|
|
# Create an idle thread we can wait on
|
|
|
|
#
|
|
|
|
def initialize_waiter_thread
|
2010-09-13 21:07:02 +00:00
|
|
|
::Thread.new do
|
|
|
|
while (! self.done)
|
|
|
|
::IO.select(nil,nil,nil,5.0)
|
|
|
|
end
|
|
|
|
end
|
2010-09-13 20:57:38 +00:00
|
|
|
end
|
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
2009-11-02 18:14:57 +00:00
|
|
|
# Checks to see if this waiter instance is waiting for the supplied
|
2005-11-15 05:22:13 +00:00
|
|
|
# packet based on its request identifier.
|
|
|
|
#
|
2005-04-10 02:05:43 +00:00
|
|
|
def waiting_for?(packet)
|
|
|
|
return (packet.rid == rid)
|
|
|
|
end
|
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
|
|
|
# Notifies the waiter that the supplied response packet has arrived.
|
|
|
|
#
|
2005-04-10 02:05:43 +00:00
|
|
|
def notify(response)
|
|
|
|
self.response = response
|
|
|
|
|
|
|
|
if (self.completion_routine)
|
2010-01-28 23:53:15 +00:00
|
|
|
self.completion_routine.call(response, self.completion_param)
|
2005-04-10 02:05:43 +00:00
|
|
|
else
|
2009-06-14 21:20:30 +00:00
|
|
|
self.done = true
|
2010-09-13 20:57:38 +00:00
|
|
|
self.wthread.kill
|
2005-04-10 02:05:43 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
|
|
|
# Waits for a given time interval for the response packet to arrive.
|
2010-01-26 00:01:55 +00:00
|
|
|
# If the interval is -1 we can wait forever.
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
2005-04-10 02:05:43 +00:00
|
|
|
def wait(interval)
|
2010-01-26 00:01:55 +00:00
|
|
|
if( interval and interval == -1 )
|
2010-09-13 20:57:38 +00:00
|
|
|
self.wthread.join
|
2010-05-20 20:42:17 +00:00
|
|
|
else
|
2010-01-26 00:01:55 +00:00
|
|
|
begin
|
2010-09-13 20:57:38 +00:00
|
|
|
Timeout.timeout(interval) { self.wthread.join }
|
2010-01-26 00:01:55 +00:00
|
|
|
rescue Timeout::Error
|
|
|
|
self.response = nil
|
|
|
|
end
|
2010-05-20 20:42:17 +00:00
|
|
|
end
|
2005-04-10 02:05:43 +00:00
|
|
|
return self.response
|
|
|
|
end
|
|
|
|
|
2010-09-13 20:57:38 +00:00
|
|
|
attr_accessor :rid, :done, :response, :wthread # :nodoc:
|
2005-11-15 05:22:13 +00:00
|
|
|
attr_accessor :completion_routine, :completion_param # :nodoc:
|
2005-04-10 02:05:43 +00:00
|
|
|
end
|
|
|
|
|
2009-06-14 21:20:30 +00:00
|
|
|
end; end; end
|
2009-11-02 18:14:57 +00:00
|
|
|
|