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;
}
Exemple #2
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params) 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;
	}