From bc5151daffe857165d599fb38aa4c393df62c342 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 4 Dec 2016 11:58:16 +0100 Subject: net.websocket: Ignore unused argument warnings [luacheck] --- net/websocket.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/websocket.lua b/net/websocket.lua index a4274eec..373210d6 100644 --- a/net/websocket.lua +++ b/net/websocket.lua @@ -44,7 +44,7 @@ local function fail(s, code, reason) return false end -function websocket_listeners.onincoming(handler, buffer, err) +function websocket_listeners.onincoming(handler, buffer, err) -- luacheck: ignore 212/err local s = websockets[handler]; s.readbuffer = s.readbuffer..buffer; while true do @@ -123,7 +123,7 @@ function websocket_listeners.onincoming(handler, buffer, err) end local websocket_methods = {}; -local function close_timeout_cb(now, timerid, s) +local function close_timeout_cb(now, timerid, s) -- luacheck: ignore 212/now 212/timerid s.close_timer = nil; log("warn", "Close timeout waiting for server to close, closing manually."); s.handler:close(); @@ -232,7 +232,7 @@ local function connect(url, ex, listeners) }, websocket_metatable); local http_url = url:gsub("^(ws)", "http"); - local http_req = http.request(http_url, { + local http_req = http.request(http_url, { -- luacheck: ignore 211/http_req method = "GET"; headers = headers; sslctx = ex.sslctx; -- cgit v1.2.3 From f758fdb4d600d74251e6c10cff8116c40fce6771 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(+) 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 1ec77e632e546e8fefe7cb7fb87f9d3c5bfdfbe0 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(-) 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 bcf02d74c72b6a90600f6615c6219952ecbda252 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(-) 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 d1eb694c30025990eeed6aef83f0f2a6ff272fd2 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(+) 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 b151bd4d64f0e25c7c73acca597eadcbbc1c812e 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(-) 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