static int hs_do_request(User * u) { char *cur_buffer; char *nick; char *rawhostmask; char hostmask[HOSTMAX]; NickAlias *na; int32 tmp_time; char *s; char *vIdent = NULL; time_t now = time(NULL); cur_buffer = moduleGetLastBuffer(); nick = u->nick; rawhostmask = myStrGetToken(cur_buffer, ' ', 0); if (!nick || !rawhostmask) { if (rawhostmask) free(rawhostmask); moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); return MOD_CONT; } vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */ if (vIdent) { rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */ if (!rawhostmask) { moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); free(vIdent); return MOD_CONT; } if (strlen(vIdent) > USERMAX - 1) { notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX); free(vIdent); free(rawhostmask); return MOD_CONT; } else { for (s = vIdent; *s; s++) { if (!my_isvalidchar(*s)) { notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR); free(vIdent); free(rawhostmask); return MOD_CONT; } } } if (!ircd->vident) { notice_lang(s_HostServ, u, HOST_NO_VIDENT); free(vIdent); free(rawhostmask); return MOD_CONT; } } if (strlen(rawhostmask) < HOSTMAX) { snprintf(hostmask, HOSTMAX, "%s", rawhostmask); } else { notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX); if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } if (!isValidHost(hostmask, 3)) { notice_lang(s_HostServ, u, HOST_SET_ERROR); if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } tmp_time = time(NULL); if ((na = findnick(nick))) { if (HSRequestMemoOper || HSRequestMemoSetters) { if (MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now) { moduleNoticeLang(s_HostServ, u, LNG_REQUEST_WAIT, MSSendDelay); u->lastmemosend = now; if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } } my_add_host_request(nick, vIdent, hostmask, u->nick, tmp_time); moduleNoticeLang(s_HostServ, u, LNG_REQUESTED); req_send_memos(u, hostmask); alog("New vHost Requested by %s", nick); } else { notice_lang(s_HostServ, u, HOST_NOREG, nick); } if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } User *u = source.GetUser(); NickServ::Nick *na = NickServ::FindNick(source.GetNick()); if (!na || na->GetAccount() != source.GetAccount()) { source.Reply(_("Access denied.")); //XXX with nonickownership this should be allowed. return; } if (source.GetAccount()->HasFieldS("UNCONFIRMED")) { source.Reply(_("You must confirm your account before you may request a vhost.")); return; } Anope::string rawhostmask = params[0]; Anope::string user, host; size_t a = rawhostmask.find('@'); if (a == Anope::string::npos) host = rawhostmask; else { user = rawhostmask.substr(0, a); host = rawhostmask.substr(a + 1); } if (host.empty()) { this->OnSyntaxError(source, ""); return; } if (!user.empty()) { if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) { source.Reply(_("The username \002{0}\002 is too long, please use a username shorter than %d characters."), Config->GetBlock("networkinfo")->Get<unsigned>("userlen")); return; } if (!IRCD->CanSetVIdent) { source.Reply(_("Vhosts may not contain a username.")); return; } if (!IRCD->IsIdentValid(user)) { source.Reply(_("The requested username is not valid.")); return; } } if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { source.Reply(_("The requested vhost is too long, please use a hostname no longer than {0} characters."), Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } if (!IRCD->IsHostValid(host)) { source.Reply(_("The requested hostname is not valid.")); return; } time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime) { source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay); u->lastmemosend = Anope::CurTime; return; } HostRequest *req = hostrequest.Create(); req->SetNick(na); req->SetIdent(user); req->SetHost(host); req->SetTime(Anope::CurTime); source.Reply(_("Your vhost has been requested.")); req_send_memos(owner, source, user, host); Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host; }