summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vassdal <shutter@canternet.org>2013-12-10 05:51:30 -0800
committerAttila Molnar <attilamolnar@hush.com>2013-12-18 15:45:29 +0100
commit96d96c48bf5fcc1c6478f4631818e2af0ceed721 (patch)
tree5c93453746277b54d7692fdab8114310fd3ac2a3
parent140e34e44b9afb0aef9c03dc571c41ba8cbd25e4 (diff)
Add a Flash Policy Daemon module
-rw-r--r--docs/conf/modules.conf.example8
-rw-r--r--src/modules/m_flashpolicyd.cpp158
2 files changed, 166 insertions, 0 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 639e3e1bd..f8bb7a87d 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -736,6 +736,14 @@
#<include file="examples/filter.conf.example">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
+# Flash Policy Daemon module: Allows Flash IRC clients (e.g. LightIRC)#
+# to connect. If no file is specified, it'll serve a default policy #
+# allowing all IPs to connect to all plaintext IRC ports #
+#<bind address="" port="8430" type="flashpolicyd"> #
+#<flashpolicyd timeout="5" file=""> #
+#<module name="m_flashpolicyd.so"> #
+
+#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Gecosban: Implements extended ban r:, which stops anyone matching
# a mask like +b r:*realname?here* from joining a channel.
#<module name="m_gecosban.so">
diff --git a/src/modules/m_flashpolicyd.cpp b/src/modules/m_flashpolicyd.cpp
new file mode 100644
index 000000000..95b82848f
--- /dev/null
+++ b/src/modules/m_flashpolicyd.cpp
@@ -0,0 +1,158 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org>
+ *
+ * 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
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+class FlashPDSocket;
+
+namespace
+{
+ std::set<FlashPDSocket*> sockets;
+ std::string policy_reply;
+ const std::string expected_request("<policy-file-request/>\0", 23);
+}
+
+class FlashPDSocket : public BufferedSocket
+{
+ public:
+ time_t created;
+
+ FlashPDSocket(int newfd)
+ : BufferedSocket(newfd)
+ , created(ServerInstance->Time())
+ {
+ }
+
+ ~FlashPDSocket()
+ {
+ sockets.erase(this);
+ }
+
+ void OnError(BufferedSocketError) CXX11_OVERRIDE
+ {
+ AddToCull();
+ }
+
+ void OnDataReady() CXX11_OVERRIDE
+ {
+ if (recvq == expected_request)
+ WriteData(policy_reply);
+ AddToCull();
+ }
+
+ void AddToCull()
+ {
+ if (created == 0)
+ return;
+
+ created = 0;
+ Close();
+ ServerInstance->GlobalCulls.AddItem(this);
+ }
+};
+
+class ModuleFlashPD : public Module
+{
+ time_t timeout;
+
+ public:
+ void OnBackgroundTimer(time_t curtime) CXX11_OVERRIDE
+ {
+ for (std::set<FlashPDSocket*>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
+ {
+ FlashPDSocket* sock = *i;
+ if ((sock->created + timeout <= curtime) && (sock->created != 0))
+ sock->AddToCull();
+ }
+ }
+
+ ModResult OnAcceptConnection(int nfd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE
+ {
+ if (from->bind_tag->getString("type") != "flashpolicyd")
+ return MOD_RES_PASSTHRU;
+
+ if (policy_reply.empty())
+ return MOD_RES_DENY;
+
+ sockets.insert(new FlashPDSocket(nfd));
+ return MOD_RES_ALLOW;
+ }
+
+ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+ {
+ ConfigTag* tag = ServerInstance->Config->ConfValue("flashpolicyd");
+ timeout = tag->getInt("timeout", 5, 1);
+ std::string file = tag->getString("file");
+
+ if (!file.empty())
+ {
+ try
+ {
+ FileReader reader(file);
+ policy_reply = reader.GetString();
+ }
+ catch (CoreException&)
+ {
+ const std::string error_message = "A file was specified for FlashPD, but it could not be loaded.";
+ ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, error_message);
+ ServerInstance->SNO->WriteGlobalSno('a', error_message);
+ policy_reply.clear();
+ }
+ return;
+ }
+
+ // A file was not specified. Set the default setting.
+ // We allow access to all client ports by default
+ std::string to_ports;
+ for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i)
+ {
+ ListenSocket* ls = *i;
+ if (ls->bind_tag->getString("type", "clients") != "clients" || ls->bind_tag->getString("ssl", "plaintext") != "plaintext")
+ continue;
+
+ to_ports.append(ConvToStr(ls->bind_port)).push_back(',');
+ }
+ to_ports.erase(to_ports.size() - 1);
+
+ policy_reply =
+"<?xml version=\"1.0\"?>\
+<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\
+<cross-domain-policy>\
+<site-control permitted-cross-domain-policies=\"master-only\"/>\
+<allow-access-from domain=\"*\" to-ports=\"" + to_ports + "\" />\
+</cross-domain-policy>";
+ }
+
+ CullResult cull()
+ {
+ for (std::set<FlashPDSocket*>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
+ {
+ FlashPDSocket* sock = *i;
+ sock->AddToCull();
+ }
+ return Module::cull();
+ }
+
+ Version GetVersion() CXX11_OVERRIDE
+ {
+ return Version("Flash Policy Daemon. Allows Flash IRC clients to connect", VF_VENDOR);
+ }
+};
+
+MODULE_INIT(ModuleFlashPD)