ns_register.c

Go to the documentation of this file.
00001 /* NickServ core functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: ns_register.c 1277 2007-08-27 22:31:45Z drstein $
00012  *
00013  */
00014 /*************************************************************************/
00015 
00016 #include "module.h"
00017 #include "encrypt.h"
00018 
00019 int do_confirm(User * u);
00020 int do_register(User * u);
00021 int do_resend(User * u);
00022 void myNickServHelp(User * u);
00023 NickRequest *makerequest(const char *nick);
00024 NickAlias *makenick(const char *nick);
00025 int do_sendregmail(User * u, NickRequest * nr);
00026 int ns_do_register(User * u);
00027 
00034 int AnopeInit(int argc, char **argv)
00035 {
00036     Command *c;
00037 
00038     moduleAddAuthor("Anope");
00039     moduleAddVersion("$Id: ns_register.c 1277 2007-08-27 22:31:45Z drstein $");
00040     moduleSetType(CORE);
00041 
00042     c = createCommand("REGISTER", do_register, NULL, NICK_HELP_REGISTER,
00043                       -1, -1, -1, -1);
00044     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00045 
00046     c = createCommand("CONFIRM", do_confirm, NULL, NICK_HELP_CONFIRM, -1, -1, -1, -1);
00047     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00048 
00049     c = createCommand("RESEND", do_resend, NULL, -1, -1, -1, -1, -1);
00050     moduleAddCommand(NICKSERV, c, MOD_UNIQUE);
00051 
00052 
00053     moduleSetNickHelp(myNickServHelp);
00054 
00055     return MOD_CONT;
00056 }
00057 
00061 void AnopeFini(void)
00062 {
00063 
00064 }
00065 
00066 
00067 
00072 void myNickServHelp(User * u)
00073 {
00074     notice_lang(s_NickServ, u, NICK_HELP_CMD_REGISTER);
00075     if (NSEmailReg) {
00076         notice_lang(s_NickServ, u, NICK_HELP_CMD_CONFIRM);
00077         notice_lang(s_NickServ, u, NICK_HELP_CMD_RESEND);
00078     }
00079 }
00080 
00086 int do_register(User * u)
00087 {
00088     NickRequest *nr = NULL, *anr = NULL;
00089     NickCore *nc = NULL;
00090     int prefixlen = strlen(NSGuestNickPrefix);
00091     int nicklen = strlen(u->nick);
00092     char *pass = strtok(NULL, " ");
00093     char *email = strtok(NULL, " ");
00094     char passcode[11];
00095     int idx, min = 1, max = 62, i = 0;
00096     int chars[] =
00097         { ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
00098         'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
00099         'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
00100         'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
00101         'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
00102     };
00103 
00104     if (readonly) {
00105         notice_lang(s_NickServ, u, NICK_REGISTRATION_DISABLED);
00106         return MOD_CONT;
00107     }
00108 
00109     if (checkDefCon(DEFCON_NO_NEW_NICKS)) {
00110         notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
00111         return MOD_CONT;
00112     }
00113 
00114     if (!is_oper(u) && NickRegDelay
00115         && ((time(NULL) - u->my_signon) < NickRegDelay)) {
00116         notice_lang(s_NickServ, u, NICK_REG_DELAY, NickRegDelay);
00117         return MOD_CONT;
00118     }
00119 
00120     if ((anr = findrequestnick(u->nick))) {
00121         notice_lang(s_NickServ, u, NICK_REQUESTED);
00122         return MOD_CONT;
00123     }
00124     /* Prevent "Guest" nicks from being registered. -TheShadow */
00125 
00126     /* Guest nick can now have a series of between 1 and 7 digits.
00127      *      --lara
00128      */
00129     if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 &&
00130         stristr(u->nick, NSGuestNickPrefix) == u->nick &&
00131         strspn(u->nick + prefixlen, "1234567890") == nicklen - prefixlen) {
00132         notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick);
00133         return MOD_CONT;
00134     }
00135 
00136     if (!anope_valid_nick(u->nick)) {
00137         notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick);
00138         return MOD_CONT;
00139     }
00140 
00141     if (RestrictOperNicks) {
00142         for (i = 0; i < RootNumber; i++) {
00143             if (stristr(u->nick, ServicesRoots[i]) && !is_oper(u)) {
00144                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00145                             u->nick);
00146                 return MOD_CONT;
00147             }
00148         }
00149         for (i = 0; i < servadmins.count && (nc = servadmins.list[i]); i++) {
00150             if (stristr(u->nick, nc->display) && !is_oper(u)) {
00151                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00152                             u->nick);
00153                 return MOD_CONT;
00154             }
00155         }
00156         for (i = 0; i < servopers.count && (nc = servopers.list[i]); i++) {
00157             if (stristr(u->nick, nc->display) && !is_oper(u)) {
00158                 notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED,
00159                             u->nick);
00160                 return MOD_CONT;
00161             }
00162         }
00163     }
00164 
00165     if (!pass) {
00166         if (NSForceEmail) {
00167             syntax_error(s_NickServ, u, "REGISTER",
00168                          NICK_REGISTER_SYNTAX_EMAIL);
00169         } else {
00170             syntax_error(s_NickServ, u, "REGISTER", NICK_REGISTER_SYNTAX);
00171         }
00172     } else if (NSForceEmail && !email) {
00173         syntax_error(s_NickServ, u, "REGISTER",
00174                      NICK_REGISTER_SYNTAX_EMAIL);
00175     } else if (time(NULL) < u->lastnickreg + NSRegDelay) {
00176         notice_lang(s_NickServ, u, NICK_REG_PLEASE_WAIT, NSRegDelay);
00177     } else if (u->na) {         /* i.e. there's already such a nick regged */
00178         if (u->na->status & NS_VERBOTEN) {
00179             alog("%s: %s@%s tried to register FORBIDden nick %s",
00180                  s_NickServ, u->username, u->host, u->nick);
00181             notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick);
00182         } else {
00183             notice_lang(s_NickServ, u, NICK_ALREADY_REGISTERED, u->nick);
00184         }
00185     } else if (stricmp(u->nick, pass) == 0
00186                || (StrictPasswords && strlen(pass) < 5)) {
00187         notice_lang(s_NickServ, u, MORE_OBSCURE_PASSWORD);
00188     } else if (email && !MailValidate(email)) {
00189         notice_lang(s_NickServ, u, MAIL_X_INVALID, email);
00190     } else {
00191         if (strlen(pass) > PASSMAX) {
00192             pass[PASSMAX] = 0;
00193             notice_lang(s_NickServ, u, PASSWORD_TRUNCATED, PASSMAX);
00194         }
00195         for (idx = 0; idx < 9; idx++) {
00196             passcode[idx] =
00197                 chars[(1 +
00198                        (int) (((float) (max - min)) * getrandom16() /
00199                               (65535 + 1.0)) + min)];
00200         } passcode[idx] = '\0';
00201         nr = makerequest(u->nick);
00202         nr->passcode = sstrdup(passcode);
00203         nr->password = sstrdup(pass);
00204         if (email) {
00205             nr->email = sstrdup(email);
00206         }
00207         nr->requested = time(NULL);
00208         if (NSEmailReg) {
00209             if (do_sendregmail(u, nr) == 0) {
00210                 notice_lang(s_NickServ, u, NICK_ENTER_REG_CODE, email,
00211                             s_NickServ);
00212                 alog("%s: sent registration verification code to %s",
00213                      s_NickServ, nr->email);
00214             } else {
00215                 alog("%s: Unable to send registration verification mail",
00216                      s_NickServ);
00217                 notice_lang(s_NickServ, u, NICK_REG_UNABLE);
00218                 delnickrequest(nr);     /* Delete the NickRequest if we couldnt send the mail */
00219                 return MOD_CONT;
00220             }
00221         } else {
00222             do_confirm(u);
00223         }
00224 
00225     }
00226     return MOD_CONT;
00227 }
00228 
00229 /*************************************************************************/
00230 
00231 int ns_do_register(User * u)
00232 {
00233     return do_register(u);
00234 }
00235 
00236 
00237 int do_confirm(User * u)
00238 {
00239 
00240     NickRequest *nr = NULL;
00241     NickAlias *na = NULL;
00242     char *passcode = strtok(NULL, " ");
00243     char *pass = NULL;
00244     char *email = NULL;
00245     int forced = 0;
00246     User *utmp = NULL;
00247     char modes[512];
00248     int len;
00249 
00250     nr = findrequestnick(u->nick);
00251 
00252     if (NSEmailReg) {
00253         if (!passcode) {
00254             notice_lang(s_NickServ, u, NICK_CONFIRM_INVALID);
00255             return MOD_CONT;
00256         }
00257 
00258         if (!nr) {
00259             if (is_services_admin(u)) {
00260 /* If an admin, thier nick is obviously already regged, so look at the passcode to get the nick
00261    of the user they are trying to validate, and push that user through regardless of passcode */
00262                 nr = findrequestnick(passcode);
00263                 if (nr) {
00264                     utmp = finduser(passcode);
00265                     if (utmp) {
00266                         sprintf(passcode,
00267                                 "FORCE_ACTIVATION_DUE_TO_OPER_CONFIRM %s",
00268                                 nr->passcode);
00269                         passcode = strtok(passcode, " ");
00270                         notice_lang(s_NickServ, u, NICK_FORCE_REG,
00271                                     nr->nick);
00272                         do_confirm(utmp);
00273                         return MOD_CONT;
00274                     } else {
00275                         passcode = sstrdup(nr->passcode);
00276                         forced = 1;
00277                     }
00278                 } else {
00279                     notice_lang(s_NickServ, u, NICK_CONFIRM_NOT_FOUND,
00280                                 s_NickServ);
00281                     return MOD_CONT;
00282                 }
00283             } else {
00284                 notice_lang(s_NickServ, u, NICK_CONFIRM_NOT_FOUND,
00285                             s_NickServ);
00286                 return MOD_CONT;
00287             }
00288         }
00289 
00290         if (stricmp(nr->passcode, passcode) != 0) {
00291             notice_lang(s_NickServ, u, NICK_CONFIRM_INVALID);
00292             return MOD_CONT;
00293         }
00294     }
00295 
00296     if (!nr) {
00297         notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);
00298         return MOD_CONT;
00299     }
00300     pass = sstrdup(nr->password);
00301 
00302     if (nr->email) {
00303         email = sstrdup(nr->email);
00304     }
00305     na = makenick(nr->nick);
00306 
00307     if (na) {
00308         int i;
00309         char tsbuf[16];
00310     char tmp_pass[PASSMAX];
00311 
00312         len = strlen(pass);
00313         na->nc->pass = smalloc(PASSMAX);
00314         if (enc_encrypt(pass, len, na->nc->pass, PASSMAX) < 0) {
00315             memset(pass, 0, strlen(pass));
00316             alog("%s: Failed to encrypt password for %s (register)",
00317                  s_NickServ, nr->nick);
00318             notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);
00319             return MOD_CONT;
00320         }
00321         memset(pass, 0, strlen(pass));
00322         na->status = (int16) (NS_IDENTIFIED | NS_RECOGNIZED);
00323 /*        na->nc->flags |= NI_ENCRYPTEDPW; */
00324 
00325         na->nc->flags |= NSDefFlags;
00326         for (i = 0; i < RootNumber; i++) {
00327             if (!stricmp(ServicesRoots[i], nr->nick)) {
00328                 na->nc->flags |= NI_SERVICES_ROOT;
00329                 break;
00330             }
00331         }
00332         na->nc->memos.memomax = MSMaxMemos;
00333         na->nc->channelmax = CSMaxReg;
00334         if (forced == 1) {
00335             na->last_usermask = sstrdup("*@*");
00336             na->last_realname = sstrdup("unknown");
00337         } else {
00338             na->last_usermask =
00339                 scalloc(strlen(common_get_vident(u)) +
00340                         strlen(common_get_vhost(u)) + 2, 1);
00341             sprintf(na->last_usermask, "%s@%s", common_get_vident(u),
00342                     common_get_vhost(u));
00343             na->last_realname = sstrdup(u->realname);
00344         }
00345         na->time_registered = na->last_seen = time(NULL);
00346         if (NSAddAccessOnReg) {
00347             na->nc->accesscount = 1;
00348             na->nc->access = scalloc(sizeof(char *), 1);
00349             na->nc->access[0] = create_mask(u);
00350         } else {
00351             na->nc->accesscount = 0;
00352             na->nc->access = NULL;
00353         }
00354         na->nc->language = NSDefLanguage;
00355         if (email)
00356             na->nc->email = sstrdup(email);
00357         if (forced != 1) {
00358             u->na = na;
00359             na->u = u;
00360             alog("%s: '%s' registered by %s@%s (e-mail: %s)", s_NickServ,
00361                  u->nick, u->username, u->host, (email ? email : "none"));
00362             if (NSAddAccessOnReg)
00363                 notice_lang(s_NickServ, u, NICK_REGISTERED, u->nick,
00364                             na->nc->access[0]);
00365             else
00366                 notice_lang(s_NickServ, u, NICK_REGISTERED_NO_MASK,
00367                             u->nick);
00368             send_event(EVENT_NICK_REGISTERED, 1, u->nick);
00369         
00370         if(enc_decrypt(na->nc->pass,tmp_pass,PASSMAX)==1) 
00371                 notice_lang(s_NickServ, u, NICK_PASSWORD_IS, tmp_pass);
00372 
00373             u->lastnickreg = time(NULL);
00374             if (ircd->modeonreg) {
00375                 len = strlen(ircd->modeonreg);
00376                 strncpy(modes,ircd->modeonreg,512);
00377             if(ircd->rootmodeonid && is_services_root(u)) { 
00378                     strncat(modes,ircd->rootmodeonid,512-len);
00379             } else if(ircd->adminmodeonid && is_services_admin(u)) {
00380                     strncat(modes,ircd->adminmodeonid,512-len);
00381             } else if(ircd->opermodeonid && is_services_oper(u)) {
00382                     strncat(modes,ircd->opermodeonid,512-len);
00383                 }
00384 
00385                 if (ircd->tsonmode) {
00386                     snprintf(tsbuf, sizeof(tsbuf), "%lu",
00387                              (unsigned long int) u->timestamp);
00388                     common_svsmode(u, modes, tsbuf);
00389                 } else {
00390                     common_svsmode(u, modes, NULL);
00391                 }
00392             }
00393 
00394         } else {
00395             notice_lang(s_NickServ, u, NICK_FORCE_REG, nr->nick);
00396         }
00397         delnickrequest(nr);     /* remove the nick request */
00398     } else {
00399         alog("%s: makenick(%s) failed", s_NickServ, u->nick);
00400         notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED);
00401     }
00402 
00403     /* Enable nick tracking if enabled */
00404     if (NSNickTracking)
00405         nsStartNickTracking(u);
00406 
00407     return MOD_CONT;
00408 }
00409 
00410 NickRequest *makerequest(const char *nick)
00411 {
00412     NickRequest *nr;
00413 
00414     nr = scalloc(1, sizeof(NickRequest));
00415     nr->nick = sstrdup(nick);
00416     insert_requestnick(nr);
00417     alog("%s: Nick %s has been requested", s_NickServ, nr->nick);
00418     return nr;
00419 }
00420 
00421 /* Creates a full new nick (alias + core) in NickServ database. */
00422 
00423 NickAlias *makenick(const char *nick)
00424 {
00425     NickAlias *na;
00426     NickCore *nc;
00427 
00428     /* First make the core */
00429     nc = scalloc(1, sizeof(NickCore));
00430     nc->display = sstrdup(nick);
00431     slist_init(&nc->aliases);
00432     insert_core(nc);
00433     alog("%s: group %s has been created", s_NickServ, nc->display);
00434 
00435     /* Then make the alias */
00436     na = scalloc(1, sizeof(NickAlias));
00437     na->nick = sstrdup(nick);
00438     na->nc = nc;
00439     slist_add(&nc->aliases, na);
00440     alpha_insert_alias(na);
00441     return na;
00442 }
00443 
00444 /* Register a nick. */
00445 
00446 int do_resend(User * u)
00447 {
00448     NickRequest *nr = NULL;
00449     if (NSEmailReg) {
00450         if ((nr = findrequestnick(u->nick))) {
00451             if (time(NULL) < nr->lastmail + NSResendDelay) {
00452                return MOD_CONT;
00453             } else {
00454                 nr->lastmail = time(NULL);
00455             }
00456             if (do_sendregmail(u, nr) == 0) {
00457                 notice_lang(s_NickServ, u, NICK_REG_RESENT, nr->email);
00458                 alog("%s: re-sent registration verification code for %s to %s", s_NickServ, nr->nick, nr->email);
00459             } else {
00460                 alog("%s: Unable to re-send registration verification mail for %s", s_NickServ, nr->nick);
00461                 return MOD_CONT;
00462             }
00463         }
00464     }
00465     return MOD_CONT;
00466 }
00467 
00468 int do_sendregmail(User * u, NickRequest * nr)
00469 {
00470     MailInfo *mail = NULL;
00471     char buf[BUFSIZE];
00472 
00473     if (!(nr || u)) {
00474         return -1;
00475     }
00476     snprintf(buf, sizeof(buf), getstring2(NULL, NICK_REG_MAIL_SUBJECT),
00477              nr->nick);
00478     mail = MailRegBegin(u, nr, buf, s_NickServ);
00479     if (!mail) {
00480         return -1;
00481     }
00482     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_HEAD));
00483     fprintf(mail->pipe, "\n\n");
00484     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_LINE_1), nr->nick);
00485     fprintf(mail->pipe, "\n\n");
00486     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_LINE_2), s_NickServ,
00487             nr->passcode);
00488     fprintf(mail->pipe, "\n\n");
00489     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_LINE_3));
00490     fprintf(mail->pipe, "\n\n");
00491     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_LINE_4));
00492     fprintf(mail->pipe, "\n\n");
00493     fprintf(mail->pipe, getstring2(NULL, NICK_REG_MAIL_LINE_5),
00494             NetworkName);
00495     fprintf(mail->pipe, "\n.\n");
00496     MailEnd(mail);
00497     return 0;
00498 }
00499 

Generated on Sun Dec 30 09:26:47 2007 for Anope by  doxygen 1.5.1-20070107