watobo 0.9.21 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +46 -1
- data/bin/nfq_server.rb +0 -9
- data/bin/watobo_gui.rb +3 -13
- data/custom-views/prettify-json.rb +9 -18
- data/icons/watobo.ico +0 -0
- data/icons/watobo.ico.old +0 -0
- data/lib/watobo.rb +10 -19
- data/lib/watobo/adapters.rb +5 -14
- data/lib/watobo/adapters/data_store.rb +50 -59
- data/lib/watobo/adapters/file/file_store.rb +287 -296
- data/lib/watobo/adapters/file/marshal_store.rb +293 -296
- data/lib/watobo/adapters/session_store.rb +5 -14
- data/lib/watobo/ca.rb +1 -10
- data/lib/watobo/config.rb +197 -206
- data/lib/watobo/constants.rb +0 -9
- data/lib/watobo/core.rb +3 -12
- data/lib/watobo/core/active_check.rb +72 -135
- data/lib/watobo/core/active_checks.rb +49 -58
- data/lib/watobo/core/ca.rb +369 -389
- data/lib/watobo/core/cert_store.rb +34 -43
- data/lib/watobo/core/chat.rb +92 -101
- data/lib/watobo/core/chats.rb +271 -280
- data/lib/watobo/core/client_cert_store.rb +106 -35
- data/lib/watobo/core/conversation.rb +48 -57
- data/lib/watobo/core/cookie.rb +23 -32
- data/lib/watobo/core/egress_handlers.rb +98 -0
- data/lib/watobo/core/finding.rb +66 -75
- data/lib/watobo/core/findings.rb +107 -114
- data/lib/watobo/core/forwarding_proxy.rb +13 -22
- data/lib/watobo/core/fuzz_gen.rb +0 -9
- data/lib/watobo/core/intercept_carver.rb +166 -177
- data/lib/watobo/core/intercept_filter.rb +235 -244
- data/lib/watobo/core/interceptor.rb +98 -107
- data/lib/watobo/core/min_class.rb +4 -13
- data/lib/watobo/core/netfilter_queue.rb +170 -179
- data/lib/watobo/core/ott_cache.rb +132 -141
- data/lib/watobo/core/parameter.rb +43 -52
- data/lib/watobo/core/passive_check.rb +103 -102
- data/lib/watobo/core/passive_checks.rb +48 -57
- data/lib/watobo/core/passive_scanner.rb +54 -55
- data/lib/watobo/core/plugin.rb +11 -20
- data/lib/watobo/core/project.rb +3 -9
- data/lib/watobo/core/proxy.rb +43 -52
- data/lib/watobo/core/request.rb +125 -123
- data/lib/watobo/core/response.rb +44 -53
- data/lib/watobo/core/scanner.rb +0 -9
- data/lib/watobo/core/scanner3.rb +405 -414
- data/lib/watobo/core/scope.rb +83 -92
- data/lib/watobo/core/session.rb +1043 -1026
- data/lib/watobo/core/sid_cache.rb +98 -107
- data/lib/watobo/core/subscriber.rb +25 -34
- data/lib/watobo/defaults.rb +21 -30
- data/lib/watobo/external/diff/lcs.rb +0 -9
- data/lib/watobo/external/diff/lcs/array.rb +0 -9
- data/lib/watobo/external/diff/lcs/block.rb +0 -9
- data/lib/watobo/external/diff/lcs/callbacks.rb +0 -9
- data/lib/watobo/external/diff/lcs/change.rb +0 -9
- data/lib/watobo/external/diff/lcs/hunk.rb +0 -9
- data/lib/watobo/external/diff/lcs/ldiff.rb +0 -9
- data/lib/watobo/external/diff/lcs/string.rb +0 -9
- data/lib/watobo/externals.rb +6 -15
- data/lib/watobo/framework.rb +4 -13
- data/lib/watobo/framework/create_project.rb +60 -69
- data/lib/watobo/framework/init.rb +0 -9
- data/lib/watobo/framework/init_modules.rb +0 -9
- data/lib/watobo/framework/license_text.rb +28 -37
- data/lib/watobo/framework/load_chat.rb +13 -22
- data/lib/watobo/gui.rb +132 -123
- data/lib/watobo/gui/about_watobo.rb +0 -9
- data/lib/watobo/gui/browser_preview.rb +0 -9
- data/lib/watobo/gui/certificate_dialog.rb +0 -9
- data/lib/watobo/gui/chat_diff.rb +0 -9
- data/lib/watobo/gui/chatviewer_frame.rb +73 -72
- data/lib/watobo/gui/checkboxtree.rb +0 -9
- data/lib/watobo/gui/checks_policy_frame.rb +0 -9
- data/lib/watobo/gui/client_cert_dialog.rb +96 -87
- data/lib/watobo/gui/confirm_scan_dialog.rb +0 -9
- data/lib/watobo/gui/conversation_table.rb +158 -164
- data/lib/watobo/gui/conversation_table_ctrl.rb +207 -216
- data/lib/watobo/gui/conversation_table_ctrl2.rb +373 -382
- data/lib/watobo/gui/csrf_token_dialog.rb +0 -9
- data/lib/watobo/gui/custom_viewer.rb +374 -383
- data/lib/watobo/gui/dashboard.rb +296 -303
- data/lib/watobo/gui/define_scope_frame.rb +0 -9
- data/lib/watobo/gui/differ_frame.rb +215 -224
- data/lib/watobo/gui/edit_comment.rb +0 -9
- data/lib/watobo/gui/edit_scope_dialog.rb +0 -9
- data/lib/watobo/gui/export_dialog.rb +104 -113
- data/lib/watobo/gui/finding_info.rb +0 -9
- data/lib/watobo/gui/findings_tree.rb +210 -217
- data/lib/watobo/gui/full_scan_dialog.rb +0 -9
- data/lib/watobo/gui/fuzzer_gui.rb +1295 -1313
- data/lib/watobo/gui/fxsave_thread.rb +14 -0
- data/lib/watobo/gui/goto_url_dialog.rb +70 -79
- data/lib/watobo/gui/hex_viewer.rb +0 -9
- data/lib/watobo/gui/html_viewer.rb +287 -296
- data/lib/watobo/gui/intercept_filter_dialog.rb +188 -197
- data/lib/watobo/gui/interceptor_gui.rb +1041 -1051
- data/lib/watobo/gui/interceptor_settings_dialog.rb +0 -9
- data/lib/watobo/gui/json_viewer.rb +287 -0
- data/lib/watobo/gui/list_box.rb +101 -110
- data/lib/watobo/gui/log_file_viewer.rb +32 -41
- data/lib/watobo/gui/log_viewer.rb +83 -88
- data/lib/watobo/gui/login_wizzard.rb +0 -9
- data/lib/watobo/gui/main_window.rb +587 -618
- data/lib/watobo/gui/manual_request_editor.rb +620 -565
- data/lib/watobo/gui/master_pw_dialog.rb +0 -9
- data/lib/watobo/gui/mixins/gui_settings.rb +29 -38
- data/lib/watobo/gui/page_tree.rb +217 -226
- data/lib/watobo/gui/password_policy_dialog.rb +0 -9
- data/lib/watobo/gui/plugin_board.rb +0 -9
- data/lib/watobo/gui/preferences_dialog.rb +0 -9
- data/lib/watobo/gui/progress_window.rb +17 -27
- data/lib/watobo/gui/project_wizzard.rb +0 -9
- data/lib/watobo/gui/proxy_dialog.rb +1 -10
- data/lib/watobo/gui/quick_scan_dialog.rb +0 -9
- data/lib/watobo/gui/request_builder_frame.rb +102 -111
- data/lib/watobo/gui/request_editor.rb +181 -137
- data/lib/watobo/gui/rewrite_filters_dialog.rb +394 -403
- data/lib/watobo/gui/rewrite_rules_dialog.rb +372 -381
- data/lib/watobo/gui/save_chat_dialog.rb +140 -149
- data/lib/watobo/gui/scanner_settings_dialog.rb +0 -9
- data/lib/watobo/gui/select_chat_dialog.rb +0 -9
- data/lib/watobo/gui/session_management_dialog.rb +0 -9
- data/lib/watobo/gui/sites_tree.rb +0 -9
- data/lib/watobo/gui/status_bar.rb +0 -9
- data/lib/watobo/gui/table_editor.rb +0 -9
- data/lib/watobo/gui/tagless_viewer.rb +0 -9
- data/lib/watobo/gui/templates/plugin.rb +0 -9
- data/lib/watobo/gui/templates/plugin2.rb +92 -100
- data/lib/watobo/gui/templates/plugin_base.rb +144 -153
- data/lib/watobo/gui/text_viewer.rb +0 -9
- data/lib/watobo/gui/transcoder_window.rb +0 -9
- data/lib/watobo/gui/utils/gui_utils.rb +0 -9
- data/lib/watobo/gui/utils/init_icons.rb +86 -95
- data/lib/watobo/gui/utils/load_icons.rb +33 -42
- data/lib/watobo/gui/utils/load_plugins.rb +116 -119
- data/lib/watobo/gui/utils/master_password.rb +68 -77
- data/lib/watobo/gui/utils/save_default_settings.rb +113 -122
- data/lib/watobo/gui/utils/save_project_settings.rb +0 -9
- data/lib/watobo/gui/utils/save_proxy_settings.rb +41 -50
- data/lib/watobo/gui/utils/save_scanner_settings.rb +18 -27
- data/lib/watobo/gui/utils/session_history.rb +112 -121
- data/lib/watobo/gui/workspace_dialog.rb +0 -9
- data/lib/watobo/gui/www_auth_dialog.rb +0 -9
- data/lib/watobo/gui/xml_viewer_frame.rb +0 -9
- data/lib/watobo/http.rb +4 -13
- data/lib/watobo/http/cookies/cookies.rb +26 -35
- data/lib/watobo/http/data/data.rb +45 -54
- data/lib/watobo/http/data/json.rb +47 -55
- data/lib/watobo/http/url/url.rb +38 -47
- data/lib/watobo/http/xml/xml.rb +124 -130
- data/lib/watobo/interceptor.rb +3 -12
- data/lib/watobo/interceptor/proxy.rb +742 -739
- data/lib/watobo/interceptor/transparent.rb +22 -24
- data/lib/watobo/mixins.rb +10 -19
- data/lib/watobo/mixins/check_info.rb +27 -36
- data/lib/watobo/mixins/httpparser.rb +613 -637
- data/lib/watobo/mixins/request_parser.rb +88 -97
- data/lib/watobo/mixins/shapers.rb +515 -529
- data/lib/watobo/mixins/transcoders.rb +3 -11
- data/lib/watobo/parser.rb +1 -10
- data/lib/watobo/parser/html.rb +83 -92
- data/lib/watobo/patch_fxruby_setfocus.rb +26 -0
- data/lib/watobo/sockets.rb +3 -12
- data/lib/watobo/sockets/agent.rb +828 -837
- data/lib/watobo/sockets/client_socket.rb +308 -312
- data/lib/watobo/sockets/connection.rb +401 -410
- data/lib/watobo/sockets/http_socket.rb +11 -13
- data/lib/watobo/sockets/ntlm_auth.rb +129 -138
- data/lib/watobo/utils.rb +10 -19
- data/lib/watobo/utils/check_regex.rb +0 -9
- data/lib/watobo/utils/copy_object.rb +0 -9
- data/lib/watobo/utils/crypto.rb +0 -9
- data/lib/watobo/utils/expand_range.rb +23 -32
- data/lib/watobo/utils/export_xml.rb +97 -106
- data/lib/watobo/utils/file_management.rb +9 -11
- data/lib/watobo/utils/hexprint.rb +9 -18
- data/lib/watobo/utils/load_chat.rb +0 -9
- data/lib/watobo/utils/load_icon.rb +0 -9
- data/lib/watobo/utils/ntlm.rb +866 -875
- data/lib/watobo/utils/print_debug.rb +12 -21
- data/lib/watobo/utils/response_builder.rb +90 -99
- data/lib/watobo/utils/response_hash.rb +0 -9
- data/lib/watobo/utils/secure_eval.rb +0 -9
- data/lib/watobo/utils/strings.rb +10 -19
- data/lib/watobo/utils/text2request.rb +0 -9
- data/lib/watobo/utils/url.rb +23 -32
- data/lib/watobo/utils/utf16.rb +11 -20
- data/modules/active/Apache/mod_status.rb +0 -9
- data/modules/active/Apache/multiview.rb +151 -160
- data/modules/active/Flash/crossdomain.rb +0 -9
- data/modules/active/JWT/jwt_oauth2_none.rb +111 -0
- data/modules/active/cq5/cq5_default_selectors.rb +106 -115
- data/modules/active/cq5/cqp_user_enumeration.rb +125 -134
- data/modules/active/directories/dirwalker.rb +0 -9
- data/modules/active/discovery/fileextensions.rb +0 -9
- data/modules/active/discovery/http_methods.rb +0 -9
- data/modules/active/discovery/jsmapfiles.rb +79 -0
- data/modules/active/domino/domino_db.rb +68 -76
- data/modules/active/dotNET/custom_errors.rb +102 -111
- data/modules/active/dotNET/dotnet_files.rb +90 -99
- data/modules/active/fileinclusion/lfi_simple.rb +0 -9
- data/modules/active/jboss/jboss_basic.rb +0 -9
- data/modules/active/sap/business_objects.rb +51 -60
- data/modules/active/sap/its_commands.rb +0 -9
- data/modules/active/sap/its_service_parameter.rb +0 -9
- data/modules/active/sap/its_services.rb +0 -9
- data/modules/active/sap/its_xss.rb +0 -9
- data/modules/active/shell_shock/shell_shock.rb +139 -148
- data/modules/active/siebel/siebel_apps.rb +160 -169
- data/modules/active/sqlinjection/sql_boolean.rb +0 -9
- data/modules/active/sqlinjection/sql_numerical.rb +198 -0
- data/modules/active/sqlinjection/sqli_error.rb +0 -9
- data/modules/active/sqlinjection/sqli_timing.rb +220 -229
- data/modules/active/struts2/default_handler_ognl.rb +106 -115
- data/modules/active/struts2/include_params_ognl.rb +105 -114
- data/modules/active/xml/xml_xxe.rb +112 -123
- data/modules/active/xss/xss_ng.rb +214 -223
- data/modules/active/xss/xss_simple.rb +0 -9
- data/modules/passive/ajax.rb +68 -77
- data/modules/passive/autocomplete.rb +56 -65
- data/modules/passive/cookie_options.rb +0 -9
- data/modules/passive/cookie_xss.rb +0 -9
- data/modules/passive/detect_code.rb +0 -9
- data/modules/passive/detect_fileupload.rb +0 -9
- data/modules/passive/detect_infrastructure.rb +0 -9
- data/modules/passive/detect_one_time_tokens.rb +0 -9
- data/modules/passive/dirindexing.rb +0 -9
- data/modules/passive/disclosure_domino.rb +55 -64
- data/modules/passive/disclosure_emails.rb +0 -9
- data/modules/passive/disclosure_ipaddr.rb +55 -53
- data/modules/passive/filename_as_parameter.rb +0 -9
- data/modules/passive/form_spotter.rb +0 -9
- data/modules/passive/hidden_fields.rb +50 -59
- data/modules/passive/hotspots.rb +0 -9
- data/modules/passive/in_script_parameter.rb +0 -9
- data/modules/passive/json_web_token.rb +93 -0
- data/modules/passive/multiple_server_headers.rb +0 -9
- data/modules/passive/possible_login.rb +0 -9
- data/modules/passive/redirect_url.rb +0 -9
- data/modules/passive/redirectionz.rb +0 -9
- data/modules/passive/sap-headers.rb +56 -65
- data/modules/passive/xss_dom.rb +0 -9
- data/plugins/aem/aem.rb +11 -20
- data/plugins/aem/gui/main.rb +118 -127
- data/plugins/aem/gui/tree_view.rb +171 -180
- data/plugins/aem/lib/agent.rb +130 -138
- data/plugins/aem/lib/dispatcher.rb +45 -51
- data/plugins/aem/lib/engine.rb +177 -186
- data/plugins/catalog/catalog.rb +345 -355
- data/plugins/crawler/crawler.rb +4 -13
- data/plugins/crawler/gui.rb +5 -14
- data/plugins/crawler/gui/auth_frame.rb +270 -279
- data/plugins/crawler/gui/crawler_gui.rb +271 -276
- data/plugins/crawler/gui/general_settings_frame.rb +96 -105
- data/plugins/crawler/gui/hooks_frame.rb +80 -89
- data/plugins/crawler/gui/scope_frame.rb +50 -59
- data/plugins/crawler/gui/settings_tabbook.rb +38 -47
- data/plugins/crawler/gui/status_frame.rb +59 -68
- data/plugins/crawler/lib/bags.rb +18 -27
- data/plugins/crawler/lib/constants.rb +11 -20
- data/plugins/crawler/lib/engine.rb +488 -497
- data/plugins/crawler/lib/grabber.rb +68 -77
- data/plugins/crawler/lib/status.rb +71 -80
- data/plugins/crawler/lib/uri_mp.rb +12 -21
- data/plugins/filefinder/filefinder.rb +326 -333
- data/plugins/sqlmap/bin/test.rb +78 -87
- data/plugins/sqlmap/gui.rb +4 -13
- data/plugins/sqlmap/gui/main.rb +218 -227
- data/plugins/sqlmap/gui/options_frame.rb +97 -106
- data/plugins/sqlmap/lib/sqlmap_ctrl.rb +90 -100
- data/plugins/sqlmap/sqlmap.rb +2 -11
- data/plugins/sslchecker/cli/sslchecker_cli.rb +0 -9
- data/plugins/sslchecker/gui/cipher_table.rb +246 -254
- data/plugins/sslchecker/gui/gui.rb +258 -264
- data/plugins/sslchecker/gui/sslchecker.rb +4 -13
- data/plugins/sslchecker/lib/check.rb +127 -133
- data/plugins/wshell/gui/main.rb +119 -117
- data/plugins/wshell/lib/core.rb +38 -88
- data/plugins/wshell/wshell.rb +11 -20
- metadata +170 -164
data/lib/watobo/core/scope.rb
CHANGED
|
@@ -1,94 +1,85 @@
|
|
|
1
|
-
#.
|
|
2
|
-
# scope.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
|
-
class Scope
|
|
13
|
-
@scope = {}
|
|
14
|
-
def self.to_s
|
|
15
|
-
@scope.to_yaml
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.to_yaml
|
|
19
|
-
@scope.to_yaml
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def self.set(scope)
|
|
23
|
-
@scope = scope
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def self.exist?
|
|
27
|
-
return false if @scope.empty?
|
|
28
|
-
@scope.each_value do |s|
|
|
29
|
-
return true if s[:enabled] == true
|
|
30
|
-
end
|
|
31
|
-
return false
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def self.reset
|
|
35
|
-
@scope = {}
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def self.each(&block)
|
|
39
|
-
if block_given?
|
|
40
|
-
@scope.each do |site, scope|
|
|
41
|
-
yield [ site, scope]
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def self.match_site?(site)
|
|
47
|
-
return true if @scope.empty?
|
|
48
|
-
@scope.has_key? site
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def self.match_chat?(chat)
|
|
52
|
-
#puts @scope.to_yaml
|
|
53
|
-
return true if @scope.empty?
|
|
54
|
-
|
|
55
|
-
site = chat.request.site
|
|
56
|
-
|
|
57
|
-
if @scope.has_key? site
|
|
58
|
-
|
|
59
|
-
path = chat.request.path
|
|
60
|
-
url = chat.request.url.to_s
|
|
61
|
-
scope = @scope[site]
|
|
62
|
-
|
|
63
|
-
if scope.has_key? :root_path
|
|
64
|
-
unless scope[:root_path].empty?
|
|
65
|
-
return false unless path =~ /^(\/)?#{scope[:root_path]}/i
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
return true unless scope.has_key? :excluded_paths
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
scope[:excluded_paths].each do |p|
|
|
72
|
-
# puts "#{url} - #{p}"
|
|
73
|
-
return false if url =~ /#{p}/
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
return true
|
|
77
|
-
end
|
|
78
|
-
return false
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def self.add(site)
|
|
82
|
-
|
|
83
|
-
scope_details = {
|
|
84
|
-
:site => site,
|
|
85
|
-
:enabled => true,
|
|
86
|
-
:root_path => '',
|
|
87
|
-
:excluded_paths => [],
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@scope[site] = scope_details
|
|
91
|
-
return true
|
|
92
|
-
end
|
|
93
|
-
end
|
|
2
|
+
module Watobo#:nodoc: all
|
|
3
|
+
class Scope
|
|
4
|
+
@scope = {}
|
|
5
|
+
def self.to_s
|
|
6
|
+
@scope.to_yaml
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.to_yaml
|
|
10
|
+
@scope.to_yaml
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.set(scope)
|
|
14
|
+
@scope = scope
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.exist?
|
|
18
|
+
return false if @scope.empty?
|
|
19
|
+
@scope.each_value do |s|
|
|
20
|
+
return true if s[:enabled] == true
|
|
21
|
+
end
|
|
22
|
+
return false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.reset
|
|
26
|
+
@scope = {}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.each(&block)
|
|
30
|
+
if block_given?
|
|
31
|
+
@scope.each do |site, scope|
|
|
32
|
+
yield [ site, scope]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.match_site?(site)
|
|
38
|
+
return true if @scope.empty?
|
|
39
|
+
@scope.has_key? site
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.match_chat?(chat)
|
|
43
|
+
#puts @scope.to_yaml
|
|
44
|
+
return true if @scope.empty?
|
|
45
|
+
|
|
46
|
+
site = chat.request.site
|
|
47
|
+
|
|
48
|
+
if @scope.has_key? site
|
|
49
|
+
|
|
50
|
+
path = chat.request.path
|
|
51
|
+
url = chat.request.url.to_s
|
|
52
|
+
scope = @scope[site]
|
|
53
|
+
|
|
54
|
+
if scope.has_key? :root_path
|
|
55
|
+
unless scope[:root_path].empty?
|
|
56
|
+
return false unless path =~ /^(\/)?#{scope[:root_path]}/i
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
return true unless scope.has_key? :excluded_paths
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
scope[:excluded_paths].each do |p|
|
|
63
|
+
# puts "#{url} - #{p}"
|
|
64
|
+
return false if url =~ /#{p}/
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
return true
|
|
68
|
+
end
|
|
69
|
+
return false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.add(site)
|
|
73
|
+
|
|
74
|
+
scope_details = {
|
|
75
|
+
:site => site,
|
|
76
|
+
:enabled => true,
|
|
77
|
+
:root_path => '',
|
|
78
|
+
:excluded_paths => [],
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@scope[site] = scope_details
|
|
82
|
+
return true
|
|
83
|
+
end
|
|
84
|
+
end
|
|
94
85
|
end
|
data/lib/watobo/core/session.rb
CHANGED
|
@@ -1,933 +1,604 @@
|
|
|
1
|
-
#.
|
|
2
|
-
# session.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
2
|
module Watobo#:nodoc: all
|
|
12
|
-
|
|
13
|
-
class Session
|
|
14
3
|
|
|
15
|
-
|
|
16
|
-
include Watobo::Subscriber
|
|
4
|
+
class Session
|
|
17
5
|
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
include Watobo::Constants
|
|
7
|
+
include Watobo::Subscriber
|
|
20
8
|
|
|
21
|
-
|
|
9
|
+
@@settings = Hash.new
|
|
10
|
+
@@proxy = Hash.new
|
|
22
11
|
|
|
23
|
-
|
|
24
|
-
@@login_cv = ConditionVariable.new
|
|
25
|
-
@@login_in_progress = false
|
|
26
|
-
|
|
12
|
+
@@session_lock = Mutex.new
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
puts "!
|
|
14
|
+
@@login_mutex = Mutex.new
|
|
15
|
+
@@login_cv = ConditionVariable.new
|
|
16
|
+
@@login_in_progress = false
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def runLogin(chat_list, prefs={})
|
|
20
|
+
#puts @session.object_id
|
|
21
|
+
@@login_mutex.synchronize do
|
|
22
|
+
begin
|
|
23
|
+
@@login_in_progress = true
|
|
24
|
+
login_prefs = Hash.new
|
|
25
|
+
login_prefs.update prefs
|
|
26
|
+
dummy = {:ignore_logout => true, :update_sids => true, :update_session => true, :update_contentlength => true}
|
|
27
|
+
login_prefs.update dummy
|
|
28
|
+
puts "! Start Login ..." if $DEBUG
|
|
29
|
+
unless chat_list.empty?
|
|
30
|
+
# puts login_prefs.to_yaml
|
|
31
|
+
chat_list.each do |chat|
|
|
32
|
+
puts "! LoginRequest: #{chat.id}" if $DEBUG
|
|
33
|
+
test_req = chat.copyRequest
|
|
34
|
+
request, response = doRequest(test_req, login_prefs)
|
|
47
35
|
end
|
|
48
|
-
|
|
49
|
-
puts "!
|
|
50
|
-
puts bang.backtrace if $DEBUG
|
|
51
|
-
ensure
|
|
52
|
-
@@login_in_progress = false
|
|
53
|
-
@@login_cv.signal
|
|
54
|
-
|
|
36
|
+
else
|
|
37
|
+
puts "! no login script configured !"
|
|
55
38
|
end
|
|
39
|
+
rescue => bang
|
|
40
|
+
puts "!ERROR in runLogin"
|
|
41
|
+
puts bang.backtrace if $DEBUG
|
|
42
|
+
ensure
|
|
43
|
+
@@login_in_progress = false
|
|
44
|
+
@@login_cv.signal
|
|
45
|
+
|
|
56
46
|
end
|
|
57
47
|
end
|
|
48
|
+
end
|
|
58
49
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
def sessionSettings()
|
|
51
|
+
@@settings
|
|
52
|
+
end
|
|
62
53
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
response_header = nil
|
|
70
|
-
|
|
71
|
-
site = request.site
|
|
72
|
-
# proxy = getProxy(site)
|
|
73
|
-
proxy = Watobo::ForwardingProxy.get(site)
|
|
74
|
-
|
|
75
|
-
unless proxy.nil?
|
|
76
|
-
host = proxy.host
|
|
77
|
-
port = proxy.port
|
|
78
|
-
else
|
|
79
|
-
host = request.host
|
|
80
|
-
port = request.port
|
|
81
|
-
end
|
|
82
|
-
# check if hostname is valid and can be resolved
|
|
83
|
-
hostip = IPSocket.getaddress(host)
|
|
84
|
-
# update current preferences, prefs given here are stronger then global settings!
|
|
85
|
-
current_prefs = Hash.new
|
|
86
|
-
[:update_session, :update_sids, :update_contentlength, :ssl_cipher, :www_auth, :client_certificates].each do |k|
|
|
87
|
-
current_prefs[k] = prefs[k].nil? ? @session[k] : prefs[k]
|
|
88
|
-
end
|
|
54
|
+
# sendHTTPRequest
|
|
55
|
+
# returns Socket, ResponseHeader
|
|
56
|
+
def sendHTTPRequest(request, prefs={})
|
|
57
|
+
begin
|
|
58
|
+
@lasterror = nil
|
|
59
|
+
response_header = nil
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
# request.removeHeader("^Proxy-Connection") #if not use_proxy
|
|
94
|
-
# request.removeHeader("^Connection") #if not use_proxy
|
|
95
|
-
|
|
96
|
-
# !!!
|
|
97
|
-
# remove Accept-Encoding header
|
|
98
|
-
# otherwise we won't get the content-length information for pass-through feature
|
|
99
|
-
request.removeHeader("^Accept-Encoding")
|
|
100
|
-
# If-Modified-Since: Tue, 28 Oct 2008 11:06:43 GMT
|
|
101
|
-
# If-None-Match: W/"3975-1225192003000"
|
|
102
|
-
# request.removeHeader("^If-")
|
|
103
|
-
# puts
|
|
104
|
-
# request.each do |line|
|
|
105
|
-
# puts line.unpack("H*")
|
|
106
|
-
#end
|
|
107
|
-
#puts
|
|
108
|
-
if current_prefs[:update_contentlength] == true and request.has_body? then
|
|
109
|
-
# puts "\n* Updating Content-Length ..."
|
|
110
|
-
# puts "OLD: #{request.content_length}"
|
|
111
|
-
# puts "BodyLen: #{request.body.length}"
|
|
112
|
-
b = request.body
|
|
113
|
-
#puts b.length
|
|
114
|
-
#puts request.body.unpack("H*")[0]
|
|
115
|
-
#puts (request.body.unpack("H*")[0].length / 2).to_s
|
|
116
|
-
request.fix_content_length()
|
|
117
|
-
#puts "New: #{request.content_length}"
|
|
118
|
-
#puts request.body.encoding
|
|
119
|
-
#puts "--"
|
|
120
|
-
end
|
|
61
|
+
site = request.site
|
|
62
|
+
# proxy = getProxy(site)
|
|
63
|
+
proxy = Watobo::ForwardingProxy.get(site)
|
|
121
64
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
65
|
+
unless proxy.nil?
|
|
66
|
+
host = proxy.host
|
|
67
|
+
port = proxy.port
|
|
68
|
+
else
|
|
69
|
+
host = request.host
|
|
70
|
+
port = request.port
|
|
71
|
+
end
|
|
72
|
+
# check if hostname is valid and can be resolved
|
|
73
|
+
hostip = IPSocket.getaddress(host)
|
|
74
|
+
# update current preferences, prefs given here are stronger then global settings!
|
|
75
|
+
current_prefs = Hash.new
|
|
76
|
+
[:update_session, :update_sids, :update_contentlength, :ssl_cipher, :www_auth, :client_certificates, :egress_handler ].each do |k|
|
|
77
|
+
current_prefs[k] = prefs[k].nil? ? @session[k] : prefs[k]
|
|
132
78
|
end
|
|
133
|
-
|
|
134
|
-
begin
|
|
135
|
-
unless proxy.nil?
|
|
136
|
-
# connection requires proxy
|
|
137
|
-
# puts "* use proxy #{proxy.name}"
|
|
138
|
-
|
|
139
|
-
# check for regular proxy authentication
|
|
140
|
-
if request.is_ssl?
|
|
141
|
-
socket, response_header = sslProxyConnect(request, proxy, current_prefs)
|
|
142
|
-
return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil?
|
|
143
|
-
|
|
144
|
-
if current_prefs[:www_auth].has_key?(site)
|
|
145
|
-
case current_prefs[:www_auth][site][:type]
|
|
146
|
-
when AUTH_TYPE_NTLM
|
|
147
|
-
# puts "* found NTLM credentials for site #{site}"
|
|
148
|
-
socket, response_header = wwwAuthNTLM(socket, request, current_prefs[:www_auth][site])
|
|
149
|
-
|
|
150
|
-
else
|
|
151
|
-
puts "* Unknown Authentication Type: #{current_prefs[:www_auth][site][:type]}"
|
|
152
|
-
end
|
|
153
|
-
else
|
|
154
|
-
|
|
155
|
-
data = request.join + "\r\n"
|
|
156
|
-
unless socket.nil?
|
|
157
|
-
socket.print data
|
|
158
|
-
response_header = readHTTPHeader(socket, current_prefs)
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
return socket, Request.new(request), Response.new(response_header)
|
|
162
|
-
end
|
|
163
|
-
# puts "* doProxyRequest"
|
|
164
|
-
socket, response_header = doProxyRequest(request, proxy, current_prefs)
|
|
165
|
-
# puts socket.class
|
|
166
|
-
return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil?
|
|
167
79
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return nil, request, [] if socket.nil?
|
|
80
|
+
@sid_cache.update_request(request) if current_prefs[:update_session] == true
|
|
81
|
+
|
|
82
|
+
#---------------------------------------
|
|
83
|
+
# request.removeHeader("^Proxy-Connection") #if not use_proxy
|
|
84
|
+
# request.removeHeader("^Connection") #if not use_proxy
|
|
85
|
+
|
|
86
|
+
# !!!
|
|
87
|
+
# remove Accept-Encoding header
|
|
88
|
+
# otherwise we won't get the content-length information for pass-through feature
|
|
89
|
+
request.removeHeader("^Accept-Encoding")
|
|
90
|
+
# If-Modified-Since: Tue, 28 Oct 2008 11:06:43 GMT
|
|
91
|
+
# If-None-Match: W/"3975-1225192003000"
|
|
92
|
+
# request.removeHeader("^If-")
|
|
93
|
+
# puts
|
|
94
|
+
# request.each do |line|
|
|
95
|
+
# puts line.unpack("H*")
|
|
96
|
+
#end
|
|
97
|
+
#puts
|
|
98
|
+
if current_prefs[:update_contentlength] == true and request.has_body? then
|
|
99
|
+
#puts request.body.unpack("H*")[0]
|
|
100
|
+
#puts (request.body.unpack("H*")[0].length / 2).to_s
|
|
101
|
+
request.fix_content_length()
|
|
102
|
+
#puts "New: #{request.content_length}"
|
|
103
|
+
#puts request.body.encoding
|
|
104
|
+
#puts "--"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# Engress Handler
|
|
109
|
+
unless current_prefs[:egress_handler].nil?
|
|
110
|
+
unless current_prefs[:egress_handler].empty?
|
|
111
|
+
h = Watobo::EgressHandlers.create current_prefs[:egress_handler]
|
|
112
|
+
unless h.nil?
|
|
113
|
+
h.execute request
|
|
203
114
|
end
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
#request.add_header("Via", "Watobo") if use_proxy
|
|
120
|
+
#puts request
|
|
121
|
+
# puts "=============="
|
|
122
|
+
rescue SocketError
|
|
123
|
+
puts "!!! unknown hostname #{host}"
|
|
124
|
+
puts request.first
|
|
125
|
+
return nil, "WATOBO: Could not resolve hostname #{host}", nil
|
|
126
|
+
rescue => bang
|
|
127
|
+
puts bang
|
|
128
|
+
puts bang.backtrace if $DEBUG
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
begin
|
|
132
|
+
unless proxy.nil?
|
|
133
|
+
# connection requires proxy
|
|
134
|
+
# puts "* use proxy #{proxy.name}"
|
|
135
|
+
|
|
136
|
+
# check for regular proxy authentication
|
|
137
|
+
if request.is_ssl?
|
|
138
|
+
socket, response_header = sslProxyConnect(request, proxy, current_prefs)
|
|
139
|
+
return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil?
|
|
212
140
|
|
|
213
141
|
if current_prefs[:www_auth].has_key?(site)
|
|
214
142
|
case current_prefs[:www_auth][site][:type]
|
|
215
143
|
when AUTH_TYPE_NTLM
|
|
216
|
-
#
|
|
144
|
+
# puts "* found NTLM credentials for site #{site}"
|
|
217
145
|
socket, response_header = wwwAuthNTLM(socket, request, current_prefs[:www_auth][site])
|
|
218
|
-
|
|
219
|
-
|
|
146
|
+
|
|
220
147
|
else
|
|
221
148
|
puts "* Unknown Authentication Type: #{current_prefs[:www_auth][site][:type]}"
|
|
222
149
|
end
|
|
223
150
|
else
|
|
224
|
-
# puts "========== Add Headers"
|
|
225
|
-
|
|
226
|
-
request.set_header("Connection", "close") #if not use_proxy
|
|
227
151
|
|
|
228
|
-
data = request.join
|
|
229
|
-
unless
|
|
230
|
-
data << "\r\n" unless data =~ /\r\n\r\n$/
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
# puts "\n*** SENDING ..."
|
|
234
|
-
# puts data
|
|
235
|
-
# if request.has_body?
|
|
236
|
-
# puts request.body.length
|
|
237
|
-
# bhex = request.body.unpack("H*")[0]
|
|
238
|
-
# puts bhex
|
|
239
|
-
# puts bhex.length
|
|
240
|
-
# end
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
# puts "= SESSION ="
|
|
245
|
-
# puts data
|
|
246
|
-
# puts data.unpack("H*")[0]#.gsub(/0d0a/,"0d0a\n")
|
|
247
|
-
# puts "---"
|
|
248
|
-
unless socket.nil?
|
|
152
|
+
data = request.join + "\r\n"
|
|
153
|
+
unless socket.nil?
|
|
249
154
|
socket.print data
|
|
250
|
-
socket.flush
|
|
251
155
|
response_header = readHTTPHeader(socket, current_prefs)
|
|
252
156
|
end
|
|
253
|
-
# RESTORE URI FOR HISTORY/LOG
|
|
254
|
-
request.restoreURI(uri_cache)
|
|
255
|
-
|
|
256
157
|
end
|
|
257
|
-
return socket,
|
|
158
|
+
return socket, Request.new(request), Response.new(response_header)
|
|
258
159
|
end
|
|
160
|
+
# puts "* doProxyRequest"
|
|
161
|
+
socket, response_header = doProxyRequest(request, proxy, current_prefs)
|
|
162
|
+
# puts socket.class
|
|
163
|
+
return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil?
|
|
259
164
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
rescue Timeout::Error
|
|
274
|
-
#request = "WATOBO: TimeOut (#{host}:#{port})\n"
|
|
275
|
-
response = error_response "TimeOut (#{host}:#{port})"
|
|
276
|
-
socket = nil
|
|
277
|
-
rescue Errno::ETIMEDOUT
|
|
278
|
-
puts "TimeOut (#{host}:#{port})"
|
|
279
|
-
response = error_response "TimeOut (#{host}:#{port})"
|
|
280
|
-
socket = nil
|
|
281
|
-
rescue Errno::ENOTCONN
|
|
282
|
-
puts "!!!ENOTCONN"
|
|
283
|
-
rescue OpenSSL::SSL::SSLError
|
|
284
|
-
response = error_response "SSL-Error", $!.to_s + "<br>" + $!.backtrace.join("<br>")
|
|
285
|
-
socket = nil
|
|
286
|
-
rescue => bang
|
|
287
|
-
response = error_response "ERROR:", "#{bang}\n#{bang.backtrace}"
|
|
288
|
-
socket = nil
|
|
289
|
-
|
|
290
|
-
puts bang
|
|
291
|
-
puts bang.backtrace if $DEBUG
|
|
292
|
-
end
|
|
293
|
-
#puts response
|
|
294
|
-
return socket, request, response
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
def sidCache()
|
|
298
|
-
#puts @project
|
|
299
|
-
@session[:valid_sids]
|
|
300
|
-
end
|
|
165
|
+
return socket, Request.new(request), Response.new(response_header)
|
|
166
|
+
else
|
|
167
|
+
# direct connection to host
|
|
168
|
+
tcp_socket = nil
|
|
169
|
+
# timeout(6) do
|
|
170
|
+
#puts "* no proxy - direct connection"
|
|
171
|
+
tcp_socket = TCPSocket.new( host, port )
|
|
172
|
+
#optval = [1, 5000].pack("I_2")
|
|
173
|
+
#tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
|
174
|
+
#tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
|
175
|
+
tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
176
|
+
#tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1
|
|
177
|
+
tcp_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
|
301
178
|
|
|
302
|
-
|
|
303
|
-
@session[:valid_sids] = new_cache if new_cache.is_a? Hash
|
|
304
|
-
end
|
|
179
|
+
tcp_socket.sync = true
|
|
305
180
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
Watobo::
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
#updateCSRFToken(csrf_cache, copy)
|
|
322
|
-
ott_cache.update_request(copy)
|
|
323
|
-
socket, csrf_request, csrf_response = sendHTTPRequest(copy, opts)
|
|
324
|
-
next if socket.nil?
|
|
325
|
-
# puts "= Response Headers:"
|
|
326
|
-
# puts csrf_response
|
|
327
|
-
# puts "==="
|
|
328
|
-
#update_sids(csrf_request.host, csrf_response.headers)
|
|
329
|
-
@sid_cache.update_sids(csrf_request.site, csrf_response.headers) if @session[:update_sids] == true
|
|
330
|
-
next if socket.nil?
|
|
331
|
-
# p "*"
|
|
332
|
-
# csrf_response = readHTTPHeader(socket)
|
|
333
|
-
readHTTPBody(socket, csrf_response, csrf_request, opts)
|
|
334
|
-
|
|
335
|
-
# response = Response.new(csrf_response)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
next unless csrf_response.has_body?
|
|
339
|
-
|
|
340
|
-
csrf_response.unchunk!
|
|
341
|
-
csrf_response.unzip!
|
|
342
|
-
|
|
343
|
-
@sid_cache.update_sids(csrf_request.site, [csrf_response.body]) if @session[:update_sids] == true
|
|
344
|
-
|
|
345
|
-
# updateCSRFCache(csrf_cache, csrf_request, [csrf_response.body]) if csrf_response.content_type =~ /text\//
|
|
346
|
-
ott_cache.update_tokens( [csrf_response.body]) if csrf_response.content_type =~ /text\//
|
|
347
|
-
|
|
348
|
-
# socket.close
|
|
349
|
-
closeSocket(socket)
|
|
181
|
+
socket = tcp_socket
|
|
182
|
+
if request.is_ssl?
|
|
183
|
+
ssl_prefs = {}
|
|
184
|
+
ssl_prefs[:ssl_cipher] = current_prefs[:ssl_cipher] if current_prefs.has_key? :ssl_cipher
|
|
185
|
+
#if current_prefs.has_key? :client_certificates
|
|
186
|
+
# if current_prefs[:client_certificates].has_key? request.site
|
|
187
|
+
# puts "* use ssl client certificate for site #{request.site}" if $DEBUG
|
|
188
|
+
# ssl_prefs[:ssl_client_cert] = current_prefs[:client_certificates][request.site][:ssl_client_cert]
|
|
189
|
+
# ssl_prefs[:ssl_client_key] = current_prefs[:client_certificates][request.site][:ssl_client_key]
|
|
190
|
+
# end
|
|
191
|
+
#end
|
|
192
|
+
unless Watobo::ClientCertStore.get(site).nil?
|
|
193
|
+
# puts "* using client cert for site #{site}"
|
|
194
|
+
client_cert = Watobo::ClientCertStore.get(site)
|
|
195
|
+
ssl_prefs[:client_certificate] = client_cert
|
|
350
196
|
end
|
|
351
|
-
#
|
|
352
|
-
#
|
|
353
|
-
|
|
197
|
+
# need hostname for SNI (Server Name Indication)
|
|
198
|
+
# http://en.wikipedia.org/wiki/Server_Name_Indication
|
|
199
|
+
ssl_prefs[:hostname] = host
|
|
200
|
+
socket = sslConnect(tcp_socket, ssl_prefs)
|
|
201
|
+
# puts "SSLSocket " + (socket.nil? ? "NO" : "OK")
|
|
202
|
+
return nil, request, [] if socket.nil?
|
|
354
203
|
end
|
|
204
|
+
#puts socket.class
|
|
205
|
+
# remove URI before sending request but cache it for restoring request
|
|
206
|
+
uri_cache = nil
|
|
207
|
+
uri_cache = request.removeURI #if proxy.nil?
|
|
208
|
+
# request.addHeader("Proxy-Connection", "Close") unless proxy.nil?
|
|
209
|
+
# request.set_header("Accept-Encoding", "gzip;q=0;identity; q=0.5, *;q=0") #don't want encoding
|
|
355
210
|
|
|
356
|
-
|
|
211
|
+
# request.set_header("Connection", "close") unless request.has_header?("Upgrade")
|
|
357
212
|
|
|
358
|
-
if
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
213
|
+
if current_prefs[:www_auth].has_key?(site)
|
|
214
|
+
case current_prefs[:www_auth][site][:type]
|
|
215
|
+
when AUTH_TYPE_NTLM
|
|
216
|
+
# puts "* found NTLM credentials for site #{site}"
|
|
217
|
+
socket, response_header = wwwAuthNTLM(socket, request, current_prefs[:www_auth][site])
|
|
218
|
+
request.restoreURI(uri_cache)
|
|
362
219
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
#response.extend Watobo::Mixin::Parser::Web10
|
|
369
|
-
#request.extend Watobo::Mixin::Shaper::Web10
|
|
370
|
-
|
|
371
|
-
loc_header = response.headers("Location:").first
|
|
372
|
-
new_location = loc_header.gsub(/^[^:]*:/,'').strip
|
|
373
|
-
unless new_location =~ /^http/
|
|
374
|
-
if new_location =~ /^\//
|
|
375
|
-
new_location = request.proto + "://" + request.site + new_location
|
|
376
|
-
else
|
|
377
|
-
new_location = request.proto + "://" + request.site + "/" + request.dir + "/" + new_location.sub(/^[\.\/]*/,'')
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
notify(:follow_redirect, new_location)
|
|
382
|
-
nr = Watobo::Request.new YAML.load(YAML.dump(request))
|
|
383
|
-
|
|
384
|
-
# create GET request for new location
|
|
385
|
-
nr.replaceMethod("GET")
|
|
386
|
-
nr.removeHeader("Content-Length")
|
|
387
|
-
nr.removeBody()
|
|
388
|
-
nr.replaceURL(new_location)
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
socket, request, response = sendHTTPRequest(nr, opts)
|
|
392
|
-
|
|
393
|
-
if socket.nil?
|
|
394
|
-
#return nil, request
|
|
395
|
-
return request, response
|
|
396
|
-
end
|
|
397
|
-
end
|
|
398
|
-
end
|
|
220
|
+
else
|
|
221
|
+
puts "* Unknown Authentication Type: #{current_prefs[:www_auth][site][:type]}"
|
|
222
|
+
end
|
|
223
|
+
else
|
|
224
|
+
# puts "========== Add Headers"
|
|
399
225
|
|
|
400
|
-
|
|
226
|
+
request.set_header("Connection", "close") #if not use_proxy
|
|
401
227
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
228
|
+
data = request.join
|
|
229
|
+
unless request.has_body?
|
|
230
|
+
data << "\r\n" unless data =~ /\r\n\r\n$/
|
|
231
|
+
end
|
|
405
232
|
|
|
406
|
-
|
|
407
|
-
|
|
233
|
+
# puts "\n*** SENDING ..."
|
|
234
|
+
# puts data
|
|
235
|
+
# if request.has_body?
|
|
236
|
+
# puts request.body.length
|
|
237
|
+
# bhex = request.body.unpack("H*")[0]
|
|
238
|
+
# puts bhex
|
|
239
|
+
# puts bhex.length
|
|
240
|
+
# end
|
|
408
241
|
|
|
409
|
-
rescue => bang
|
|
410
|
-
# puts "! Error in doRequest"
|
|
411
|
-
puts "! Module #{Module.nesting[0].name}"
|
|
412
|
-
puts bang
|
|
413
|
-
puts bang.backtrace if $DEBUG
|
|
414
|
-
@lasterror = bang
|
|
415
|
-
# raise
|
|
416
|
-
# ensure
|
|
417
|
-
end
|
|
418
242
|
|
|
419
|
-
#response.extend Watobo::Mixin::Parser::Web10
|
|
420
|
-
# resp = Watobo::Response.new(response)
|
|
421
|
-
|
|
422
|
-
response.unchunk!
|
|
423
|
-
response.unzip!
|
|
424
|
-
|
|
425
|
-
return Request.new(request), response
|
|
426
|
-
end
|
|
427
243
|
|
|
428
|
-
|
|
244
|
+
#puts "= SESSION ="
|
|
245
|
+
#puts data
|
|
246
|
+
#puts data.unpack("H*")[0]#.gsub(/0d0a/,"0d0a\n")
|
|
247
|
+
# puts "---"
|
|
248
|
+
unless socket.nil?
|
|
249
|
+
socket.print data
|
|
250
|
+
socket.flush
|
|
251
|
+
response_header = readHTTPHeader(socket, current_prefs)
|
|
252
|
+
end
|
|
253
|
+
# RESTORE URI FOR HISTORY/LOG
|
|
254
|
+
request.restoreURI(uri_cache)
|
|
429
255
|
|
|
430
|
-
proxy = nil
|
|
431
|
-
unless prefs.nil?
|
|
432
|
-
proxy = Proxy.new(prefs)
|
|
433
|
-
# proxy.setCredentials(prefs[:credentials]) unless prefs[:credentials].nil?
|
|
434
|
-
unless prefs[:site].nil?
|
|
435
|
-
@@proxy[prefs[:site]] = proxy
|
|
436
|
-
return
|
|
437
256
|
end
|
|
257
|
+
return socket, Watobo::Request.new(request), Watobo::Response.new(response_header)
|
|
438
258
|
end
|
|
439
259
|
|
|
440
|
-
|
|
260
|
+
rescue Errno::ECONNREFUSED
|
|
261
|
+
response = error_response "connection refused (#{host}:#{port})"
|
|
262
|
+
puts response
|
|
263
|
+
socket = nil
|
|
264
|
+
rescue Errno::ECONNRESET
|
|
265
|
+
response = error_response "connection reset (#{host}:#{port})"
|
|
266
|
+
socket = nil
|
|
267
|
+
rescue Errno::ECONNABORTED
|
|
268
|
+
response = error_response "connection aborted (#{host}:#{port})"
|
|
269
|
+
socket = nil
|
|
270
|
+
rescue Errno::EHOSTUNREACH
|
|
271
|
+
response = error_response "host unreachable (#{host}:#{port})"
|
|
272
|
+
socket = nil
|
|
273
|
+
rescue Timeout::Error
|
|
274
|
+
#request = "WATOBO: TimeOut (#{host}:#{port})\n"
|
|
275
|
+
response = error_response "TimeOut (#{host}:#{port})"
|
|
276
|
+
socket = nil
|
|
277
|
+
rescue Errno::ETIMEDOUT
|
|
278
|
+
puts "TimeOut (#{host}:#{port})"
|
|
279
|
+
response = error_response "TimeOut (#{host}:#{port})"
|
|
280
|
+
socket = nil
|
|
281
|
+
rescue Errno::ENOTCONN
|
|
282
|
+
puts "!!!ENOTCONN"
|
|
283
|
+
rescue OpenSSL::SSL::SSLError
|
|
284
|
+
response = error_response "SSL-Error", $!.to_s + "<br>" + $!.backtrace.join("<br>")
|
|
285
|
+
socket = nil
|
|
286
|
+
rescue => bang
|
|
287
|
+
response = error_response "ERROR:", "#{bang}\n#{bang.backtrace}"
|
|
288
|
+
socket = nil
|
|
289
|
+
|
|
290
|
+
puts bang
|
|
291
|
+
puts bang.backtrace if $DEBUG
|
|
441
292
|
end
|
|
293
|
+
#puts response
|
|
294
|
+
return socket, request, response
|
|
295
|
+
end
|
|
442
296
|
|
|
443
|
-
def
|
|
444
|
-
|
|
445
|
-
|
|
297
|
+
def sidCache()
|
|
298
|
+
#puts @project
|
|
299
|
+
@session[:valid_sids]
|
|
300
|
+
end
|
|
446
301
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
end
|
|
451
|
-
return @@proxy[:default]
|
|
452
|
-
end
|
|
302
|
+
def setSIDCache(new_cache = {} )
|
|
303
|
+
@session[:valid_sids] = new_cache if new_cache.is_a? Hash
|
|
304
|
+
end
|
|
453
305
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
@event_dispatcher_listeners = Hash.new
|
|
468
|
-
# @session = {}
|
|
469
|
-
|
|
470
|
-
session = nil
|
|
471
|
-
|
|
472
|
-
session = ( session_id.is_a? Fixnum ) ? session_id : session_id.object_id
|
|
473
|
-
session = Digest::MD5.hexdigest(Time.now.to_f.to_s) if session_id.nil?
|
|
474
|
-
|
|
475
|
-
@sid_cache = Watobo::SIDCache.acquire(session)
|
|
476
|
-
|
|
477
|
-
unless @@settings.has_key? session
|
|
478
|
-
@@settings[session] = {
|
|
479
|
-
:logout_signatures => [],
|
|
480
|
-
:logout_content_types => Hash.new,
|
|
481
|
-
:update_valid_sids => false,
|
|
482
|
-
:update_sids => false,
|
|
483
|
-
:update_otts => false,
|
|
484
|
-
:update_session => true,
|
|
485
|
-
:update_contentlength => true,
|
|
486
|
-
:login_chats => [],
|
|
487
|
-
:www_auth => Hash.new,
|
|
488
|
-
:client_certificates => {},
|
|
489
|
-
:proxy_auth => Hash.new
|
|
490
|
-
}
|
|
491
|
-
end
|
|
492
|
-
@session = @@settings[session] # shortcut to settings
|
|
493
|
-
@session.update prefs
|
|
306
|
+
# +++ doRequest(request) +++
|
|
307
|
+
# + function:
|
|
308
|
+
#
|
|
309
|
+
def doRequest(request, opts={} )
|
|
310
|
+
begin
|
|
311
|
+
ott_cache = Watobo::OTTCache.acquire(request)
|
|
312
|
+
@session.update opts
|
|
313
|
+
# puts "[doRequest] #{@session.to_yaml}"
|
|
314
|
+
# puts "#[#{self.class}]" + @session[:csrf_requests].first.object_id.to_s
|
|
315
|
+
# unless @session[:csrf_requests].empty? or @session[:csrf_patterns].empty?
|
|
316
|
+
unless Watobo::OTTCache.requests(request).empty? or @session[:update_otts] == false
|
|
317
|
+
Watobo::OTTCache.requests(request).each do |req|
|
|
494
318
|
|
|
495
|
-
|
|
319
|
+
copy = Watobo::Request.new YAML.load(YAML.dump(req))
|
|
496
320
|
|
|
497
|
-
|
|
321
|
+
#updateCSRFToken(csrf_cache, copy)
|
|
322
|
+
ott_cache.update_request(copy)
|
|
323
|
+
socket, csrf_request, csrf_response = sendHTTPRequest(copy, opts)
|
|
324
|
+
next if socket.nil?
|
|
325
|
+
# puts "= Response Headers:"
|
|
326
|
+
# puts csrf_response
|
|
327
|
+
# puts "==="
|
|
328
|
+
#update_sids(csrf_request.host, csrf_response.headers)
|
|
329
|
+
@sid_cache.update_sids(csrf_request.site, csrf_response.headers) if @session[:update_sids] == true
|
|
330
|
+
next if socket.nil?
|
|
331
|
+
# p "*"
|
|
332
|
+
# csrf_response = readHTTPHeader(socket)
|
|
333
|
+
readHTTPBody(socket, csrf_response, csrf_request, opts)
|
|
498
334
|
|
|
499
|
-
|
|
335
|
+
# response = Response.new(csrf_response)
|
|
500
336
|
|
|
501
|
-
@ctx = OpenSSL::SSL::SSLContext.new()
|
|
502
|
-
@ctx.key = nil
|
|
503
|
-
@ctx.cert = nil
|
|
504
337
|
|
|
505
|
-
|
|
506
|
-
# TODO: Implement switches for Following Redirects
|
|
507
|
-
# TODO: Implement switches for Logging, Debugging, ...
|
|
508
|
-
end
|
|
338
|
+
next unless csrf_response.has_body?
|
|
509
339
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
data = ""
|
|
513
|
-
|
|
514
|
-
begin
|
|
515
|
-
if response.is_chunked?
|
|
516
|
-
Watobo::HTTPSocket.readChunkedBody(socket) { |c|
|
|
517
|
-
data += c
|
|
518
|
-
}
|
|
519
|
-
elsif clen > 0
|
|
520
|
-
# puts "* read #{clen} bytes for body"
|
|
521
|
-
Watobo::HTTPSocket.read_body(socket, :max_bytes => clen) { |c|
|
|
522
|
-
|
|
523
|
-
data += c
|
|
524
|
-
break if data.length == clen
|
|
525
|
-
}
|
|
526
|
-
elsif clen < 0
|
|
527
|
-
# puts "* no content-length information ... mmmmmpf"
|
|
528
|
-
# eofcount = 0
|
|
529
|
-
Watobo::HTTPSocket.read_body(socket) do |c|
|
|
530
|
-
data += c
|
|
531
|
-
end
|
|
340
|
+
csrf_response.unchunk!
|
|
341
|
+
csrf_response.unzip!
|
|
532
342
|
|
|
343
|
+
@sid_cache.update_sids(csrf_request.site, [csrf_response.body]) if @session[:update_sids] == true
|
|
344
|
+
|
|
345
|
+
# updateCSRFCache(csrf_cache, csrf_request, [csrf_response.body]) if csrf_response.content_type =~ /text\//
|
|
346
|
+
ott_cache.update_tokens( [csrf_response.body]) if csrf_response.content_type =~ /text\//
|
|
347
|
+
|
|
348
|
+
# socket.close
|
|
349
|
+
closeSocket(socket)
|
|
533
350
|
end
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
end
|
|
351
|
+
#p @session[:csrf_requests].length
|
|
352
|
+
#updateCSRFToken(csrf_cache, request)
|
|
353
|
+
ott_cache.update_request(request)
|
|
354
|
+
end
|
|
539
355
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
puts e
|
|
546
|
-
# puts e.backtrace
|
|
356
|
+
socket, request, response = sendHTTPRequest(request, opts)
|
|
357
|
+
|
|
358
|
+
if socket.nil?
|
|
359
|
+
return request, response
|
|
360
|
+
#return request, nil
|
|
547
361
|
end
|
|
548
362
|
|
|
549
|
-
|
|
550
|
-
end
|
|
363
|
+
@sid_cache.update_sids(request.site, response.headers) if @session[:update_sids] == true
|
|
551
364
|
|
|
552
|
-
|
|
365
|
+
if @session[:follow_redirect]
|
|
366
|
+
# puts response.status
|
|
367
|
+
if response.status =~ /^30(1|2|8)/
|
|
368
|
+
#response.extend Watobo::Mixin::Parser::Web10
|
|
369
|
+
#request.extend Watobo::Mixin::Shaper::Web10
|
|
553
370
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
head_request.removeHeader("Content-Length")
|
|
563
|
-
data = head_request.join + "\r\n"
|
|
564
|
-
|
|
565
|
-
socket.print data
|
|
566
|
-
|
|
567
|
-
response_header = readHTTPHeader(socket)
|
|
568
|
-
response_header.each do |line|
|
|
569
|
-
if line =~ /^www-authenticat.*((Negotiate|NTLM))/i then
|
|
570
|
-
#puts line
|
|
571
|
-
auth_method = $1
|
|
572
|
-
break
|
|
371
|
+
loc_header = response.headers("Location:").first
|
|
372
|
+
new_location = loc_header.gsub(/^[^:]*:/,'').strip
|
|
373
|
+
unless new_location =~ /^http/
|
|
374
|
+
if new_location =~ /^\//
|
|
375
|
+
new_location = request.proto + "://" + request.site + new_location
|
|
376
|
+
else
|
|
377
|
+
new_location = request.proto + "://" + request.site + "/" + request.dir + "/" + new_location.sub(/^[\.\/]*/,'')
|
|
378
|
+
end
|
|
573
379
|
end
|
|
574
|
-
#break if line.strip.empty?
|
|
575
|
-
end
|
|
576
380
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
%w(workstation domain).each do |a|
|
|
580
|
-
t1.send("#{a}=",'')
|
|
581
|
-
t1.enable(a.to_sym)
|
|
582
|
-
end
|
|
583
|
-
|
|
584
|
-
msg = "#{auth_method} #{t1.encode64}"
|
|
585
|
-
head_request.set_header("Authorization", msg)
|
|
586
|
-
|
|
587
|
-
data = head_request.join + "\r\n"
|
|
588
|
-
|
|
589
|
-
socket.print data
|
|
590
|
-
|
|
591
|
-
response_header = []
|
|
592
|
-
rcode = nil
|
|
593
|
-
clen = nil
|
|
594
|
-
ntlm_challenge = nil
|
|
595
|
-
response_header = readHTTPHeader(socket)
|
|
596
|
-
response_header.each do |line|
|
|
597
|
-
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
598
|
-
rcode = $1.to_i
|
|
599
|
-
rmsg = $2
|
|
600
|
-
end
|
|
601
|
-
if line =~ /^WWW-Authenticate: (NTLM|Negotiate) (.+)\r\n/
|
|
602
|
-
ntlm_challenge = $2
|
|
603
|
-
end
|
|
604
|
-
if line =~ /^Content-Length: (\d{1,})\r\n/
|
|
605
|
-
clen = $1.to_i
|
|
606
|
-
end
|
|
607
|
-
break if line.strip.empty?
|
|
608
|
-
end
|
|
609
|
-
|
|
610
|
-
if rcode == 401 #Authentication Required
|
|
611
|
-
puts "[NTLM] got ntlm challenge: #{ntlm_challenge}" if $DEBUG
|
|
612
|
-
return socket, response_header if ntlm_challenge.nil?
|
|
613
|
-
elsif rcode == 200 # Ok
|
|
614
|
-
puts "[NTLM] seems request doesn't need authentication" if $DEBUG
|
|
615
|
-
return socket, Watobo::Response.new(response_header)
|
|
616
|
-
else
|
|
617
|
-
if $DEBUG
|
|
618
|
-
puts "[NTLM] ... !#*+.!*peep* ...."
|
|
619
|
-
puts response_header
|
|
620
|
-
end
|
|
621
|
-
return socket, Watobo::Response.new(response_header)
|
|
622
|
-
end
|
|
381
|
+
notify(:follow_redirect, new_location)
|
|
382
|
+
nr = Watobo::Request.new YAML.load(YAML.dump(request))
|
|
623
383
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
:domain => domain,
|
|
630
|
-
:workstation => Watobo::UTF16.encode_utf16le(Socket.gethostname)
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
t3 = t2.response( creds,
|
|
634
|
-
{:ntlmv2 => true}
|
|
635
|
-
)
|
|
636
|
-
|
|
637
|
-
auth_request = request.copy
|
|
638
|
-
|
|
639
|
-
auth_request.set_header("Connection", "close")
|
|
640
|
-
|
|
641
|
-
msg = "#{auth_method} #{t3.encode64}"
|
|
642
|
-
auth_request.set_header("Authorization", msg)
|
|
643
|
-
# puts "============= T3 ======================="
|
|
384
|
+
# create GET request for new location
|
|
385
|
+
nr.replaceMethod("GET")
|
|
386
|
+
nr.removeHeader("Content-Length")
|
|
387
|
+
nr.removeBody()
|
|
388
|
+
nr.replaceURL(new_location)
|
|
644
389
|
|
|
645
|
-
data = auth_request.join + "\r\n"
|
|
646
|
-
socket.print data
|
|
647
390
|
|
|
648
|
-
|
|
649
|
-
response_header = readHTTPHeader(socket)
|
|
650
|
-
response_header.each do |line|
|
|
391
|
+
socket, request, response = sendHTTPRequest(nr, opts)
|
|
651
392
|
|
|
652
|
-
if
|
|
653
|
-
|
|
654
|
-
|
|
393
|
+
if socket.nil?
|
|
394
|
+
#return nil, request
|
|
395
|
+
return request, response
|
|
655
396
|
end
|
|
656
|
-
break if line.strip.empty?
|
|
657
|
-
end
|
|
658
|
-
|
|
659
|
-
if rcode == 200 # Ok
|
|
660
|
-
puts "[NTLM] Authentication Successfull" if $DEBUG
|
|
661
|
-
elsif rcode == 401 # Authentication Required
|
|
662
|
-
# TODO: authorization didn't work -> do some notification
|
|
663
|
-
# ...
|
|
664
|
-
puts "[NTLM] could not authenticate. Bad credentials?"
|
|
665
397
|
end
|
|
398
|
+
end
|
|
666
399
|
|
|
667
|
-
|
|
668
|
-
rescue => bang
|
|
669
|
-
puts "!!! ERROR: in ntlm_auth"
|
|
670
|
-
puts bang
|
|
400
|
+
readHTTPBody(socket, response, request, opts)
|
|
671
401
|
|
|
672
|
-
|
|
673
|
-
|
|
402
|
+
unless response.body.nil?
|
|
403
|
+
@sid_cache.update_sids(request.site, [response.body]) if @session[:update_sids] == true and response.content_type =~ /text\//
|
|
674
404
|
end
|
|
405
|
+
|
|
406
|
+
#socket.close
|
|
407
|
+
closeSocket(socket)
|
|
408
|
+
|
|
409
|
+
rescue => bang
|
|
410
|
+
# puts "! Error in doRequest"
|
|
411
|
+
puts "! Module #{Module.nesting[0].name}"
|
|
412
|
+
puts bang
|
|
413
|
+
puts bang.backtrace if $DEBUG
|
|
414
|
+
@lasterror = bang
|
|
415
|
+
# raise
|
|
416
|
+
# ensure
|
|
675
417
|
end
|
|
676
418
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
# @ctx = OpenSSL::SSL::SSLContext.new()
|
|
680
|
-
# @ctx.key = nil
|
|
681
|
-
# @ctx.cert = nil
|
|
682
|
-
ctx = OpenSSL::SSL::SSLContext.new()
|
|
683
|
-
ctx.ciphers = current_prefs[:ssl_cipher] if current_prefs.has_key? :ssl_cipher
|
|
684
|
-
|
|
685
|
-
if current_prefs.has_key? :ssl_client_cert and current_prefs.has_key? :ssl_client_key
|
|
686
|
-
|
|
687
|
-
ctx.cert = current_prefs[:ssl_client_cert]
|
|
688
|
-
ctx.key = current_prefs[:ssl_client_key]
|
|
689
|
-
if $DEBUG
|
|
690
|
-
puts "[SSLconnect] Client Certificates"
|
|
691
|
-
puts "= CERT ="
|
|
692
|
-
# puts @ctx.cert.methods.sort
|
|
693
|
-
puts ctx.cert.display
|
|
694
|
-
puts "---"
|
|
695
|
-
p
|
|
696
|
-
puts "= KEY ="
|
|
697
|
-
puts ctx.key.display
|
|
698
|
-
puts "---"
|
|
699
|
-
end
|
|
419
|
+
#response.extend Watobo::Mixin::Parser::Web10
|
|
420
|
+
# resp = Watobo::Response.new(response)
|
|
700
421
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
# OpenSSL::PKey::DH.new(128)
|
|
704
|
-
#}
|
|
705
|
-
if current_prefs.has_key? :client_certificate
|
|
706
|
-
ccp = current_prefs[:client_certificate]
|
|
707
|
-
ctx.cert = ccp[:ssl_client_cert]
|
|
708
|
-
ctx.key = ccp[:ssl_client_key]
|
|
709
|
-
ctx.extra_chain_cert = ccp[:extra_chain_certs] if ccp.has_key?(:extra_chain_certs)
|
|
710
|
-
end
|
|
422
|
+
response.unchunk!
|
|
423
|
+
response.unzip!
|
|
711
424
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
rescue => bang
|
|
725
|
-
if current_prefs[:ssl_cipher].nil?
|
|
726
|
-
puts "[SSLconnect] ... gr#!..*peep*.. "
|
|
727
|
-
puts bang
|
|
728
|
-
puts bang.backtrace if $DEBUG
|
|
729
|
-
end
|
|
425
|
+
return Request.new(request), response
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def addProxy(prefs=nil)
|
|
429
|
+
|
|
430
|
+
proxy = nil
|
|
431
|
+
unless prefs.nil?
|
|
432
|
+
proxy = Proxy.new(prefs)
|
|
433
|
+
# proxy.setCredentials(prefs[:credentials]) unless prefs[:credentials].nil?
|
|
434
|
+
unless prefs[:site].nil?
|
|
435
|
+
@@proxy[prefs[:site]] = proxy
|
|
436
|
+
return
|
|
730
437
|
end
|
|
731
438
|
end
|
|
732
439
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
# On error SSLSocket is nil
|
|
736
|
-
def sslProxyConnect(orig_request, proxy, prefs)
|
|
737
|
-
begin
|
|
738
|
-
tcp_socket = nil
|
|
739
|
-
response_header = []
|
|
440
|
+
@@proxy[:default] = proxy
|
|
441
|
+
end
|
|
740
442
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
request.extend Watobo::Mixin::Shaper::Web10
|
|
745
|
-
# timeout(6) do
|
|
443
|
+
def get_settings
|
|
444
|
+
@@settings
|
|
445
|
+
end
|
|
746
446
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
# puts "* sslProxyConnect"
|
|
754
|
-
# puts "Host: #{request.host}"
|
|
755
|
-
# puts "Port: #{request.port}"
|
|
756
|
-
# setup request
|
|
757
|
-
dummy = "CONNECT #{request.host}:#{request.port} HTTP/1.0\r\n"
|
|
758
|
-
request.shift
|
|
759
|
-
request.unshift dummy
|
|
760
|
-
|
|
761
|
-
#request.removeHeader("Proxy-Connection")
|
|
762
|
-
request.removeHeader("Connection")
|
|
763
|
-
request.removeHeader("Content-Length")
|
|
764
|
-
request.removeBody()
|
|
765
|
-
request.set_header("Proxy-Connection", "Keep-Alive")
|
|
766
|
-
request.addHeader("Pragma", "no-cache")
|
|
767
|
-
|
|
768
|
-
# puts "=== sslProxyConnect ==="
|
|
769
|
-
# puts request
|
|
770
|
-
|
|
771
|
-
if proxy.has_login?
|
|
772
|
-
case proxy.auth_type
|
|
773
|
-
when AUTH_TYPE_NTLM
|
|
447
|
+
def getProxy(site=nil)
|
|
448
|
+
unless site.nil?
|
|
449
|
+
return @@proxy[site] unless @@proxy[site].nil?
|
|
450
|
+
end
|
|
451
|
+
return @@proxy[:default]
|
|
452
|
+
end
|
|
774
453
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
454
|
+
#
|
|
455
|
+
# INITIALIZE
|
|
456
|
+
#
|
|
457
|
+
# Possible preferences:
|
|
458
|
+
# :proxy => '127.0.0.1:port'
|
|
459
|
+
# :valid_sids => Hash.new,
|
|
460
|
+
# :sid_patterns => [],
|
|
461
|
+
# :logout_signatures => [],
|
|
462
|
+
# :update_valid_sids => false,
|
|
463
|
+
# :update_sids => false,
|
|
464
|
+
# :update_contentlength => true
|
|
465
|
+
def initialize( session_id=nil, prefs={} )
|
|
466
|
+
|
|
467
|
+
@event_dispatcher_listeners = Hash.new
|
|
468
|
+
# @session = {}
|
|
469
|
+
|
|
470
|
+
session = nil
|
|
471
|
+
|
|
472
|
+
session = ( session_id.is_a? Fixnum ) ? session_id : session_id.object_id
|
|
473
|
+
session = Digest::MD5.hexdigest(Time.now.to_f.to_s) if session_id.nil?
|
|
474
|
+
|
|
475
|
+
@sid_cache = Watobo::SIDCache.acquire(session)
|
|
476
|
+
|
|
477
|
+
unless @@settings.has_key? session
|
|
478
|
+
@@settings[session] = {
|
|
479
|
+
:logout_signatures => [],
|
|
480
|
+
:logout_content_types => Hash.new,
|
|
481
|
+
:update_valid_sids => false,
|
|
482
|
+
:update_sids => false,
|
|
483
|
+
:update_otts => false,
|
|
484
|
+
:update_session => true,
|
|
485
|
+
:update_contentlength => true,
|
|
486
|
+
:login_chats => [],
|
|
487
|
+
:www_auth => Hash.new,
|
|
488
|
+
:client_certificates => {},
|
|
489
|
+
:proxy_auth => Hash.new
|
|
490
|
+
}
|
|
491
|
+
end
|
|
492
|
+
@session = @@settings[session] # shortcut to settings
|
|
493
|
+
@session.update prefs
|
|
778
494
|
|
|
779
|
-
|
|
780
|
-
puts "============= PROXY NTLM: T1 ======================="
|
|
781
|
-
puts request
|
|
782
|
-
puts "---"
|
|
783
|
-
end
|
|
784
|
-
data = request.join + "\r\n"
|
|
495
|
+
# @valid_csrf_tokens = Hash.new
|
|
785
496
|
|
|
786
|
-
|
|
787
|
-
# puts "-----------------"
|
|
788
|
-
cl = 0
|
|
789
|
-
ntlm_challenge = nil
|
|
790
|
-
while (line = tcp_socket.gets)
|
|
791
|
-
response_header.push line
|
|
792
|
-
puts line if $DEBUG
|
|
793
|
-
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
794
|
-
rcode = $1.to_i
|
|
795
|
-
rmsg = $2
|
|
796
|
-
end
|
|
797
|
-
if line =~ /^Proxy-Authenticate: (NTLM) (.+)\r\n/
|
|
798
|
-
ntlm_challenge = $2
|
|
799
|
-
end
|
|
800
|
-
if line =~ /^Content-Length: (\d*)/i
|
|
801
|
-
cl = $1.to_i
|
|
802
|
-
end
|
|
803
|
-
break if line.strip.empty?
|
|
804
|
-
end
|
|
497
|
+
addProxy( prefs[:proxy] ) if prefs.is_a? Hash and prefs[:proxy]
|
|
805
498
|
|
|
806
|
-
|
|
807
|
-
if cl > 0
|
|
808
|
-
Watobo::HTTPSocket.read_body(tcp_socket) { |d|
|
|
809
|
-
# puts d
|
|
810
|
-
}
|
|
811
|
-
end
|
|
499
|
+
@socket = nil
|
|
812
500
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
return socket, response_header
|
|
817
|
-
end
|
|
501
|
+
@ctx = OpenSSL::SSL::SSLContext.new()
|
|
502
|
+
@ctx.key = nil
|
|
503
|
+
@ctx.cert = nil
|
|
818
504
|
|
|
819
|
-
|
|
505
|
+
# TODO: Implement switches for URL-Encoding (http://www.blooberry.com/indexdot/html/topics/urlencoding.htm)
|
|
506
|
+
# TODO: Implement switches for Following Redirects
|
|
507
|
+
# TODO: Implement switches for Logging, Debugging, ...
|
|
508
|
+
end
|
|
820
509
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
:domain => proxy.domain },
|
|
825
|
-
{ :workstation => proxy.workstation, :ntlmv2 => true } )
|
|
826
|
-
request.removeHeader("Proxy-Authorization")
|
|
510
|
+
def readHTTPBody(socket, response, request, prefs={})
|
|
511
|
+
clen = response.content_length
|
|
512
|
+
data = ""
|
|
827
513
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
end
|
|
514
|
+
begin
|
|
515
|
+
if response.is_chunked?
|
|
516
|
+
Watobo::HTTPSocket.readChunkedBody(socket) { |c|
|
|
517
|
+
data += c
|
|
518
|
+
}
|
|
519
|
+
elsif clen > 0
|
|
520
|
+
# puts "* read #{clen} bytes for body"
|
|
521
|
+
Watobo::HTTPSocket.read_body(socket, :max_bytes => clen) { |c|
|
|
837
522
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
socket = sslConnect(tcp_socket, prefs)
|
|
848
|
-
return socket, response_header
|
|
849
|
-
elsif rcode =~ /^407/ # ProxyAuthentication Required
|
|
850
|
-
# if rcode is still 407 authentication didn't work -> break
|
|
851
|
-
msg = "NTLM-Authentication failed!"
|
|
852
|
-
puts "[ProxyAuth-NTLM] #{msg}" if $DEBUG
|
|
853
|
-
return nil, msg
|
|
854
|
-
else
|
|
855
|
-
puts "[SSLconnect] NTLM Authentication"
|
|
856
|
-
puts "> #{rcode} <"
|
|
857
|
-
return nil, response_header
|
|
858
|
-
end
|
|
859
|
-
end
|
|
860
|
-
end # END OF PROXY AUTH
|
|
523
|
+
data += c
|
|
524
|
+
break if data.length == clen
|
|
525
|
+
}
|
|
526
|
+
elsif clen < 0
|
|
527
|
+
# puts "* no content-length information ... mmmmmpf"
|
|
528
|
+
# eofcount = 0
|
|
529
|
+
Watobo::HTTPSocket.read_body(socket) do |c|
|
|
530
|
+
data += c
|
|
531
|
+
end
|
|
861
532
|
|
|
862
|
-
|
|
863
|
-
data = request.join + "\r\n"
|
|
864
|
-
tcp_socket.print data
|
|
865
|
-
# puts "-----------------"
|
|
533
|
+
end
|
|
866
534
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
# puts "* proxy connection successfull"
|
|
872
|
-
elsif rcode =~ /^407/ # ProxyAuthentication Required
|
|
873
|
-
# if rcode is still 407 authentication didn't work -> break
|
|
535
|
+
response.push data unless data.empty?
|
|
536
|
+
unless prefs[:ignore_logout]==true or @session[:logout_signatures].empty?
|
|
537
|
+
notify(:logout, self) if loggedOut?(response)
|
|
538
|
+
end
|
|
874
539
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
puts "> #{rcode} <"
|
|
878
|
-
end
|
|
540
|
+
@sid_cache.update_sids(request.site, response) if prefs[:update_sids] == true
|
|
541
|
+
return true
|
|
879
542
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
puts proxy
|
|
885
|
-
puts prefs
|
|
886
|
-
return nil, error_response(bang)
|
|
887
|
-
end
|
|
888
|
-
# return nil, nil
|
|
543
|
+
rescue => e
|
|
544
|
+
puts "! Could not read response"
|
|
545
|
+
puts e
|
|
546
|
+
# puts e.backtrace
|
|
889
547
|
end
|
|
890
548
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
def proxyAuthNTLM(tcp_socket, orig_request, proxy)
|
|
894
|
-
|
|
895
|
-
if orig_request.respond_to? :copy
|
|
896
|
-
request = orig_request.copy
|
|
897
|
-
else
|
|
898
|
-
request = Watobo::Response.new YAML.load(YAML.dump(orig_request))
|
|
899
|
-
end
|
|
900
|
-
|
|
901
|
-
request.removeHeader("Proxy-Authorization")
|
|
902
|
-
request.removeHeader("Proxy-Connection")
|
|
549
|
+
return false
|
|
550
|
+
end
|
|
903
551
|
|
|
904
|
-
|
|
552
|
+
private
|
|
553
|
+
|
|
554
|
+
#def doNtlmAuth(socket, request, ntlm_credentials)
|
|
555
|
+
def wwwAuthNTLM(socket, request, ntlm_credentials)
|
|
556
|
+
response_header = nil
|
|
557
|
+
auth_method = "NTLM"
|
|
558
|
+
begin
|
|
559
|
+
head_request = request.copy
|
|
560
|
+
head_request.setMethod(:head)
|
|
561
|
+
head_request.removeBody
|
|
562
|
+
head_request.removeHeader("Content-Length")
|
|
563
|
+
data = head_request.join + "\r\n"
|
|
564
|
+
|
|
565
|
+
socket.print data
|
|
566
|
+
|
|
567
|
+
response_header = readHTTPHeader(socket)
|
|
568
|
+
response_header.each do |line|
|
|
569
|
+
if line =~ /^www-authenticat.*((Negotiate|NTLM))/i then
|
|
570
|
+
#puts line
|
|
571
|
+
auth_method = $1
|
|
572
|
+
break
|
|
573
|
+
end
|
|
574
|
+
#break if line.strip.empty?
|
|
575
|
+
end
|
|
905
576
|
|
|
906
577
|
ntlm_challenge = nil
|
|
907
578
|
t1 = Watobo::NTLM::Message::Type1.new()
|
|
908
|
-
|
|
579
|
+
%w(workstation domain).each do |a|
|
|
580
|
+
t1.send("#{a}=",'')
|
|
581
|
+
t1.enable(a.to_sym)
|
|
582
|
+
end
|
|
909
583
|
|
|
910
|
-
|
|
911
|
-
|
|
584
|
+
msg = "#{auth_method} #{t1.encode64}"
|
|
585
|
+
head_request.set_header("Authorization", msg)
|
|
912
586
|
|
|
913
|
-
|
|
914
|
-
# puts auth_request
|
|
915
|
-
data = request.join + "\r\n"
|
|
587
|
+
data = head_request.join + "\r\n"
|
|
916
588
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
response_header =
|
|
589
|
+
socket.print data
|
|
590
|
+
|
|
591
|
+
response_header = []
|
|
920
592
|
rcode = nil
|
|
921
|
-
|
|
593
|
+
clen = nil
|
|
922
594
|
ntlm_challenge = nil
|
|
923
|
-
|
|
595
|
+
response_header = readHTTPHeader(socket)
|
|
924
596
|
response_header.each do |line|
|
|
925
|
-
# puts line
|
|
926
597
|
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
927
598
|
rcode = $1.to_i
|
|
928
599
|
rmsg = $2
|
|
929
600
|
end
|
|
930
|
-
if line =~ /^
|
|
601
|
+
if line =~ /^WWW-Authenticate: (NTLM|Negotiate) (.+)\r\n/
|
|
931
602
|
ntlm_challenge = $2
|
|
932
603
|
end
|
|
933
604
|
if line =~ /^Content-Length: (\d{1,})\r\n/
|
|
@@ -936,217 +607,563 @@ end
|
|
|
936
607
|
break if line.strip.empty?
|
|
937
608
|
end
|
|
938
609
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
610
|
+
if rcode == 401 #Authentication Required
|
|
611
|
+
puts "[NTLM] got ntlm challenge: #{ntlm_challenge}" if $DEBUG
|
|
612
|
+
return socket, response_header if ntlm_challenge.nil?
|
|
613
|
+
elsif rcode == 200 # Ok
|
|
614
|
+
puts "[NTLM] seems request doesn't need authentication" if $DEBUG
|
|
615
|
+
return socket, Watobo::Response.new(response_header)
|
|
943
616
|
else
|
|
944
|
-
|
|
945
|
-
|
|
617
|
+
if $DEBUG
|
|
618
|
+
puts "[NTLM] ... !#*+.!*peep* ...."
|
|
619
|
+
puts response_header
|
|
620
|
+
end
|
|
621
|
+
return socket, Watobo::Response.new(response_header)
|
|
946
622
|
end
|
|
947
623
|
|
|
948
|
-
Watobo::HTTPSocket.read_body(tcp_socket, :max_bytes => clen){ |d|
|
|
949
|
-
#puts d
|
|
950
|
-
}
|
|
951
624
|
|
|
952
625
|
t2 = Watobo::NTLM::Message.decode64(ntlm_challenge)
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
msg = "NTLM " + t3.encode64
|
|
960
|
-
request.addHeader("Proxy-Authorization", msg)
|
|
961
|
-
# puts "============= T3 ======================="
|
|
962
|
-
# puts request
|
|
963
|
-
# puts "------------------------"
|
|
964
|
-
data = request.join + "\r\n"
|
|
965
|
-
tcp_socket.print data
|
|
626
|
+
domain = ntlm_credentials.has_key?(:domain) ? Watobo::UTF16.encode_utf16le(ntlm_credentials[:domain].upcase) : ""
|
|
627
|
+
creds = {:user => ntlm_credentials[:username],
|
|
628
|
+
:password => ntlm_credentials[:password],
|
|
629
|
+
:domain => domain,
|
|
630
|
+
:workstation => Watobo::UTF16.encode_utf16le(Socket.gethostname)
|
|
631
|
+
}
|
|
966
632
|
|
|
967
|
-
|
|
633
|
+
t3 = t2.response( creds,
|
|
634
|
+
{:ntlmv2 => true}
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
auth_request = request.copy
|
|
638
|
+
|
|
639
|
+
auth_request.set_header("Connection", "close")
|
|
640
|
+
|
|
641
|
+
msg = "#{auth_method} #{t3.encode64}"
|
|
642
|
+
auth_request.set_header("Authorization", msg)
|
|
643
|
+
# puts "============= T3 ======================="
|
|
644
|
+
|
|
645
|
+
data = auth_request.join + "\r\n"
|
|
646
|
+
socket.print data
|
|
647
|
+
|
|
648
|
+
response_header = []
|
|
649
|
+
response_header = readHTTPHeader(socket)
|
|
968
650
|
response_header.each do |line|
|
|
969
|
-
|
|
651
|
+
|
|
970
652
|
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
971
653
|
rcode = $1.to_i
|
|
972
654
|
rmsg = $2
|
|
973
655
|
end
|
|
974
|
-
if line =~ /^Proxy-Authenticate: (NTLM) (.+)\r\n/
|
|
975
|
-
ntlm_challenge = $2
|
|
976
|
-
end
|
|
977
|
-
if line =~ /^Content-Length: (\d{1,})\r\n/
|
|
978
|
-
clen = $1.to_i
|
|
979
|
-
end
|
|
980
656
|
break if line.strip.empty?
|
|
981
657
|
end
|
|
982
|
-
# Watobo::HTTPSocket.read_body(tcp_socket, :max_bytes => clen){ |d|
|
|
983
|
-
#puts d
|
|
984
|
-
# }
|
|
985
|
-
return response_header
|
|
986
|
-
end
|
|
987
658
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
case proxy.auth_type
|
|
996
|
-
when AUTH_TYPE_NTLM
|
|
997
|
-
return proxyAuthNTLM(tcp_socket, orig_request, proxy)
|
|
659
|
+
if rcode == 200 # Ok
|
|
660
|
+
puts "[NTLM] Authentication Successfull" if $DEBUG
|
|
661
|
+
elsif rcode == 401 # Authentication Required
|
|
662
|
+
# TODO: authorization didn't work -> do some notification
|
|
663
|
+
# ...
|
|
664
|
+
puts "[NTLM] could not authenticate. Bad credentials?"
|
|
665
|
+
end
|
|
998
666
|
|
|
999
|
-
|
|
667
|
+
return socket, Watobo::Response.new(response_header)
|
|
668
|
+
rescue => bang
|
|
669
|
+
puts "!!! ERROR: in ntlm_auth"
|
|
670
|
+
puts bang
|
|
1000
671
|
|
|
672
|
+
puts bang.backtrace if $DEBUG
|
|
673
|
+
return nil, nil
|
|
1001
674
|
end
|
|
675
|
+
end
|
|
1002
676
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
#
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
677
|
+
def sslConnect(tcp_socket, current_prefs = {} )
|
|
678
|
+
begin
|
|
679
|
+
# @ctx = OpenSSL::SSL::SSLContext.new()
|
|
680
|
+
# @ctx.key = nil
|
|
681
|
+
# @ctx.cert = nil
|
|
682
|
+
ctx = OpenSSL::SSL::SSLContext.new()
|
|
683
|
+
ctx.ciphers = current_prefs[:ssl_cipher] if current_prefs.has_key? :ssl_cipher
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
if current_prefs.has_key? :ssl_client_cert and current_prefs.has_key? :ssl_client_key
|
|
687
|
+
|
|
688
|
+
ctx.cert = current_prefs[:ssl_client_cert]
|
|
689
|
+
ctx.key = current_prefs[:ssl_client_key]
|
|
690
|
+
if $DEBUG
|
|
691
|
+
puts "[SSLconnect] Client Certificates"
|
|
692
|
+
puts "= CERT ="
|
|
693
|
+
# puts @ctx.cert.methods.sort
|
|
694
|
+
puts ctx.cert.display
|
|
695
|
+
puts "---"
|
|
696
|
+
p
|
|
697
|
+
puts "= KEY ="
|
|
698
|
+
puts ctx.key.display
|
|
699
|
+
puts "---"
|
|
700
|
+
end
|
|
1012
701
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
702
|
+
end
|
|
703
|
+
# @ctx.tmp_dh_callback = proc { |*args|
|
|
704
|
+
# OpenSSL::PKey::DH.new(128)
|
|
705
|
+
#}
|
|
706
|
+
if current_prefs.has_key? :client_certificate
|
|
707
|
+
ccp = current_prefs[:client_certificate]
|
|
708
|
+
ctx.cert = ccp[:ssl_client_cert]
|
|
709
|
+
ctx.key = ccp[:ssl_client_key]
|
|
710
|
+
ctx.extra_chain_cert = ccp[:extra_chain_certs] if ccp.has_key?(:extra_chain_certs)
|
|
711
|
+
end
|
|
1018
712
|
|
|
1019
|
-
|
|
1020
|
-
tcp_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
|
1021
|
-
tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
1022
|
-
tcp_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
|
1023
|
-
tcp_socket.sync = true
|
|
1024
|
-
# end
|
|
713
|
+
socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ctx)
|
|
1025
714
|
|
|
1026
|
-
|
|
1027
|
-
|
|
715
|
+
# need hostname for SNI (Server Name Indication)
|
|
716
|
+
# http://en.wikipedia.org/wiki/Server_Name_Indication
|
|
717
|
+
socket.hostname = current_prefs[:hostname] if current_prefs.has_key?(:hostname)
|
|
718
|
+
socket.sync_close = true
|
|
1028
719
|
|
|
1029
|
-
auth_request.addHeader("Pragma", "no-cache")
|
|
1030
720
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
721
|
+
socket.connect
|
|
722
|
+
#socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
|
723
|
+
puts "[SSLconnect]: #{socket.state}" if $DEBUG
|
|
724
|
+
return socket
|
|
725
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
726
|
+
# puts "[SSLconnect] Failure"
|
|
727
|
+
# puts e
|
|
728
|
+
raise e
|
|
729
|
+
#return nil
|
|
730
|
+
rescue => bang
|
|
731
|
+
if current_prefs[:ssl_cipher].nil?
|
|
732
|
+
puts "[SSLconnect] ... gr#!..*peep*.. "
|
|
733
|
+
puts bang
|
|
734
|
+
puts bang.backtrace if $DEBUG
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
end
|
|
1039
738
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
739
|
+
# SSLProxyConnect
|
|
740
|
+
# return SSLSocket, ResponseHeader of ConnectionSetup
|
|
741
|
+
# On error SSLSocket is nil
|
|
742
|
+
def sslProxyConnect(orig_request, proxy, prefs)
|
|
743
|
+
begin
|
|
744
|
+
tcp_socket = nil
|
|
745
|
+
response_header = []
|
|
746
|
+
|
|
747
|
+
request = Watobo::Utils::copyObject(orig_request)
|
|
748
|
+
request.extend Watobo::Mixin::Parser::Url
|
|
749
|
+
request.extend Watobo::Mixin::Parser::Web10
|
|
750
|
+
request.extend Watobo::Mixin::Shaper::Web10
|
|
751
|
+
# timeout(6) do
|
|
752
|
+
|
|
753
|
+
tcp_socket = TCPSocket.new( proxy.host, proxy.port)
|
|
754
|
+
tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
755
|
+
#tcp_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
|
756
|
+
tcp_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
|
757
|
+
tcp_socket.sync = true
|
|
758
|
+
# end
|
|
759
|
+
# puts "* sslProxyConnect"
|
|
760
|
+
# puts "Host: #{request.host}"
|
|
761
|
+
# puts "Port: #{request.port}"
|
|
762
|
+
# setup request
|
|
763
|
+
dummy = "CONNECT #{request.host}:#{request.port} HTTP/1.0\r\n"
|
|
764
|
+
request.shift
|
|
765
|
+
request.unshift dummy
|
|
766
|
+
|
|
767
|
+
#request.removeHeader("Proxy-Connection")
|
|
768
|
+
request.removeHeader("Connection")
|
|
769
|
+
request.removeHeader("Content-Length")
|
|
770
|
+
request.removeBody()
|
|
771
|
+
request.set_header("Proxy-Connection", "Keep-Alive")
|
|
772
|
+
request.addHeader("Pragma", "no-cache")
|
|
773
|
+
|
|
774
|
+
# puts "=== sslProxyConnect ==="
|
|
775
|
+
# puts request
|
|
776
|
+
|
|
777
|
+
if proxy.has_login?
|
|
778
|
+
case proxy.auth_type
|
|
779
|
+
when AUTH_TYPE_NTLM
|
|
780
|
+
|
|
781
|
+
t1 = Watobo::NTLM::Message::Type1.new()
|
|
782
|
+
msg = "NTLM " + t1.encode64
|
|
783
|
+
request.addHeader("Proxy-Authorization", msg)
|
|
784
|
+
|
|
785
|
+
if $DEBUG
|
|
786
|
+
puts "============= PROXY NTLM: T1 ======================="
|
|
787
|
+
puts request
|
|
788
|
+
puts "---"
|
|
789
|
+
end
|
|
790
|
+
data = request.join + "\r\n"
|
|
791
|
+
|
|
792
|
+
tcp_socket.print data
|
|
793
|
+
# puts "-----------------"
|
|
794
|
+
cl = 0
|
|
795
|
+
ntlm_challenge = nil
|
|
796
|
+
while (line = tcp_socket.gets)
|
|
797
|
+
response_header.push line
|
|
798
|
+
puts line if $DEBUG
|
|
799
|
+
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
800
|
+
rcode = $1.to_i
|
|
801
|
+
rmsg = $2
|
|
802
|
+
end
|
|
803
|
+
if line =~ /^Proxy-Authenticate: (NTLM) (.+)\r\n/
|
|
804
|
+
ntlm_challenge = $2
|
|
805
|
+
end
|
|
806
|
+
if line =~ /^Content-Length: (\d*)/i
|
|
807
|
+
cl = $1.to_i
|
|
808
|
+
end
|
|
809
|
+
break if line.strip.empty?
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
if cl > 0
|
|
814
|
+
Watobo::HTTPSocket.read_body(tcp_socket) { |d|
|
|
815
|
+
# puts d
|
|
816
|
+
}
|
|
817
|
+
end
|
|
1047
818
|
|
|
1048
|
-
|
|
1049
|
-
|
|
819
|
+
if rcode == 200 # Ok
|
|
820
|
+
puts "* seems proxy doesn't require authentication"
|
|
821
|
+
socket = sslConnect(tcp_socket, prefs)
|
|
1050
822
|
return socket, response_header
|
|
1051
|
-
else
|
|
1052
|
-
puts "* Unknown Authentication Type: #{prefs[:www_auth][site][:type]}"
|
|
1053
823
|
end
|
|
1054
|
-
|
|
1055
|
-
|
|
824
|
+
|
|
825
|
+
return socket, response_header if ntlm_challenge.nil? or ntlm_challenge == ""
|
|
826
|
+
|
|
827
|
+
t2 = Watobo::NTLM::Message.decode64(ntlm_challenge)
|
|
828
|
+
t3 = t2.response( { :user => proxy.username,
|
|
829
|
+
:password => proxy.password,
|
|
830
|
+
:domain => proxy.domain },
|
|
831
|
+
{ :workstation => proxy.workstation, :ntlmv2 => true } )
|
|
832
|
+
request.removeHeader("Proxy-Authorization")
|
|
833
|
+
|
|
834
|
+
msg = "NTLM " + t3.encode64
|
|
835
|
+
request.addHeader("Proxy-Authorization", msg)
|
|
836
|
+
|
|
837
|
+
data = request.join + "\r\n"
|
|
838
|
+
if $DEBUG
|
|
839
|
+
puts "============= T3 ======================="
|
|
840
|
+
puts data
|
|
841
|
+
puts "---"
|
|
842
|
+
end
|
|
1056
843
|
|
|
1057
844
|
tcp_socket.print data
|
|
845
|
+
# puts "-----------------"
|
|
1058
846
|
|
|
847
|
+
response_header = []
|
|
848
|
+
rcode = 0
|
|
1059
849
|
response_header = readHTTPHeader(tcp_socket)
|
|
1060
|
-
|
|
850
|
+
rcode = response_header.status
|
|
851
|
+
if rcode =~/^200/ # Ok
|
|
852
|
+
puts "[ProxyAuth-NTLM] Authorization Successful" if $DEBUG
|
|
853
|
+
socket = sslConnect(tcp_socket, prefs)
|
|
854
|
+
return socket, response_header
|
|
855
|
+
elsif rcode =~ /^407/ # ProxyAuthentication Required
|
|
856
|
+
# if rcode is still 407 authentication didn't work -> break
|
|
857
|
+
msg = "NTLM-Authentication failed!"
|
|
858
|
+
puts "[ProxyAuth-NTLM] #{msg}" if $DEBUG
|
|
859
|
+
return nil, msg
|
|
860
|
+
else
|
|
861
|
+
puts "[SSLconnect] NTLM Authentication"
|
|
862
|
+
puts "> #{rcode} <"
|
|
863
|
+
return nil, response_header
|
|
864
|
+
end
|
|
1061
865
|
end
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
866
|
+
end # END OF PROXY AUTH
|
|
867
|
+
|
|
868
|
+
# Start ProxyConnect Without Authentication
|
|
869
|
+
data = request.join + "\r\n"
|
|
870
|
+
tcp_socket.print data
|
|
871
|
+
# puts "-----------------"
|
|
1065
872
|
|
|
873
|
+
response_header = []
|
|
874
|
+
response_header = readHTTPHeader(tcp_socket)
|
|
875
|
+
rcode = response_header.status
|
|
876
|
+
if rcode =~ /^200/ # Ok
|
|
877
|
+
# puts "* proxy connection successfull"
|
|
878
|
+
elsif rcode =~ /^407/ # ProxyAuthentication Required
|
|
879
|
+
# if rcode is still 407 authentication didn't work -> break
|
|
880
|
+
|
|
881
|
+
else
|
|
882
|
+
puts "[SSLconnect] Response Status"
|
|
883
|
+
puts "> #{rcode} <"
|
|
1066
884
|
end
|
|
1067
|
-
|
|
885
|
+
|
|
886
|
+
socket = sslConnect(tcp_socket, prefs)
|
|
887
|
+
return socket, response_header
|
|
888
|
+
rescue => bang
|
|
889
|
+
puts bang
|
|
890
|
+
puts proxy
|
|
891
|
+
puts prefs
|
|
892
|
+
return nil, error_response(bang)
|
|
1068
893
|
end
|
|
894
|
+
# return nil, nil
|
|
895
|
+
end
|
|
1069
896
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
897
|
+
# proxyAuthNTLM
|
|
898
|
+
# returns: ResponseHeaders
|
|
899
|
+
def proxyAuthNTLM(tcp_socket, orig_request, proxy)
|
|
900
|
+
|
|
901
|
+
if orig_request.respond_to? :copy
|
|
902
|
+
request = orig_request.copy
|
|
903
|
+
else
|
|
904
|
+
request = Watobo::Response.new YAML.load(YAML.dump(orig_request))
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
request.removeHeader("Proxy-Authorization")
|
|
908
|
+
request.removeHeader("Proxy-Connection")
|
|
909
|
+
|
|
910
|
+
response_header = []
|
|
911
|
+
|
|
912
|
+
ntlm_challenge = nil
|
|
913
|
+
t1 = Watobo::NTLM::Message::Type1.new()
|
|
914
|
+
msg = "NTLM " + t1.encode64
|
|
915
|
+
|
|
916
|
+
request.addHeader("Proxy-Authorization", msg)
|
|
917
|
+
request.addHeader("Proxy-Connection", "Keep-Alive")
|
|
918
|
+
|
|
919
|
+
# puts "============= T1 ======================="
|
|
920
|
+
# puts auth_request
|
|
921
|
+
data = request.join + "\r\n"
|
|
922
|
+
|
|
923
|
+
tcp_socket.print data
|
|
924
|
+
# puts "-----------------"
|
|
925
|
+
response_header = readHTTPHeader(tcp_socket)
|
|
926
|
+
rcode = nil
|
|
927
|
+
rmsg = nil
|
|
928
|
+
ntlm_challenge = nil
|
|
929
|
+
clen = 0
|
|
930
|
+
response_header.each do |line|
|
|
931
|
+
# puts line
|
|
932
|
+
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
933
|
+
rcode = $1.to_i
|
|
934
|
+
rmsg = $2
|
|
935
|
+
end
|
|
936
|
+
if line =~ /^Proxy-Authenticate: (NTLM) (.+)\r\n/
|
|
937
|
+
ntlm_challenge = $2
|
|
938
|
+
end
|
|
939
|
+
if line =~ /^Content-Length: (\d{1,})\r\n/
|
|
940
|
+
clen = $1.to_i
|
|
941
|
+
end
|
|
942
|
+
break if line.strip.empty?
|
|
943
|
+
end
|
|
944
|
+
|
|
945
|
+
#puts "* reading #{clen} bytes"
|
|
946
|
+
|
|
947
|
+
if rcode == 407 # ProxyAuthentication Required
|
|
948
|
+
return response_header if ntlm_challenge.nil? or ntlm_challenge == ""
|
|
949
|
+
else
|
|
950
|
+
puts "* no proxy authentication required!"
|
|
951
|
+
return response_header
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
Watobo::HTTPSocket.read_body(tcp_socket, :max_bytes => clen){ |d|
|
|
955
|
+
#puts d
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
t2 = Watobo::NTLM::Message.decode64(ntlm_challenge)
|
|
959
|
+
t3 = t2.response({:user => proxy.username, :password => proxy.password, :workstation => proxy.workstation, :domain => proxy.domain}, {:ntlmv2 => true})
|
|
960
|
+
#request.removeHeader("Proxy-Authorization")
|
|
961
|
+
# request.removeHeader("Proxy-Connection")
|
|
962
|
+
|
|
963
|
+
# request.addHeader("Proxy-Connection", "Close")
|
|
964
|
+
# request.addHeader("Pragma", "no-cache")
|
|
965
|
+
msg = "NTLM " + t3.encode64
|
|
966
|
+
request.addHeader("Proxy-Authorization", msg)
|
|
967
|
+
# puts "============= T3 ======================="
|
|
968
|
+
# puts request
|
|
969
|
+
# puts "------------------------"
|
|
970
|
+
data = request.join + "\r\n"
|
|
971
|
+
tcp_socket.print data
|
|
972
|
+
|
|
973
|
+
response_header = readHTTPHeader(tcp_socket)
|
|
974
|
+
response_header.each do |line|
|
|
975
|
+
# puts line
|
|
976
|
+
if line =~ /^HTTP\/\d\.\d (\d+) (.*)/ then
|
|
977
|
+
rcode = $1.to_i
|
|
978
|
+
rmsg = $2
|
|
979
|
+
end
|
|
980
|
+
if line =~ /^Proxy-Authenticate: (NTLM) (.+)\r\n/
|
|
981
|
+
ntlm_challenge = $2
|
|
982
|
+
end
|
|
983
|
+
if line =~ /^Content-Length: (\d{1,})\r\n/
|
|
984
|
+
clen = $1.to_i
|
|
985
|
+
end
|
|
986
|
+
break if line.strip.empty?
|
|
987
|
+
end
|
|
988
|
+
# Watobo::HTTPSocket.read_body(tcp_socket, :max_bytes => clen){ |d|
|
|
989
|
+
#puts d
|
|
990
|
+
# }
|
|
991
|
+
return response_header
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
#
|
|
995
|
+
# doProxyAuth
|
|
996
|
+
#
|
|
997
|
+
def doProxyAuth(tcp_socket, orig_request, proxy)
|
|
998
|
+
# puts "DO PROXY AUTH"
|
|
999
|
+
# puts proxy.to_yaml
|
|
1000
|
+
response_headers = nil
|
|
1001
|
+
case proxy.auth_type
|
|
1002
|
+
when AUTH_TYPE_NTLM
|
|
1003
|
+
return proxyAuthNTLM(tcp_socket, orig_request, proxy)
|
|
1004
|
+
|
|
1005
|
+
end # END OF NTLM
|
|
1006
|
+
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
##################################################
|
|
1010
|
+
# doProxyRequest
|
|
1011
|
+
################################################
|
|
1012
|
+
def doProxyRequest(request, proxy, prefs={})
|
|
1013
|
+
#puts "DO PROXY REQUEST"
|
|
1014
|
+
# puts prefs.to_yaml
|
|
1015
|
+
begin
|
|
1016
|
+
tcp_socket = nil
|
|
1017
|
+
site = request.site
|
|
1018
|
+
|
|
1019
|
+
auth_request = Watobo::Utils::copyObject(request)
|
|
1020
|
+
auth_request.extend Watobo::Mixin::Parser::Url
|
|
1021
|
+
auth_request.extend Watobo::Mixin::Parser::Web10
|
|
1022
|
+
auth_request.extend Watobo::Mixin::Shaper::Web10
|
|
1023
|
+
# timeout(6) do
|
|
1024
|
+
|
|
1025
|
+
tcp_socket = TCPSocket.new( proxy.host, proxy.port)
|
|
1026
|
+
tcp_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
|
1027
|
+
tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
1028
|
+
tcp_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
|
1029
|
+
tcp_socket.sync = true
|
|
1030
|
+
# end
|
|
1031
|
+
|
|
1032
|
+
auth_request.removeHeader("Proxy-Connection")
|
|
1033
|
+
auth_request.removeHeader("Connection")
|
|
1034
|
+
|
|
1035
|
+
auth_request.addHeader("Pragma", "no-cache")
|
|
1036
|
+
|
|
1037
|
+
if proxy.has_login?
|
|
1038
|
+
response_header = doProxyAuth(tcp_socket, auth_request, proxy)
|
|
1039
|
+
# puts "* got request_header from doProxy Auth"
|
|
1040
|
+
# puts request_header.class
|
|
1041
|
+
puts "[Proxy Auth] Status: #{response_header.status}" if $DEBUG
|
|
1042
|
+
return tcp_socket, response_header unless response_header.status =~ /401/
|
|
1043
|
+
return tcp_socket, response_header unless prefs[:www_auth].has_key?(site)
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
# puts "CHECK WWW_AUTH"
|
|
1047
|
+
# puts prefs.to_yaml
|
|
1048
|
+
if prefs[:www_auth].has_key?(site)
|
|
1049
|
+
case prefs[:www_auth][site][:type]
|
|
1050
|
+
when AUTH_TYPE_NTLM
|
|
1051
|
+
# puts "* found NTLM credentials for site #{site}"
|
|
1052
|
+
socket, response_header = wwwAuthNTLM(tcp_socket, request, prefs[:www_auth][site])
|
|
1053
|
+
|
|
1054
|
+
#response_header.extend Watobo::Mixin::Parser::Url
|
|
1055
|
+
#response_header.extend Watobo::Mixin::Parser::Web10
|
|
1056
|
+
return socket, response_header
|
|
1057
|
+
else
|
|
1058
|
+
puts "* Unknown Authentication Type: #{prefs[:www_auth][site][:type]}"
|
|
1059
|
+
end
|
|
1060
|
+
else
|
|
1061
|
+
data = auth_request.join + "\r\n"
|
|
1062
|
+
|
|
1063
|
+
tcp_socket.print data
|
|
1064
|
+
|
|
1065
|
+
response_header = readHTTPHeader(tcp_socket)
|
|
1066
|
+
return tcp_socket, response_header
|
|
1067
|
+
end
|
|
1068
|
+
rescue => bang
|
|
1069
|
+
puts bang
|
|
1070
|
+
puts bang.backtrace if $DEBUG
|
|
1071
|
+
|
|
1072
|
+
end
|
|
1073
|
+
return nil
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
def loggedOut?(response, prefs={})
|
|
1077
|
+
begin
|
|
1078
|
+
return false if @session[:logout_signatures].empty?
|
|
1079
|
+
response.each do |line|
|
|
1080
|
+
@session[:logout_signatures].each do |p|
|
|
1081
|
+
# puts "!!!*LOGOUT*!!!" if line =~ /#{p}/
|
|
1082
|
+
return true if line =~ /#{p}/
|
|
1078
1083
|
end
|
|
1079
|
-
rescue => bang
|
|
1080
|
-
puts bang
|
|
1081
|
-
puts bang.backtrace if $DEBUG
|
|
1082
1084
|
end
|
|
1083
|
-
|
|
1085
|
+
rescue => bang
|
|
1086
|
+
puts bang
|
|
1087
|
+
puts bang.backtrace if $DEBUG
|
|
1084
1088
|
end
|
|
1089
|
+
return false
|
|
1090
|
+
end
|
|
1085
1091
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1092
|
+
def error_response(msg, comment=nil)
|
|
1093
|
+
er = []
|
|
1088
1094
|
er << "HTTP/1.1 555 Watobo Error\r\n"
|
|
1089
|
-
er << "WATOBO: #{msg.gsub(/\r?\n/," ").strip}\r\n"
|
|
1095
|
+
#er << "WATOBO: #{msg.gsub(/\r?\n/," ").strip}\r\n"
|
|
1096
|
+
er << "WATOBO: Error\r\n"
|
|
1097
|
+
er << "Date: #{Time.now.to_s}\r\n"
|
|
1090
1098
|
er << "Content-Length: 0\r\n"
|
|
1099
|
+
er << "Content-Type: text/html\r\n"
|
|
1091
1100
|
er << "Connection: close\r\n"
|
|
1092
1101
|
er << "\r\n"
|
|
1093
1102
|
unless comment.nil?
|
|
1094
|
-
|
|
1095
|
-
|
|
1103
|
+
body = "<html><head><title>Watobo Error</title></head><body><H1>#{msg}</H1></br><H2>#{comment.gsub(/\r?\n/,"</br>")}</H2></body></html>"
|
|
1104
|
+
er << body
|
|
1096
1105
|
end
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
def readHTTPHeader(socket, prefs={})
|
|
1105
|
-
|
|
1106
|
-
header = []
|
|
1107
|
-
msg = nil
|
|
1108
|
-
begin
|
|
1106
|
+
er.extend Watobo::Mixin::Parser::Url
|
|
1107
|
+
er.extend Watobo::Mixin::Parser::Web10
|
|
1108
|
+
er.extend Watobo::Mixin::Shaper::Web10
|
|
1109
|
+
er.fix_content_length
|
|
1110
|
+
er
|
|
1111
|
+
end
|
|
1109
1112
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
puts "!ERROR: read_header"
|
|
1121
|
-
return nil
|
|
1113
|
+
def readHTTPHeader(socket, prefs={})
|
|
1114
|
+
|
|
1115
|
+
header = []
|
|
1116
|
+
msg = nil
|
|
1117
|
+
begin
|
|
1118
|
+
|
|
1119
|
+
Watobo::HTTPSocket.read_header(socket) do |line|
|
|
1120
|
+
# puts line
|
|
1121
|
+
# puts line.unpack("H*")
|
|
1122
|
+
header.push line
|
|
1122
1123
|
end
|
|
1123
|
-
|
|
1124
|
-
|
|
1124
|
+
rescue Errno::ECONNRESET
|
|
1125
|
+
msg = "<html><head><title>WATOBO</title></head><body>WATOBO: Connection Reset By Peer</body></html>"
|
|
1126
|
+
rescue Timeout::Error
|
|
1127
|
+
msg = "<html><head><title>WATOBO</title></head><body>WATOBO: Timeout</body></html>"
|
|
1128
|
+
rescue => bang
|
|
1129
|
+
puts "!ERROR: read_header"
|
|
1130
|
+
return nil
|
|
1131
|
+
end
|
|
1125
1132
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1133
|
+
unless msg.nil?
|
|
1134
|
+
header = [ "HTTP/1.1 502 Bad Gateway\r\n"]
|
|
1135
|
+
header << "Server: WATOBO\r\n"
|
|
1136
|
+
header << "Date: #{Time.now.to_s}\r\n"
|
|
1137
|
+
header << "Content-Length: #{msg.length.to_i}\r\n"
|
|
1138
|
+
header << "Content-Type: text/html\r\n"
|
|
1139
|
+
header << "\r\n"
|
|
1140
|
+
header << "#{msg}"
|
|
1141
|
+
end
|
|
1128
1142
|
|
|
1129
|
-
|
|
1143
|
+
response = Watobo::Response.new header
|
|
1144
|
+
# update_sids(header)
|
|
1130
1145
|
|
|
1131
|
-
|
|
1132
|
-
notify(:logout, self) if loggedOut?(response)
|
|
1133
|
-
end
|
|
1146
|
+
# update_sids(request.site, response) if prefs[:update_sids] == true
|
|
1134
1147
|
|
|
1135
|
-
|
|
1148
|
+
unless prefs[:ignore_logout] == true or @session[:logout_signatures].empty?
|
|
1149
|
+
notify(:logout, self) if loggedOut?(response)
|
|
1136
1150
|
end
|
|
1137
1151
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1152
|
+
return response
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
def closeSocket(socket)
|
|
1140
1157
|
return false if socket.nil?
|
|
1141
1158
|
begin
|
|
1142
1159
|
if socket.respond_to? :sysclose
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1160
|
+
#socket.io.shutdown(2)
|
|
1161
|
+
# puts "sysclose"
|
|
1162
|
+
socket.sysclose
|
|
1146
1163
|
elsif socket.respond_to? :shutdown
|
|
1147
|
-
|
|
1164
|
+
socket.shutdown(2)
|
|
1148
1165
|
elsif socket.respond_to? :close
|
|
1149
|
-
|
|
1166
|
+
socket.close
|
|
1150
1167
|
end
|
|
1151
1168
|
return true
|
|
1152
1169
|
rescue => bang
|
|
@@ -1156,73 +1173,73 @@ end
|
|
|
1156
1173
|
false
|
|
1157
1174
|
end
|
|
1158
1175
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
end
|
|
1176
|
+
def updateSessionSettings(settings={})
|
|
1177
|
+
[
|
|
1178
|
+
:ssl_client_cert,
|
|
1179
|
+
:ssl_client_key,
|
|
1180
|
+
:ssl_client_pass,
|
|
1181
|
+
:csrf_requests,
|
|
1182
|
+
:valid_sids,
|
|
1183
|
+
:sid_patterns,
|
|
1184
|
+
:logout_signatures,
|
|
1185
|
+
:logout_content_types,
|
|
1186
|
+
:update_valid_sids,
|
|
1187
|
+
:update_sids,
|
|
1188
|
+
:update_session,
|
|
1189
|
+
:update_contentlength,
|
|
1190
|
+
:login_chats,
|
|
1191
|
+
:follow_redirect
|
|
1192
|
+
].each do |k|
|
|
1193
|
+
@session[k] = settings[k] if settings.has_key? k
|
|
1178
1194
|
end
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
# this function updates specific patterns of a request, e.g. CSRF Tokens
|
|
1200
|
+
# Parameters:
|
|
1201
|
+
# request - the request which has to be updated
|
|
1202
|
+
# cache - the value store of already collected key-value-pairs
|
|
1203
|
+
# patterns - pattern expressions, similar to session-id-patterns, e.g. /name="(sessid)" value="([0-9a-zA-Z!-]*)"/
|
|
1204
|
+
def updateRequestPattern(request, cache, patterns)
|
|
1179
1205
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
if not
|
|
1198
|
-
|
|
1199
|
-
# puts "+ update sid #{sid_key}"
|
|
1200
|
-
# puts "-OLD: #{old_value}"
|
|
1201
|
-
# puts "-NEW: #{@session[:valid_sids][request.site][sid_key]}"
|
|
1202
|
-
|
|
1203
|
-
# puts "---"
|
|
1204
|
-
# dummy = Regexp.quote(old_value)
|
|
1205
|
-
res = line.gsub!(/#{old_value}/, cache[sid_key])
|
|
1206
|
-
if not res then puts "!!!could not update sid (#{sid_key})"; end
|
|
1207
|
-
# puts "->#{line}"
|
|
1208
|
-
end
|
|
1206
|
+
request.map!{ |line|
|
|
1207
|
+
res = line
|
|
1208
|
+
patterns.each do |pat|
|
|
1209
|
+
begin
|
|
1210
|
+
if line =~ /#{pat}/i then
|
|
1211
|
+
pattern_key = Regexp.quote($1.upcase)
|
|
1212
|
+
old_value = Regexp.quote($2)
|
|
1213
|
+
if cache.has_key?(sid_key) then
|
|
1214
|
+
if not old_value =~ /#{cache[sid_key]}/ then # sid value has changed and needs update
|
|
1215
|
+
# print "S"
|
|
1216
|
+
# puts "+ update sid #{sid_key}"
|
|
1217
|
+
# puts "-OLD: #{old_value}"
|
|
1218
|
+
# puts "-NEW: #{@session[:valid_sids][request.site][sid_key]}"
|
|
1219
|
+
|
|
1220
|
+
# puts "---"
|
|
1221
|
+
# dummy = Regexp.quote(old_value)
|
|
1222
|
+
res = line.gsub!(/#{old_value}/, cache[sid_key])
|
|
1223
|
+
if not res then puts "!!!could not update sid (#{sid_key})"; end
|
|
1224
|
+
# puts "->#{line}"
|
|
1209
1225
|
end
|
|
1210
1226
|
end
|
|
1211
|
-
rescue => bang
|
|
1212
|
-
puts bang
|
|
1213
|
-
puts bang.backtrace if $DEBUG
|
|
1214
|
-
# puts @session.to_yaml
|
|
1215
1227
|
end
|
|
1228
|
+
rescue => bang
|
|
1229
|
+
puts bang
|
|
1230
|
+
puts bang.backtrace if $DEBUG
|
|
1231
|
+
# puts @session.to_yaml
|
|
1216
1232
|
end
|
|
1217
|
-
res
|
|
1218
|
-
}
|
|
1219
|
-
end
|
|
1220
|
-
|
|
1221
|
-
def applySessionSettings(prefs)
|
|
1222
|
-
[ :update_valid_sids, :update_session, :update_contentlength, :valid_sids, :sid_patterns, :logout_signatures ].each do |v|
|
|
1223
|
-
@@settings[v] = prefs[v] if prefs[v]
|
|
1224
1233
|
end
|
|
1225
|
-
|
|
1234
|
+
res
|
|
1235
|
+
}
|
|
1236
|
+
end
|
|
1226
1237
|
|
|
1238
|
+
def applySessionSettings(prefs)
|
|
1239
|
+
[ :update_valid_sids, :update_session, :update_contentlength, :valid_sids, :sid_patterns, :logout_signatures ].each do |v|
|
|
1240
|
+
@@settings[v] = prefs[v] if prefs[v]
|
|
1241
|
+
end
|
|
1227
1242
|
end
|
|
1228
|
-
|
|
1243
|
+
|
|
1244
|
+
end
|
|
1245
|
+
end
|