rex 2.0.9 → 2.0.10

Sign up to get free protection for your applications and to get access to all the features.
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