X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=81f83058387fc544245ec01bbb1d4395c9da344c;hb=61197974c5f7ce009096468b208c3abf2c25810b;hp=58c1050473701b5e7c44f1f813bca41ac670129f;hpb=6fe52cbb3ba72a5ecdded3f51c8515bf75e6801f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index 58c105047..81f830583 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2009 InspIRCd Development Team + * InspIRCd: (C) 2002-2010 InspIRCd Development Team * See: http://wiki.inspircd.org/Credits * * This program is free but copyrighted software; see @@ -18,37 +18,7 @@ #include "bancache.h" #include "commands/cmd_whowas.h" -typedef unsigned int uniq_id_t; -class sent -{ - uniq_id_t uniq_id; - uniq_id_t* array; - void init() - { - if (!array) - array = new uniq_id_t[ServerInstance->SE->GetMaxFds()]; - memset(array, 0, ServerInstance->SE->GetMaxFds() * sizeof(uniq_id_t)); - uniq_id++; - } - public: - sent() : uniq_id(static_cast(-1)), array(NULL) {} - inline uniq_id_t operator++() - { - if (++uniq_id == 0) - init(); - return uniq_id; - } - inline uniq_id_t& operator[](int i) - { - return array[i]; - } - ~sent() - { - delete[] array; - } -}; - -static sent already_sent; +already_sent_t LocalUser::already_sent_id = 0; std::string User::ProcessNoticeMasks(const char *sm) { @@ -67,9 +37,9 @@ std::string User::ProcessNoticeMasks(const char *sm) adding = false; break; case '*': - for (unsigned char d = 'A'; d <= 'z'; d++) + for (unsigned char d = 'a'; d <= 'z'; d++) { - if (ServerInstance->SNO->IsEnabled(d)) + if (!ServerInstance->SNO->masks[d - 'a'].Description.empty()) { if ((!IsNoticeMaskSet(d) && adding) || (IsNoticeMaskSet(d) && !adding)) { @@ -80,12 +50,23 @@ std::string User::ProcessNoticeMasks(const char *sm) output += d; } + oldadding = adding; + char u = toupper(d); + if ((!IsNoticeMaskSet(u) && adding) || (IsNoticeMaskSet(u) && !adding)) + { + if ((oldadding != adding) || (!output.length())) + output += (adding ? '+' : '-'); + + this->SetNoticeMask(u, adding); + + output += u; + } + oldadding = adding; } - oldadding = adding; } break; default: - if ((*c >= 'A') && (*c <= 'z') && (ServerInstance->SNO->IsEnabled(*c))) + if (isalpha(*c)) { if ((!IsNoticeMaskSet(*c) && adding) || (IsNoticeMaskSet(*c) && !adding)) { @@ -104,7 +85,7 @@ std::string User::ProcessNoticeMasks(const char *sm) break; } - *c++; + c++; } std::string s = this->FormatNoticeMasks(); @@ -203,24 +184,6 @@ const char* User::FormatModes(bool showparameters) return data; } -void User::DecrementModes() -{ - ServerInstance->Logs->Log("USERS", DEBUG, "DecrementModes()"); - for (unsigned char n = 'A'; n <= 'z'; n++) - { - if (modes[n-65]) - { - ServerInstance->Logs->Log("USERS", DEBUG,"DecrementModes() found mode %c", n); - ModeHandler* mh = ServerInstance->Modes->FindMode(n, MODETYPE_USER); - if (mh) - { - ServerInstance->Logs->Log("USERS", DEBUG,"Found handler %c and call ChangeCount", n); - mh->ChangeCount(-1); - } - } - } -} - User::User(const std::string &uid, const std::string& sid, int type) : uuid(uid), server(sid), usertype(type) { @@ -239,18 +202,21 @@ User::User(const std::string &uid, const std::string& sid, int type) throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor"); } -LocalUser::LocalUser() : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL) +LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr) + : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this), + bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0), + already_sent(0) { - bytes_in = bytes_out = cmds_in = cmds_out = 0; - server_sa.sa.sa_family = AF_UNSPEC; - Penalty = 0; - lastping = nping = 0; + lastping = 0; + eh.SetFd(myfd); + memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs)); + memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs)); } User::~User() { if (ServerInstance->Users->uuidlist->find(uuid) != ServerInstance->Users->uuidlist->end()) - ServerInstance->Logs->Log("USERS", ERROR, "User destructor for %s called without cull", uuid.c_str()); + ServerInstance->Logs->Log("USERS", DEFAULT, "User destructor for %s called without cull", uuid.c_str()); } const std::string& User::MakeHost() @@ -491,29 +457,25 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy) return false; } -void User::OnDataReady() +void UserIOHandler::OnDataReady() { -} - -void LocalUser::OnDataReady() -{ - if (quitting) + if (user->quitting) return; - if (recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (recvq.length() > user->MyClass->GetRecvqMax() && !user->HasPrivPermission("users/flood/increased-buffers")) { - ServerInstance->Users->QuitUser(this, "RecvQ exceeded"); + ServerInstance->Users->QuitUser(user, "RecvQ exceeded"); ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu", - nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax()); + user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax()); } unsigned long sendqmax = ULONG_MAX; - if (!HasPrivPermission("users/flood/increased-buffers")) - sendqmax = MyClass->GetSendqSoftMax(); - int penaltymax = MyClass->GetPenaltyThreshold(); - if (penaltymax == 0 || HasPrivPermission("users/flood/no-fakelag")) - penaltymax = INT_MAX; + if (!user->HasPrivPermission("users/flood/increased-buffers")) + sendqmax = user->MyClass->GetSendqSoftMax(); + unsigned long penaltymax = ULONG_MAX; + if (!user->HasPrivPermission("users/flood/no-fakelag")) + penaltymax = user->MyClass->GetPenaltyThreshold() * 1000; - while (Penalty < penaltymax && getSendQSize() < sendqmax) + while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax) { std::string line; line.reserve(MAXBUF); @@ -542,29 +504,32 @@ eol_found: // TODO should this be moved to when it was inserted in recvq? ServerInstance->stats->statsRecv += qpos; - this->bytes_in += qpos; - this->cmds_in++; + user->bytes_in += qpos; + user->cmds_in++; - ServerInstance->Parser->ProcessBuffer(line, this); - if (quitting) + ServerInstance->Parser->ProcessBuffer(line, user); + if (user->quitting) return; } // Add pseudo-penalty so that we continue processing after sendq recedes - if (Penalty == 0 && getSendQSize() >= sendqmax) - Penalty++; + if (user->CommandFloodPenalty == 0 && getSendQSize() >= sendqmax) + user->CommandFloodPenalty++; + if (user->CommandFloodPenalty >= penaltymax && !user->MyClass->fakelag) + ServerInstance->Users->QuitUser(user, "Excess Flood"); } -void LocalUser::AddWriteBuf(const std::string &data) +void UserIOHandler::AddWriteBuf(const std::string &data) { - if (!quitting && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (!user->quitting && getSendQSize() + data.length() > user->MyClass->GetSendqHardMax() && + !user->HasPrivPermission("users/flood/increased-buffers")) { /* * Quit the user FIRST, because otherwise we could recurse * here and hit the same limit. */ - ServerInstance->Users->QuitUser(this, "SendQ exceeded"); + ServerInstance->Users->QuitUser(user, "SendQ exceeded"); ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ exceeds connect class maximum of %lu", - nick.c_str(), MyClass->GetSendqHardMax()); + user->nick.c_str(), user->MyClass->GetSendqHardMax()); return; } @@ -574,9 +539,9 @@ void LocalUser::AddWriteBuf(const std::string &data) WriteData(data); } -void User::OnError(BufferedSocketError) +void UserIOHandler::OnError(BufferedSocketError) { - ServerInstance->Users->QuitUser(this, getError()); + ServerInstance->Users->QuitUser(user, getError()); } CullResult User::cull() @@ -586,9 +551,10 @@ CullResult User::cull() PurgeEmptyChannels(); this->InvalidateCache(); - this->DecrementModes(); - ServerInstance->Users->uuidlist->erase(uuid); + if (client_sa.sa.sa_family != AF_UNSPEC) + ServerInstance->Users->RemoveCloneCounts(this); + return Extensible::cull(); } @@ -600,9 +566,7 @@ CullResult LocalUser::cull() else ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); - if (client_sa.sa.sa_family != AF_UNSPEC) - ServerInstance->Users->RemoveCloneCounts(this); - Close(); + eh.cull(); return User::cull(); } @@ -610,6 +574,8 @@ CullResult FakeUser::cull() { // Fake users don't quit, they just get culled. quitting = true; + ServerInstance->Users->clientlist->erase(nick); + ServerInstance->Users->uuidlist->erase(uuid); return User::cull(); } @@ -635,10 +601,7 @@ void User::Oper(OperInfo* info) l->ChangeDisplayedHost(vhost.c_str()); std::string opClass = oper->getConfig("class"); if (!opClass.empty()) - { l->SetClass(opClass); - l->CheckClass(); - } } ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')", @@ -767,7 +730,7 @@ void LocalUser::CheckClass() } else if (a->type == CC_DENY) { - ServerInstance->Users->QuitUser(this, "Unauthorised connection"); + ServerInstance->Users->QuitUser(this, a->config->getString("reason", "Unauthorised connection")); return; } else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal())) @@ -818,21 +781,11 @@ void LocalUser::FullConnect() * may put the user into a totally seperate class with different restrictions! so we *must* check again. * Don't remove this! -- w00t */ - this->SetClass(); + SetClass(); + CheckClass(); + CheckLines(); - /* Check the password, if one is required by the user's connect class. - * This CANNOT be in CheckClass(), because that is called prior to PASS as well! - */ - if (!MyClass->pass.empty()) - { - if (ServerInstance->PassCompare(this, MyClass->pass.c_str(), password.c_str(), MyClass->hash.c_str())) - { - ServerInstance->Users->QuitUser(this, "Invalid password"); - return; - } - } - - if (this->CheckLines()) + if (quitting) return; this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network.c_str()); @@ -844,18 +797,21 @@ void LocalUser::FullConnect() ServerInstance->Config->Send005(this); this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str()); - - this->ShowMOTD(); - /* Now registered */ if (ServerInstance->Users->unregistered_count) ServerInstance->Users->unregistered_count--; - /* Trigger LUSERS output, give modules a chance too */ + /* Trigger MOTD and LUSERS output, give modules a chance too */ ModResult MOD_RESULT; - std::string command("LUSERS"); + std::string command("MOTD"); std::vector parameters; - FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true, "LUSERS")); + FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true, command)); + if (!MOD_RESULT) + ServerInstance->CallCommandHandler(command, parameters, this); + + MOD_RESULT = MOD_RES_PASSTHRU; + command = "LUSERS"; + FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true, command)); if (!MOD_RESULT) ServerInstance->CallCommandHandler(command, parameters, this); @@ -875,27 +831,6 @@ void LocalUser::FullConnect() ServerInstance->BanCache->AddHit(this->GetIPString(), "", ""); } -/** User::UpdateNick() - * re-allocates a nick in the user_hash after they change nicknames, - * returns a pointer to the new user as it may have moved - */ -User* User::UpdateNickHash(const char* New) -{ - //user_hash::iterator newnick; - user_hash::iterator oldnick = ServerInstance->Users->clientlist->find(this->nick); - - if (!irc::string(this->nick.c_str()).compare(New)) - return oldnick->second; - - if (oldnick == ServerInstance->Users->clientlist->end()) - return NULL; /* doesnt exist */ - - User* olduser = oldnick->second; - ServerInstance->Users->clientlist->erase(oldnick); - (*(ServerInstance->Users->clientlist))[New] = olduser; - return olduser; -} - void User::InvalidateCache() { /* Invalidate cache */ @@ -905,13 +840,12 @@ void User::InvalidateCache() cached_fullrealhost.clear(); } -bool User::ForceNickChange(const char* newnick) +bool User::ChangeNick(const std::string& newnick, bool force) { ModResult MOD_RESULT; - this->InvalidateCache(); - - ServerInstance->NICKForced.set(this, 1); + if (force) + ServerInstance->NICKForced.set(this, 1); FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick)); ServerInstance->NICKForced.set(this, 0); @@ -921,20 +855,98 @@ bool User::ForceNickChange(const char* newnick) return false; } - std::deque dummy; - Command* nickhandler = ServerInstance->Parser->GetHandler("NICK"); - if (nickhandler) // wtfbbq, when would this not be here + if (assign(newnick) == assign(nick)) { - std::vector parameters; - parameters.push_back(newnick); - ServerInstance->NICKForced.set(this, 1); - bool result = (ServerInstance->Parser->CallHandler("NICK", parameters, this) == CMD_SUCCESS); - ServerInstance->NICKForced.set(this, 0); - return result; + // case change, don't need to check Q:lines and such + // and, if it's identical including case, we can leave right now + if (newnick == nick) + return true; } + else + { + /* + * Don't check Q:Lines if it's a server-enforced change, just on the off-chance some fucking *moron* + * tries to Q:Line SIDs, also, this means we just get our way period, as it really should be. + * Thanks Kein for finding this. -- w00t + * + * Also don't check Q:Lines for remote nickchanges, they should have our Q:Lines anyway to enforce themselves. + * -- w00t + */ + if (IS_LOCAL(this) && !force) + { + XLine* mq = ServerInstance->XLines->MatchesLine("Q",newnick); + if (mq) + { + if (this->registered == REG_ALL) + { + ServerInstance->SNO->WriteGlobalSno('a', "Q-Lined nickname %s from %s!%s@%s: %s", + newnick.c_str(), this->nick.c_str(), this->ident.c_str(), this->host.c_str(), mq->reason.c_str()); + } + this->WriteNumeric(432, "%s %s :Invalid nickname: %s",this->nick.c_str(), newnick.c_str(), mq->reason.c_str()); + return false; + } - // Unreachable, we hope - return false; + if (ServerInstance->Config->RestrictBannedUsers) + { + for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) + { + Channel *chan = *i; + if (chan->GetPrefixValue(this) < VOICE_VALUE && chan->IsBanned(this)) + { + this->WriteNumeric(404, "%s %s :Cannot send to channel (you're banned)", this->nick.c_str(), chan->name.c_str()); + return false; + } + } + } + } + + /* + * Uh oh.. if the nickname is in use, and it's not in use by the person using it (doh) -- + * then we have a potential collide. Check whether someone else is camping on the nick + * (i.e. connect -> send NICK, don't send USER.) If they are camping, force-change the + * camper to their UID, and allow the incoming nick change. + * + * If the guy using the nick is already using it, tell the incoming nick change to gtfo, + * because the nick is already (rightfully) in use. -- w00t + */ + User* InUse = ServerInstance->FindNickOnly(newnick); + if (InUse && (InUse != this)) + { + if (InUse->registered != REG_ALL) + { + /* force the camper to their UUID, and ask them to re-send a NICK. */ + InUse->WriteTo(InUse, "NICK %s", InUse->uuid.c_str()); + InUse->WriteNumeric(433, "%s %s :Nickname overruled.", InUse->nick.c_str(), InUse->nick.c_str()); + + ServerInstance->Users->clientlist->erase(InUse->nick); + (*(ServerInstance->Users->clientlist))[InUse->uuid] = InUse; + + InUse->nick = InUse->uuid; + InUse->InvalidateCache(); + InUse->registered &= ~REG_NICK; + } + else + { + /* No camping, tell the incoming user to stop trying to change nick ;p */ + this->WriteNumeric(433, "%s %s :Nickname is already in use.", this->registered >= REG_NICK ? this->nick.c_str() : "*", newnick.c_str()); + return false; + } + } + } + + if (this->registered == REG_ALL) + this->WriteCommon("NICK %s",newnick.c_str()); + std::string oldnick = nick; + nick = newnick; + + InvalidateCache(); + ServerInstance->Users->clientlist->erase(oldnick); + (*(ServerInstance->Users->clientlist))[newnick] = this; + + if (registered == REG_ALL) + FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(this,oldnick)); + + return true; } int LocalUser::GetServerPort() @@ -996,7 +1008,7 @@ void User::Write(const char *text, ...) void LocalUser::Write(const std::string& text) { - if (!ServerInstance->SE->BoundsCheckFd(this)) + if (!ServerInstance->SE->BoundsCheckFd(&eh)) return; if (text.length() > MAXBUF - 2) @@ -1007,10 +1019,10 @@ void LocalUser::Write(const std::string& text) return; } - ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%d] O %s", this->GetFd(), text.c_str()); + ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%s] O %s", uuid.c_str(), text.c_str()); - this->AddWriteBuf(text); - this->AddWriteBuf(wide_newline); + eh.AddWriteBuf(text); + eh.AddWriteBuf(wide_newline); ServerInstance->stats->statsSent += text.length() + 2; this->bytes_out += text.length() + 2; @@ -1161,7 +1173,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) if (this->registered != REG_ALL || quitting) return; - uniq_id_t uniq_id = ++already_sent; + LocalUser::already_sent_id++; UserChanList include_c(chans); std::map exceptions; @@ -1175,7 +1187,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) LocalUser* u = IS_LOCAL(i->first); if (u && !u->quitting) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = LocalUser::already_sent_id; if (i->second) u->Write(line); } @@ -1187,9 +1199,9 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); - if (u && !u->quitting && already_sent[u->GetFd()] != uniq_id) + if (u && !u->quitting && u->already_sent != LocalUser::already_sent_id) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = LocalUser::already_sent_id; u->Write(line); } } @@ -1204,7 +1216,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op if (this->registered != REG_ALL) return; - uniq_id_t uniq_id = ++already_sent; + already_sent_t uniq_id = ++LocalUser::already_sent_id; snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str()); snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str()); @@ -1221,7 +1233,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op LocalUser* u = IS_LOCAL(i->first); if (u && !u->quitting) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = uniq_id; if (i->second) u->Write(IS_OPER(u) ? out2 : out1); } @@ -1232,9 +1244,9 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); - if (u && !u->quitting && (already_sent[u->GetFd()] != uniq_id)) + if (u && !u->quitting && (u->already_sent != uniq_id)) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = uniq_id; u->Write(IS_OPER(u) ? out2 : out1); } } @@ -1345,8 +1357,8 @@ void User::DoHostCycle(const std::string &quitline) if (!ServerInstance->Config->CycleHosts) return; - uniq_id_t silent_id = ++already_sent; - uniq_id_t seen_id = ++already_sent; + already_sent_t silent_id = ++LocalUser::already_sent_id; + already_sent_t seen_id = ++LocalUser::already_sent_id; UserChanList include_c(chans); std::map exceptions; @@ -1360,12 +1372,12 @@ void User::DoHostCycle(const std::string &quitline) { if (i->second) { - already_sent[u->GetFd()] = seen_id; + u->already_sent = seen_id; u->Write(quitline); } else { - already_sent[u->GetFd()] = silent_id; + u->already_sent = silent_id; } } } @@ -1390,13 +1402,13 @@ void User::DoHostCycle(const std::string &quitline) LocalUser* u = IS_LOCAL(i->first); if (u == NULL || u == this) continue; - if (already_sent[u->GetFd()] == silent_id) + if (u->already_sent == silent_id) continue; - if (already_sent[u->GetFd()] != seen_id) + if (u->already_sent != seen_id) { u->Write(quitline); - already_sent[u->GetFd()] = seen_id; + u->already_sent = seen_id; } u->Write(joinline); if (modeline.length() > 0) @@ -1558,16 +1570,26 @@ void LocalUser::SetClass(const std::string &explicit_name) for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { ConnectClass* c = *i; + ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Checking %s", c->GetName().c_str()); - if (c->type == CC_ALLOW) - { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "ALLOW %s %d %s", c->host.c_str(), c->GetPort(), c->GetName().c_str()); - } - else + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnSetConnectClass, MOD_RESULT, (this,c)); + if (MOD_RESULT == MOD_RES_DENY) + continue; + if (MOD_RESULT == MOD_RES_ALLOW) { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "DENY %s %d %s", c->GetHost().c_str(), c->GetPort(), c->GetName().c_str()); + ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Class forced by module to %s", c->GetName().c_str()); + found = c; + break; } + if (c->type == CC_NAMED) + continue; + + bool regdone = (registered != REG_NONE); + if (c->config->getBool("registered", regdone) != regdone) + continue; + /* check if host matches.. */ if (c->GetHost().length() && !InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) && !InspIRCd::MatchCIDR(this->host, c->GetHost(), NULL)) @@ -1587,14 +1609,21 @@ void LocalUser::SetClass(const std::string &explicit_name) } /* if it requires a port ... */ - if (c->GetPort()) + int port = c->config->getInt("port"); + if (port) { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Requires port (%d)", c->GetPort()); + ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Requires port (%d)", port); /* and our port doesn't match, fail. */ - if (this->GetServerPort() != c->GetPort()) + if (this->GetServerPort() != port) + continue; + } + + if (!c->config->getString("pass").empty()) + { + if (ServerInstance->PassCompare(this, c->config->getString("pass"), password, c->config->getString("hash"))) { - ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Port match failed (%d)", this->GetServerPort()); + ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Bad password, skipping"); continue; } } @@ -1641,37 +1670,6 @@ void User::PurgeEmptyChannels() this->UnOper(); } -void User::ShowMOTD() -{ - if (!ServerInstance->Config->MOTD.size()) - { - this->WriteNumeric(ERR_NOMOTD, "%s :Message of the day file is missing.",this->nick.c_str()); - return; - } - this->WriteNumeric(RPL_MOTDSTART, "%s :%s message of the day", this->nick.c_str(), ServerInstance->Config->ServerName.c_str()); - - for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++) - this->WriteNumeric(RPL_MOTD, "%s :- %s",this->nick.c_str(),i->c_str()); - - this->WriteNumeric(RPL_ENDOFMOTD, "%s :End of message of the day.", this->nick.c_str()); -} - -void User::ShowRULES() -{ - if (!ServerInstance->Config->RULES.size()) - { - this->WriteNumeric(ERR_NORULES, "%s :RULES File is missing",this->nick.c_str()); - return; - } - - this->WriteNumeric(RPL_RULESTART, "%s :- %s Server Rules -",this->nick.c_str(),ServerInstance->Config->ServerName.c_str()); - - for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++) - this->WriteNumeric(RPL_RULES, "%s :- %s",this->nick.c_str(),i->c_str()); - - this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str()); -} - const std::string& FakeUser::GetFullHost() { if (!ServerInstance->Config->HideWhoisServer.empty()) @@ -1687,20 +1685,19 @@ const std::string& FakeUser::GetFullRealHost() } ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) - : config(tag), type(t), name("unnamed"), registration_timeout(0), host(mask), - pingtime(0), pass(""), hash(""), softsendqmax(0), hardsendqmax(0), - recvqmax(0), penaltythreshold(0), maxlocal(0), maxglobal(0), maxchans(0), port(0), limit(0) + : config(tag), type(t), fakelag(true), name("unnamed"), registration_timeout(0), host(mask), + pingtime(0), softsendqmax(0), hardsendqmax(0), recvqmax(0), + penaltythreshold(0), commandrate(0), maxlocal(0), maxglobal(0), maxchans(0), limit(0) { } ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask, const ConnectClass& parent) - : config(tag), type(t), name("unnamed"), - registration_timeout(parent.registration_timeout), host(mask), - pingtime(parent.pingtime), pass(parent.pass), hash(parent.hash), - softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax), - recvqmax(parent.recvqmax), penaltythreshold(parent.penaltythreshold), maxlocal(parent.maxlocal), - maxglobal(parent.maxglobal), maxchans(parent.maxchans), - port(parent.port), limit(parent.limit) + : config(tag), type(t), fakelag(parent.fakelag), name("unnamed"), + registration_timeout(parent.registration_timeout), host(mask), pingtime(parent.pingtime), + softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax), recvqmax(parent.recvqmax), + penaltythreshold(parent.penaltythreshold), commandrate(parent.commandrate), + maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxchans(parent.maxchans), + limit(parent.limit) { } @@ -1710,8 +1707,6 @@ void ConnectClass::Update(const ConnectClass* src) registration_timeout = src->registration_timeout; host = src->host; pingtime = src->pingtime; - pass = src->pass; - hash = src->hash; softsendqmax = src->softsendqmax; hardsendqmax = src->hardsendqmax; recvqmax = src->recvqmax;