ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/nickserv/register.C
Revision: 1.1
Committed: Thu Jul 19 08:24:54 2007 UTC (19 years, 2 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Log Message:
initial import. the most important changes since Atheme are:
- fixed many memory leaks
- fixed many bugs
- converted to C++ and use more STL containers
- added a (not very enhanced yet) perl module
- greatly improved XML-RPC speed
- added a JSON-RPC module with code from json-cpp
- added a valgrind memcheck module to operserv
- added a more object oriented base64 implementation
- added a specialised unit test framework
- improved stability
- use gettimeofday() if available
- reworked adding/removing commands
- MemoServ IGNORE DEL can now remove indices

File Contents

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