]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_flashpolicyd.cpp
c2a965687842e53cfde716e543cc644357459817
[user/henk/code/inspircd.git] / src / modules / m_flashpolicyd.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2019 Robby <robby@chatbelgie.be>
5  *   Copyright (C) 2018 linuxdaemon <linuxdaemon.irc@gmail.com>
6  *   Copyright (C) 2017-2018, 2020 Sadie Powell <sadie@witchery.services>
7  *   Copyright (C) 2014 JustArchi <JustArchi@JustArchi.net>
8  *   Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
9  *   Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org>
10  *
11  * This file is part of InspIRCd.  InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24
25 #include "inspircd.h"
26
27 class FlashPDSocket;
28
29 namespace
30 {
31         insp::intrusive_list<FlashPDSocket> sockets;
32         std::string policy_reply;
33         const std::string expected_request("<policy-file-request/>\0", 23);
34 }
35
36 class FlashPDSocket : public BufferedSocket, public Timer, public insp::intrusive_list_node<FlashPDSocket>
37 {
38         /** True if this object is in the cull list
39          */
40         bool waitingcull;
41
42         bool Tick(time_t currtime) CXX11_OVERRIDE
43         {
44                 AddToCull();
45                 return false;
46         }
47
48  public:
49         FlashPDSocket(int newfd, unsigned int timeoutsec)
50                 : BufferedSocket(newfd)
51                 , Timer(timeoutsec)
52                 , waitingcull(false)
53         {
54                 ServerInstance->Timers.AddTimer(this);
55         }
56
57         ~FlashPDSocket()
58         {
59                 sockets.erase(this);
60         }
61
62         void OnError(BufferedSocketError) CXX11_OVERRIDE
63         {
64                 AddToCull();
65         }
66
67         void OnDataReady() CXX11_OVERRIDE
68         {
69                 if (recvq == expected_request)
70                         WriteData(policy_reply);
71                 AddToCull();
72         }
73
74         void AddToCull()
75         {
76                 if (waitingcull)
77                         return;
78
79                 waitingcull = true;
80                 Close();
81                 ServerInstance->GlobalCulls.AddItem(this);
82         }
83 };
84
85 class ModuleFlashPD : public Module
86 {
87         unsigned int timeout;
88
89  public:
90         ModResult OnAcceptConnection(int nfd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE
91         {
92                 if (!stdalgo::string::equalsci(from->bind_tag->getString("type"), "flashpolicyd"))
93                         return MOD_RES_PASSTHRU;
94
95                 if (policy_reply.empty())
96                         return MOD_RES_DENY;
97
98                 sockets.push_front(new FlashPDSocket(nfd, timeout));
99                 return MOD_RES_ALLOW;
100         }
101
102         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
103         {
104                 ConfigTag* tag = ServerInstance->Config->ConfValue("flashpolicyd");
105                 std::string file = tag->getString("file");
106
107                 if (!file.empty())
108                 {
109                         try
110                         {
111                                 FileReader reader(file);
112                                 policy_reply = reader.GetString();
113                         }
114                         catch (CoreException&)
115                         {
116                                 throw ModuleException("A file was specified for FlashPD, but it could not be loaded at " + tag->getTagLocation());
117                         }
118                         return;
119                 }
120
121                 // A file was not specified. Set the default setting.
122                 // We allow access to all client ports by default
123                 std::string to_ports;
124                 for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i)
125                 {
126                                 ListenSocket* ls = *i;
127                                 if (!stdalgo::string::equalsci(ls->bind_tag->getString("type", "clients", 1), "clients"))
128                                         continue;
129
130                                 if (!ls->bind_tag->getString("sslprofile", ls->bind_tag->getString("ssl")).empty())
131                                         continue;
132
133                                 to_ports.append(ConvToStr(ls->bind_sa.port())).push_back(',');
134                 }
135
136                 if (to_ports.empty())
137                 {
138                         policy_reply.clear();
139                         return;
140                 }
141
142                 to_ports.erase(to_ports.size() - 1);
143
144                 policy_reply =
145 "<?xml version=\"1.0\"?>\
146 <!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\
147 <cross-domain-policy>\
148 <site-control permitted-cross-domain-policies=\"master-only\"/>\
149 <allow-access-from domain=\"*\" to-ports=\"" + to_ports + "\" />\
150 </cross-domain-policy>";
151                 timeout = tag->getDuration("timeout", 5, 1);
152         }
153
154         CullResult cull() CXX11_OVERRIDE
155         {
156                 for (insp::intrusive_list<FlashPDSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
157                 {
158                         FlashPDSocket* sock = *i;
159                         sock->AddToCull();
160                 }
161                 return Module::cull();
162         }
163
164         Version GetVersion() CXX11_OVERRIDE
165         {
166                 return Version("Allows connection policies to be served to IRC clients that use Adobe Flash.", VF_VENDOR);
167         }
168 };
169
170 MODULE_INIT(ModuleFlashPD)