* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
*/
#include "inspircd.h"
-#include "users.h"
-#include "channels.h"
-#include "modules.h"
/* $ModDesc: Provides support for RFC1413 ident lookups */
* Using this framework we have a much more stable module.
*
* A few things to note:
- *
+ *
* O The only place that may *delete* an active or inactive
* ident socket is OnUserDisconnect in the module class.
* Because this is out of scope of the socket class there is
*
* O Closure of the ident socket with the Close() method will
* not cause removal of the socket from memory or detatchment
- * from its 'parent' User class. It will only flag it as an
+ * from its 'parent' User class. It will only flag it as an
* inactive socket in the socket engine.
*
* O Timeouts are handled in OnCheckReaady at the same time as
class IdentRequestSocket : public EventHandler
{
private:
-
- User *user; /* User we are attached to */
- InspIRCd* ServerInstance; /* Server instance */
- bool done; /* True if lookup is finished */
- std::string result; /* Holds the ident string if done */
-
+ User *user; /* User we are attached to */
+ InspIRCd* ServerInstance; /* Server instance */
+ bool done; /* True if lookup is finished */
+ std::string result; /* Holds the ident string if done */
public:
IdentRequestSocket(InspIRCd *Server, User* u, const std::string &bindip) : user(u), ServerInstance(Server), result(u->ident)
if (GetFd() == -1)
throw ModuleException("Could not create socket");
+ done = false;
+
/* We allocate two of these because sizeof(sockaddr_in6) > sizeof(sockaddr_in) */
sockaddr* s = new sockaddr[2];
sockaddr* addr = new sockaddr[2];
-
+
#ifdef IPV6
/* Horrid icky nasty ugly berkely socket crap. */
if (v6)
#else
int req_size = snprintf(req, sizeof(req), "%d,%d\r\n", ntohs(raddr.sin6_port), ntohs(laddr.sin6_port));
#endif
-
+
/* Send failed if we didnt write the whole ident request --
* might as well give up if this happens!
*/
if (i < 3)
continue;
- char ident[IDENTMAX + 2];
+ std::string ident;
/* Truncate the ident at any characters we don't like, skip leading spaces */
- int k = 0;
- for (const char *j = token.c_str(); *j && (k < IDENTMAX + 1); j++)
+ size_t k = 0;
+ for (const char *j = token.c_str(); *j && (k < ServerInstance->Config->Limits.IdentMax + 1); j++)
{
if (*j == ' ')
continue;
/* Rules taken from InspIRCd::IsIdent */
if (((*j >= 'A') && (*j <= '}')) || ((*j >= '0') && (*j <= '9')) || (*j == '-') || (*j == '.'))
{
- ident[k++] = *j;
+ ident += *j;
continue;
}
break;
}
- ident[k] = '\0';
-
/* Re-check with IsIdent, in case that changes and this doesn't (paranoia!) */
- if (*ident && ServerInstance->IsIdent(ident))
+ if (!ident.empty() && ServerInstance->IsIdent(ident.c_str()))
{
result = ident;
}
{
private:
int RequestTimeout;
+ ConfigReader *Conf;
public:
- ModuleIdent(InspIRCd *Me)
- : Module(Me)
+ ModuleIdent(InspIRCd *Me) : Module(Me)
{
+ Conf = new ConfigReader(ServerInstance);
OnRehash(NULL, "");
Implementation eventlist[] = { I_OnRehash, I_OnUserRegister, I_OnCheckReady, I_OnCleanup, I_OnUserDisconnect };
ServerInstance->Modules->Attach(eventlist, this, 5);
}
-
+
+ ~ModuleIdent()
+ {
+ delete Conf;
+ }
+
virtual Version GetVersion()
{
- return Version(1, 2, 1, 0, VF_VENDOR, API_VERSION);
+ return Version("$Id$", VF_VENDOR, API_VERSION);
}
-
-
+
virtual void OnRehash(User *user, const std::string ¶m)
{
- ConfigReader MyConf(ServerInstance);
-
- RequestTimeout = MyConf.ReadInteger("ident", "timeout", 0, true);
+ delete Conf;
+ Conf = new ConfigReader(ServerInstance);
+
+ RequestTimeout = Conf->ReadInteger("ident", "timeout", 0, true);
if (!RequestTimeout)
RequestTimeout = 5;
}
-
+
virtual int OnUserRegister(User *user)
{
+ for (int j = 0; j < Conf->Enumerate("connect"); j++)
+ {
+ std::string hostn = Conf->ReadValue("connect","allow",j);
+ /* XXX: Fixme: does not respect port, limit, etc */
+ if ((InspIRCd::MatchCIDR(user->GetIPString(),hostn, ascii_case_insensitive_map)) || (InspIRCd::Match(user->host,hostn, ascii_case_insensitive_map)))
+ {
+ bool useident = Conf->ReadFlag("connect", "useident", "yes", j);
+
+ if (!useident)
+ return 0;
+ }
+ }
+
/* User::ident is currently the username field from USER; with m_ident loaded, that
- * should be preceded by a ~. The field is actually IDENTMAX+2 characters wide. */
- memmove(user->ident + 1, user->ident, IDENTMAX);
- user->ident[0] = '~';
- /* Ensure that it is null terminated */
- user->ident[IDENTMAX + 1] = '\0';
+ * should be preceded by a ~. The field is actually IdentMax+2 characters wide. */
+ if (user->ident.length() > ServerInstance->Config->Limits.IdentMax + 1)
+ user->ident.assign(user->ident, 0, ServerInstance->Config->Limits.IdentMax);
+ user->ident.insert(0, "~");
user->WriteServ("NOTICE Auth :*** Looking up your ident...");
if (getsockname(user->GetFd(), (sockaddr*) &laddr, &laddrsz) != 0)
{
- user->WriteServ("NOTICE Auth :*** Could not find your ident, using %s instead.", user->ident);
+ user->WriteServ("NOTICE Auth :*** Could not find your ident, using %s instead.", user->ident.c_str());
return 0;
}
*/
virtual bool OnCheckReady(User *user)
{
- ServerInstance->Logs->Log("m_ident",DEBUG,"OnCheckReady %s", user->nick);
-
/* Does user have an ident socket attached at all? */
IdentRequestSocket *isock = NULL;
if (!user->GetExt("ident_socket", isock))
user->WriteServ("NOTICE Auth :*** Could not find your ident, using %s instead.", isock->GetResult());
/* Copy the ident string to the user */
- strlcpy(user->ident, isock->GetResult(), IDENTMAX+1);
+ user->ident.assign(isock->GetResult(), 0, ServerInstance->Config->Limits.IdentMax + 1);
/* The user isnt actually disconnecting, we call this to clean up the user */
OnUserDisconnect(user);
isock->Close();
delete isock;
user->Shrink("ident_socket");
- ServerInstance->Logs->Log("m_ident",DEBUG, "Removed ident socket from %s", user->nick);
}
}
};