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