watobo 0.9.19 → 0.9.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (266) hide show
  1. data/CHANGELOG.md +104 -0
  2. data/bin/nfq_server.rb +8 -20
  3. data/bin/watobo_gui.rb +8 -20
  4. data/config/forwarding_proxy.yml +2 -2
  5. data/lib/watobo.rb +12 -22
  6. data/lib/watobo/adapters.rb +12 -24
  7. data/lib/watobo/adapters/data_store.rb +76 -66
  8. data/lib/watobo/adapters/file/file_store.rb +295 -307
  9. data/lib/watobo/adapters/session_store.rb +13 -25
  10. data/lib/watobo/ca.rb +9 -21
  11. data/lib/watobo/config.rb +205 -217
  12. data/lib/watobo/constants.rb +8 -20
  13. data/lib/watobo/core.rb +11 -23
  14. data/lib/watobo/core/active_check.rb +11 -21
  15. data/lib/watobo/core/active_checks.rb +57 -69
  16. data/lib/watobo/core/ca.rb +388 -398
  17. data/lib/watobo/core/cert_store.rb +42 -54
  18. data/lib/watobo/core/chat.rb +100 -112
  19. data/lib/watobo/core/chats.rb +271 -275
  20. data/lib/watobo/core/client_cert_store.rb +33 -45
  21. data/lib/watobo/core/conversation.rb +56 -68
  22. data/lib/watobo/core/cookie.rb +31 -43
  23. data/lib/watobo/core/finding.rb +74 -86
  24. data/lib/watobo/core/findings.rb +113 -125
  25. data/lib/watobo/core/forwarding_proxy.rb +44 -35
  26. data/lib/watobo/core/fuzz_gen.rb +8 -20
  27. data/lib/watobo/core/intercept_carver.rb +176 -188
  28. data/lib/watobo/core/intercept_filter.rb +243 -255
  29. data/lib/watobo/core/interceptor.rb +106 -118
  30. data/lib/watobo/core/min_class.rb +12 -24
  31. data/lib/watobo/core/netfilter_queue.rb +178 -190
  32. data/lib/watobo/core/ott_cache.rb +152 -148
  33. data/lib/watobo/core/parameter.rb +53 -58
  34. data/lib/watobo/core/passive_check.rb +8 -20
  35. data/lib/watobo/core/passive_checks.rb +56 -68
  36. data/lib/watobo/core/passive_scanner.rb +54 -66
  37. data/lib/watobo/core/plugin.rb +19 -31
  38. data/lib/watobo/core/project.rb +8 -20
  39. data/lib/watobo/core/proxy.rb +51 -63
  40. data/lib/watobo/core/request.rb +128 -120
  41. data/lib/watobo/core/response.rb +59 -61
  42. data/lib/watobo/core/scanner.rb +8 -20
  43. data/lib/watobo/core/scanner3.rb +413 -425
  44. data/lib/watobo/core/scope.rb +91 -103
  45. data/lib/watobo/core/session.rb +109 -87
  46. data/lib/watobo/core/sid_cache.rb +106 -118
  47. data/lib/watobo/core/subscriber.rb +33 -45
  48. data/lib/watobo/defaults.rb +29 -41
  49. data/lib/watobo/external/diff/lcs.rb +8 -20
  50. data/lib/watobo/external/diff/lcs/array.rb +8 -20
  51. data/lib/watobo/external/diff/lcs/block.rb +8 -20
  52. data/lib/watobo/external/diff/lcs/callbacks.rb +8 -20
  53. data/lib/watobo/external/diff/lcs/change.rb +8 -20
  54. data/lib/watobo/external/diff/lcs/hunk.rb +8 -20
  55. data/lib/watobo/external/diff/lcs/ldiff.rb +8 -20
  56. data/lib/watobo/external/diff/lcs/string.rb +8 -20
  57. data/lib/watobo/externals.rb +14 -26
  58. data/lib/watobo/framework.rb +12 -24
  59. data/lib/watobo/framework/create_project.rb +68 -80
  60. data/lib/watobo/framework/init.rb +8 -20
  61. data/lib/watobo/framework/init_modules.rb +8 -20
  62. data/lib/watobo/framework/license_text.rb +36 -48
  63. data/lib/watobo/framework/load_chat.rb +21 -33
  64. data/lib/watobo/gui.rb +121 -133
  65. data/lib/watobo/gui/about_watobo.rb +8 -20
  66. data/lib/watobo/gui/browser_preview.rb +8 -20
  67. data/lib/watobo/gui/certificate_dialog.rb +8 -20
  68. data/lib/watobo/gui/chat_diff.rb +11 -21
  69. data/lib/watobo/gui/chatviewer_frame.rb +10 -22
  70. data/lib/watobo/gui/checkboxtree.rb +8 -20
  71. data/lib/watobo/gui/checks_policy_frame.rb +8 -20
  72. data/lib/watobo/gui/client_cert_dialog.rb +10 -21
  73. data/lib/watobo/gui/confirm_scan_dialog.rb +8 -20
  74. data/lib/watobo/gui/conversation_table.rb +54 -44
  75. data/lib/watobo/gui/conversation_table_ctrl.rb +215 -227
  76. data/lib/watobo/gui/conversation_table_ctrl2.rb +385 -393
  77. data/lib/watobo/gui/csrf_token_dialog.rb +11 -25
  78. data/lib/watobo/gui/custom_viewer.rb +357 -369
  79. data/lib/watobo/gui/dashboard.rb +8 -20
  80. data/lib/watobo/gui/define_scope_frame.rb +8 -20
  81. data/lib/watobo/gui/differ_frame.rb +223 -235
  82. data/lib/watobo/gui/edit_comment.rb +8 -20
  83. data/lib/watobo/gui/edit_scope_dialog.rb +8 -20
  84. data/lib/watobo/gui/export_dialog.rb +114 -0
  85. data/lib/watobo/gui/finding_info.rb +9 -21
  86. data/lib/watobo/gui/findings_tree.rb +8 -20
  87. data/lib/watobo/gui/full_scan_dialog.rb +8 -20
  88. data/lib/watobo/gui/fuzzer_gui.rb +8 -20
  89. data/lib/watobo/gui/goto_url_dialog.rb +78 -90
  90. data/lib/watobo/gui/hex_viewer.rb +25 -27
  91. data/lib/watobo/gui/html_viewer.rb +295 -307
  92. data/lib/watobo/gui/intercept_filter_dialog.rb +196 -208
  93. data/lib/watobo/gui/interceptor_gui.rb +1046 -1041
  94. data/lib/watobo/gui/interceptor_settings_dialog.rb +8 -20
  95. data/lib/watobo/gui/list_box.rb +109 -121
  96. data/lib/watobo/gui/log_file_viewer.rb +40 -52
  97. data/lib/watobo/gui/log_viewer.rb +87 -99
  98. data/lib/watobo/gui/login_wizzard.rb +8 -20
  99. data/lib/watobo/gui/main_window.rb +34 -33
  100. data/lib/watobo/gui/manual_request_editor.rb +25 -35
  101. data/lib/watobo/gui/master_pw_dialog.rb +8 -20
  102. data/lib/watobo/gui/mixins/gui_settings.rb +37 -49
  103. data/lib/watobo/gui/page_tree.rb +225 -237
  104. data/lib/watobo/gui/password_policy_dialog.rb +8 -20
  105. data/lib/watobo/gui/plugin_board.rb +8 -20
  106. data/lib/watobo/gui/preferences_dialog.rb +8 -20
  107. data/lib/watobo/gui/progress_window.rb +8 -20
  108. data/lib/watobo/gui/project_wizzard.rb +8 -20
  109. data/lib/watobo/gui/proxy_dialog.rb +117 -85
  110. data/lib/watobo/gui/quick_scan_dialog.rb +8 -20
  111. data/lib/watobo/gui/request_builder_frame.rb +125 -122
  112. data/lib/watobo/gui/request_editor.rb +53 -28
  113. data/lib/watobo/gui/rewrite_filters_dialog.rb +402 -414
  114. data/lib/watobo/gui/rewrite_rules_dialog.rb +380 -392
  115. data/lib/watobo/gui/save_chat_dialog.rb +148 -160
  116. data/lib/watobo/gui/scanner_settings_dialog.rb +8 -20
  117. data/lib/watobo/gui/select_chat_dialog.rb +8 -20
  118. data/lib/watobo/gui/session_management_dialog.rb +8 -20
  119. data/lib/watobo/gui/sites_tree.rb +118 -22
  120. data/lib/watobo/gui/status_bar.rb +8 -20
  121. data/lib/watobo/gui/table_editor.rb +76 -53
  122. data/lib/watobo/gui/tagless_viewer.rb +10 -21
  123. data/lib/watobo/gui/templates/plugin.rb +8 -20
  124. data/lib/watobo/gui/templates/plugin2.rb +99 -111
  125. data/lib/watobo/gui/templates/plugin_base.rb +152 -164
  126. data/lib/watobo/gui/text_viewer.rb +8 -20
  127. data/lib/watobo/gui/transcoder_window.rb +15 -22
  128. data/lib/watobo/gui/utils/gui_utils.rb +8 -20
  129. data/lib/watobo/gui/utils/init_icons.rb +94 -106
  130. data/lib/watobo/gui/utils/load_icons.rb +41 -53
  131. data/lib/watobo/gui/utils/load_plugins.rb +118 -130
  132. data/lib/watobo/gui/utils/master_password.rb +76 -88
  133. data/lib/watobo/gui/utils/save_default_settings.rb +121 -133
  134. data/lib/watobo/gui/utils/save_project_settings.rb +8 -20
  135. data/lib/watobo/gui/utils/save_proxy_settings.rb +53 -21
  136. data/lib/watobo/gui/utils/save_scanner_settings.rb +26 -38
  137. data/lib/watobo/gui/utils/session_history.rb +120 -132
  138. data/lib/watobo/gui/workspace_dialog.rb +8 -20
  139. data/lib/watobo/gui/www_auth_dialog.rb +8 -20
  140. data/lib/watobo/gui/xml_viewer_frame.rb +8 -20
  141. data/lib/watobo/http.rb +12 -23
  142. data/lib/watobo/http/cookies/cookies.rb +63 -70
  143. data/lib/watobo/http/data/data.rb +56 -64
  144. data/lib/watobo/http/data/json.rb +51 -0
  145. data/lib/watobo/http/url/url.rb +46 -58
  146. data/lib/watobo/http/xml/xml.rb +129 -141
  147. data/lib/watobo/interceptor.rb +11 -23
  148. data/lib/watobo/interceptor/proxy.rb +624 -625
  149. data/lib/watobo/interceptor/transparent.rb +22 -34
  150. data/lib/watobo/mixins.rb +18 -30
  151. data/lib/watobo/mixins/check_info.rb +35 -47
  152. data/lib/watobo/mixins/httpparser.rb +42 -35
  153. data/lib/watobo/mixins/request_parser.rb +8 -20
  154. data/lib/watobo/mixins/shapers.rb +484 -477
  155. data/lib/watobo/mixins/transcoders.rb +8 -20
  156. data/lib/watobo/parser.rb +9 -21
  157. data/lib/watobo/parser/html.rb +91 -103
  158. data/lib/watobo/sockets.rb +11 -23
  159. data/lib/watobo/sockets/agent.rb +836 -848
  160. data/lib/watobo/sockets/client_socket.rb +283 -277
  161. data/lib/watobo/sockets/connection.rb +409 -421
  162. data/lib/watobo/sockets/http_socket.rb +16 -23
  163. data/lib/watobo/sockets/ntlm_auth.rb +137 -149
  164. data/lib/watobo/utils.rb +18 -30
  165. data/lib/watobo/utils/check_regex.rb +8 -20
  166. data/lib/watobo/utils/copy_object.rb +8 -20
  167. data/lib/watobo/utils/crypto.rb +8 -20
  168. data/lib/watobo/utils/expand_range.rb +31 -43
  169. data/lib/watobo/utils/export_xml.rb +108 -0
  170. data/lib/watobo/utils/file_management.rb +8 -20
  171. data/lib/watobo/utils/hexprint.rb +17 -29
  172. data/lib/watobo/utils/load_chat.rb +8 -20
  173. data/lib/watobo/utils/load_icon.rb +8 -20
  174. data/lib/watobo/{external/ntlm → utils}/ntlm.rb +874 -796
  175. data/lib/watobo/utils/print_debug.rb +20 -32
  176. data/lib/watobo/utils/response_builder.rb +98 -110
  177. data/lib/watobo/utils/response_hash.rb +9 -20
  178. data/lib/watobo/utils/secure_eval.rb +10 -22
  179. data/lib/watobo/utils/strings.rb +18 -30
  180. data/lib/watobo/utils/text2request.rb +12 -20
  181. data/lib/watobo/utils/url.rb +31 -43
  182. data/lib/watobo/utils/utf16.rb +22 -0
  183. data/modules/active/Apache/mod_status.rb +9 -0
  184. data/modules/active/Apache/multiview.rb +161 -0
  185. data/modules/active/Flash/crossdomain.rb +9 -0
  186. data/modules/active/directories/dirwalker.rb +8 -20
  187. data/modules/active/discovery/fileextensions.rb +10 -22
  188. data/modules/active/discovery/http_methods.rb +8 -20
  189. data/modules/active/domino/domino_db.rb +8 -20
  190. data/modules/active/dotNET/custom_errors.rb +110 -122
  191. data/modules/active/dotNET/dotnet_files.rb +98 -110
  192. data/modules/active/fileinclusion/lfi_simple.rb +8 -20
  193. data/modules/active/jboss/jboss_basic.rb +8 -20
  194. data/modules/active/sap/business_objects.rb +63 -0
  195. data/modules/active/sap/its_commands.rb +8 -20
  196. data/modules/active/sap/its_service_parameter.rb +8 -20
  197. data/modules/active/sap/its_services.rb +8 -20
  198. data/modules/active/sap/its_xss.rb +8 -20
  199. data/modules/active/shell_shock/shell_shock.rb +149 -0
  200. data/modules/active/siebel/siebel_apps.rb +168 -180
  201. data/modules/active/sqlinjection/sql_boolean.rb +9 -21
  202. data/modules/active/sqlinjection/sqli_error.rb +10 -22
  203. data/modules/active/sqlinjection/sqli_timing.rb +228 -240
  204. data/modules/active/struts2/default_handler_ognl.rb +114 -126
  205. data/modules/active/struts2/include_params_ognl.rb +113 -125
  206. data/modules/active/xml/xml_xxe.rb +122 -127
  207. data/modules/active/xss/xss_ng.rb +223 -234
  208. data/modules/active/xss/xss_simple.rb +8 -20
  209. data/modules/passive/ajax.rb +76 -84
  210. data/modules/passive/autocomplete.rb +64 -76
  211. data/modules/passive/cookie_options.rb +8 -20
  212. data/modules/passive/cookie_xss.rb +9 -21
  213. data/modules/passive/detect_code.rb +9 -21
  214. data/modules/passive/detect_fileupload.rb +11 -22
  215. data/modules/passive/detect_infrastructure.rb +23 -35
  216. data/modules/passive/detect_one_time_tokens.rb +8 -20
  217. data/modules/passive/dirindexing.rb +9 -21
  218. data/modules/passive/disclosure_domino.rb +66 -79
  219. data/modules/passive/disclosure_emails.rb +9 -21
  220. data/modules/passive/disclosure_ipaddr.rb +15 -23
  221. data/modules/passive/filename_as_parameter.rb +8 -20
  222. data/modules/passive/form_spotter.rb +15 -21
  223. data/modules/passive/hidden_fields.rb +64 -70
  224. data/modules/passive/hotspots.rb +13 -22
  225. data/modules/passive/in_script_parameter.rb +15 -24
  226. data/modules/passive/multiple_server_headers.rb +8 -20
  227. data/modules/passive/possible_login.rb +12 -23
  228. data/modules/passive/redirect_url.rb +10 -22
  229. data/modules/passive/redirectionz.rb +9 -21
  230. data/modules/passive/sap-headers.rb +64 -76
  231. data/modules/passive/xss_dom.rb +10 -21
  232. data/plugins/catalog/catalog.rb +17 -23
  233. data/plugins/crawler/crawler.rb +12 -24
  234. data/plugins/crawler/gui.rb +13 -25
  235. data/plugins/crawler/gui/auth_frame.rb +278 -290
  236. data/plugins/crawler/gui/crawler_gui.rb +302 -320
  237. data/plugins/crawler/gui/general_settings_frame.rb +104 -116
  238. data/plugins/crawler/gui/hooks_frame.rb +88 -100
  239. data/plugins/crawler/gui/scope_frame.rb +58 -70
  240. data/plugins/crawler/gui/settings_tabbook.rb +46 -58
  241. data/plugins/crawler/gui/status_frame.rb +67 -78
  242. data/plugins/crawler/lib/bags.rb +26 -38
  243. data/plugins/crawler/lib/constants.rb +19 -31
  244. data/plugins/crawler/lib/engine.rb +505 -508
  245. data/plugins/crawler/lib/grabber.rb +77 -87
  246. data/plugins/crawler/lib/status.rb +82 -0
  247. data/plugins/crawler/lib/uri_mp.rb +20 -32
  248. data/plugins/filefinder/dbs/siebel_paths.txt +1118 -0
  249. data/plugins/filefinder/dbs/subs-big.lst +31986 -0
  250. data/plugins/filefinder/filefinder.rb +13 -23
  251. data/plugins/sqlmap/bin/test.rb +86 -98
  252. data/plugins/sqlmap/gui.rb +12 -24
  253. data/plugins/sqlmap/gui/main.rb +226 -238
  254. data/plugins/sqlmap/gui/options_frame.rb +105 -117
  255. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +103 -115
  256. data/plugins/sqlmap/sqlmap.rb +10 -22
  257. data/plugins/sslchecker/cli/sslchecker_cli.rb +8 -20
  258. data/plugins/sslchecker/gui/cipher_table.rb +252 -264
  259. data/plugins/sslchecker/gui/gui.rb +267 -276
  260. data/plugins/sslchecker/gui/sslchecker.rb +12 -24
  261. data/plugins/sslchecker/lib/check.rb +172 -80
  262. data/plugins/wshell/gui/main.rb +115 -127
  263. data/plugins/wshell/lib/core.rb +85 -97
  264. data/plugins/wshell/wshell.rb +19 -31
  265. metadata +14 -6
  266. data/.yardopts +0 -24
@@ -1,25 +1,13 @@
1
- # .
1
+ #.
2
2
  # interceptor.rb
3
- #
4
- # Copyright 2013 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
- %w( proxy transparent ).each do |lib|
23
- require "watobo/interceptor/#{lib}"
24
- end
3
+ #.
4
+ # Copyright 2014 by siberas, http://www.siberas.de
5
+ # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
+ # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
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
+ # 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
25
9
 
10
+ %w( proxy transparent ).each do |lib|
11
+ require "watobo/interceptor/#{lib}"
12
+ end
13
+
@@ -1,214 +1,213 @@
1
- # .
1
+ #.
2
2
  # proxy.rb
3
- #
4
- # Copyright 2013 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
- # @private
23
- module Watobo#:nodoc: all
24
- module Interceptor
25
- #
26
- class Proxy
27
-
28
- include Watobo::Constants
29
-
30
- attr :port
31
-
32
- attr_accessor :proxy_mode
33
-
34
- # attr_accessor :contentLength
35
- #attr_accessor :contentTypes
36
- attr_accessor :target
37
- #attr :www_auth
38
- attr_accessor :client_certificates
39
- def self.transparent?
40
- return true if ( Watobo::Conf::Interceptor.proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
41
- return false
42
- end
43
-
44
- def server
45
- @bind_addr
46
- end
47
-
48
- def subscribe(event, &callback)
49
- (@event_dispatcher_listeners[event] ||= []) << callback
50
- end
51
-
52
- def clearEvents(event)
53
- @event_dispatcher_listener[event].clear
54
- end
55
-
56
- def getResponseFilter()
57
- YAML.load(YAML.dump(@response_filter_settings))
58
- end
59
-
60
- def getRequestFilter()
61
- YAML.load(YAML.dump(@request_filter_settings))
62
- end
63
-
64
- def setResponseFilter(new_settings)
65
- @response_filter_settings.update new_settings unless new_settings.nil?
66
- end
67
-
68
- def setRequestFilter(new_settings)
69
- @request_filter_settings.update new_settings unless new_settings.nil?
70
- # puts @request_filter_settings.to_yaml
71
- end
72
-
73
- def clear_request_carvers
74
- @request_carvers.clear unless @request_carvers.nil?
75
-
76
- end
77
-
78
- def clear_response_carvers
79
- @response_carvers.clear unless @response_carvers.nil?
80
- end
81
-
82
- def addPreview(response)
83
- preview_id = Digest::MD5.hexdigest(response.join)
84
- @preview[preview_id] = response
85
- return preview_id
86
- end
3
+ #.
4
+ # Copyright 2014 by siberas, http://www.siberas.de
5
+ # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
+ # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
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
+ # 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
87
9
 
88
- def stop()
89
- begin
90
- puts "[#{self.class}] stop"
91
- if @t_server.respond_to? :status
92
- puts @t_server.status
93
- Thread.kill @t_server
94
- @intercept_srv.close
95
- end
96
- rescue IOError => bang
97
- puts bang
98
- puts bang.backtrace if $DEBUG
99
- end
100
- end
101
-
102
- #
103
- # R U N
104
- #
105
-
106
- def self.start(settings = {})
107
- proxy = Proxy.new(settings)
108
- proxy.start
109
- proxy
110
- end
10
+ # @private
11
+ module Watobo#:nodoc: all
12
+ module Interceptor
13
+ #
14
+ class Proxy
15
+
16
+ include Watobo::Constants
17
+
18
+ attr :port
19
+
20
+ attr_accessor :proxy_mode
21
+
22
+ # attr_accessor :contentLength
23
+ #attr_accessor :contentTypes
24
+ attr_accessor :target
25
+ #attr :www_auth
26
+ attr_accessor :client_certificates
27
+ def self.transparent?
28
+ return true if ( Watobo::Conf::Interceptor.proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
29
+ return false
30
+ end
31
+
32
+ def server
33
+ @bind_addr
34
+ end
35
+
36
+ def subscribe(event, &callback)
37
+ (@event_dispatcher_listeners[event] ||= []) << callback
38
+ end
39
+
40
+ def clearEvents(event)
41
+ @event_dispatcher_listener[event].clear
42
+ end
43
+
44
+ def getResponseFilter()
45
+ YAML.load(YAML.dump(@response_filter_settings))
46
+ end
47
+
48
+ def getRequestFilter()
49
+ YAML.load(YAML.dump(@request_filter_settings))
50
+ end
51
+
52
+ def setResponseFilter(new_settings)
53
+ @response_filter_settings.update new_settings unless new_settings.nil?
54
+ end
55
+
56
+ def setRequestFilter(new_settings)
57
+ @request_filter_settings.update new_settings unless new_settings.nil?
58
+ # puts @request_filter_settings.to_yaml
59
+ end
60
+
61
+ def clear_request_carvers
62
+ @request_carvers.clear unless @request_carvers.nil?
63
+
64
+ end
65
+
66
+ def clear_response_carvers
67
+ @response_carvers.clear unless @response_carvers.nil?
68
+ end
69
+
70
+ def addPreview(response)
71
+ preview_id = Digest::MD5.hexdigest(response.join)
72
+ @preview[preview_id] = response
73
+ return preview_id
74
+ end
75
+
76
+ def stop()
77
+ begin
78
+ puts "[#{self.class}] stop"
79
+ if @t_server.respond_to? :status
80
+ puts @t_server.status
81
+ Thread.kill @t_server
82
+ @intercept_srv.close
83
+ end
84
+ rescue IOError => bang
85
+ puts bang
86
+ puts bang.backtrace if $DEBUG
87
+ end
88
+ end
89
+
90
+ #
91
+ # R U N
92
+ #
93
+
94
+ def self.start(settings = {})
95
+ proxy = Proxy.new(settings)
96
+ proxy.start
97
+ proxy
98
+ end
111
99
 
112
100
  def start()
113
- @wait_queue = Queue.new
114
-
115
- if transparent?
116
- Watobo::Interceptor::Transparent.start
117
- end
118
-
119
- begin
120
- @intercept_srv = TCPServer.new(@bind_addr, @port)
121
- @intercept_srv.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1 )
122
-
123
- rescue => bang
124
- puts "\n!!!Could not start InterceptProxy"
125
- puts bang
126
- return nil
127
- end
128
- puts "\n* Intercepor started on #{@bind_addr}:#{@port}"
129
- session_list = []
130
- puts "!!! TRANSPARENT MODE ENABLED !!!" if transparent?
131
-
132
- @t_server = Thread.new(@intercept_srv) { |server|
133
- while (new_session = server.accept)
101
+ @wait_queue = Queue.new
102
+
103
+ if transparent?
104
+ Watobo::Interceptor::Transparent.start
105
+ end
106
+
107
+ begin
108
+ @intercept_srv = TCPServer.new(@bind_addr, @port)
109
+ @intercept_srv.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1 )
110
+
111
+ rescue => bang
112
+ puts "\n!!!Could not start InterceptProxy"
113
+ puts bang
114
+ return nil
115
+ end
116
+ puts "\n* Intercepor started on #{@bind_addr}:#{@port}"
117
+ session_list = []
118
+ puts "!!! TRANSPARENT MODE ENABLED !!!" if transparent?
119
+
120
+ @t_server = Thread.new(@intercept_srv) { |server|
121
+ while (new_session = server.accept)
134
122
  # new_session.sync = true
135
- new_sender = Watobo::Session.new(@target)
136
- Thread.new(new_sender, new_session) { |sender, session|
137
-
123
+ new_sender = Watobo::Session.new(@target)
124
+ Thread.new(new_sender, new_session) { |sender, session|
125
+
138
126
  c_sock = Watobo::HTTPSocket::ClientSocket.connect(session)
139
127
 
140
- #puts "ClientSocket: #{c_sock}"
128
+ #puts "ClientSocket: #{c_sock}"
141
129
  Thread.exit if c_sock.nil?
142
130
 
143
131
  #
144
132
  # loop for reusing client connections
145
133
 
146
- max_loop = 0
147
- loop do
148
- flags = []
134
+ max_loop = 0
135
+ loop do
136
+ flags = []
149
137
  begin
150
138
 
151
139
  # puts "#{c_sock} - read request"
152
140
  request = c_sock.request
141
+
142
+ #if request.is_multipart?
143
+ # puts request
144
+ # puts request.body.to_s.length
145
+ # puts request.body.to_s.unpack("H*")[0]
146
+ #end
153
147
 
154
148
  if request.nil? or request.empty? then
155
- print "c/"
156
- c_sock.close
157
- Thread.exit
158
- end
149
+ print "c/"
150
+ c_sock.close
151
+ Thread.exit
152
+ end
159
153
 
160
154
  url = ( request.url.to_s.length > 65 ) ? request.url.to_s.slice(0,65) + "..." : request.url.to_s
161
- puts "\n[I] #{url}"
162
-
163
- rescue => bang
164
- puts "!!! Error reading client request "
165
- puts bang
166
- puts bang.backtrace
167
- # puts request.class
168
- # puts request
169
- c_sock.close
170
- Thread.exit
171
- #break
155
+ puts "\n[I] #{url}"
156
+
157
+ rescue => bang
158
+ puts "!!! Error reading client request "
159
+ puts bang
160
+ puts bang.backtrace
161
+ # puts request.class
162
+ # puts request
163
+ c_sock.close
164
+ Thread.exit
165
+ #break
172
166
  end
173
-
174
- # check if preview is requested
175
- if request.host =='watobo.localhost' or request.first =~ /WATOBOPreview/ then
167
+
168
+ if request.host =~ /safebrowsing.*google\.com/
169
+ c_sock.close
170
+ Thread.exit
171
+ end
172
+
173
+ # check if preview is requested
174
+ if request.host =='watobo.localhost' or request.first =~ /WATOBOPreview/ then
176
175
  if request.first =~ /WATOBOPreview=([0-9a-zA-Z]*)/ then
177
- hashid = $1
178
- response = @preview[hashid]
179
-
180
- if response then
181
- c_sock.write response.join
182
- c_sock.close
183
- end
184
- end
185
- #next
186
- Thread.exit
187
- end
188
-
189
- request_intercepted = false
190
- # no preview, check if interception request is turned on
191
- if Watobo::Interceptor.rewrite_requests? then
192
- Interceptor::RequestCarver.shape(request, flags)
193
- puts "FLAGS >>"
194
- puts flags
195
- end
196
-
197
- if @target and Watobo::Interceptor.intercept_requests? then
198
- if matchRequestFilter(request)
199
- @awaiting_requests += 1
200
- request_intercepted = true
201
-
202
- if @target.respond_to? :addRequest
203
- Watobo.print_debug "send request to target"
204
- @target.addRequest(request, Thread.current)
205
- Thread.stop
206
- else
207
- p "! no target for editing request"
208
- end
209
- @awaiting_requests -= 1
210
- end
211
- end
176
+ hashid = $1
177
+ response = @preview[hashid]
178
+
179
+ if response then
180
+ c_sock.write response.join
181
+ c_sock.close
182
+ end
183
+ end
184
+ #next
185
+ Thread.exit
186
+ end
187
+
188
+ request_intercepted = false
189
+ # no preview, check if interception request is turned on
190
+ if Watobo::Interceptor.rewrite_requests? then
191
+ Interceptor::RequestCarver.shape(request, flags)
192
+ puts "FLAGS >>"
193
+ puts flags
194
+ end
195
+
196
+ if @target and Watobo::Interceptor.intercept_requests? then
197
+ if matchRequestFilter(request)
198
+ @awaiting_requests += 1
199
+ request_intercepted = true
200
+
201
+ if @target.respond_to? :addRequest
202
+ Watobo.print_debug "send request to target"
203
+ @target.addRequest(request, Thread.current)
204
+ Thread.stop
205
+ else
206
+ p "! no target for editing request"
207
+ end
208
+ @awaiting_requests -= 1
209
+ end
210
+ end
212
211
 
213
212
  begin
214
213
  s_sock, req, resp = sender.sendHTTPRequest(request, :update_sids => true,
@@ -216,115 +215,115 @@ module Watobo#:nodoc: all
216
215
  :update_contentlength => true,
217
216
  :www_auth => @www_auth
218
217
  # :client_certificates => @client_certificates
219
- )
218
+ )
220
219
  if s_sock.nil? then
221
- puts "s_sock is nil! bye, bye, ..."
222
- puts request if $DEBUG
223
- c_sock.write resp.join unless resp.nil?
220
+ puts "s_sock is nil! bye, bye, ..."
221
+ puts request if $DEBUG
222
+ c_sock.write resp.join unless resp.nil?
224
223
  c_sock.close
225
- Thread.exit
224
+ Thread.exit
225
+ end
226
+
227
+ rescue => bang
228
+ puts bang
229
+ puts bang.backtrace if $DEBUG
230
+ c_sock.close
231
+ Thread.exit
226
232
  end
227
-
228
- rescue => bang
229
- puts bang
230
- puts bang.backtrace if $DEBUG
231
- c_sock.close
232
- Thread.exit
233
- end
234
-
235
- # check if response should be passed throug
233
+
234
+ # check if response should be passed throug
236
235
  #Thread.current.exit if isPassThrough?(req, resp, s_sock, c_sock)
237
236
  if isPassThrough?(req, resp, s_sock, c_sock)
238
237
  Watobo::HTTPSocket.close s_sock
239
238
  c_sock.close
240
239
  Thread.exit
241
- end
242
- #p "no pass-through"
243
-
244
- begin
245
- # puts "* got response status: #{resp.status}"
246
- missing_credentials = false
240
+ end
241
+ #p "no pass-through"
242
+
243
+ begin
244
+ # puts "* got response status: #{resp.status}"
245
+ missing_credentials = false
247
246
  rs = resp.status
248
- auth_type = AUTH_TYPE_NONE
247
+ auth_type = AUTH_TYPE_NONE
249
248
  if rs =~ /^(401|407)/ then
250
-
251
- missing_credentials = true
252
-
253
- resp.each do |rl|
254
- if rl =~ /^(Proxy|WWW)-Authenticate: Basic/i
255
- auth_type = AUTH_TYPE_BASIC
256
- break
257
- elsif rl =~ /^(Proxy|WWW)-Authenticate: NTLM/i
258
- auth_type = AUTH_TYPE_NTLM
259
- break
260
- end
261
- end
262
- # when auth type not basic assume it's ntlm -> ntlm credentials must be set in watobo
263
- unless auth_type == AUTH_TYPE_NONE
264
- if auth_type == AUTH_TYPE_NTLM
265
- if rs =~ /^401/ then
266
- resp.push "WATOBO: Server requires (NTLM) authorization, please set WWW_Auth Credentials!"
267
- resp.shift
268
- resp.unshift "HTTP/1.1 200 OK\r\n"
269
- else
270
- resp.push "WATOBO: Proxy requires (NTLM) authorization, please set Proxy Credentials!"
271
- resp.shift
272
- resp.unshift "HTTP/1.1 200 OK\r\n"
273
- end
274
- end
275
- #else
276
-
277
- #resp.push "WATOBO: Unknown authorization type.<br><br>\r\n" + resp.join("<br>\r\n")
278
- #resp.shift
279
- #resp.unshift "HTTP/1.1 200 OK\r\n"
280
- #resp.fix_content_length
281
-
282
- end
249
+
250
+ missing_credentials = true
251
+
252
+ resp.each do |rl|
253
+ if rl =~ /^(Proxy|WWW)-Authenticate: Basic/i
254
+ auth_type = AUTH_TYPE_BASIC
255
+ break
256
+ elsif rl =~ /^(Proxy|WWW)-Authenticate: NTLM/i
257
+ auth_type = AUTH_TYPE_NTLM
258
+ break
259
+ end
260
+ end
261
+ # when auth type not basic assume it's ntlm -> ntlm credentials must be set in watobo
262
+ unless auth_type == AUTH_TYPE_NONE
263
+ if auth_type == AUTH_TYPE_NTLM
264
+ if rs =~ /^401/ then
265
+ resp.push "WATOBO: Server requires (NTLM) authorization, please set WWW_Auth Credentials!"
266
+ resp.shift
267
+ resp.unshift "HTTP/1.1 200 OK\r\n"
268
+ else
269
+ resp.push "WATOBO: Proxy requires (NTLM) authorization, please set Proxy Credentials!"
270
+ resp.shift
271
+ resp.unshift "HTTP/1.1 200 OK\r\n"
272
+ end
273
+ end
274
+ #else
275
+
276
+ #resp.push "WATOBO: Unknown authorization type.<br><br>\r\n" + resp.join("<br>\r\n")
277
+ #resp.shift
278
+ #resp.unshift "HTTP/1.1 200 OK\r\n"
279
+ #resp.fix_content_length
280
+
281
+ end
283
282
  end
284
283
 
285
- unless auth_type == AUTH_TYPE_UNKNOWN or req.method =~ /^head/i
286
- # don't try to read body if request method is HEAD
284
+ unless auth_type == AUTH_TYPE_UNKNOWN or req.method =~ /^head/i
285
+ # don't try to read body if request method is HEAD
287
286
  sender.readHTTPBody(s_sock, resp, req, :update_sids => true)
288
- Watobo::HTTPSocket.close s_sock
289
- end
290
-
291
- rescue => bang
292
- puts "!!! could not send request !!!"
293
- puts bang
294
- puts bang.backtrace if $DEBUG
295
- # puts "* Error sending request"
296
- end
297
-
298
- begin
299
- # Watobo::Response.create resp
300
- resp = Watobo::Response.new resp
301
- # puts "* unchunk response ..."
302
- resp.unchunk
303
- # puts "* unzip response ..."
304
- resp.unzip
305
-
306
- if Watobo::Interceptor.rewrite_responses? then
307
- Interceptor::ResponseCarver.shape(resp, flags)
287
+ Watobo::HTTPSocket.close s_sock
308
288
  end
309
-
310
- if @target and Watobo::Interceptor.intercept_responses? then
311
- if matchResponseFilter(resp)
312
- # if resp.content_type =~ /text/ or resp.content_type =~ /application\/javascript/ then
313
- if @target.respond_to? :modifyResponse
314
- @target.modifyResponse(resp, Thread.current)
315
- Thread.stop
316
- else
317
- p "! no target for editing response"
318
- end
319
- end
320
- end
321
-
289
+
290
+ rescue => bang
291
+ puts "!!! could not send request !!!"
292
+ puts bang
293
+ puts bang.backtrace if $DEBUG
294
+ # puts "* Error sending request"
295
+ end
296
+
297
+ begin
298
+ # Watobo::Response.create resp
299
+ #resp = Watobo::Response.new resp
300
+ # puts "* unchunk response ..."
301
+ resp.unchunk!
302
+ # puts "* unzip response ..."
303
+ resp.unzip!
304
+
305
+ if Watobo::Interceptor.rewrite_responses? then
306
+ Interceptor::ResponseCarver.shape(resp, flags)
307
+ end
308
+
309
+ if @target and Watobo::Interceptor.intercept_responses? then
310
+ if matchResponseFilter(resp)
311
+ # if resp.content_type =~ /text/ or resp.content_type =~ /application\/javascript/ then
312
+ if @target.respond_to? :modifyResponse
313
+ @target.modifyResponse(resp, Thread.current)
314
+ Thread.stop
315
+ else
316
+ p "! no target for editing response"
317
+ end
318
+ end
319
+ end
320
+
322
321
  # puts ">> SEND TO CLIENT"
323
322
  # puts ">>C<< - Close: #{request.connection_close?}"
324
- #request.headers("Connection"){ |h| puts h }
323
+ #request.headers("Connection"){ |h| puts h }
325
324
 
326
- if missing_credentials
327
- resp.set_header("Connection", "close")
325
+ if missing_credentials
326
+ resp.set_header("Connection", "close")
328
327
  elsif request.connection_close? or resp.content_length < 0 or max_loop > 4
329
328
  # resp.set_header("Proxy-Connection","close")
330
329
  resp.set_header("Connection","close")
@@ -333,32 +332,32 @@ module Watobo#:nodoc: all
333
332
  resp.set_header("Keep-Alive", "max=4, timeout=120")
334
333
  end
335
334
 
336
- resp_data = resp.join
335
+ resp_data = resp.join
337
336
  c_sock.write resp_data
338
337
 
339
338
  # puts "---"
340
339
  # puts resp_data.unpack("H*")[0]
341
340
  # puts "==="
342
-
343
- rescue Errno::ECONNRESET
344
- print "x"
345
- # puts "!!! ERROR (Reset): reading body"
346
- # puts "* last data seen on socket: #{buf}"
347
- #return
348
- rescue Errno::ECONNABORTED
349
- print "x"
350
- #return
351
- rescue => bang
352
- puts "!!! Error (???) in Client Communication:"
353
- puts bang
354
- puts bang.class
355
- puts bang.backtrace #if $DEBUG
356
- #return
357
- end
358
-
359
- chat = Chat.new(request.copy, resp.copy, :source => CHAT_SOURCE_INTERCEPT)
360
-
361
- Watobo::Chats.add chat
341
+
342
+ rescue Errno::ECONNRESET
343
+ print "x"
344
+ # puts "!!! ERROR (Reset): reading body"
345
+ # puts "* last data seen on socket: #{buf}"
346
+ #return
347
+ rescue Errno::ECONNABORTED
348
+ print "x"
349
+ #return
350
+ rescue => bang
351
+ puts "!!! Error (???) in Client Communication:"
352
+ puts bang
353
+ puts bang.class
354
+ puts bang.backtrace #if $DEBUG
355
+ #return
356
+ end
357
+
358
+ chat = Chat.new(request.copy, resp.copy, :source => CHAT_SOURCE_INTERCEPT)
359
+
360
+ Watobo::Chats.add chat
362
361
 
363
362
  # TODO: place check into ClientSocket, because headers must be checked and changed too
364
363
  # e.g. if c_sock.open?
@@ -369,341 +368,341 @@ module Watobo#:nodoc: all
369
368
  print "o"
370
369
  max_loop += 1
371
370
 
372
- end
373
- }
374
-
375
- end
376
- }
377
- end
378
-
379
- def refresh_www_auth
380
- @www_auth = Watobo::Conf::Scanner.www_auth
381
- end
382
-
383
- def initialize(settings=nil)
384
- @event_dispatcher_listeners = Hash.new
385
- begin
386
-
387
- puts
388
- puts "=== Initialize Interceptor/Proxy ==="
389
-
390
- #Watobo::Interceptor.proxy_mode = INTERCEPT_NONE
391
-
392
- init_instance_vars
393
-
394
- @awaiting_requests = 0
395
- @awaiting_responses = 0
396
-
397
- @request_filter_settings = {
398
- :site_in_scope => false,
399
- :method_filter => '(get|post|put)',
400
- :negate_method_filter => false,
401
- :negate_url_filter => false,
402
- :url_filter => '',
403
- :file_type_filter => '(jpg|gif|png|jpeg|bmp)',
404
- :negate_file_type_filter => true,
405
-
406
- :parms_filter => '',
407
- :negate_parms_filter => false
408
- #:regex_location => 0, # TODO: HEADER_LOCATION, BODY_LOCATION, ALL
409
-
410
- }
411
-
412
- @response_filter_settings = {
413
- :content_type_filter => '(text|script)',
414
- :negate_content_type_filter => false,
415
- :response_code_filter => '2\d{2}',
416
- :negate_response_code_filter => false,
417
- :request_intercepted => false,
418
- :content_printable => true,
419
- :enable_printable_check => false
420
- }
421
-
422
- @preview = Hash.new
423
- @preview['ProxyTest'] = ["HTTP/1.0 200 OK\r\nServer: Watobo-Interceptor\r\nConnection: close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><body>PROXY_OK</body></html>"]
424
-
425
- @dh_key = Watobo::CA.dh_key
426
-
427
- rescue => bang
428
- puts "!!!could not read certificate files:"
429
- puts bang
430
- puts bang.backtrace if $DEBUG
431
- end
432
-
433
- end
434
-
435
- private
436
-
437
- def init_instance_vars
438
- @www_auth = Watobo::Conf::Scanner.www_auth
439
- @fake_certs = {}
440
- @client_certificates = {}
441
- @target = nil
442
- # @sender = Watobo::Session.new(@target)
443
-
444
- @bind_addr = Watobo::Conf::Interceptor.bind_addr
445
- # puts "> Server: #{@bind_addr}"
446
- @port = Watobo::Conf::Interceptor.port
447
- # puts "> Port: #{@port}"
448
- @proxy_mode = Watobo::Conf::Interceptor.proxy_mode
449
-
450
- pt = Watobo::Conf::Interceptor.pass_through
451
- @contentLength = pt[:content_length]
452
- # puts "> PT-ContentLength: #{@contentLength}"
453
- @contentTypes = pt[:content_types]
454
- # puts "> PT-ContentTypes: #{@contentTypes}"
455
- end
456
-
457
- #
458
- #
459
- # matchContentType(content_type)
460
- #
461
- #
462
- def matchContentType?(content_type)
463
- @contentTypes.each do |p|
464
- return true if content_type =~ /#{p}/
465
- end
466
- return false
467
- end
468
-
469
- #
470
- #
471
- # matchRequestFilter(request)
472
- #
473
- #
474
- def matchRequestFilter(request)
475
- match_url = true
476
- # puts @request_filter_settings.to_yaml
477
- url_filter = @request_filter_settings[:url_filter]
478
- if url_filter != ''
479
- match_url = false
480
- if request.url.to_s =~ /#{url_filter}/i
481
- match_url = true
482
- end
483
- if @request_filter_settings[:negate_url_filter] == true
484
- match_url = ( match_url == true ) ? false : true
485
- end
486
- end
487
-
488
- return false if match_url == false
489
-
490
- match_method = true
491
- method_filter = @request_filter_settings[:method_filter]
492
- if method_filter != ''
493
- match_method = false
494
- if request.method =~ /#{method_filter}/i
495
- match_method = true
496
- end
497
-
498
- if @request_filter_settings[:negate_method_filter] == true
499
- match_method = ( match_method == true ) ? false : true
500
- end
501
- end
502
-
503
- return false if match_method == false
504
-
505
- match_ftype = true
506
- ftype_filter = @request_filter_settings[:file_type_filter]
507
- if ftype_filter != ''
508
- match_ftype = false
509
- if request.doctype != '' and request.doctype =~ /#{ftype_filter}/i
510
- match_ftype = true
511
- end
512
- if @request_filter_settings[:negate_file_type_filter] == true
513
- match_ftype = ( match_ftype == true ) ? false : true
514
- end
515
- end
516
- return false if match_ftype == false
517
-
518
- match_parms = true
519
- parms_filter = @request_filter_settings[:parms_filter]
520
- if parms_filter != ''
521
- # puts "!PARMS FILTER: #{parms_filter}"
522
- match_parms = false
523
- puts request.parms
524
- match_parms = request.parms.find {|x| x =~ /#{parms_filter}/ }
525
- match_parms = ( match_parms.nil? ) ? false : true
526
- if @request_filter_settings[:negate_parms_filter] == true
527
- match_parms = ( match_parms == true ) ? false : true
528
- end
529
- end
530
- return false if match_parms == false
531
-
532
- true
533
- end
534
-
535
- #
536
- #
537
- # matchResponseFilter(response)
538
- #
539
- #
540
-
541
- def matchResponseFilter(response)
542
- match_ctype = true
543
- ct_filter = @response_filter_settings[:content_type_filter]
544
- unless ct_filter.empty?
545
- match_ctype = false
546
- negate = @response_filter_settings[:negate_content_type_filter]
547
- if response.content_type =~ /#{ct_filter}/
548
- match_ctype = true
549
-
550
- end
551
- if negate == true
552
- match_ctype = ( match_ctype == true ) ? false : true
553
- end
554
- end
555
- return false if match_ctype == false
556
- #puts "* pass ctype filter"
557
- match_rcode = true
558
- rcode_filter = @response_filter_settings[:response_code_filter]
559
- negate = @response_filter_settings[:negate_response_code_filter]
560
- unless rcode_filter.empty?
561
- match_rcode = false
562
- puts rcode_filter
563
- puts response.responseCode
564
- if response.responseCode =~ /#{rcode_filter}/
565
- match_rcode = true
566
- end
567
- if negate == true
568
- match_rcode = ( match_rcode == true ) ? false : true
569
- end
570
- end
571
- return false if match_rcode == false
572
- #puts "* pass rcode filter"
573
- true
574
- end
575
-
576
- #
577
- #
578
- # pass_through(server, client, maxbytes)
579
- #
580
- #
581
- def pass_through(server, client, maxbytes = 0)
582
-
583
- bytes_read = 0
584
- while 1
585
- begin
586
- #timeout(2) do
587
- buf = nil
588
- buf = server.readpartial(2048)
589
- #end
590
- rescue EOFError
591
- #client.write buf if buf
371
+ end
372
+ }
373
+
374
+ end
375
+ }
376
+ end
377
+
378
+ def refresh_www_auth
379
+ @www_auth = Watobo::Conf::Scanner.www_auth
380
+ end
381
+
382
+ def initialize(settings=nil)
383
+ @event_dispatcher_listeners = Hash.new
384
+ begin
385
+
386
+ puts
387
+ puts "=== Initialize Interceptor/Proxy ==="
388
+
389
+ #Watobo::Interceptor.proxy_mode = INTERCEPT_NONE
390
+
391
+ init_instance_vars
392
+
393
+ @awaiting_requests = 0
394
+ @awaiting_responses = 0
395
+
396
+ @request_filter_settings = {
397
+ :site_in_scope => false,
398
+ :method_filter => '(get|post|put)',
399
+ :negate_method_filter => false,
400
+ :negate_url_filter => false,
401
+ :url_filter => '',
402
+ :file_type_filter => '(jpg|gif|png|jpeg|bmp)',
403
+ :negate_file_type_filter => true,
404
+
405
+ :parms_filter => '',
406
+ :negate_parms_filter => false
407
+ #:regex_location => 0, # TODO: HEADER_LOCATION, BODY_LOCATION, ALL
408
+
409
+ }
410
+
411
+ @response_filter_settings = {
412
+ :content_type_filter => '(text|script)',
413
+ :negate_content_type_filter => false,
414
+ :response_code_filter => '2\d{2}',
415
+ :negate_response_code_filter => false,
416
+ :request_intercepted => false,
417
+ :content_printable => true,
418
+ :enable_printable_check => false
419
+ }
420
+
421
+ @preview = Hash.new
422
+ @preview['ProxyTest'] = ["HTTP/1.0 200 OK\r\nServer: Watobo-Interceptor\r\nConnection: close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><body>PROXY_OK</body></html>"]
423
+
424
+ @dh_key = Watobo::CA.dh_key
425
+
426
+ rescue => bang
427
+ puts "!!!could not read certificate files:"
428
+ puts bang
429
+ puts bang.backtrace if $DEBUG
430
+ end
431
+
432
+ end
433
+
434
+ private
435
+
436
+ def init_instance_vars
437
+ @www_auth = Watobo::Conf::Scanner.www_auth
438
+ @fake_certs = {}
439
+ @client_certificates = {}
440
+ @target = nil
441
+ # @sender = Watobo::Session.new(@target)
442
+
443
+ @bind_addr = Watobo::Conf::Interceptor.bind_addr
444
+ # puts "> Server: #{@bind_addr}"
445
+ @port = Watobo::Conf::Interceptor.port
446
+ # puts "> Port: #{@port}"
447
+ @proxy_mode = Watobo::Conf::Interceptor.proxy_mode
448
+
449
+ pt = Watobo::Conf::Interceptor.pass_through
450
+ @contentLength = pt[:content_length]
451
+ # puts "> PT-ContentLength: #{@contentLength}"
452
+ @contentTypes = pt[:content_types]
453
+ # puts "> PT-ContentTypes: #{@contentTypes}"
454
+ end
455
+
456
+ #
457
+ #
458
+ # matchContentType(content_type)
459
+ #
460
+ #
461
+ def matchContentType?(content_type)
462
+ @contentTypes.each do |p|
463
+ return true if content_type =~ /#{p}/
464
+ end
465
+ return false
466
+ end
467
+
468
+ #
469
+ #
470
+ # matchRequestFilter(request)
471
+ #
472
+ #
473
+ def matchRequestFilter(request)
474
+ match_url = true
475
+ # puts @request_filter_settings.to_yaml
476
+ url_filter = @request_filter_settings[:url_filter]
477
+ if url_filter != ''
478
+ match_url = false
479
+ if request.url.to_s =~ /#{url_filter}/i
480
+ match_url = true
481
+ end
482
+ if @request_filter_settings[:negate_url_filter] == true
483
+ match_url = ( match_url == true ) ? false : true
484
+ end
485
+ end
486
+
487
+ return false if match_url == false
488
+
489
+ match_method = true
490
+ method_filter = @request_filter_settings[:method_filter]
491
+ if method_filter != ''
492
+ match_method = false
493
+ if request.method =~ /#{method_filter}/i
494
+ match_method = true
495
+ end
496
+
497
+ if @request_filter_settings[:negate_method_filter] == true
498
+ match_method = ( match_method == true ) ? false : true
499
+ end
500
+ end
501
+
502
+ return false if match_method == false
503
+
504
+ match_ftype = true
505
+ ftype_filter = @request_filter_settings[:file_type_filter]
506
+ if ftype_filter != ''
507
+ match_ftype = false
508
+ if request.doctype != '' and request.doctype =~ /#{ftype_filter}/i
509
+ match_ftype = true
510
+ end
511
+ if @request_filter_settings[:negate_file_type_filter] == true
512
+ match_ftype = ( match_ftype == true ) ? false : true
513
+ end
514
+ end
515
+ return false if match_ftype == false
516
+
517
+ match_parms = true
518
+ parms_filter = @request_filter_settings[:parms_filter]
519
+ if parms_filter != ''
520
+ # puts "!PARMS FILTER: #{parms_filter}"
521
+ match_parms = false
522
+ puts request.parms
523
+ match_parms = request.parms.find {|x| x =~ /#{parms_filter}/ }
524
+ match_parms = ( match_parms.nil? ) ? false : true
525
+ if @request_filter_settings[:negate_parms_filter] == true
526
+ match_parms = ( match_parms == true ) ? false : true
527
+ end
528
+ end
529
+ return false if match_parms == false
530
+
531
+ true
532
+ end
533
+
534
+ #
535
+ #
536
+ # matchResponseFilter(response)
537
+ #
538
+ #
539
+
540
+ def matchResponseFilter(response)
541
+ match_ctype = true
542
+ ct_filter = @response_filter_settings[:content_type_filter]
543
+ unless ct_filter.empty?
544
+ match_ctype = false
545
+ negate = @response_filter_settings[:negate_content_type_filter]
546
+ if response.content_type =~ /#{ct_filter}/
547
+ match_ctype = true
548
+
549
+ end
550
+ if negate == true
551
+ match_ctype = ( match_ctype == true ) ? false : true
552
+ end
553
+ end
554
+ return false if match_ctype == false
555
+ #puts "* pass ctype filter"
556
+ match_rcode = true
557
+ rcode_filter = @response_filter_settings[:response_code_filter]
558
+ negate = @response_filter_settings[:negate_response_code_filter]
559
+ unless rcode_filter.empty?
560
+ match_rcode = false
561
+ puts rcode_filter
562
+ puts response.responseCode
563
+ if response.responseCode =~ /#{rcode_filter}/
564
+ match_rcode = true
565
+ end
566
+ if negate == true
567
+ match_rcode = ( match_rcode == true ) ? false : true
568
+ end
569
+ end
570
+ return false if match_rcode == false
571
+ #puts "* pass rcode filter"
572
+ true
573
+ end
574
+
575
+ #
576
+ #
577
+ # pass_through(server, client, maxbytes)
578
+ #
579
+ #
580
+ def pass_through(server, client, maxbytes = 0)
581
+
582
+ bytes_read = 0
583
+ while 1
584
+ begin
585
+ #timeout(2) do
586
+ buf = nil
587
+ buf = server.readpartial(2048)
588
+ #end
589
+ rescue EOFError
590
+ #client.write buf if buf
592
591
  #print "~]"
593
592
  # msg = "\n[pass_through] EOF - "
594
593
  # msg += buf.nil? ? "nil" : buf.size
595
- # puts msg
596
- return if buf.nil?
597
- rescue Errno::ECONNRESET
598
- # puts "!!! ERROR (Reset): reading body"
594
+ # puts msg
595
+ return if buf.nil?
596
+ rescue Errno::ECONNRESET
597
+ # puts "!!! ERROR (Reset): reading body"
599
598
  # puts "* last data seen on socket: #{buf}"
600
599
  # msg = "!R - "
601
600
  # msg += buf.nil? ? "nil" : buf.size
602
601
  # msg << " !\n"
603
- # puts msg
604
-
605
- return if buf.nil?
606
- rescue Timeout::Error
607
- #puts "!!! ERROR (Timeout): reading body"
608
- #puts "* last data seen on socket:"
609
- #client.write buf if buf
610
- print "T"
611
- return
612
- rescue => bang
613
- puts "!!! could not read body !!!"
614
- puts bang
615
- puts bang.class
616
- puts bang.backtrace if $DEBUG
617
- # puts "* last data seen on socket:"
618
- # print "~]"
619
- #client.write buf if buf
620
- return
621
- end
622
-
623
- begin
624
- return if buf.nil?
625
- # print "~"
626
- client.write buf
627
- bytes_read += buf.length
628
- # puts "#{server} #{bytes_read} of #{maxbytes}"
629
- if maxbytes > 0 and bytes_read >= maxbytes
630
- #print "~]"
631
- return
632
- end
633
- rescue Errno::ECONNRESET
634
- #print "~x]"
635
- # puts "!!! ERROR (Reset): reading body"
636
- # puts "* last data seen on socket: #{buf}"
637
- return
638
- rescue Errno::ECONNABORTED
639
- # print "~x]"
640
- return
641
- rescue Errno::EPIPE
642
- # print "~x]"
643
- return
644
- rescue => bang
645
- puts "!!! client communication broken !!!"
646
- puts bang
647
- puts bang.class
648
- puts bang.backtrace if $DEBUG
649
- return
650
- end
651
- end
652
- end
653
-
654
- def transparent?
655
- ( @proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
656
- end
657
-
658
- def isPassThrough?(request, response, s_sock, c_sock)
602
+ # puts msg
603
+
604
+ return if buf.nil?
605
+ rescue Timeout::Error
606
+ #puts "!!! ERROR (Timeout): reading body"
607
+ #puts "* last data seen on socket:"
608
+ #client.write buf if buf
609
+ print "T"
610
+ return
611
+ rescue => bang
612
+ puts "!!! could not read body !!!"
613
+ puts bang
614
+ puts bang.class
615
+ puts bang.backtrace if $DEBUG
616
+ # puts "* last data seen on socket:"
617
+ # print "~]"
618
+ #client.write buf if buf
619
+ return
620
+ end
621
+
622
+ begin
623
+ return if buf.nil?
624
+ # print "~"
625
+ client.write buf
626
+ bytes_read += buf.length
627
+ # puts "#{server} #{bytes_read} of #{maxbytes}"
628
+ if maxbytes > 0 and bytes_read >= maxbytes
629
+ #print "~]"
630
+ return
631
+ end
632
+ rescue Errno::ECONNRESET
633
+ #print "~x]"
634
+ # puts "!!! ERROR (Reset): reading body"
635
+ # puts "* last data seen on socket: #{buf}"
636
+ return
637
+ rescue Errno::ECONNABORTED
638
+ # print "~x]"
639
+ return
640
+ rescue Errno::EPIPE
641
+ # print "~x]"
642
+ return
643
+ rescue => bang
644
+ puts "!!! client communication broken !!!"
645
+ puts bang
646
+ puts bang.class
647
+ puts bang.backtrace if $DEBUG
648
+ return
649
+ end
650
+ end
651
+ end
652
+
653
+ def transparent?
654
+ ( @proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
655
+ end
656
+
657
+ def isPassThrough?(request, response, s_sock, c_sock)
659
658
  begin
660
- # return false if true
661
- reason = nil
662
- clen = response.content_length
663
- # no pass-through necessary if request method is HEAD
664
- return false if request.method =~ /^head/i
665
-
666
- if matchContentType?(response.content_type) then
667
- # first forward headers
668
- #c_sock.write response.join
669
- reason = []
670
- reason.push "---> WATOBO: PASS_THROUGH <---"
671
- reason.push "Reason: Content-Type = #{response.content_type}"
672
- elsif clen > @contentLength
673
- # puts "PASS-THROUGH: #{response.content_length}"
674
- #c_sock.write response.join
675
- reason = []
676
- reason.push "---> WATOBO: PASS_THROUGH <---"
677
- reason.push "Reason: Content-Length > #{@contentLength} (#{response.content_length})"
678
- end
679
-
659
+ # return false if true
660
+ reason = nil
661
+ clen = response.content_length
662
+ # no pass-through necessary if request method is HEAD
663
+ return false if request.method =~ /^head/i
664
+
665
+ if matchContentType?(response.content_type) then
666
+ # first forward headers
667
+ #c_sock.write response.join
668
+ reason = []
669
+ reason.push "---> WATOBO: PASS_THROUGH <---"
670
+ reason.push "Reason: Content-Type = #{response.content_type}"
671
+ elsif clen > @contentLength
672
+ # puts "PASS-THROUGH: #{response.content_length}"
673
+ #c_sock.write response.join
674
+ reason = []
675
+ reason.push "---> WATOBO: PASS_THROUGH <---"
676
+ reason.push "Reason: Content-Length > #{@contentLength} (#{response.content_length})"
677
+ end
678
+
680
679
  return false if reason.nil?
681
680
 
682
681
  response.remove_header("Keep-Alive")
683
682
  response.set_header("Connection", "close")
684
683
 
685
684
  c_sock.write response.join
686
-
687
- reason.push "* DO MANUAL REQUEST TO GET FULL RESPONSE *"
688
- response.push reason.join("\n")
689
- chat = Watobo::Chat.new(request, response, :source => CHAT_SOURCE_INTERCEPT)
690
- #notify(:new_interception, chat)
691
- Watobo::Chats.add chat
692
-
693
- pass_through(s_sock, c_sock, clen)
694
- # puts "* Close Server Socket..."
695
- #closeSocket(c_sock)
696
- # puts "* Close Client Socket..."
697
- #closeSocket(s_sock)
698
- # puts "... done."
699
- return true
700
- rescue => bang
701
- puts bang
702
- puts bang.backtrace if $DEBUG
685
+
686
+ reason.push "* DO MANUAL REQUEST TO GET FULL RESPONSE *"
687
+ response.push reason.join("\n")
688
+ chat = Watobo::Chat.new(request, response, :source => CHAT_SOURCE_INTERCEPT)
689
+ #notify(:new_interception, chat)
690
+ Watobo::Chats.add chat
691
+
692
+ pass_through(s_sock, c_sock, clen)
693
+ # puts "* Close Server Socket..."
694
+ #closeSocket(c_sock)
695
+ # puts "* Close Client Socket..."
696
+ #closeSocket(s_sock)
697
+ # puts "... done."
698
+ return true
699
+ rescue => bang
700
+ puts bang
701
+ puts bang.backtrace if $DEBUG
703
702
  end
704
- return false
705
- end
706
-
707
- end
708
- end
709
- end
703
+ return false
704
+ end
705
+
706
+ end
707
+ end
708
+ end