]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_customtitle.cpp
ec82119146ee6a569a0e008284f3faba803f1dfd
[user/henk/code/inspircd.git] / src / modules / m_customtitle.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
6  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
7  *
8  * This file is part of InspIRCd.  InspIRCd is free software: you can
9  * redistribute it and/or modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include "inspircd.h"
23 #include "modules/whois.h"
24
25 enum
26 {
27         // From UnrealIRCd.
28         RPL_WHOISSPECIAL = 320
29 };
30
31 struct CustomTitle
32 {
33         const std::string name;
34         const std::string password;
35         const std::string hash;
36         const std::string host;
37         const std::string title;
38         const std::string vhost;
39
40         CustomTitle(const std::string& n, const std::string& p, const std::string& h, const std::string& hst, const std::string& t, const std::string& v)
41                 : name(n)
42                 , password(p)
43                 , hash(h)
44                 , host(hst)
45                 , title(t)
46                 , vhost(v)
47         {
48         }
49
50         bool MatchUser(User* user) const
51         {
52                 const std::string userHost = user->ident + "@" + user->GetRealHost();
53                 const std::string userIP = user->ident + "@" + user->GetIPString();
54                 return InspIRCd::MatchMask(host, userHost, userIP);
55         }
56
57         bool CheckPass(User* user, const std::string& pass) const
58         {
59                 return ServerInstance->PassCompare(user, password, pass, hash);
60         }
61 };
62
63 typedef std::multimap<std::string, CustomTitle> CustomVhostMap;
64 typedef std::pair<CustomVhostMap::iterator, CustomVhostMap::iterator> MatchingConfigs;
65
66 /** Handle /TITLE
67  */
68 class CommandTitle : public Command
69 {
70  public:
71         StringExtItem ctitle;
72         CustomVhostMap configs;
73
74         CommandTitle(Module* Creator) : Command(Creator,"TITLE", 2),
75                 ctitle("ctitle", ExtensionItem::EXT_USER, Creator)
76         {
77                 syntax = "<username> <password>";
78         }
79
80         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
81         {
82                 MatchingConfigs matching = configs.equal_range(parameters[0]);
83
84                 for (MatchingConfigs::first_type i = matching.first; i != matching.second; ++i)
85                 {
86                         CustomTitle config = i->second;
87                         if (config.MatchUser(user) && config.CheckPass(user, parameters[1]))
88                         {
89                                 ctitle.set(user, config.title);
90
91                                 ServerInstance->PI->SendMetaData(user, "ctitle", config.title);
92
93                                 if (!config.vhost.empty())
94                                         user->ChangeDisplayedHost(config.vhost);
95
96                                 user->WriteNotice("Custom title set to '" + config.title + "'");
97
98                                 return CMD_SUCCESS;
99                         }
100                 }
101
102                 user->WriteNotice("Invalid title credentials");
103                 return CMD_SUCCESS;
104         }
105
106 };
107
108 class ModuleCustomTitle : public Module, public Whois::LineEventListener
109 {
110         CommandTitle cmd;
111
112  public:
113         ModuleCustomTitle()
114                 : Whois::LineEventListener(this)
115                 , cmd(this)
116         {
117         }
118
119         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
120         {
121                 ConfigTagList tags = ServerInstance->Config->ConfTags("title");
122                 CustomVhostMap newtitles;
123                 for (ConfigIter i = tags.first; i != tags.second; ++i)
124                 {
125                         reference<ConfigTag> tag = i->second;
126                         std::string name = tag->getString("name", "", 1);
127                         if (name.empty())
128                                 throw ModuleException("<title:name> is empty at " + tag->getTagLocation());
129
130                         std::string pass = tag->getString("password");
131                         if (pass.empty())
132                                 throw ModuleException("<title:password> is empty at " + tag->getTagLocation());
133
134                         std::string hash = tag->getString("hash");
135                         std::string host = tag->getString("host", "*@*");
136                         std::string title = tag->getString("title");
137                         std::string vhost = tag->getString("vhost");
138                         CustomTitle config(name, pass, hash, host, title, vhost);
139                         newtitles.insert(std::make_pair(name, config));
140                 }
141                 cmd.configs.swap(newtitles);
142         }
143
144         // :kenny.chatspike.net 320 Brain Azhrarn :is getting paid to play games.
145         ModResult OnWhoisLine(Whois::Context& whois, Numeric::Numeric& numeric) CXX11_OVERRIDE
146         {
147                 /* We use this and not OnWhois because this triggers for remote, too */
148                 if (numeric.GetNumeric() == 312)
149                 {
150                         /* Insert our numeric before 312 */
151                         const std::string* ctitle = cmd.ctitle.get(whois.GetTarget());
152                         if (ctitle)
153                         {
154                                 whois.SendLine(RPL_WHOISSPECIAL, ctitle);
155                         }
156                 }
157                 /* Don't block anything */
158                 return MOD_RES_PASSTHRU;
159         }
160
161         Version GetVersion() CXX11_OVERRIDE
162         {
163                 return Version("Custom title for users", VF_OPTCOMMON | VF_VENDOR);
164         }
165 };
166
167 MODULE_INIT(ModuleCustomTitle)