watobo 0.9.9.pre3 → 0.9.9

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 (90) hide show
  1. data/.yardopts +24 -0
  2. data/CHANGELOG +17 -7
  3. data/README +4 -60
  4. data/bin/nfq_server.rb +191 -0
  5. data/config/interceptor.yml +2 -6
  6. data/lib/watobo/adapters/data_store.rb +1 -1
  7. data/lib/watobo/adapters/file/file_store.rb +50 -33
  8. data/lib/watobo/ca.rb +22 -0
  9. data/lib/watobo/config.rb +6 -0
  10. data/lib/watobo/core/ca.rb +411 -0
  11. data/lib/watobo/core/cert_store.rb +56 -0
  12. data/lib/watobo/core/forwarding_proxy.rb +38 -0
  13. data/lib/watobo/core/http_socket.rb +18 -0
  14. data/lib/watobo/core/intercept_carver.rb +179 -0
  15. data/lib/watobo/core/intercept_filter.rb +257 -0
  16. data/lib/watobo/core/interceptor.rb +342 -79
  17. data/lib/watobo/core/netfilter_queue.rb +191 -0
  18. data/lib/watobo/core/project.rb +84 -138
  19. data/lib/watobo/core/proxy.rb +61 -0
  20. data/lib/watobo/core/request.rb +40 -0
  21. data/lib/watobo/core/response.rb +30 -0
  22. data/lib/watobo/core/scanner.rb +64 -58
  23. data/lib/watobo/core/session.rb +70 -77
  24. data/lib/watobo/core.rb +1 -1
  25. data/lib/watobo/framework/create_project.rb +25 -10
  26. data/lib/watobo/framework/init.rb +13 -0
  27. data/lib/watobo/gui/browser_preview.rb +5 -4
  28. data/lib/watobo/gui/checks_policy_frame.rb +1 -0
  29. data/lib/watobo/gui/client_cert_dialog.rb +11 -6
  30. data/lib/watobo/gui/conversation_table.rb +7 -4
  31. data/lib/watobo/gui/fuzzer_gui.rb +9 -11
  32. data/lib/watobo/gui/intercept_filter_dialog.rb +210 -0
  33. data/lib/watobo/gui/interceptor_gui.rb +59 -21
  34. data/lib/watobo/gui/interceptor_settings_dialog.rb +39 -5
  35. data/lib/watobo/gui/list_box.rb +2 -1
  36. data/lib/watobo/gui/log_viewer.rb +79 -5
  37. data/lib/watobo/gui/main_window.rb +159 -113
  38. data/lib/watobo/gui/manual_request_editor.rb +11 -5
  39. data/lib/watobo/gui/mixins/subscriber.rb +47 -0
  40. data/lib/watobo/gui/project_wizzard.rb +3 -3
  41. data/lib/watobo/gui/proxy_dialog.rb +17 -18
  42. data/lib/watobo/gui/request_editor.rb +1 -1
  43. data/lib/watobo/gui/rewrite_filters_dialog.rb +416 -0
  44. data/lib/watobo/gui/rewrite_rules_dialog.rb +394 -0
  45. data/lib/watobo/gui/scanner_settings_dialog.rb +9 -6
  46. data/lib/watobo/gui/session_management_dialog.rb +33 -23
  47. data/lib/watobo/gui/sites_tree.rb +5 -6
  48. data/lib/watobo/gui/status_bar.rb +101 -49
  49. data/lib/watobo/gui/table_editor.rb +1 -1
  50. data/lib/watobo/gui/templates/plugin2.rb +23 -27
  51. data/lib/watobo/gui/utils/save_default_settings.rb +9 -9
  52. data/lib/watobo/gui/utils/save_proxy_settings.rb +25 -9
  53. data/lib/watobo/gui/utils/save_scanner_settings.rb +10 -7
  54. data/lib/watobo/gui/utils/session_history.rb +1 -1
  55. data/lib/watobo/gui/www_auth_dialog.rb +25 -21
  56. data/lib/watobo/gui.rb +3 -1
  57. data/lib/watobo/mixins/httpparser.rb +47 -40
  58. data/lib/watobo/mixins/request_parser.rb +126 -41
  59. data/lib/watobo/mixins/shapers.rb +124 -15
  60. data/lib/watobo/utils/hexprint.rb +31 -0
  61. data/lib/watobo/utils/load_chat.rb +2 -0
  62. data/lib/watobo/utils/response_builder.rb +111 -0
  63. data/lib/watobo.rb +4 -1
  64. data/modules/active/discovery/http_methods.rb +6 -4
  65. data/modules/active/fileinclusion/lfi_simple.rb +3 -3
  66. data/modules/active/sqlinjection/sqli_timing.rb +6 -6
  67. data/modules/passive/redirectionz.rb +5 -6
  68. data/plugins/catalog/catalog.rb +240 -56
  69. data/plugins/catalog/db_tests +1 -6483
  70. data/plugins/catalog/db_variables +2 -29
  71. data/plugins/crawler/gui/auth_frame.rb +15 -3
  72. data/plugins/crawler/gui/crawler_gui.rb +24 -0
  73. data/plugins/crawler/gui/hooks_frame.rb +7 -2
  74. data/plugins/crawler/gui/settings_tabbook.rb +4 -0
  75. data/plugins/crawler/gui.rb +3 -3
  76. data/plugins/crawler/lib/engine.rb +1 -1
  77. data/plugins/filefinder/filefinder.rb +21 -17
  78. data/plugins/sqlmap/bin/test.rb +100 -0
  79. data/plugins/sqlmap/gui/main.rb +227 -0
  80. data/plugins/sqlmap/gui/options_frame.rb +119 -0
  81. data/plugins/sqlmap/gui.rb +27 -0
  82. data/plugins/sqlmap/icons/sqlmap.ico +0 -0
  83. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +116 -0
  84. data/plugins/sqlmap/sqlmap.rb +26 -0
  85. data/plugins/sslchecker/gui/gui.rb +45 -30
  86. metadata +32 -9
  87. data/certificates/cert.pem +0 -19
  88. data/certificates/privkey.pem +0 -15
  89. data/certificates/watobo_dh.key +0 -5
  90. data/lib/watobo/core/simple_ca.rb +0 -393
@@ -996,12 +996,10 @@ module Watobo
996
996
  scan_prefs[:check_online] = false
997
997
  # check if logging all scan chat
998
998
 
999
- if @logScanChats.checked? and File.exist?(@log_dir_dt.value)
1000
- new_dir = File.join(@log_dir_dt.value, "fuzzer-" + Time.now.to_f.to_s )
1001
- Dir.mkdir(new_dir)
1002
- scan_prefs[:scanlog_dir] = new_dir
1003
- end
1004
-
999
+ if @logScanChats.checked?
1000
+ scan_prefs[:scanlog_name] = @log_dir_dt.value unless @log_dir_dt.value.empty?
1001
+ end
1002
+
1005
1003
  @scanner = Watobo::Scanner2.new(chat_list, check_list, @project.passive_checks, scan_prefs)
1006
1004
  @pbar.total = @scanner.numTotalChecks
1007
1005
  @pbar.progress = 0
@@ -1136,29 +1134,29 @@ puts "run scanner"
1136
1134
  if @logScanChats.checked? then
1137
1135
  @log_dir_text.enabled = true
1138
1136
  @log_dir_label.enabled = true
1139
- @log_dir_btn.enable
1137
+ # @log_dir_btn.enable
1140
1138
  else
1141
1139
  @log_dir_text.enabled = false
1142
1140
  @log_dir_label.enabled = false
1143
- @log_dir_btn.disable
1141
+ # @log_dir_btn.disable
1144
1142
  end
1145
1143
  end
1146
1144
 
1147
1145
 
1148
1146
  @log_dir_dt = FXDataTarget.new('')
1149
1147
  # @log_dir_dt.value = @project.scanLogDirectory() if File.exist?(@project.scanLogDirectory())
1150
- @log_dir_label = FXLabel.new(opt, "Scan-Log Directory:" )
1148
+ @log_dir_label = FXLabel.new(opt, "Scan Name:" )
1151
1149
  scanlog_frame = FXHorizontalFrame.new(opt,:opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
1152
1150
  @log_dir_text = FXTextField.new(scanlog_frame, 20,
1153
1151
  :target => @log_dir_dt, :selector => FXDataTarget::ID_VALUE,
1154
1152
  :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN)
1155
1153
  @log_dir_text.handle(self, FXSEL(SEL_UPDATE, 0), nil)
1156
- @log_dir_btn = FXButton.new(scanlog_frame, "Change")
1154
+ # @log_dir_btn = FXButton.new(scanlog_frame, "Change")
1157
1155
  # @log_dir_btn.connect(SEL_COMMAND, method(:selectLogDirectory))
1158
1156
 
1159
1157
  @log_dir_text.enabled = false
1160
1158
  @log_dir_label.enabled = false
1161
- @log_dir_btn.disable
1159
+ #@log_dir_btn.disable
1162
1160
 
1163
1161
 
1164
1162
 
@@ -0,0 +1,210 @@
1
+ # .
2
+ # intercept_filter_dialog.rb
3
+ #
4
+ # Copyright 2012 by siberas, http://www.siberas.de
5
+ #
6
+ # This file is part of WATOBO (Web Application Tool Box)
7
+ # http://watobo.sourceforge.com
8
+ #
9
+ # WATOBO is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation version 2 of the License.
12
+ #
13
+ # WATOBO is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with WATOBO; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # .
22
+ module Watobo
23
+ module Gui
24
+ class InterceptFilterDialog < FXDialogBox
25
+
26
+ include Responder
27
+ def getRequestFilter()
28
+ @request_filter
29
+ end
30
+
31
+ def getResponseFilter()
32
+ @response_filter
33
+ end
34
+
35
+ def initialize(owner, settings = {} )
36
+ super(owner, "Rewrite Settings", DECOR_ALL, :width => 300, :height => 425)
37
+
38
+ @request_filter = { }
39
+
40
+ @response_filter = { }
41
+
42
+ @request_filter.update settings[:request_filter_settings]
43
+ @response_filter.update settings[:response_filter_settings]
44
+
45
+ FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
46
+
47
+ base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
48
+ @tabbook = FXTabBook.new(base_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
49
+ buttons_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FILL_X)
50
+ @req_opt_tab = FXTabItem.new(@tabbook, "Request Options", nil)
51
+ frame = FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
52
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
53
+ @req_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
54
+
55
+ @resp_opt_tab = FXTabItem.new(@tabbook, "Response Options", nil)
56
+ frame= FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
57
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
58
+ @resp_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
59
+
60
+ initRequestFilterFrame()
61
+ updateRequestFilterFrame()
62
+
63
+ initResponseFilterFrame()
64
+ updateResponseFilterFrame()
65
+
66
+ @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
67
+ @finishButton.enable
68
+ @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
69
+ #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
70
+ self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
71
+ end
72
+
73
+ @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
74
+ :target => self, :selector => FXDialogBox::ID_CANCEL,
75
+ :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
76
+ end
77
+
78
+ private
79
+
80
+ def onAccept(sender, sel, event)
81
+ #TODO: Check if regex is valid
82
+ @request_filter[:method_filter] = @method_filter_dt.value
83
+ @request_filter[:negate_method_filter] = @neg_method_filter_cb.checked?
84
+ @request_filter[:negate_url_filter] = @neg_url_filter_cb.checked?
85
+ @request_filter[:url_filter] = @url_filter_dt.value
86
+ @request_filter[:file_type_filter] = @ftype_filter_dt.value
87
+ @request_filter[:negate_file_type_filter] = @neg_ftype_filter_cb.checked?
88
+
89
+ @request_filter[:parms_filter] = @parms_filter_dt.value
90
+ @request_filter[:negate_parms_filter] = @neg_parms_filter_cb.checked?
91
+
92
+ @response_filter[:content_type_filter] = @content_type_filter_dt.value
93
+ @response_filter[:negate_content_type_filter] = @neg_ctype_filter_cb.checked?
94
+
95
+ @response_filter[:response_code_filter] = @rcode_filter_dt.value
96
+ @response_filter[:negate_response_code_filter] = @neg_rcode_filter_cb.checked?
97
+
98
+ getApp().stopModal(self, 1)
99
+ self.hide()
100
+ return 1
101
+ end
102
+
103
+ def updateRequestFilterFrame()
104
+ @parms_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
105
+ @url_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
106
+ @ftype_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
107
+ @method_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
108
+ end
109
+
110
+ def updateResponseFilterFrame()
111
+ @content_type_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
112
+ @rcode_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
113
+ # @neg_rcode_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
114
+ # @neg_ctype_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
115
+ end
116
+
117
+ def initResponseFilterFrame()
118
+
119
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Content Type", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
120
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
121
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
122
+ fxtext.backColor = fxtext.parent.backColor
123
+ fxtext.disable
124
+ text = "Regular expression for HTTP Content-Type. E.g., '(text|script)'"
125
+ fxtext.setText(text)
126
+ @content_type_filter_dt = FXDataTarget.new('')
127
+ @content_type_filter_dt.value = @response_filter[:content_type_filter]
128
+ @content_type_filter = FXTextField.new(frame, 20, :target => @content_type_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
129
+ @neg_ctype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
130
+ #@neg_method_filter_cb.checkState = false
131
+ @neg_ctype_filter_cb.checkState = @response_filter[:negate_content_type_filter]
132
+
133
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Response Code", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
134
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
135
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
136
+ fxtext.backColor = fxtext.parent.backColor
137
+ fxtext.disable
138
+ text = "Regular expression for HTTP Content-Type. E.g., '200'"
139
+ fxtext.setText(text)
140
+ @rcode_filter_dt = FXDataTarget.new('')
141
+ @rcode_filter_dt.value = @response_filter[:response_code_filter]
142
+
143
+ @rcode_filter = FXTextField.new(frame, 20, :target => @rcode_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
144
+ @neg_rcode_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
145
+ #@neg_method_filter_cb.checkState = false
146
+ @neg_rcode_filter_cb.checkState = @response_filter[:negate_response_code_filter]
147
+
148
+ end
149
+
150
+ def initRequestFilterFrame()
151
+ gbframe = FXGroupBox.new(@req_opt_frame, "URL Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
152
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
153
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
154
+ fxtext.backColor = fxtext.parent.backColor
155
+ fxtext.disable
156
+ text = "Regular Expression Filter For URL. E.g., '.*www.mysite.com.*login.php'"
157
+ fxtext.setText(text)
158
+
159
+ @url_filter_dt = FXDataTarget.new('')
160
+ @url_filter_dt.value = @request_filter[:url_filter]
161
+ @url_filter = FXTextField.new(frame, 20, :target => @url_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
162
+ @neg_url_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
163
+ #@neg_url_filter_cb.checkState = false
164
+ @neg_url_filter_cb.checkState = @request_filter[:negate_url_filter]
165
+
166
+ gbframe = FXGroupBox.new(@req_opt_frame, "Method Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
167
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
168
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
169
+ fxtext.backColor = fxtext.parent.backColor
170
+ fxtext.disable
171
+ text = "Regular expression for HTTP method. E.g., '(get|PoSt)'"
172
+ fxtext.setText(text)
173
+ @method_filter_dt = FXDataTarget.new('')
174
+ @method_filter_dt.value = @request_filter[:method_filter]
175
+ @method_filter = FXTextField.new(frame, 20, :target => @method_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
176
+ @neg_method_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
177
+ #@neg_method_filter_cb.checkState = false
178
+ @neg_method_filter_cb.checkState = @request_filter[:negate_method_filter]
179
+
180
+ gbframe = FXGroupBox.new(@req_opt_frame, "Parm Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
181
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
182
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
183
+ fxtext.backColor = fxtext.parent.backColor
184
+ fxtext.disable
185
+ text = "Regular Expression Filter For Parameter Names. E.g., for intercepting requests containing parameters beginning with 'act' use the regex pattern '^act.*' (without single quotes)"
186
+ fxtext.setText(text)
187
+ @parms_filter_dt = FXDataTarget.new('')
188
+ @parms_filter_dt.value = @request_filter[:parms_filter]
189
+ @parms_filter = FXTextField.new(frame, 20, :target => @parms_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
190
+ @neg_parms_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
191
+ #@neg_parm_filter_cb.checkState = false
192
+ @neg_parms_filter_cb.checkState = @request_filter[:negate_parms_filter]
193
+
194
+ gbframe = FXGroupBox.new(@req_opt_frame, "File Type Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
195
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
196
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
197
+ fxtext.backColor = fxtext.parent.backColor
198
+ fxtext.disable
199
+ text = "Regular expression for file types by its extension. E.g., for intercepting requests where file type is PHP use '^php$' (without single quotes)"
200
+ fxtext.setText(text)
201
+ @ftype_filter_dt = FXDataTarget.new('')
202
+ @ftype_filter_dt.value = @request_filter[:file_type_filter]
203
+ @ftype_filter = FXTextField.new(frame, 20, :target => @ftype_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
204
+ @neg_ftype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
205
+ #@neg_parm_filter_cb.checkState = false
206
+ @neg_ftype_filter_cb.checkState = @request_filter[:negate_file_type_filter]
207
+ end
208
+ end
209
+ end
210
+ end
@@ -24,6 +24,7 @@ module Watobo
24
24
  class InterceptEditor < FXVerticalFrame
25
25
 
26
26
  include Watobo::Constants
27
+ include Watobo::Interceptor
27
28
  include Watobo::Gui::Utils
28
29
 
29
30
  def initialize(owner, opts)
@@ -411,6 +412,7 @@ module Watobo
411
412
 
412
413
  include Responder
413
414
  include Watobo
415
+ include Watobo::Interceptor
414
416
  include Watobo::Gui::Icons
415
417
  def execute
416
418
  create
@@ -465,13 +467,13 @@ module Watobo
465
467
  end
466
468
  end
467
469
 
468
- def initialize(owner, interceptor, opts)
470
+ def initialize(owner, opts)
469
471
  # Invoke base class initialize function first
470
472
 
471
473
  super( owner, 'Interceptor', nil, nil, DECOR_ALL|DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE, 0, 0, 600, 400, 0, 0, 0, 0, 0, 0)
472
474
  self.connect(SEL_CLOSE, method(:onClose))
473
475
  self.icon = ICON_INTERCEPTOR
474
- @interceptor = interceptor
476
+ #@interceptor = interceptor
475
477
 
476
478
  @request_list = []
477
479
  @response_list = []
@@ -491,23 +493,39 @@ module Watobo
491
493
  #log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
492
494
 
493
495
  filter_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
494
- FXLabel.new(filter_frame, "Intercept:" )
495
- @intercept_request = FXCheckButton.new(filter_frame, "Requests", nil, 0,
496
+ gbframe = FXGroupBox.new(filter_frame, "Intercept", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
497
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
498
+ # FXLabel.new(filter_frame, "Intercept:" )
499
+ @intercept_request = FXCheckButton.new(frame, "Requests", nil, 0,
496
500
  ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
497
501
  @intercept_request.connect(SEL_COMMAND, method(:onInterceptChanged))
498
502
 
499
- @intercept_response = FXCheckButton.new(filter_frame, "Response", nil, 0,
503
+ @intercept_response = FXCheckButton.new(frame, "Response", nil, 0,
500
504
  ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
501
505
  @intercept_response.connect(SEL_COMMAND, method(:onInterceptChanged))
502
-
503
- @filter_options_btn = FXButton.new(filter_frame, "Filter Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
506
+ @filter_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
504
507
  @filter_options_btn.connect(SEL_COMMAND, method(:onBtnFilterOptions))
508
+
509
+ gbframe = FXGroupBox.new(filter_frame, "Rewrite", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
510
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
511
+ #FXLabel.new(filter_frame, "Rewrite:" )
512
+ @rewrite_request = FXCheckButton.new(frame, "Requests", nil, 0,
513
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
514
+ @rewrite_request.connect(SEL_COMMAND, method(:onInterceptChanged))
515
+
516
+ @rewrite_response = FXCheckButton.new(frame, "Response", nil, 0,
517
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
518
+ @rewrite_response.connect(SEL_COMMAND, method(:onInterceptChanged))
519
+
520
+ @rewrite_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
521
+ @rewrite_options_btn.connect(SEL_COMMAND){ open_rewrite_options_dialog }
522
+
505
523
  #@intercept_request.checkState = false
506
524
  #@intercept_response.checkState = false
507
- unless @interceptor.nil?
525
+ if Watobo::Interceptor.active?
508
526
 
509
- @intercept_request.checkState = @interceptor.mode & INTERCEPT_REQUEST > 0
510
- @intercept_response.checkState = @interceptor.mode & INTERCEPT_RESPONSE > 0
527
+ @intercept_request.checkState = Watobo::Interceptor.intercept_requests?
528
+ @intercept_response.checkState = Watobo::Interceptor.intercept_requests?
511
529
  end
512
530
 
513
531
  view_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
@@ -702,7 +720,7 @@ end
702
720
 
703
721
  # def onHide
704
722
  # # puts "* hiding interceptor"
705
- # @interceptor.mode = INTERCEPT_NONE
723
+ # Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
706
724
  # @mutex.synchronize {
707
725
  # @cv.signal
708
726
  # }
@@ -711,7 +729,8 @@ end
711
729
  def onClose(sender, sel, ptr)
712
730
  puts "* closing Interceptor UI"
713
731
  puts "+ stop intercepting"
714
- @interceptor.mode = INTERCEPT_NONE
732
+ Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
733
+ Watobo::Interceptor.rewrite_mode = REWRITE_NONE
715
734
  puts "+ release all interceptions"
716
735
  releaseAll()
717
736
  #getApp().stopModal(self, 1)
@@ -756,24 +775,41 @@ end
756
775
  def onBtnFilterOptions(sender, sel, ptr)
757
776
 
758
777
  dlg = Watobo::Gui::InterceptorFilterSettingsDialog.new( self,
759
- :request_filter_settings => @interceptor.getRequestFilter(),
760
- :response_filter_settings => @interceptor.getResponseFilter()
778
+ :request_filter_settings => Interceptor.proxy.getRequestFilter(),
779
+ :response_filter_settings => Interceptor.proxy.getResponseFilter()
761
780
  )
762
781
  if dlg.execute != 0 then
763
782
  # TODO: Apply interceptor settings
764
- @interceptor.setRequestFilter(dlg.getRequestFilter)
765
- @interceptor.setResponseFilter(dlg.getResponseFilter)
783
+ Interceptor.proxy.setRequestFilter(dlg.getRequestFilter)
784
+ Interceptor.proxy.setResponseFilter(dlg.getResponseFilter)
766
785
  end
767
786
 
768
787
  end
788
+
789
+ def open_rewrite_options_dialog
790
+ dlg = Watobo::Gui::RewriteRulesDialog.new( self )
791
+ if dlg.execute != 0 then
792
+ # TODO: Apply interceptor settings
793
+ Interceptor::RequestCarver.set_carving_rules dlg.request_rules
794
+ Interceptor::ResponseCarver.set_carving_rules dlg.response_rules
795
+ end
796
+ end
769
797
 
770
798
  def onInterceptChanged(sender, sel, ptr)
771
799
  begin
772
- unless @interceptor.nil? then
773
- @interceptor.mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
774
- @interceptor.mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
775
- #puts @interceptor.mode
776
- end
800
+ # unless @interceptor.nil? then
801
+ mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
802
+ mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
803
+ #Watobo::Interceptor.intercept_mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
804
+ # Watobo::Interceptor.intercept_mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
805
+ #puts Watobo::Interceptor.intercept_mode
806
+ # puts "New Proxy Mode: #{mode}"
807
+ Watobo::Interceptor.intercept_mode = mode
808
+
809
+ mode = @rewrite_request.checked? ? REWRITE_REQUEST : 0
810
+ mode |= @rewrite_response.checked? ? REWRITE_RESPONSE : 0
811
+ Watobo::Interceptor.rewrite_mode = mode
812
+ # end
777
813
  rescue => bang
778
814
  puts bang
779
815
  puts bang.backtrace if $DEBUG
@@ -785,6 +821,8 @@ end
785
821
  class InterceptorFilterSettingsDialog < FXDialogBox
786
822
 
787
823
  include Responder
824
+ include Watobo::Interceptor
825
+
788
826
  def getRequestFilter()
789
827
  @request_filter
790
828
  end
@@ -23,10 +23,15 @@ module Watobo
23
23
  module Gui
24
24
 
25
25
  class InterceptorSettingsFrame < FXVerticalFrame
26
+
26
27
 
27
28
  def getSettings()
28
29
  settings = Hash.new
29
30
  settings[:port] = @port_dt.value
31
+ settings[:bind_addr] = @bind_addr_dt.value
32
+ mode = Watobo::Interceptor::MODE_REGULAR
33
+ mode = Watobo::Interceptor::MODE_TRANSPARENT if @transparent_mode_chk.checked?
34
+ settings[:proxy_mode] = mode
30
35
 
31
36
 
32
37
 
@@ -42,6 +47,10 @@ module Watobo
42
47
  return settings
43
48
  end
44
49
 
50
+ def transparent_mode?
51
+ @transparent_mode_chk.checked?
52
+ end
53
+
45
54
  def addItem(list_box, item)
46
55
  if item != "" then
47
56
  list_item = list_box.appendItem("#{item}")
@@ -63,12 +72,34 @@ module Watobo
63
72
  #@settings = interceptor_settings
64
73
  scroller = FXScrollWindow.new(self, :opts => SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
65
74
  scroll_area = FXVerticalFrame.new(scroller, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
66
-
67
- gbox = FXGroupBox.new(scroll_area, "Listening Port", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
68
- gbox_frame = FXVerticalFrame.new(gbox, :opts => LAYOUT_SIDE_TOP|PACK_UNIFORM_WIDTH)
75
+ gbox = FXGroupBox.new(scroll_area, "Transparent Mode", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
76
+ gbox_frame = FXVerticalFrame.new(gbox, :opts => LAYOUT_SIDE_TOP)
77
+ @transparent_mode_chk = FXCheckButton.new(gbox_frame, "enable", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_LEFT)
78
+ @transparent_mode_chk.setCheck false
79
+ if RUBY_PLATFORM =~ /linux|bsd|solaris|hpux|darwin/i
80
+ @transparent_mode_chk.setCheck true if Watobo::Conf::Interceptor.proxy_mode == Watobo::Interceptor::MODE_TRANSPARENT
81
+ else
82
+ @transparent_mode_chk.disable
83
+ note = FXLabel.new(gbox_frame, "Transparent Mode Not Available On This Platform.")
84
+ note.textColor = FXColor::Red
85
+
86
+ end
87
+
88
+ gbox = FXGroupBox.new(scroll_area, "Listener", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
89
+ #gbox_frame = FXVerticalFrame.new(gbox, :opts => LAYOUT_SIDE_TOP|PACK_UNIFORM_WIDTH)
90
+ frame = FXMatrix.new(gbox, 2, :opts => MATRIX_BY_COLUMNS|LAYOUT_FILL_X|LAYOUT_FILL_Y)
91
+
92
+ # frame = FXHorizontalFrame.new(gbox_frame, :opts => LAYOUT_FILL_X)
93
+ FXLabel.new(frame, "Bind Address:")
94
+ @bind_addr_dt = FXDataTarget.new(0)
95
+ #@port_dt.value = @settings[:port]
96
+ @bind_addr_dt.value = Watobo::Conf::Interceptor.bind_addr
97
+ bind_addr_txt = FXTextField.new(frame, 15, @bind_addr_dt, FXDataTarget::ID_VALUE, :opts => JUSTIFY_RIGHT|FRAME_GROOVE|FRAME_SUNKEN)
98
+ bind_addr_txt .handle(self, FXSEL(SEL_UPDATE, 0), nil)
69
99
 
70
- frame = FXHorizontalFrame.new(gbox_frame, :opts => LAYOUT_FILL_X)
71
- FXLabel.new(frame, "Listen Port:")
100
+
101
+ # frame = FXHorizontalFrame.new(gbox_frame, :opts => LAYOUT_FILL_X)
102
+ FXLabel.new(frame, "Port:")
72
103
  @port_dt = FXDataTarget.new(0)
73
104
  #@port_dt.value = @settings[:port]
74
105
  @port_dt.value = Watobo::Conf::Interceptor.port
@@ -151,6 +182,9 @@ module Watobo
151
182
  include Responder
152
183
  attr :interceptor_settings
153
184
 
185
+ def transparent?
186
+ @interceptorSettingsFrame.transparent_mode?
187
+ end
154
188
 
155
189
  def onAccept(sender, sel, event)
156
190
 
@@ -83,7 +83,8 @@ module Watobo
83
83
  end
84
84
 
85
85
  input_frame = FXHorizontalFrame.new(frame, :opts => LAYOUT_FILL_X)
86
- @text = FXTextField.new(input_frame, 20, :target => @expath_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
86
+ #@text = FXTextField.new(input_frame, 20, :target => @expath_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
87
+ @text = FXTextField.new(input_frame, 20, nil, 0, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
87
88
  @rem_btn = FXButton.new(input_frame, "Remove" , :opts => BUTTON_NORMAL|BUTTON_DEFAULT|LAYOUT_RIGHT)
88
89
  @add_btn = FXButton.new(input_frame, "Add" , :opts => BUTTON_NORMAL|BUTTON_DEFAULT|LAYOUT_RIGHT)
89
90
 
@@ -23,10 +23,84 @@ module Watobo
23
23
  module Gui
24
24
  class LogViewer < FXVerticalFrame
25
25
 
26
+ include Watobo::Constants
27
+ def purge_logs
28
+ begin
29
+ @log_text_lock.synchronize do
30
+ @textbox.setText('')
31
+ # @textbox.makePositionVisible 0
32
+ end
33
+ rescue => bang
34
+ puts "! Could not purge logs"
35
+ puts bang
36
+ puts bang.backtrace if $DEBUG
37
+ end
38
+ end
39
+
40
+ def log(log_level, msg )
41
+
42
+ t = Time.now
43
+ now = t.strftime("%m/%d/%Y @ %H:%M:%S")
44
+
45
+ begin
46
+ log_text = case log_level
47
+ when LOG_INFO
48
+ "#{now}: #{msg}\n"
49
+ else
50
+ ""
51
+ end
52
+ @log_queue << log_text
53
+ rescue => bang
54
+ puts bang
55
+ puts bang.backtrace if $DEBUG
56
+ end
57
+ end
58
+
59
+ def initialize(parent, mode = nil, opts)
60
+ opts[:padding]=0
61
+ @mode = :insert if mode.nil?
62
+
63
+ super(parent, opts)
64
+
65
+ @log_queue = Queue.new
66
+
67
+ @log_text_lock = Mutex.new
68
+
69
+ @textbox = FXText.new(self, nil, 0, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
70
+ @textbox.editable = false
71
+ start_update_timer
72
+ end
73
+
74
+ private
75
+
76
+ def start_update_timer
77
+ @timer = FXApp.instance.addTimeout( 150, :repeat => true) {
78
+ #print @log_queue.length
79
+ if @log_queue.length > 0
80
+ msg = @log_queue.deq
81
+ if @mode == :insert
82
+ @log_text_lock.synchronize do
83
+ @textbox.insertText(0,msg)
84
+ end
85
+ else
86
+ @log_text_lock.synchronize do
87
+ @textbox.appendText(msg)
88
+ end
89
+ end
90
+ @textbox.handle(self, FXSEL(SEL_UPDATE, 0), nil)
91
+ end
92
+ }
93
+
94
+ end
95
+
96
+ end
97
+
98
+ class LogViewer_UNUSED < FXVerticalFrame
99
+
26
100
  include Watobo::Constants
27
101
  def purge
28
102
  @lock.synchronize do
29
- @log_viewer.text = ''
103
+ @textbox.text = ''
30
104
  end
31
105
  end
32
106
 
@@ -65,9 +139,9 @@ module Watobo
65
139
  unless @log_message.empty?
66
140
  case @mode
67
141
  when :insert
68
- @log_viewer.insertText(0,@log_message)
142
+ @textbox.insertText(0,@log_message)
69
143
  when :append
70
- @log_viewer.appendText(@log_message)
144
+ @textbox.appendText(@log_message)
71
145
  end
72
146
  end
73
147
  @log_message = nil
@@ -94,8 +168,8 @@ module Watobo
94
168
 
95
169
  #self.connect(SEL_CLOSE, method(:onClose))
96
170
 
97
- @log_viewer = FXText.new(self, nil, 0, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
98
- @log_viewer.editable = false
171
+ @textbox = FXText.new(self, nil, 0, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
172
+ @textbox.editable = false
99
173
  start_update_timer
100
174
  end
101
175