diff options
-rw-r--r-- | include/usermanager.h | 12 | ||||
-rw-r--r-- | include/users.h | 12 | ||||
-rw-r--r-- | src/socket.cpp | 2 | ||||
-rw-r--r-- | src/usermanager.cpp | 151 | ||||
-rw-r--r-- | src/users.cpp | 175 |
5 files changed, 178 insertions, 174 deletions
diff --git a/include/usermanager.h b/include/usermanager.h index 5ca6401bb..9cc3e0309 100644 --- a/include/usermanager.h +++ b/include/usermanager.h @@ -36,6 +36,18 @@ class CoreExport UserManager : public classbase */ clonemap global_clones; + /** Add a client to the system. + * This will create a new User, insert it into the user_hash, + * initialize it as not yet registered, and add it to the socket engine. + * @param Instance a pointer to the server instance + * @param socket The socket id (file descriptor) this user is on + * @param port The port number this user connected on + * @param iscached This variable is reserved for future use + * @param ip The IP address of the user + * @return This function has no return value, but a call to AddClient may remove the user. + */ + void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip); + /** Add a user to the local clone map * @param user The user to add */ diff --git a/include/users.h b/include/users.h index 67ea63a31..c795ae1a4 100644 --- a/include/users.h +++ b/include/users.h @@ -916,18 +916,6 @@ class CoreExport User : public connection */ bool ForceNickChange(const char* newnick); - /** Add a client to the system. - * This will create a new User, insert it into the user_hash, - * initialize it as not yet registered, and add it to the socket engine. - * @param Instance a pointer to the server instance - * @param socket The socket id (file descriptor) this user is on - * @param port The port number this user connected on - * @param iscached This variable is reserved for future use - * @param ip The IP address of the user - * @return This function has no return value, but a call to AddClient may remove the user. - */ - static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip); - /** Oper down. * This will clear the +o usermode and unset the user's oper type */ diff --git a/src/socket.cpp b/src/socket.cpp index 2aa2c73b0..48c0170d3 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -117,7 +117,7 @@ void ListenSocket::HandleEvent(EventType, int) } } ServerInstance->stats->statsAccept++; - User::AddClient(ServerInstance, incomingSockfd, in_port, false, this->family, client); + ServerInstance->Users->AddClient(ServerInstance, incomingSockfd, in_port, false, this->family, client); } else { diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 2bb4ee685..d518b790e 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -14,6 +14,157 @@ /* $Core: libIRCDusermanager */ #include "inspircd.h" +#include "xline.h" +#include "bancache.h" + +/* add a client connection to the sockets list */ +void UserManager::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip) +{ + /* NOTE: Calling this one parameter constructor for User automatically + * allocates a new UUID and places it in the hash_map. + */ + User* New = NULL; + try + { + New = new User(Instance); + } + catch (...) + { + Instance->Log(DEFAULT,"*** WTF *** Duplicated UUID! -- Crack smoking monkies have been unleashed."); + Instance->WriteOpers("*** WARNING *** Duplicate UUID allocated!"); + return; + } + + Instance->Log(DEBUG,"New user fd: %d", socket); + + int j = 0; + + Instance->unregistered_count++; + + char ipaddr[MAXBUF]; +#ifdef IPV6 + if (socketfamily == AF_INET6) + inet_ntop(AF_INET6, &((const sockaddr_in6*)ip)->sin6_addr, ipaddr, sizeof(ipaddr)); + else +#endif + inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); + + New->SetSockAddr(socketfamily, ipaddr, port); + + New->SetFd(socket); + + /* Smarter than your average bear^H^H^H^Hset of strlcpys. */ + for (const char* temp = New->GetIPString(); *temp && j < 64; temp++, j++) + New->dhost[j] = New->host[j] = *temp; + New->dhost[j] = New->host[j] = 0; + + Instance->Users->AddLocalClone(New); + Instance->Users->AddGlobalClone(New); + + /* + * First class check. We do this again in FullConnect after DNS is done, and NICK/USER is recieved. + * See my note down there for why this is required. DO NOT REMOVE. :) -- w00t + */ + ConnectClass* i = New->SetClass(); + + if (!i) + { + User::QuitUser(Instance, New, "Access denied by configuration"); + return; + } + + /* + * Check connect class settings and initialise settings into User. + * This will be done again after DNS resolution. -- w00t + */ + New->CheckClass(); + + Instance->local_users.push_back(New); + + if ((Instance->local_users.size() > Instance->Config->SoftLimit) || (Instance->local_users.size() >= MAXCLIENTS)) + { + Instance->WriteOpers("*** Warning: softlimit value has been reached: %d clients", Instance->Config->SoftLimit); + User::QuitUser(Instance, New,"No more connections allowed"); + return; + } + + /* + * XXX - + * this is done as a safety check to keep the file descriptors within range of fd_ref_table. + * its a pretty big but for the moment valid assumption: + * file descriptors are handed out starting at 0, and are recycled as theyre freed. + * therefore if there is ever an fd over 65535, 65536 clients must be connected to the + * irc server at once (or the irc server otherwise initiating this many connections, files etc) + * which for the time being is a physical impossibility (even the largest networks dont have more + * than about 10,000 users on ONE server!) + */ +#ifndef WINDOWS + if ((unsigned int)socket >= MAX_DESCRIPTORS) + { + User::QuitUser(Instance, New, "Server is full"); + return; + } +#endif + /* + * even with bancache, we still have to keep User::exempt current. + * besides that, if we get a positive bancache hit, we still won't fuck + * them over if they are exempt. -- w00t + */ + New->exempt = (Instance->XLines->MatchesLine("E",New) != NULL); + + if (BanCacheHit *b = Instance->BanCache->GetHit(New->GetIPString())) + { + if (!b->Type.empty() && !New->exempt) + { + /* user banned */ + Instance->Log(DEBUG, std::string("BanCache: Positive hit for ") + New->GetIPString()); + if (*Instance->Config->MoronBanner) + New->WriteServ("NOTICE %s :*** %s", New->nick, Instance->Config->MoronBanner); + User::QuitUser(Instance, New, b->Reason); + return; + } + else + { + Instance->Log(DEBUG, std::string("BanCache: Negative hit for ") + New->GetIPString()); + } + } + else + { + if (!New->exempt) + { + XLine* r = Instance->XLines->MatchesLine("Z",New); + + if (r) + { + r->Apply(New); + return; + } + } + } + + if (socket > -1) + { + if (!Instance->SE->AddFd(New)) + { + Instance->Log(DEBUG,"Internal error on new connection"); + User::QuitUser(Instance, New, "Internal error handling connection"); + } + } + + /* NOTE: even if dns lookups are *off*, we still need to display this. + * BOPM and other stuff requires it. + */ + New->WriteServ("NOTICE Auth :*** Looking up your hostname..."); + + if (Instance->Config->NoUserDns) + { + New->dns_done = true; + } + else + { + New->StartDNSLookup(); + } +} void UserManager::AddLocalClone(User *user) { diff --git a/src/users.cpp b/src/users.cpp index 22dead793..2f1c86a33 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -210,6 +210,20 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance (*Instance->uuidlist)[uuid] = this; else throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor"); + + (*(Instance->clientlist))[this->uuid] = this; + + /* The users default nick is their UUID */ + strlcpy(this->nick, this->uuid, NICKMAX - 1); + + this->server = Instance->FindServerNamePtr(Instance->Config->ServerName); + /* We don't need range checking here, we KNOW 'unknown\0' will fit into the ident field. */ + strcpy(this->ident, "unknown"); + + this->registered = REG_NONE; + this->signon = Instance->Time() + Instance->Config->dns_timeout; + this->lastping = 1; + } User::~User() @@ -725,167 +739,6 @@ void User::AddToWhoWas() } } -/* add a client connection to the sockets list */ -void User::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip) -{ - /* NOTE: Calling this one parameter constructor for User automatically - * allocates a new UUID and places it in the hash_map. - */ - User* New = NULL; - try - { - New = new User(Instance); - } - catch (...) - { - Instance->Log(DEFAULT,"*** WTF *** Duplicated UUID! -- Crack smoking monkies have been unleashed."); - Instance->WriteOpers("*** WARNING *** Duplicate UUID allocated!"); - return; - } - - Instance->Log(DEBUG,"New user fd: %d", socket); - - int j = 0; - - Instance->unregistered_count++; - - char ipaddr[MAXBUF]; -#ifdef IPV6 - if (socketfamily == AF_INET6) - inet_ntop(AF_INET6, &((const sockaddr_in6*)ip)->sin6_addr, ipaddr, sizeof(ipaddr)); - else -#endif - inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); - - (*(Instance->clientlist))[New->uuid] = New; - New->SetFd(socket); - - /* The users default nick is their UUID */ - strlcpy(New->nick, New->uuid, NICKMAX - 1); - - New->server = Instance->FindServerNamePtr(Instance->Config->ServerName); - /* We don't need range checking here, we KNOW 'unknown\0' will fit into the ident field. */ - strcpy(New->ident, "unknown"); - - New->registered = REG_NONE; - New->signon = Instance->Time() + Instance->Config->dns_timeout; - New->lastping = 1; - - New->SetSockAddr(socketfamily, ipaddr, port); - - /* Smarter than your average bear^H^H^H^Hset of strlcpys. */ - for (const char* temp = New->GetIPString(); *temp && j < 64; temp++, j++) - New->dhost[j] = New->host[j] = *temp; - New->dhost[j] = New->host[j] = 0; - - Instance->Users->AddLocalClone(New); - Instance->Users->AddGlobalClone(New); - - /* - * First class check. We do this again in FullConnect after DNS is done, and NICK/USER is recieved. - * See my note down there for why this is required. DO NOT REMOVE. :) -- w00t - */ - ConnectClass* i = New->SetClass(); - - if (!i) - { - User::QuitUser(Instance, New, "Access denied by configuration"); - return; - } - - /* - * Check connect class settings and initialise settings into User. - * This will be done again after DNS resolution. -- w00t - */ - New->CheckClass(); - - Instance->local_users.push_back(New); - - if ((Instance->local_users.size() > Instance->Config->SoftLimit) || (Instance->local_users.size() >= MAXCLIENTS)) - { - Instance->WriteOpers("*** Warning: softlimit value has been reached: %d clients", Instance->Config->SoftLimit); - User::QuitUser(Instance, New,"No more connections allowed"); - return; - } - - /* - * XXX - - * this is done as a safety check to keep the file descriptors within range of fd_ref_table. - * its a pretty big but for the moment valid assumption: - * file descriptors are handed out starting at 0, and are recycled as theyre freed. - * therefore if there is ever an fd over 65535, 65536 clients must be connected to the - * irc server at once (or the irc server otherwise initiating this many connections, files etc) - * which for the time being is a physical impossibility (even the largest networks dont have more - * than about 10,000 users on ONE server!) - */ -#ifndef WINDOWS - if ((unsigned int)socket >= MAX_DESCRIPTORS) - { - User::QuitUser(Instance, New, "Server is full"); - return; - } -#endif - /* - * even with bancache, we still have to keep User::exempt current. - * besides that, if we get a positive bancache hit, we still won't fuck - * them over if they are exempt. -- w00t - */ - New->exempt = (Instance->XLines->MatchesLine("E",New) != NULL); - - if (BanCacheHit *b = Instance->BanCache->GetHit(New->GetIPString())) - { - if (!b->Type.empty() && !New->exempt) - { - /* user banned */ - Instance->Log(DEBUG, std::string("BanCache: Positive hit for ") + New->GetIPString()); - if (*Instance->Config->MoronBanner) - New->WriteServ("NOTICE %s :*** %s", New->nick, Instance->Config->MoronBanner); - User::QuitUser(Instance, New, b->Reason); - return; - } - else - { - Instance->Log(DEBUG, std::string("BanCache: Negative hit for ") + New->GetIPString()); - } - } - else - { - if (!New->exempt) - { - XLine* r = Instance->XLines->MatchesLine("Z",New); - - if (r) - { - r->Apply(New); - return; - } - } - } - - if (socket > -1) - { - if (!Instance->SE->AddFd(New)) - { - Instance->Log(DEBUG,"Internal error on new connection"); - User::QuitUser(Instance, New, "Internal error handling connection"); - } - } - - /* NOTE: even if dns lookups are *off*, we still need to display this. - * BOPM and other stuff requires it. - */ - New->WriteServ("NOTICE Auth :*** Looking up your hostname..."); - - if (Instance->Config->NoUserDns) - { - New->dns_done = true; - } - else - { - New->StartDNSLookup(); - } -} - /* * Check class restrictions */ |