watobo 0.9.21 → 0.9.23

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