watobo 0.9.20 → 0.9.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGELOG.md +54 -2
  2. data/README.md +1 -1
  3. data/config/scanner.yml +1 -0
  4. data/custom-views/prettify-json.rb +19 -0
  5. data/lib/watobo/adapters/file/marshal_store.rb +297 -0
  6. data/lib/watobo/adapters.rb +2 -1
  7. data/lib/watobo/core/active_check.rb +4 -0
  8. data/lib/watobo/core/chat.rb +8 -0
  9. data/lib/watobo/core/chats.rb +2 -1
  10. data/lib/watobo/core/cookie.rb +3 -3
  11. data/lib/watobo/core/finding.rb +7 -0
  12. data/lib/watobo/core/request.rb +3 -3
  13. data/lib/watobo/core/session.rb +6 -2
  14. data/lib/watobo/framework/init_modules.rb +18 -16
  15. data/lib/watobo/gui/conversation_table.rb +13 -16
  16. data/lib/watobo/gui/conversation_table_ctrl2.rb +1 -0
  17. data/lib/watobo/gui/custom_viewer.rb +101 -76
  18. data/lib/watobo/gui/define_scope_frame.rb +44 -10
  19. data/lib/watobo/gui/edit_scope_dialog.rb +1 -1
  20. data/lib/watobo/gui/fuzzer_gui.rb +61 -23
  21. data/lib/watobo/gui/main_window.rb +1 -1
  22. data/lib/watobo/gui/scanner_settings_dialog.rb +15 -0
  23. data/lib/watobo/http/data/json.rb +6 -0
  24. data/lib/watobo/interceptor/html/favicon.ico +0 -0
  25. data/lib/watobo/interceptor/html/index.html +13 -0
  26. data/lib/watobo/interceptor/proxy.rb +70 -18
  27. data/lib/watobo/mixins/httpparser.rb +26 -16
  28. data/lib/watobo/mixins/shapers.rb +49 -5
  29. data/lib/watobo/mixins/transcoders.rb +8 -8
  30. data/lib/watobo/sockets/connection.rb +1 -1
  31. data/lib/watobo/utils/load_chat.rb +62 -0
  32. data/lib/watobo/utils/response_hash.rb +3 -3
  33. data/lib/watobo.rb +1 -1
  34. data/modules/active/cq5/cq5_default_selectors.rb +116 -0
  35. data/modules/active/cq5/cqp_user_enumeration.rb +134 -0
  36. data/modules/active/struts2/include_params_ognl.rb +1 -1
  37. data/modules/active/xml/xml_xxe.rb +6 -1
  38. data/modules/passive/disclosure_domino.rb +1 -1
  39. data/modules/passive/in_script_parameter.rb +9 -4
  40. data/plugins/aem/aem.rb +21 -0
  41. data/plugins/aem/gui/main.rb +128 -0
  42. data/plugins/aem/gui/tree_view.rb +180 -0
  43. data/plugins/aem/icons/aem.ico +0 -0
  44. data/plugins/aem/lib/agent.rb +140 -0
  45. data/plugins/aem/lib/dispatcher.rb +53 -0
  46. data/plugins/aem/lib/engine.rb +187 -0
  47. data/plugins/filefinder/dbs/cq5.db +23 -0
  48. data/plugins/filefinder/dbs/subs-big.lst +44 -44
  49. data/plugins/filefinder/filefinder.rb +4 -4
  50. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +11 -10
  51. metadata +16 -2
@@ -35,9 +35,9 @@ module Watobo#:nodoc: all
35
35
  @name = prefs[:name]
36
36
  @value = prefs[:value]
37
37
  else
38
- puts "= NEW COOKIE ="
39
- puts prefs
40
- puts prefs.class
38
+ # puts "= NEW COOKIE ="
39
+ # puts prefs
40
+ # puts prefs.class
41
41
  chunks = prefs.split(";")
42
42
  # first chunk
43
43
  @name, @value = chunks.first.split(":").last.split("=")
@@ -45,6 +45,13 @@ module Watobo#:nodoc: all
45
45
  return @details[name]
46
46
  end
47
47
  super
48
+ end
49
+
50
+ def to_h
51
+ h = { :details => @details }
52
+ h[:request] = @request.to_a
53
+ h[:response] = @response.to_a
54
+ h
48
55
  end
49
56
 
50
57
  def initialize(request, response, details = {})
@@ -124,7 +124,7 @@ module Watobo#:nodoc: all
124
124
  elsif r.is_a? String
125
125
  if r =~ /^http/
126
126
  uri = URI.parse r
127
- self << "GET #{uri.to_s} HTTP/1.0\r\n"
127
+ self << "GET #{uri.to_s} HTTP/1.1\r\n"
128
128
  self << "Host: #{uri.host}\r\n"
129
129
  else
130
130
  r.extend Watobo::Mixins::RequestParser
@@ -134,8 +134,8 @@ module Watobo#:nodoc: all
134
134
  end
135
135
  self.extend Watobo::Mixin::Parser::Url
136
136
  self.extend Watobo::Mixin::Parser::Web10
137
- self.extend Watobo::Mixin::Shaper::Web10
138
-
137
+ self.extend Watobo::Mixin::Shaper::Web10
138
+
139
139
  @url = Watobo::HTTP::Url.new(self)
140
140
  case self.content_type
141
141
  when /www-form/i
@@ -92,7 +92,11 @@ module Watobo#:nodoc: all
92
92
  #---------------------------------------
93
93
  # request.removeHeader("^Proxy-Connection") #if not use_proxy
94
94
  # request.removeHeader("^Connection") #if not use_proxy
95
- #request.removeHeader("^Accept-Encoding")
95
+
96
+ # !!!
97
+ # remove Accept-Encoding header
98
+ # otherwise we won't get the content-length information for pass-through feature
99
+ request.removeHeader("^Accept-Encoding")
96
100
  # If-Modified-Since: Tue, 28 Oct 2008 11:06:43 GMT
97
101
  # If-None-Match: W/"3975-1225192003000"
98
102
  # request.removeHeader("^If-")
@@ -1117,7 +1121,7 @@ end
1117
1121
  return nil
1118
1122
  end
1119
1123
 
1120
- header = [ "HTTP/1.1 200 OK\r\n", "Server: WATOBO\r\n", "Content-Length: #{msg.length.to_i}\r\n", "Content-Type: text/html\r\n", "\r\n", "#{msg}" ] unless msg.nil?
1124
+ header = [ "HTTP/1.1 502 Bad Gateway\r\n", "Server: WATOBO\r\n", "Content-Length: #{msg.length.to_i}\r\n", "Content-Type: text/html\r\n", "\r\n", "#{msg}" ] unless msg.nil?
1121
1125
 
1122
1126
  response = Watobo::Response.new header
1123
1127
  # update_sids(header)
@@ -7,7 +7,7 @@
7
7
  # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
8
  # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9
9
 
10
- # @private
10
+ # @private
11
11
  module Watobo#:nodoc: all
12
12
 
13
13
  private
@@ -36,14 +36,14 @@ module Watobo#:nodoc: all
36
36
  # notify(:logger, LOG_DEBUG, "#{modules} loaded.")
37
37
 
38
38
  rescue => bang
39
- puts "!!!"
40
- puts bang
39
+ puts "!!!"
40
+ puts bang
41
41
  end
42
42
  end
43
43
  passive_modules
44
44
  end
45
-
46
- def self.init_passive_modules(filter='')
45
+
46
+ def self.init_passive_modules(filter='')
47
47
  # puts "get passive modules from path #{@settings[:module_path]}/passive"
48
48
  passive_modules = []
49
49
 
@@ -52,25 +52,24 @@ module Watobo#:nodoc: all
52
52
  mod = File.basename(mod_file)
53
53
 
54
54
  load mod_file
55
- rescue => bang
56
- puts "!!!"
57
- puts bang
55
+ rescue => bang
56
+ puts "!!!"
57
+ puts bang
58
58
  end
59
59
  end
60
-
60
+
61
61
  Watobo::Modules::Passive.constants.each do |m|
62
62
  begin
63
63
  class_constant = Watobo::Modules::Passive.const_get(m)
64
64
  passive_modules.push class_constant
65
65
  rescue => bang
66
- puts "!!!"
67
- puts bang
66
+ puts "!!!"
67
+ puts bang
68
68
  end
69
69
  end
70
70
  passive_modules
71
71
  end
72
72
 
73
-
74
73
  def self.init_active_modules()
75
74
 
76
75
  active_path = Watobo.active_module_path
@@ -96,7 +95,10 @@ module Watobo#:nodoc: all
96
95
  # notify(:logger, LOG_INFO, "#{module_class} loaded.")
97
96
  active_checks.push class_constant
98
97
  rescue => bang
99
- puts bang
98
+ puts '---'
99
+ puts bang
100
+ puts "when loading module file #{mod_file}"
101
+ puts '---'
100
102
  # notify(:logger, LOG_DEBUG, "problems loading module: #{@settings[:module_path]}/active/#{group}/#{modules}")
101
103
  end
102
104
  end
@@ -125,9 +127,9 @@ module Watobo#:nodoc: all
125
127
  #@interface.log("#{modules} loaded.")
126
128
 
127
129
  rescue => bang
128
- puts bang
129
- #@interface.log("problems loading module: #{module_path}/#{group}/#{modules}")
130
- puts "problems loading module: #{filename}"
130
+ puts bang
131
+ #@interface.log("problems loading module: #{module_path}/#{group}/#{modules}")
132
+ puts "problems loading module: #{filename}"
131
133
  end
132
134
  end
133
135
  end
@@ -436,23 +436,19 @@ module Watobo#:nodoc: all
436
436
 
437
437
  parms = ""
438
438
  unless ps.empty?
439
- # parms = ps[0..50]
440
- # parms += "..." if ps.length > 50
439
+ ps_ascii = ps.force_encoding('ASCII-8BIT')
440
+
441
441
  if @url_decode == true
442
442
  if chat.request.content_type =~ /(json|xml)/
443
- parms = ps.unpack('C*').pack('U*')
444
- else
445
- parms = CGI.unescape(ps).unpack('C*').pack('U*')
443
+ parms = ps_ascii
444
+ else
445
+ parms = CGI.unescape(ps_ascii)
446
446
  end
447
447
  end
448
448
  parms.gsub!(/[^[:print:]]/,'.')
449
449
 
450
450
  end
451
451
 
452
- #if parms.length > 50
453
- # parms = parms[0..50] + "..."
454
- #end
455
-
456
452
  self.setItemText(lastRowIndex, index, parms)
457
453
  self.getItem(lastRowIndex, index).justify = FXTableItem::LEFT
458
454
 
@@ -478,7 +474,9 @@ module Watobo#:nodoc: all
478
474
  self.setItemData(lastRowIndex, 0, chat)
479
475
 
480
476
  #self.makePositionVisible(self.numRows-1, 0) if @autoscroll == true
481
- self.setPosition(self.xPosition, (self.viewportHeight - self.contentHeight - 20 ))
477
+ if @autoscroll == true
478
+ self.setPosition(self.xPosition, (self.viewportHeight - self.contentHeight - 20 ))
479
+ end
482
480
  end
483
481
 
484
482
  def update_table()
@@ -611,14 +609,13 @@ module Watobo#:nodoc: all
611
609
  else
612
610
  sel = ni
613
611
  end
614
- puts "neares: #{sel}"
615
- if sel >= 0
616
- selectRow(sel, false)
617
-
618
- setCurrentItem(sel, 2)
619
- makePositionVisible(i,2)
620
612
 
613
+ if sel >= 0
614
+ selectRow(sel, false)
615
+ setCurrentItem(sel, 2)
616
+ makePositionVisible(sel,2)
621
617
  end
618
+
622
619
  false
623
620
  end
624
621
 
@@ -296,6 +296,7 @@ module Watobo#:nodoc: all
296
296
  @table_option_autoscroll.setCheck(true)
297
297
 
298
298
  @table_option_autoscroll.connect(SEL_COMMAND){
299
+ puts "* Autoscroll >> #{@table_option_autoscroll.checked?.class}"
299
300
  @table.autoscroll = @table_option_autoscroll.checked?
300
301
  }
301
302
 
@@ -10,12 +10,99 @@
10
10
  # @private
11
11
  module Watobo#:nodoc: all
12
12
  module Gui
13
+
14
+ class ViewerHandlerCtrl < FXHorizontalFrame
15
+ attr :handler
16
+
17
+ def has_handler?
18
+ !@handler.nil?
19
+ end
20
+
21
+ def initialize(parent, opts = { :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM, :padding => 0 })
22
+ super parent, opts
23
+ @parent = parent
24
+ #handler_ctrl_frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X, :padding => 0)
25
+ FXLabel.new(self, "View Handler:")
26
+ @handler_status_lbl = FXLabel.new(self, "None")
27
+ @handler_status_lbl.backColor = "red"
28
+ add_handler_btn = FXButton.new(self, "add", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
29
+ add_handler_btn.connect(SEL_COMMAND){ add_handler }
30
+ reload_handler_btn = FXButton.new(self, "reload", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
31
+ reload_handler_btn.connect(SEL_COMMAND){ load_handler(@handler_file) }
32
+ reset_handler_btn = FXButton.new(self, "reset", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
33
+
34
+ reset_handler_btn.connect(SEL_COMMAND){
35
+ @handler = nil
36
+ @handler_file = nil
37
+ @handler_status_lbl.text = "None"
38
+ @handler_status_lbl.backColor = "red"
39
+ }
40
+ end
41
+
42
+
43
+ def add_handler
44
+ handler_filename = FXFileDialog.getOpenFilename(self, "Select handler file", @handler_path, "*.rb\n*")
45
+ if handler_filename != "" then
46
+ if File.exists?(handler_filename) then
47
+ @handler_file = handler_filename
48
+ @handler_path = File.dirname(handler_filename) + "/"
49
+ load_handler(handler_filename)
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ def load_handler(file)
56
+ @handler = nil
57
+ @handler_status_lbl.text = "None"
58
+ @handler_status_lbl.backColor = "red"
59
+
60
+ return false if file.nil?
61
+ return false unless File.exist? file
62
+ begin
63
+ source = File.read(file)
64
+ #puts source
65
+ result = eval(source)
66
+ if result.respond_to? :call
67
+ @handler = result
68
+ @handler_status_lbl.text = "#{File.basename(file).gsub(/\.rb$/,'')}"
69
+ @handler_status_lbl.textColor = 'black'
70
+ @handler_status_lbl.backColor = 'green'
71
+ @parent.setText
72
+ end
73
+ return true
74
+
75
+ rescue SyntaxError, LocalJumpError, NameError => e
76
+ out = e.to_s
77
+ out << e.backtrace.join("\n")
78
+ rescue => bang
79
+ out = bang
80
+ out << bang.backtrace.join("\n")
81
+ end
82
+ puts out
83
+ return false
84
+ end
85
+
86
+ def call_handler(object)
87
+ return object if @handler.nil?
88
+ begin
89
+ result = @handler.call(object)
90
+ return result
91
+ rescue => bang
92
+ result = bang.to_s
93
+ result << bang.backtrace.join("\n")
94
+ return result
95
+ end
96
+
97
+ end
98
+ end
13
99
 
14
100
 
15
101
  class CustomViewer < FXVerticalFrame
16
- SEL_TYPE_GREP = 0
17
- SEL_TYPE_HIGHLIGHT = 1
102
+ SEL_TYPE_GREP = 0
103
+ SEL_TYPE_HIGHLIGHT = 1
18
104
  attr_accessor :max_len
105
+
19
106
  def style=(new_style)
20
107
  @simple_text_view.style = new_style
21
108
  end
@@ -24,13 +111,17 @@ module Watobo#:nodoc: all
24
111
  @simple_text_view.editable = value
25
112
  end
26
113
 
27
- def setText(text, prefs={})
114
+ def setText(object=nil, prefs={})
28
115
 
29
- normalized_text = text
30
- if text.is_a? Watobo::Request or text.is_a? Watobo::Response
31
- return false unless @handler.respond_to? :call
32
- result = call_handler(text)
33
- normalized_text = result
116
+ o = object.nil? ? @object : object
117
+ return false if o.nil?
118
+ @object = o
119
+ normalized_text = o.to_s
120
+ if o.is_a? Watobo::Request or o.is_a? Watobo::Response
121
+ if @handler_ctrl.has_handler?
122
+ result = @handler_ctrl.call_handler(o)
123
+ normalized_text = result
124
+ end
34
125
  else
35
126
  return false
36
127
  end
@@ -64,6 +155,7 @@ module Watobo#:nodoc: all
64
155
 
65
156
  @style = 2 # default style
66
157
  @text = ''
158
+ @object = nil
67
159
  @max_len = 5000
68
160
  @filter_mode = SEL_TYPE_HIGHLIGHT
69
161
  @cur_match_pos = 0
@@ -74,20 +166,7 @@ module Watobo#:nodoc: all
74
166
  @handler_file = nil
75
167
  @handler_path = nil
76
168
 
77
- handler_ctrl_frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X, :padding => 0)
78
- @handler_status_lbl = FXLabel.new(handler_ctrl_frame, "No handler!")
79
- @handler_status_lbl.textColor = "red"
80
- add_handler_btn = FXButton.new(handler_ctrl_frame, "add", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
81
- add_handler_btn.connect(SEL_COMMAND){ add_handler }
82
- reload_handler_btn = FXButton.new(handler_ctrl_frame, "reload", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
83
- reload_handler_btn.connect(SEL_COMMAND){ load_handler(@handler_file) }
84
- reset_handler_btn = FXButton.new(handler_ctrl_frame, "reset", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
85
- reset_handler_btn.connect(SEL_COMMAND){
86
- @handler = nil
87
- @handler_file = nil
88
- @handler_status_lbl = FXLabel.new(handler_ctrl_frame, "No handler!")
89
- @handler_status_lbl.textColor = "red"
90
- }
169
+ @handler_ctrl = ViewerHandlerCtrl.new(self)
91
170
 
92
171
  text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT,:height => 24, :padding => 0)
93
172
 
@@ -163,60 +242,6 @@ module Watobo#:nodoc: all
163
242
  end
164
243
 
165
244
  private
166
-
167
- def add_handler
168
-
169
- handler_filename = FXFileDialog.getOpenFilename(self, "Select handler file", @handler_path, "*.rb\n*")
170
- if handler_filename != "" then
171
- if File.exists?(handler_filename) then
172
- @handler_file = handler_filename
173
- @handler_path = File.dirname(handler_filename) + "/"
174
- load_handler(handler_filename)
175
- end
176
- end
177
-
178
- end
179
-
180
- def load_handler(file)
181
- @handler = nil
182
- @handler_status_lbl.text = "No handler!"
183
- @handler_status_lbl.textColor = "red"
184
-
185
- return false if file.nil?
186
- return false unless File.exist? file
187
- begin
188
- source = File.read(file)
189
- #puts source
190
- result = eval(source)
191
- if result.respond_to? :call
192
- @handler = result
193
- @handler_status_lbl.text = "Handler ready!"
194
- @handler_status_lbl.textColor = "green"
195
- end
196
- return true
197
-
198
- rescue SyntaxError, LocalJumpError, NameError => e
199
- out = e.to_s
200
- out << e.backtrace.join("\n")
201
- rescue => bang
202
- out = bang
203
- out << bang.backtrace.join("\n")
204
- end
205
- puts out
206
- return false
207
- end
208
-
209
- def call_handler(object)
210
- begin
211
- result = @handler.call(object)
212
- return result
213
- rescue => bang
214
- result = bang.to_s
215
- result << bang.backtrace.join("\n")
216
- return result
217
- end
218
-
219
- end
220
245
 
221
246
  def gotoNextMatch()
222
247
  @cur_match_pos += 1 if @cur_match_pos < @simple_text_view.numMatches-1
@@ -187,7 +187,7 @@ module Watobo#:nodoc: all
187
187
  class DefineScopeFrame < FXVerticalFrame
188
188
 
189
189
  def onDeselectAll(sender, sel, item)
190
- @scope.each do |site, val|
190
+ @cb_sites.each_key do |site|
191
191
  @cb_sites[site].setCheck(false)
192
192
  @edit_btns[site].disable
193
193
  end
@@ -198,7 +198,7 @@ module Watobo#:nodoc: all
198
198
 
199
199
  def onSelectAll(sender, sel, item)
200
200
  sites = []
201
- @scope.each do |site, scope|
201
+ @cb_sites.each_key do |site|
202
202
  @cb_sites[site].setCheck(true)
203
203
  @edit_btns[site].enable
204
204
  end
@@ -266,6 +266,17 @@ EOF
266
266
  #btn.font = @font
267
267
  #btn.backColor = FXColor::White
268
268
  btn.justify = JUSTIFY_LEFT
269
+
270
+ quickFilterFrame = FXHorizontalFrame.new(self, LAYOUT_FILL_X)
271
+ FXLabel.new(quickFilterFrame, "Filter:", nil, :opts => LAYOUT_TOP|JUSTIFY_RIGHT)
272
+ filter_regexp = FXTextField.new(quickFilterFrame, 25, nil, 0, :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_LEFT)
273
+ filter_btn = FXButton.new(quickFilterFrame, "apply")
274
+
275
+ filter_regexp.connect(SEL_COMMAND){ list_sites(filter_regexp.text.strip) }
276
+ filter_btn.connect(SEL_COMMAND){ list_sites(filter_regexp.text.strip) }
277
+
278
+
279
+
269
280
  quickSelectFrame = FXHorizontalFrame.new(self, LAYOUT_FILL_X)
270
281
  @sel_all_btn = FXButton.new(quickSelectFrame, "Select All", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X)
271
282
  @sel_all_btn.connect(SEL_COMMAND, method(:onSelectAll))
@@ -275,18 +286,41 @@ EOF
275
286
 
276
287
  @desel_all_btn = FXButton.new(quickSelectFrame, "Deselect All", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X)
277
288
  @desel_all_btn.connect(SEL_COMMAND, method(:onDeselectAll))
278
- frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE, :padding => 0)
289
+ frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE, :padding => 0)
290
+
279
291
  sitesArea = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
280
- sitesFrame = FXVerticalFrame.new(sitesArea, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
281
- puts "list sites"
292
+ @sitesFrame = FXVerticalFrame.new(sitesArea, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
293
+
294
+ list_sites
295
+
296
+ updateFrame()
297
+ end
298
+
299
+ private
300
+
301
+ def list_sites(p='.*')
302
+ @cb_sites.clear
303
+ @edit_btns.clear
304
+ # clear container
305
+ @sitesFrame.each_child do |c|
306
+ @sitesFrame.removeChild c
307
+ end
308
+ @sitesFrame.recalc
309
+ @sitesFrame.update
310
+
311
+ pattern = p
312
+ pattern = '.*' if p.nil? or p.empty?
313
+
282
314
  sites = Watobo::Chats.sites()
283
- puts sites.length
315
+ sites.compact!
316
+
284
317
  sites.sort.each do |site|
285
- puts site
286
- site_frame = FXHorizontalFrame.new(sitesFrame, :opts => LAYOUT_FILL_X)
318
+ next unless site =~ /#{pattern}/
319
+ site_frame = FXHorizontalFrame.new(@sitesFrame, :opts => LAYOUT_FILL_X)
287
320
  b = FXCheckButton.new(site_frame, site, nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
288
321
  eb = FXButton.new(site_frame, "edit..", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT)
289
322
  @edit_btns[site] = eb
323
+ site_frame.create if self.parent.created?
290
324
 
291
325
  b.connect(SEL_COMMAND){
292
326
  b.checked? ? @edit_btns[site].enable : @edit_btns[site].disable
@@ -316,11 +350,11 @@ EOF
316
350
  }
317
351
 
318
352
  end
319
- updateFrame()
353
+ @sitesFrame.recalc
354
+ @sitesFrame.update
320
355
  end
321
356
 
322
357
 
323
-
324
358
  end #EOC
325
359
  #--
326
360
  end