X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_websocket.cpp;h=e2b0ee30ad8d4b08217f0e159ca5952175cc033b;hb=3151d60c1ecc9462e4c335282ee6c31672f45111;hp=3437fdb1a84938541584ea0b507c65a14f936e52;hpb=6f2d0b505f4715c696cc5d49874d442cf790b98a;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp index 3437fdb1a..e2b0ee30a 100644 --- a/src/modules/m_websocket.cpp +++ b/src/modules/m_websocket.cpp @@ -1,7 +1,9 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2016 Attila Molnar + * Copyright (C) 2019 iwalkalone + * Copyright (C) 2017-2019 Sadie Powell + * Copyright (C) 2016-2017 Attila Molnar * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -25,17 +27,21 @@ #include -typedef std::vector OriginList; - static const char MagicGUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; static const char whitespace[] = " \t\r\n"; static dynamic_reference_nocheck* sha1; struct WebSocketConfig { + typedef std::vector OriginList; + typedef std::vector ProxyRanges; + // The HTTP origins that can connect to the server. OriginList allowedorigins; + // The IP ranges which send trustworthy X-Real-IP or X-Forwarded-For headers. + ProxyRanges proxyranges; + // Whether to send as UTF-8 text instead of binary data. bool sendastext; }; @@ -324,7 +330,7 @@ class WebSocketHook : public IOHookMiddle if (originheader.Find(recvq, "Origin:", 7, reqend)) { const std::string origin = originheader.ExtractValue(recvq); - for (OriginList::const_iterator iter = config.allowedorigins.begin(); iter != config.allowedorigins.end(); ++iter) + for (WebSocketConfig::OriginList::const_iterator iter = config.allowedorigins.begin(); iter != config.allowedorigins.end(); ++iter) { if (InspIRCd::Match(origin, *iter, ascii_case_insensitive_map)) { @@ -340,6 +346,36 @@ class WebSocketHook : public IOHookMiddle return -1; } + if (!config.proxyranges.empty() && sock->type == StreamSocket::SS_USER) + { + LocalUser* luser = static_cast(sock)->user; + irc::sockets::sockaddrs realsa(luser->client_sa); + + HTTPHeaderFinder proxyheader; + if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend) + && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa)) + { + // Nothing to do here. + } + else if (proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend) + && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa)) + { + // Nothing to do here. + } + + for (WebSocketConfig::ProxyRanges::const_iterator iter = config.proxyranges.begin(); iter != config.proxyranges.end(); ++iter) + { + if (InspIRCd::MatchCIDR(luser->GetIPString(), *iter, ascii_case_insensitive_map)) + { + // Give the user their real IP address. + if (realsa != luser->client_sa) + luser->SetClientIP(realsa); + break; + } + } + } + + HTTPHeaderFinder keyheader; if (!keyheader.Find(recvq, "Sec-WebSocket-Key:", 18, reqend)) { @@ -494,6 +530,10 @@ class ModuleWebSocket : public Module ConfigTag* tag = ServerInstance->Config->ConfValue("websocket"); config.sendastext = tag->getBool("sendastext", true); + irc::spacesepstream proxyranges(tag->getString("proxyranges")); + for (std::string proxyrange; proxyranges.GetToken(proxyrange); ) + config.proxyranges.push_back(proxyrange); + // Everything is okay; apply the new config. hookprov->config = config; } @@ -510,7 +550,7 @@ class ModuleWebSocket : public Module Version GetVersion() CXX11_OVERRIDE { - return Version("Provides RFC 6455 WebSocket support", VF_VENDOR); + return Version("Allows WebSocket clients to connect to the IRC server.", VF_VENDOR); } };