ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/nickserv/register.C
Revision: 1.11
Committed: Sat Sep 22 14:27:28 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +5 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * register.C: This file contains code for the NickServ REGISTER function.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Copyright © 2005 William Pitcock, et al.
10 * Rights to this code are as documented in doc/pod/license.pod.
11 *
12 * $Id: register.C,v 1.10 2007-09-16 18:54:43 pippijn Exp $
13 */
14
15 #include "atheme.h"
16 #include <util/numeric.h>
17 #include <libermyth.h>
18 #include <ermyth/module.h>
19 #include <account/mynick.h>
20 #include <account/myuser.h>
21 #include <boost/foreach.hpp>
22
23 static char const rcsid[] = "$Id: register.C,v 1.10 2007-09-16 18:54:43 pippijn Exp $";
24
25 REGISTER_MODULE ("nickserv/register", false, "The Ermyth Team <http://ermyth.xinutec.org>");
26
27 static void ns_cmd_register (sourceinfo_t *si, int parc, char *parv[]);
28
29 command_t const ns_register = { "REGISTER", N_("Registers a nickname."), AC_NONE, 3, ns_cmd_register };
30
31 E cmdvec ns_cmdtree;
32 E helpvec ns_helptree;
33
34 static unsigned tcnt = 0;
35
36 static void
37 ns_cmd_register (sourceinfo_t *si, int parc, char *parv[])
38 {
39 myuser_t *mu;
40 myuser_t *tmu;
41 mynick_t *mn;
42 char *account;
43 char *pass = parv[0];
44 char *email = parv[1];
45 char lau[BUFSIZE], lao[BUFSIZE];
46
47 if (si->smu)
48 {
49 command_fail (si, fault::already_authed, _("You are already logged in."));
50 return;
51 }
52
53 if (nicksvs.no_nick_ownership || si->su == NULL)
54 account = parv[0], pass = parv[1], email = parv[2];
55 else
56 account = si->su->nick, pass = parv[0], email = parv[1];
57
58 if (!account || !pass || !email)
59 {
60 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "REGISTER");
61 if (nicksvs.no_nick_ownership || si->su == NULL)
62 command_fail (si, fault::needmoreparams, _("Syntax: REGISTER <account> <password> <email>"));
63 else
64 command_fail (si, fault::needmoreparams, _("Syntax: REGISTER <password> <email>"));
65 return;
66 }
67
68 if ((strlen (pass) > 32) || (strlen (email) >= EMAILLEN))
69 {
70 command_fail (si, fault::badparams, STR_INVALID_PARAMS, "REGISTER");
71 return;
72 }
73
74 if (!nicksvs.no_nick_ownership && si->su == NULL && user_find_named (account))
75 {
76 command_fail (si, fault::noprivs, _("A user matching this account is already on IRC."));
77 return;
78 }
79
80 if (!nicksvs.no_nick_ownership && IsDigit (*account))
81 {
82 command_fail (si, fault::badparams, _("For security reasons, you can't register your UID."));
83 command_fail (si, fault::badparams, _("Please change to a real nickname, and try again."));
84 return;
85 }
86
87 if (nicksvs.no_nick_ownership || si->su == NULL)
88 {
89 if (strchr (account, ' ') || strchr (account, '\n') || strchr (account, '\r') || account[0] == '=' || account[0] == '#' || account[0] == '@' || account[0] == '+' || account[0] == '%' || account[0] == '!' || strchr (account, ','))
90 {
91 command_fail (si, fault::badparams, _("The account name \2%s\2 is invalid."), account);
92 return;
93 }
94 }
95
96 if ((si->su != NULL && !strcasecmp (pass, si->su->nick)) || !strcasecmp (pass, account))
97 {
98 command_fail (si, fault::badparams, _("You cannot use your nickname as a password."));
99 if (nicksvs.no_nick_ownership || si->su == NULL)
100 command_fail (si, fault::needmoreparams, _("Syntax: REGISTER <account> <password> <email>"));
101 else
102 command_fail (si, fault::needmoreparams, _("Syntax: REGISTER <password> <email>"));
103 return;
104 }
105
106 if (!validemail (email))
107 {
108 command_fail (si, fault::badparams, _("\2%s\2 is not a valid email address."), email);
109 return;
110 }
111
112 /* make sure it isn't registered already */
113 if (nicksvs.no_nick_ownership ? myuser_t::find (account) != NULL : mynick_t::find (account) != NULL)
114 {
115 command_fail (si, fault::alreadyexists, _("\2%s\2 is already registered."), account);
116 return;
117 }
118
119 if (!user_t::callback.can_register (si, account, email))
120 return;
121
122 /* make sure they're within limits */
123 tcnt = 0;
124 foreach (myuser_t::pair_type &mupair, myuser_t::map)
125 {
126 tmu = mupair.second;
127
128 if (!strcasecmp (email, tmu->email))
129 tcnt++;
130
131 /* optimization: if tcnt >= me.maxusers, quit iterating. -nenolod */
132 if (tcnt >= me.maxusers)
133 break;
134 }
135
136 if (tcnt >= me.maxusers)
137 {
138 command_fail (si, fault::toomany, _("\2%s\2 has too many nicknames registered."), email);
139 return;
140 }
141
142 mu = myuser_t::create (account, pass, email, config_options.defuflags | MU_NOBURSTLOGIN);
143 mu->registered = NOW;
144 mu->lastlogin = NOW;
145 if (!nicksvs.no_nick_ownership)
146 {
147 mn = mynick_t::create (mu, mu->name);
148 mn->registered = NOW;
149 mn->lastseen = NOW;
150 }
151
152 if (me.auth == AUTH_EMAIL)
153 {
154 char *key = gen_pw (12);
155 mu->flags |= MU_WAITAUTH;
156
157 mu->add_metadata ("private:verify:register:key", key);
158 mu->add_metadata ("private:verify:register:timestamp", itoa (NOW));
159
160 if (!sendemail (si->su != NULL ? si->su : si->service->me, EMAIL_REGISTER, mu, key))
161 {
162 command_fail (si, fault::emailfail, _("Sending email failed, sorry! Registration aborted."));
163 mu->refcnt_dec ();
164 sfree (key);
165 return;
166 }
167
168 command_success_nodata (si, _("An email containing nickname activation instructions has been sent to \2%s\2."), mu->email);
169 command_success_nodata (si, _("If you do not complete registration within one day, your nickname will expire."));
170
171 sfree (key);
172 }
173
174 if (si->su != NULL)
175 {
176 si->su->myuser = mu;
177 mu->logins.insert (si->su);
178
179 if (!(mu->flags & MU_WAITAUTH))
180 /* only grant ircd registered status if it's verified */
181 phandler->ircd_on_login (si->su->nick, mu->name, NULL);
182 }
183
184 if (!nicksvs.no_nick_ownership && si->su != NULL)
185 snoop ("REGISTER: \2%s\2 to \2%s\2", account, email);
186 else
187 snoop ("REGISTER: \2%s\2 to \2%s\2 by \2%s\2", account, email, si->su != NULL ? si->su->nick : get_source_name (si));
188 logcommand (si, CMDLOG_REGISTER, "REGISTER to %s", email);
189 if (is_soper (mu))
190 {
191 wallops ("%s registered the nick \2%s\2 and gained services operator privileges.", get_oper_name (si), mu->name);
192 snoop ("SOPER: \2%s\2 as \2%s\2", get_oper_name (si), mu->name);
193 }
194
195 command_success_nodata (si, _("\2%s\2 is now registered to \2%s\2."), mu->name, mu->email);
196 command_success_nodata (si, _("The password is \2%s\2. Please write this down for future reference."), pass);
197 mu->callback.registered (mu);
198
199 if (si->su != NULL)
200 {
201 snprintf (lau, BUFSIZE, "%s@%s", si->su->user, si->su->vhost);
202 mu->add_metadata ("private:host:vhost", lau);
203
204 snprintf (lao, BUFSIZE, "%s@%s", si->su->user, si->su->host);
205 mu->add_metadata ("private:host:actual", lao);
206 }
207 }
208
209 bool
210 _modinit (module *m)
211 {
212 ns_cmdtree << ns_register;
213 help_addentry (ns_helptree, "REGISTER", "help/nickserv/register", NULL);
214
215 return true;
216 }
217
218 void
219 _moddeinit ()
220 {
221 ns_cmdtree >> ns_register;
222 help_delentry (ns_helptree, "REGISTER");
223 }