rex 2.0.9 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex/exploitation/cmdstager/bourne.rb +14 -8
  3. data/lib/rex/exploitation/cmdstager/echo.rb +3 -3
  4. data/lib/rex/exploitation/js/memory.rb +1 -1
  5. data/lib/rex/java/serialization/model/contents.rb +1 -1
  6. data/lib/rex/mime/message.rb +1 -1
  7. data/lib/rex/parser/acunetix_nokogiri.rb +2 -0
  8. data/lib/rex/parser/appscan_nokogiri.rb +1 -1
  9. data/lib/rex/parser/burp_issue_nokogiri.rb +139 -0
  10. data/lib/rex/parser/burp_session_nokogiri.rb +1 -1
  11. data/lib/rex/parser/fs/bitlocker.rb +233 -0
  12. data/lib/rex/parser/fusionvm_nokogiri.rb +2 -2
  13. data/lib/rex/parser/ini.rb +1 -8
  14. data/lib/rex/parser/nokogiri_doc_mixin.rb +5 -0
  15. data/lib/rex/payloads/meterpreter/config.rb +23 -4
  16. data/lib/rex/post/meterpreter/channel.rb +8 -3
  17. data/lib/rex/post/meterpreter/client.rb +1 -0
  18. data/lib/rex/post/meterpreter/client_core.rb +2 -2
  19. data/lib/rex/post/meterpreter/extensions/android/android.rb +86 -1
  20. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +29 -0
  21. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +1 -1
  22. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +75 -89
  23. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +8 -2
  24. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +10 -5
  25. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +7 -2
  26. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +10 -5
  27. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +8 -2
  28. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +1 -1
  29. data/lib/rex/post/meterpreter/packet.rb +38 -0
  30. data/lib/rex/post/meterpreter/packet_dispatcher.rb +101 -108
  31. data/lib/rex/post/meterpreter/packet_parser.rb +14 -6
  32. data/lib/rex/post/meterpreter/packet_response_waiter.rb +42 -21
  33. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +54 -4
  34. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +39 -13
  35. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +8 -0
  36. data/lib/rex/proto/adb.rb +7 -0
  37. data/lib/rex/proto/adb/client.rb +39 -0
  38. data/lib/rex/proto/adb/message.rb +164 -0
  39. data/lib/rex/proto/dcerpc/svcctl/packet.rb +9 -9
  40. data/lib/rex/proto/http/client_request.rb +2 -1
  41. data/lib/rex/proto/http/response.rb +1 -1
  42. data/lib/rex/proto/kademlia/bootstrap_response.rb +2 -2
  43. data/lib/rex/proto/ntp/modes.rb +17 -0
  44. data/lib/rex/text.rb +12 -0
  45. data/lib/rex/zip/blocks.rb +1 -1
  46. data/lib/rex/zip/entry.rb +1 -1
  47. data/rex.gemspec +28 -1
  48. metadata +106 -3
@@ -59,7 +59,7 @@ module Parser
59
59
  unless in_tag("JobOrder")
60
60
  case name
61
61
  when "OS"
62
- unless @host.nil? or @text.blank?
62
+ unless @host.nil? or @text.to_s.empty?
63
63
  tnote = {
64
64
  :type => "host.os.fusionvm_fingerprint",
65
65
  :data => { :os => @text.strip },
@@ -86,7 +86,7 @@ module Parser
86
86
  when "CVE"
87
87
  @vuln[:refs] << "CVE-#{@text.strip}"
88
88
  when "References"
89
- unless @text.blank?
89
+ unless @text.to_s.empty?
90
90
  @text.split(' ').each do |ref|
91
91
  next unless ref.start_with? "http"
92
92
  if ref =~ /MS\d{2}-\d{3}/
@@ -49,14 +49,7 @@ class Ini < Hash
49
49
  end
50
50
  end
51
51
 
52
- #
53
- # Enumerates the groups hash keys.
54
- #
55
- def each_group(&block)
56
- self.keys.each { |k|
57
- yield
58
- }
59
- end
52
+ alias each_group each_key
60
53
 
61
54
  #
62
55
  # Adds a group of the supplied name if it doesn't already exist.
@@ -200,6 +200,11 @@ module Parser
200
200
  return attr_pairs
201
201
  end
202
202
 
203
+ # Removes HTML from a string
204
+ def strip_html_tags(text)
205
+ return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "}
206
+ end
207
+
203
208
  # This breaks xml-encoded characters, so need to append.
204
209
  # It's on the end_element tag name to turn the appending
205
210
  # off and clear out the data.
@@ -120,6 +120,20 @@ private
120
120
  extension_data = [ ext.length, ext ].pack('VA*')
121
121
  end
122
122
 
123
+ def extension_init_block(name, value)
124
+ # for now, we're going to blindly assume that the value is a path to a file
125
+ # which contains the data that gets passed to the extension
126
+ content = ::File.read(value)
127
+ data = [
128
+ name,
129
+ "\x00",
130
+ content.length,
131
+ content
132
+ ]
133
+
134
+ data.pack('A*A*VA*')
135
+ end
136
+
123
137
  def config_block
124
138
  # start with the session information
125
139
  config = session_block(@opts)
@@ -142,12 +156,17 @@ private
142
156
  end
143
157
 
144
158
  # terminate the extensions with a 0 size
145
- if is_x86?
146
- config << [0].pack('V')
147
- else
148
- config << [0].pack('Q<')
159
+ config << [0].pack('V')
160
+
161
+ # wire in the extension init data
162
+ (@opts[:ext_init] || '').split(':').each do |cfg|
163
+ name, value = cfg.split(',')
164
+ config << extension_init_block(name, value)
149
165
  end
150
166
 
167
+ # terminate the ext init config with a final null byte
168
+ config << "\x00"
169
+
151
170
  # and we're done
152
171
  config
153
172
  end
@@ -141,7 +141,9 @@ class Channel
141
141
  if (cid and client)
142
142
  client.add_channel(self)
143
143
  end
144
- ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.cid) )
144
+
145
+ # Ensure the remote object is closed when all references are removed
146
+ ObjectSpace.define_finalizer(self, self.class.finalize(client, cid))
145
147
  end
146
148
 
147
149
  def self.finalize(client,cid)
@@ -288,8 +290,11 @@ class Channel
288
290
  end
289
291
 
290
292
  def _close(addends = nil)
291
- self.class._close(self.client, self.cid, addends)
292
- self.cid = nil
293
+ unless self.cid.nil?
294
+ ObjectSpace.undefine_finalizer(self)
295
+ self.class._close(self.client, self.cid, addends)
296
+ self.cid = nil
297
+ end
293
298
  end
294
299
  #
295
300
  # Enables or disables interactive mode.
@@ -112,6 +112,7 @@ class Client
112
112
  self.target_id = opts[:target_id]
113
113
  self.capabilities = opts[:capabilities] || {}
114
114
  self.commands = []
115
+ self.last_checkin = Time.now
115
116
 
116
117
  self.conn_id = opts[:conn_id]
117
118
  self.url = opts[:url]
@@ -469,7 +469,7 @@ class ClientCore < Extension
469
469
  end
470
470
 
471
471
  if client.platform =~ /linux/
472
- if writable_dir.blank?
472
+ if writable_dir.to_s.empty?
473
473
  writable_dir = tmp_folder
474
474
  end
475
475
 
@@ -752,7 +752,7 @@ class ClientCore < Extension
752
752
  def tmp_folder
753
753
  tmp = client.sys.config.getenv('TMPDIR')
754
754
 
755
- if tmp.blank?
755
+ if tmp.to_s.empty?
756
756
  tmp = '/tmp'
757
757
  end
758
758
 
@@ -20,6 +20,8 @@ module Android
20
20
  class Android < Extension
21
21
 
22
22
  COLLECT_TYPE_WIFI = 1
23
+ COLLECT_TYPE_GEO = 2
24
+ COLLECT_TYPE_CELL = 3
23
25
 
24
26
  COLLECT_ACTION_START = 1
25
27
  COLLECT_ACTION_PAUSE = 2
@@ -28,7 +30,9 @@ class Android < Extension
28
30
  COLLECT_ACTION_DUMP = 5
29
31
 
30
32
  COLLECT_TYPES = {
31
- 'wifi' => COLLECT_TYPE_WIFI
33
+ 'wifi' => COLLECT_TYPE_WIFI,
34
+ 'geo' => COLLECT_TYPE_GEO,
35
+ 'cell' => COLLECT_TYPE_CELL,
32
36
  }
33
37
 
34
38
  COLLECT_ACTIONS = {
@@ -68,6 +72,12 @@ class Android < Extension
68
72
  response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
69
73
  end
70
74
 
75
+ def set_audio_mode(n)
76
+ request = Packet.create_request('set_audio_mode')
77
+ request.add_tlv(TLV_TYPE_AUDIO_MODE, n)
78
+ response = client.send_request(request)
79
+ end
80
+
71
81
  def interval_collect(opts)
72
82
  request = Packet.create_request('interval_collect')
73
83
  request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]])
@@ -107,6 +117,64 @@ class Android < Extension
107
117
  records.each do |k, v|
108
118
  result[:entries] << v
109
119
  end
120
+
121
+ when COLLECT_TYPE_GEO
122
+ result[:headers] = ['Timestamp', 'Latitude', 'Longitude']
123
+ result[:entries] = []
124
+ records = {}
125
+
126
+ response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
127
+ timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
128
+ timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
129
+
130
+ g.each(TLV_TYPE_COLLECT_RESULT_GEO) do |w|
131
+ lat = w.get_tlv_value(TLV_TYPE_GEO_LAT)
132
+ lng = w.get_tlv_value(TLV_TYPE_GEO_LONG)
133
+ result[:entries] << [timestamp, lat, lng]
134
+ end
135
+ end
136
+
137
+ when COLLECT_TYPE_CELL
138
+ result[:headers] = ['Timestamp', 'Cell Info']
139
+ result[:entries] = []
140
+ records = {}
141
+
142
+ response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
143
+ timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
144
+ timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
145
+
146
+ g.each(TLV_TYPE_COLLECT_RESULT_CELL) do |cell|
147
+
148
+ cell.each(TLV_TYPE_CELL_ACTIVE_GSM) do |info|
149
+ cid = info.get_tlv_value(TLV_TYPE_CELL_CID)
150
+ lac = info.get_tlv_value(TLV_TYPE_CELL_LAC)
151
+ psc = info.get_tlv_value(TLV_TYPE_CELL_PSC)
152
+ info = sprintf("cid=%d lac=%d psc=%d", cid, lac, psc)
153
+ result[:entries] << [timestamp, "GSM: #{info}"]
154
+ end
155
+
156
+ cell.each(TLV_TYPE_CELL_ACTIVE_CDMA) do |info|
157
+ bid = info.get_tlv_value(TLV_TYPE_CELL_BASE_ID)
158
+ lat = info.get_tlv_value(TLV_TYPE_CELL_BASE_LAT)
159
+ lng = info.get_tlv_value(TLV_TYPE_CELL_BASE_LONG)
160
+ net = info.get_tlv_value(TLV_TYPE_CELL_NET_ID)
161
+ sys = info.get_tlv_value(TLV_TYPE_CELL_SYSTEM_ID)
162
+ info = sprintf("base_id=%d lat=%d lng=%d net_id=%d sys_id=%d", bid, lat, lng, net, sys)
163
+ result[:entries] << [timestamp, "CDMA: #{info}"]
164
+ end
165
+
166
+ cell.each(TLV_TYPE_CELL_NEIGHBOR) do |w|
167
+ net = w.get_tlv_value(TLV_TYPE_CELL_NET_TYPE)
168
+ cid = w.get_tlv_value(TLV_TYPE_CELL_CID)
169
+ lac = w.get_tlv_value(TLV_TYPE_CELL_LAC)
170
+ psc = w.get_tlv_value(TLV_TYPE_CELL_PSC)
171
+ sig = w.get_tlv_value(TLV_TYPE_CELL_RSSI) * -1
172
+ inf = sprintf("network_type=%d cid=%d lac=%d psc=%d rssi=%d", net, cid, lac, psc, sig)
173
+ result[:entries] << [timestamp, inf]
174
+ end
175
+
176
+ end
177
+ end
110
178
  end
111
179
 
112
180
  result
@@ -180,6 +248,23 @@ class Android < Extension
180
248
  response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value
181
249
  end
182
250
 
251
+ def activity_start(uri)
252
+ request = Packet.create_request('activity_start')
253
+ request.add_tlv(TLV_TYPE_URI_STRING, uri)
254
+ response = client.send_request(request)
255
+ if response.get_tlv(TLV_TYPE_ACTIVITY_START_RESULT).value
256
+ return nil
257
+ else
258
+ return response.get_tlv(TLV_TYPE_ACTIVITY_START_ERROR).value
259
+ end
260
+ end
261
+
262
+ def set_wallpaper(data)
263
+ request = Packet.create_request('set_wallpaper')
264
+ request.add_tlv(TLV_TYPE_WALLPAPER_DATA, data)
265
+ response = client.send_request(request)
266
+ end
267
+
183
268
  def send_sms(dest, body, dr)
184
269
  request = Packet.create_request('send_sms')
185
270
  request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest)
@@ -54,6 +54,35 @@ TLV_TYPE_COLLECT_RESULT_WIFI_BSSID = TLV_TYPE_WLAN_BSSID
54
54
  TLV_TYPE_COLLECT_RESULT_WIFI_SSID = TLV_TYPE_WLAN_SSID
55
55
  TLV_TYPE_COLLECT_RESULT_WIFI_LEVEL = TLV_TYPE_WLAN_LEVEL
56
56
 
57
+
58
+ TLV_TYPE_COLLECT_RESULT_GEO = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9030)
59
+
60
+ TLV_TYPE_COLLECT_RESULT_CELL = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9060)
61
+
62
+ TLV_TYPE_CELL_ACTIVE_GSM = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9061)
63
+ TLV_TYPE_CELL_ACTIVE_CDMA = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9062)
64
+ TLV_TYPE_CELL_NEIGHBOR = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9063)
65
+
66
+ TLV_TYPE_CELL_NET_TYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9065)
67
+ TLV_TYPE_CELL_CID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9066)
68
+ TLV_TYPE_CELL_LAC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9067)
69
+ TLV_TYPE_CELL_PSC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9068)
70
+ TLV_TYPE_CELL_RSSI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9069)
71
+
72
+
73
+ TLV_TYPE_CELL_BASE_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9070)
74
+ TLV_TYPE_CELL_BASE_LAT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9071)
75
+ TLV_TYPE_CELL_BASE_LONG = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9072)
76
+ TLV_TYPE_CELL_NET_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9073)
77
+ TLV_TYPE_CELL_SYSTEM_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9074)
78
+ TLV_TYPE_AUDIO_MODE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9075)
79
+
80
+ TLV_TYPE_URI_STRING = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9101)
81
+ TLV_TYPE_ACTIVITY_START_RESULT = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9102)
82
+ TLV_TYPE_ACTIVITY_START_ERROR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9103)
83
+
84
+ TLV_TYPE_WALLPAPER_DATA = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 9201)
85
+
57
86
  end
58
87
  end
59
88
  end
@@ -31,7 +31,7 @@ class Wmi
31
31
  def query(query, root = nil)
32
32
  request = Packet.create_request('extapi_wmi_query')
33
33
 
34
- request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.blank?
34
+ request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.to_s.empty?
35
35
  request.add_tlv(TLV_TYPE_EXT_WMI_QUERY, query)
36
36
 
37
37
  response = client.send_request(request)
@@ -24,73 +24,59 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
24
24
  #
25
25
  @@server_channels = {}
26
26
 
27
- class << self
28
- include Rex::Post::Meterpreter::InboundPacketHandler
29
-
30
- #
31
- # This is the request handler which is registerd to the respective meterpreter instance via
32
- # Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket. All incoming requests from the meterpreter
33
- # for a 'tcp_channel_open' will be processed here. We create a new TcpClientChannel for each request
34
- # received and store it in the respective tcp server channels list of new pending client channels.
35
- # These new tcp client channels are passed off via a call the the tcp server channels accept() method.
36
- #
37
- def request_handler( client, packet )
38
-
39
- if( packet.method == "tcp_channel_open" )
40
-
41
- cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
42
- pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
43
- localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
44
- localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
45
- peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
46
- peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
47
-
48
- if( cid == nil or pid == nil )
49
- return false
50
- end
51
-
52
- server_channel = client.find_channel( pid )
53
- if( server_channel == nil )
54
- return false
55
- end
56
-
57
- params = Rex::Socket::Parameters.from_hash(
58
- {
59
- 'Proto' => 'tcp',
60
- 'LocalHost' => localhost,
61
- 'LocalPort' => localport,
62
- 'PeerHost' => peerhost,
63
- 'PeerPort' => peerport,
64
- 'Comm' => server_channel.client
65
- }
66
- )
67
-
68
- client_channel = TcpClientChannel.new( client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS )
69
-
70
- client_channel.params = params
71
-
72
- if( @@server_channels[server_channel] == nil )
73
- @@server_channels[server_channel] = []
74
- end
75
-
76
- @@server_channels[server_channel] << client_channel
77
-
78
- return true
79
- end
80
-
81
- return false
82
- end
27
+ #
28
+ # This is the request handler which is registered to the respective meterpreter instance via
29
+ # Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket. All incoming requests from the meterpreter
30
+ # for a 'tcp_channel_open' will be processed here. We create a new TcpClientChannel for each request
31
+ # received and store it in the respective tcp server channels list of new pending client channels.
32
+ # These new tcp client channels are passed off via a call the the tcp server channels accept() method.
33
+ #
34
+ def self.request_handler(client, packet)
35
+ return false unless packet.method == "tcp_channel_open"
83
36
 
84
- def cls
85
- return CHANNEL_CLASS_STREAM
86
- end
37
+ cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
38
+ pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
39
+ localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
40
+ localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
41
+ peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
42
+ peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
43
+
44
+ return false if cid.nil? || pid.nil?
45
+
46
+ server_channel = client.find_channel(pid)
47
+
48
+ return false if server_channel.nil?
87
49
 
50
+ params = Rex::Socket::Parameters.from_hash(
51
+ {
52
+ 'Proto' => 'tcp',
53
+ 'LocalHost' => localhost,
54
+ 'LocalPort' => localport,
55
+ 'PeerHost' => peerhost,
56
+ 'PeerPort' => peerport,
57
+ 'Comm' => server_channel.client
58
+ }
59
+ )
60
+
61
+ client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS)
62
+
63
+ client_channel.params = params
64
+
65
+ @@server_channels[server_channel] ||= ::Queue.new
66
+ @@server_channels[server_channel].enq(client_channel)
67
+
68
+ true
69
+ end
70
+
71
+ def self.cls
72
+ CHANNEL_CLASS_STREAM
88
73
  end
89
74
 
90
75
  #
91
76
  # Open a new tcp server channel on the remote end.
92
77
  #
93
- def TcpServerChannel.open(client, params)
78
+ # @return [Channel]
79
+ def self.open(client, params)
94
80
  c = Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
95
81
  [
96
82
  {
@@ -112,7 +98,7 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
112
98
  def initialize(client, cid, type, flags)
113
99
  super(client, cid, type, flags)
114
100
  # add this instance to the class variables dictionary of tcp server channels
115
- @@server_channels[self] = []
101
+ @@server_channels[self] ||= ::Queue.new
116
102
  end
117
103
 
118
104
  #
@@ -120,46 +106,46 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
120
106
  # and returns nil if no new client connection is available.
121
107
  #
122
108
  def accept_nonblock
123
- result = nil
124
- if( @@server_channels[self].length > 0 )
125
- channel = @@server_channels[self].shift
126
- result = channel.lsock
127
- end
128
- return result
109
+ _accept(true)
129
110
  end
130
111
 
131
112
  #
132
113
  # Accept a new tcp client connection form this tcp server channel. This method will block indefinatly
133
114
  # if no timeout is specified.
134
115
  #
135
- def accept( opts={} )
136
- timeout = opts['Timeout'] || -1
137
- if( timeout == -1 )
138
- result = _accept
139
- else
140
- begin
141
- ::Timeout.timeout( timeout ) {
142
- result = _accept
143
- }
144
- rescue Timeout::Error
145
- result = nil
146
- end
116
+ def accept(opts = {})
117
+ timeout = opts['Timeout']
118
+ if (timeout.nil? || timeout <= 0)
119
+ timeout = 0
147
120
  end
148
- return result
121
+
122
+ result = nil
123
+ begin
124
+ ::Timeout.timeout(timeout) {
125
+ result = _accept
126
+ }
127
+ rescue Timeout::Error
128
+ end
129
+
130
+ result
149
131
  end
150
132
 
151
133
  protected
152
134
 
153
- def _accept
154
- while( true )
155
- if( @@server_channels[self].empty? )
156
- Rex::ThreadSafe.sleep( 0.2 )
157
- next
158
- end
159
- result = accept_nonblock
160
- break if result != nil
135
+ def _accept(nonblock = false)
136
+ result = nil
137
+
138
+ channel = @@server_channels[self].deq(nonblock)
139
+
140
+ if channel
141
+ result = channel.lsock
161
142
  end
162
- return result
143
+
144
+ if result != nil && !result.kind_of?(Rex::Socket::Tcp)
145
+ result.extend(Rex::Socket::Tcp)
146
+ end
147
+
148
+ result
163
149
  end
164
150
 
165
151
  end