* ---------------------------------------------------
*/
+/* $Core: libIRCDusers */
+
#include "inspircd.h"
#include <stdarg.h>
#include "socketengine.h"
/* XXX: Used for speeding up WriteCommon operations */
unsigned long uniq_id = 0;
-bool InitTypes(ServerConfig* conf, const char* tag)
-{
- if (conf->opertypes.size())
- {
- for (opertype_t::iterator n = conf->opertypes.begin(); n != conf->opertypes.end(); n++)
- {
- if (n->second)
- delete[] n->second;
- }
- }
-
- conf->opertypes.clear();
- return true;
-}
-
-bool InitClasses(ServerConfig* conf, const char* tag)
-{
- if (conf->operclass.size())
- {
- for (operclass_t::iterator n = conf->operclass.begin(); n != conf->operclass.end(); n++)
- {
- if (n->second)
- delete[] n->second;
- }
- }
-
- conf->operclass.clear();
- return true;
-}
-
-bool DoType(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
-{
- const char* TypeName = values[0].GetString();
- const char* Classes = values[1].GetString();
-
- conf->opertypes[TypeName] = strnewdup(Classes);
- return true;
-}
-
-bool DoClass(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
-{
- const char* ClassName = values[0].GetString();
- const char* CommandList = values[1].GetString();
-
- conf->operclass[ClassName] = strnewdup(CommandList);
- return true;
-}
-
-bool DoneClassesAndTypes(ServerConfig* conf, const char* tag)
-{
- return true;
-}
-
std::string User::ProcessNoticeMasks(const char *sm)
{
bool adding = true, oldadding = false;
}
}
-UserResolver::UserResolver(InspIRCd* Instance, User* user, std::string to_resolve, QueryType qt, bool &cache) :
- Resolver(Instance, to_resolve, qt, cache), bound_user(user)
-{
- this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
- this->bound_fd = user->GetFd();
-}
-
-void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached, int resultnum)
-{
- /* We are only interested in the first matching result */
- if (resultnum)
- return;
-
- if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
- {
- this->bound_user->stored_host = result;
- try
- {
- /* Check we didnt time out */
- if (this->bound_user->registered != REG_ALL)
- {
- bool cached;
-#ifdef IPV6
- if (this->bound_user->GetProtocolFamily() == AF_INET6)
- {
- /* IPV6 forward lookup (with possibility of 4in6) */
- const char* ip = this->bound_user->GetIPString();
- bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (!strncmp(ip, "0::ffff:", 8) ? DNS_QUERY_A : DNS_QUERY_AAAA), cached);
- }
- else
- /* IPV4 lookup (mixed protocol mode) */
-#endif
- /* IPV4 lookup (ipv4 only mode) */
- bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, DNS_QUERY_A, cached);
- this->ServerInstance->AddResolver(bound_user->res_forward, cached);
- }
- }
- catch (CoreException& e)
- {
- ServerInstance->Log(DEBUG,"Error in resolver: %s",e.GetReason());
- }
- }
- else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
- {
- /* Both lookups completed */
- std::string result2("0::ffff:");
- result2.append(result);
- if (this->bound_user->GetIPString() == result || this->bound_user->GetIPString() == result2)
- {
- std::string hostname = this->bound_user->stored_host;
- if (hostname.length() < 65)
- {
- /* Check we didnt time out */
- if ((this->bound_user->registered != REG_ALL) && (!this->bound_user->dns_done))
- {
- /* Hostnames starting with : are not a good thing (tm) */
- if (*(hostname.c_str()) == ':')
- hostname.insert(0, "0");
-
- this->bound_user->WriteServ("NOTICE Auth :*** Found your hostname (%s)%s", hostname.c_str(), (cached ? " -- cached" : ""));
- this->bound_user->dns_done = true;
- strlcpy(this->bound_user->dhost, hostname.c_str(),64);
- strlcpy(this->bound_user->host, hostname.c_str(),64);
- /* Invalidate cache */
- this->bound_user->InvalidateCache();
- }
- }
- else
- {
- if (!this->bound_user->dns_done)
- {
- this->bound_user->WriteServ("NOTICE Auth :*** Your hostname is longer than the maximum of 64 characters, using your IP address (%s) instead.", this->bound_user->GetIPString());
- this->bound_user->dns_done = true;
- }
- }
- }
- else
- {
- if (!this->bound_user->dns_done)
- {
- this->bound_user->WriteServ("NOTICE Auth :*** Your hostname does not match up with your IP address. Sorry, using your IP address (%s) instead.", this->bound_user->GetIPString());
- this->bound_user->dns_done = true;
- }
- }
- }
-}
-
-void UserResolver::OnError(ResolverError e, const std::string &errormessage)
-{
- if (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user)
- {
- /* Since dns timeout is implemented outside of the resolver, this was a race condition that could result in this message being sent *after*
- * the user was fully connected. This check fixes that issue - Special */
- if (!this->bound_user->dns_done)
- {
- /* Error message here */
- this->bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), this->bound_user->GetIPString());
- this->bound_user->dns_done = true;
- }
- }
-}
-
-
bool User::IsNoticeMaskSet(unsigned char sm)
{
return (snomasks[sm-65]);
server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
reset_due = ServerInstance->Time();
age = ServerInstance->Time(true);
+ Penalty = 0;
lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
- muted = exempt = haspassed = dns_done = false;
+ OverPenalty = ExemptFromPenalty = muted = exempt = haspassed = dns_done = false;
fd = -1;
recvq.clear();
sendq.clear();
return true;
// are they even an oper at all?
- if (IS_OPER(this))
+ if (!IS_OPER(this))
{
- opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper);
- if (iter_opertype != ServerInstance->Config->opertypes.end())
+ return false;
+ }
+
+ // check their opertype exists (!). This won't affect local users, of course.
+ opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper);
+ if (iter_opertype == ServerInstance->Config->opertypes.end())
+ {
+ return false;
+ }
+
+ /* XXX all this strtok/strdup stuff is a bit ick and horrid -- w00t */
+ char* Classes = strdup(iter_opertype->second);
+ char* myclass = strtok_r(Classes," ",&savept);
+ while (myclass)
+ {
+ operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass);
+ if (iter_operclass != ServerInstance->Config->operclass.end())
{
- char* Classes = strdup(iter_opertype->second);
- char* myclass = strtok_r(Classes," ",&savept);
- while (myclass)
+ char* CommandList = strdup(iter_operclass->second);
+ mycmd = strtok_r(CommandList," ",&savept2);
+ while (mycmd)
{
- operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass);
- if (iter_operclass != ServerInstance->Config->operclass.end())
+ if ((!strcasecmp(mycmd,command.c_str())) || (*mycmd == '*'))
{
- char* CommandList = strdup(iter_operclass->second);
- mycmd = strtok_r(CommandList," ",&savept2);
- while (mycmd)
- {
- if ((!strcasecmp(mycmd,command.c_str())) || (*mycmd == '*'))
- {
- free(Classes);
- free(CommandList);
- return true;
- }
- mycmd = strtok_r(NULL," ",&savept2);
- }
+ free(Classes);
free(CommandList);
+ return true;
}
- myclass = strtok_r(NULL," ",&savept);
+ mycmd = strtok_r(NULL," ",&savept2);
}
- free(Classes);
+ free(CommandList);
}
+ myclass = strtok_r(NULL," ",&savept);
}
+ free(Classes);
+
return false;
}
{
try
{
- if (!recvq.length())
+ if (recvq.empty())
return "";
/* Strip any leading \r or \n off the string.
void User::QuitUser(InspIRCd* Instance, User *user, const std::string &quitreason, const char* operreason)
{
- user->Write("ERROR :Closing link (%s@%s) [%s]", user->ident, user->host, operreason);
+ Instance->Log(DEBUG,"QuitUser: %s '%s'", user->nick, quitreason.c_str());
+ user->Write("ERROR :Closing link (%s@%s) [%s]", user->ident, user->host, *operreason ? operreason : quitreason.c_str());
user->muted = true;
Instance->GlobalCulls.AddItem(user, quitreason.c_str(), operreason);
}
return;
}
+ Instance->Log(DEBUG,"New user fd: %d", socket);
+
int j = 0;
Instance->unregistered_count++;
{
if (!Instance->SE->AddFd(New))
{
+ Instance->Log(DEBUG,"Internal error on new connection");
User::QuitUser(Instance, New, "Internal error handling connection");
}
}
* 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();
+ }
}
unsigned long User::GlobalCloneCount()
ServerInstance->CallCommandHandler("LUSERS", NULL, 0, this);
/*
- * fix 3 by brain, move registered = 7 below these so that spurious modes and host
- * changes dont go out onto the network and produce 'fake direction'.
+ * We don't set REG_ALL until triggering OnUserConnect, so some module events don't spew out stuff
+ * for a user that doesn't exist yet.
*/
FOREACH_MOD(I_OnUserConnect,OnUserConnect(this));
}
break;
default:
- ServerInstance->Log(DEBUG,"Ut oh, I dont know protocol %d to be set on '%s'!", protocol_family, this->nick);
+ ServerInstance->Log(DEBUG,"Uh oh, I dont know protocol %d to be set on '%s'!", protocol_family, this->nick);
break;
}
}
return sin->sin_family;
}
+/*
+ * XXX the duplication here is horrid..
+ * do we really need two methods doing essentially the same thing?
+ */
const char* User::GetIPString()
{
static char buf[1024];
return "";
}
-const char* User::GetIPString(char* buf)
-{
- if (this->ip == NULL)
- {
- *buf = 0;
- return buf;
- }
-
- switch (this->GetProtocolFamily())
- {
-#ifdef SUPPORT_IP6LINKS
- case AF_INET6:
- {
- static char temp[1024];
-
- sockaddr_in6* sin = (sockaddr_in6*)this->ip;
- inet_ntop(sin->sin6_family, &sin->sin6_addr, buf, sizeof(buf));
- /* IP addresses starting with a : on irc are a Bad Thing (tm) */
- if (*buf == ':')
- {
- strlcpy(&temp[1], buf, sizeof(temp) - 1);
- *temp = '0';
- strlcpy(buf, temp, sizeof(temp));
- }
- return buf;
- }
- break;
-#endif
- case AF_INET:
- {
- sockaddr_in* sin = (sockaddr_in*)this->ip;
- inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf));
- return buf;
- }
- break;
-
- default:
- break;
- }
- return "";
-}
-
/** NOTE: We cannot pass a const reference to this method.
* The string is changed by the workings of the method,
* so that if we pass const ref, we end up copying it to
return operquit ? operquit : "";
}
+void User::IncreasePenalty(int increase)
+{
+ this->Penalty += increase;
+}
+
+void User::DecreasePenalty(int decrease)
+{
+ this->Penalty -= decrease;
+}
+
VisData::VisData()
{
}