From 499ca748ea137da5bb722f05b99c003a91264a73 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 4 Dec 2016 11:52:22 +0100 Subject: mod_websocket: Add some debug messages --- plugins/mod_websocket.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index ea736800..26f4c124 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -148,6 +148,7 @@ function handle_request(event) end); if not wants_xmpp then + module:log("debug", "Client didn't want to talk XMPP, list of protocols was %s", request.headers.sec_websocket_protocol or "(empty)"); return 501; end @@ -287,6 +288,8 @@ function handle_request(event) response.headers.sec_webSocket_protocol = "xmpp"; response.headers.access_control_allow_origin = cross_domain; + session.log("debug", "Sending WebSocket handshake"); + return ""; end -- cgit v1.2.3 From de2540b480a7e955d6d2cce95912108c21d5f23e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 4 Dec 2016 11:57:26 +0100 Subject: mod_websocket: Use contains_token from util.http for checking if the requested WebSocket sub-protocols include XMPP --- plugins/mod_websocket.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index 26f4c124..66e214fd 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -14,6 +14,7 @@ local sha1 = require "util.hashes".sha1; local base64 = require "util.encodings".base64.encode; local st = require "util.stanza"; local parse_xml = require "util.xml".parse; +local contains_token = require "util.http".contains_token; local portmanager = require "core.portmanager"; local sm_destroy_session = require"core.sessionmanager".destroy_session; local log = module._log; @@ -142,10 +143,7 @@ function handle_request(event) ]]; end - local wants_xmpp = false; - (request.headers.sec_websocket_protocol or ""):gsub("([^,]*),?", function (proto) - if proto == "xmpp" then wants_xmpp = true; end - end); + local wants_xmpp = contains_token(request.headers.sec_websocket_protocol or "", "xmpp"); if not wants_xmpp then module:log("debug", "Client didn't want to talk XMPP, list of protocols was %s", request.headers.sec_websocket_protocol or "(empty)"); -- cgit v1.2.3 From 947faa1ccd09773d64d6fca51430b9832e15d72e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 5 Dec 2016 12:22:41 +0100 Subject: mod_websocket: Verify that the client-sent Origin header matches cross_domain_websocket (fixes #652) --- plugins/mod_websocket.lua | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index 66e214fd..10aa0d38 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -29,16 +29,16 @@ local t_concat = table.concat; local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); -local cross_domain = module:get_option("cross_domain_websocket"); -if cross_domain then +local cross_domain = module:get_option_set("cross_domain_websocket", {}); +if cross_domain:contains("*") or cross_domain:contains(true) then + cross_domain = true; +end + +local function check_origin(origin) if cross_domain == true then - cross_domain = "*"; - elseif type(cross_domain) == "table" then - cross_domain = t_concat(cross_domain, ", "); - end - if type(cross_domain) ~= "string" then - cross_domain = nil; + return true; end + return cross_domain:contains(origin); end local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; @@ -150,6 +150,11 @@ function handle_request(event) return 501; end + if not check_origin(request.headers.origin or "") then + module:log("debug", "Origin %s is not allowed by 'cross_domain_websocket'", request.headers.origin or "(missing header)"); + return 403; + end + local function websocket_close(code, message) conn:write(build_close(code, message)); conn:close(); @@ -284,7 +289,6 @@ function handle_request(event) response.headers.connection = "Upgrade"; response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); response.headers.sec_webSocket_protocol = "xmpp"; - response.headers.access_control_allow_origin = cross_domain; session.log("debug", "Sending WebSocket handshake"); -- cgit v1.2.3 From a6443e8ff35cadd1ec395d8d464e4d7119fb1259 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 5 Dec 2016 12:23:41 +0100 Subject: mod_websocket: Add the base URL of each host module is enabled on to 'cross_domain_websocket' --- plugins/mod_websocket.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index 10aa0d38..f6525df5 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -315,4 +315,17 @@ function module.add_host(module) }; }); module:hook("c2s-read-timeout", keepalive, -0.9); + + if cross_domain ~= true then + local url = require "socket.url"; + local ws_url = module:http_url("websocket", "xmpp-websocket"); + local url_components = url.parse(ws_url); + -- The 'Origin' consists of the base URL without path + url_components.path = nil; + local this_origin = url.build(url_components); + cross_domain:add(this_origin); + function module.unload() + cross_domain:remove(this_origin); + end + end end -- cgit v1.2.3 From cc617421b1b118c4bfa7067f4ff6a3ee001143f1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 5 Dec 2016 12:23:51 +0100 Subject: mod_websocket: Allow per-host cross_domain_websocket, defaulting to the base URL of the current host --- plugins/mod_websocket.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index f6525df5..c19ad566 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -323,9 +323,13 @@ function module.add_host(module) -- The 'Origin' consists of the base URL without path url_components.path = nil; local this_origin = url.build(url_components); - cross_domain:add(this_origin); + local local_cross_domain = module:get_option_set("cross_domain_websocket", { this_origin }); + -- Don't add / remove something added by another host + -- This might be weird with random load order + local_cross_domain:exclude(cross_domain); + cross_domain:include(local_cross_domain); function module.unload() - cross_domain:remove(this_origin); + cross_domain:exclude(local_cross_domain); end end end -- cgit v1.2.3