std::string hostname = this->bound_user->stored_host;
if (hostname.length() < 65)
{
- WriteServ(this->bound_fd, "NOTICE Auth :*** Found your hostname (%s)", this->bound_user->stored_host.c_str());
+ /* Hostnames starting with : are not a good thing (tm) */
+ if (*(hostname.c_str()) == ':')
+ hostname = "0" + hostname;
+
+ WriteServ(this->bound_fd, "NOTICE Auth :*** Found your hostname (%s)", hostname.c_str());
this->bound_user->dns_done = true;
strlcpy(this->bound_user->dhost, hostname.c_str(),64);
strlcpy(this->bound_user->host, hostname.c_str(),64);
haspassed = dns_done = false;
recvq = "";
sendq = "";
+ WriteError = "";
res_forward = res_reverse = NULL;
+ ip = NULL;
chans.clear();
invites.clear();
chans.resize(MAXCHANS);
ucrec* x = (ucrec*)*n;
delete x;
}
+
+ if (ip)
+ {
+ if (this->GetProtocolFamily() == AF_INET)
+ {
+ delete (sockaddr_in*)ip;
+ }
+#ifdef SUPPORT_IP6LINKS
+ else
+ {
+ delete (sockaddr_in6*)ip;
+ }
+#endif
+ }
}
/* XXX - minor point, other *Host functions return a char *, this one creates it. Might be nice to be consistant? */
void userrec::SetWriteError(const std::string &error)
{
+ log(DEBUG,"SetWriteError: %s",error.c_str());
// don't try to set the error twice, its already set take the first string.
if (!this->WriteError.length())
{
_new->fd = socket;
strlcpy(_new->nick,tempnick.c_str(),NICKMAX-1);
- /* Smarter than your average bear^H^H^H^Hset of strlcpys. */
- for (const char* temp = ipaddr; *temp && j < 64; temp++, j++)
- _new->dhost[j] = _new->host[j] = *temp;
- _new->dhost[j] = _new->host[j] = 0;
-
_new->server = FindServerNamePtr(Config->ServerName);
/* We don't need range checking here, we KNOW 'unknown\0' will fit into the ident field. */
strcpy(_new->ident, "unknown");
_new->SetSockAddr(AF_FAMILY, ipaddr, port);
log(DEBUG,"Socket addresses set.");
+ /* 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;
+
// set the registration timeout for this user
unsigned long class_regtimeout = 90;
int class_flood = 0;
for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
{
- if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str())))
+ if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str(),true)))
{
class_regtimeout = (unsigned long)i->registration_timeout;
class_flood = i->flood;
if (socket > -1)
{
- ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT);
+ if (!ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT))
+ {
+ kill_link(_new, "Internal error handling connection");
+ return;
+ }
}
- log(DEBUG,"Writing to client %d",_new->fd);
WriteServ(_new->fd,"NOTICE Auth :*** Looking up your hostname...");
}
long FindMatchingGlobal(userrec* user)
{
+ char u1[1024];
+ char u2[1024];
long x = 0;
for (user_hash::const_iterator a = clientlist.begin(); a != clientlist.end(); a++)
{
/* We have to match ip's as strings - we don't know what protocol
* a remote user may be using
*/
- if (!strcasecmp(a->second->GetIPString(), user->GetIPString()))
+ if (!strcasecmp(a->second->GetIPString(u1), user->GetIPString(u2)))
x++;
}
return x;
userrec* comp = *a;
#ifdef IPV6
/* I dont think theres any faster way of matching two ipv6 addresses than memcmp */
- in6_addr* s1 = &(((sockaddr_in6*)&comp->ip)->sin6_addr);
- in6_addr* s2 = &(((sockaddr_in6*)&user->ip)->sin6_addr);
+ in6_addr* s1 = &(((sockaddr_in6*)comp->ip)->sin6_addr);
+ in6_addr* s2 = &(((sockaddr_in6*)user->ip)->sin6_addr);
if (!memcmp(s1->s6_addr, s2->s6_addr, sizeof(in6_addr)))
x++;
#else
- in_addr* s1 = &((sockaddr_in*)&comp->ip)->sin_addr;
- in_addr* s2 = &((sockaddr_in*)&user->ip)->sin_addr;
+ in_addr* s1 = &((sockaddr_in*)comp->ip)->sin_addr;
+ in_addr* s2 = &((sockaddr_in*)user->ip)->sin_addr;
if (s1->s_addr == s2->s_addr)
x++;
#endif
case AF_INET6:
{
log(DEBUG,"Set inet6 protocol address");
- sockaddr_in6* sin = (sockaddr_in6*)&this->ip;
+ sockaddr_in6* sin = new sockaddr_in6;
sin->sin6_family = AF_INET6;
sin->sin6_port = port;
inet_pton(AF_INET6, ip, &sin->sin6_addr);
+ this->ip = (sockaddr*)sin;
}
break;
#endif
case AF_INET:
{
log(DEBUG,"Set inet4 protocol address");
- sockaddr_in* sin = (sockaddr_in*)&this->ip;
+ sockaddr_in* sin = new sockaddr_in;
sin->sin_family = AF_INET;
sin->sin_port = port;
inet_pton(AF_INET, ip, &sin->sin_addr);
+ this->ip = (sockaddr*)sin;
}
break;
default:
int userrec::GetPort()
{
+ if (this->ip == NULL)
+ return 0;
+
switch (this->GetProtocolFamily())
{
#ifdef SUPPORT_IP6LINKS
case AF_INET6:
{
- sockaddr_in6* sin = (sockaddr_in6*)&this->ip;
+ sockaddr_in6* sin = (sockaddr_in6*)this->ip;
return sin->sin6_port;
}
break;
#endif
case AF_INET:
{
- sockaddr_in* sin = (sockaddr_in*)&this->ip;
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
return sin->sin_port;
}
break;
int userrec::GetProtocolFamily()
{
- sockaddr_in* sin = (sockaddr_in*)&this->ip;
+ if (this->ip == NULL)
+ return 0;
+
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
return sin->sin_family;
}
const char* userrec::GetIPString()
{
static char buf[1024];
+ static char temp[1024];
+
+ if (this->ip == NULL)
+ return "";
switch (this->GetProtocolFamily())
{
#ifdef SUPPORT_IP6LINKS
case AF_INET6:
{
- sockaddr_in6* sin = (sockaddr_in6*)&this->ip;
+ 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));
+ *temp = '0';
+ return temp;
+ }
return buf;
}
break;
#endif
case AF_INET:
{
- sockaddr_in* sin = (sockaddr_in*)&this->ip;
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf));
return buf;
}
return "";
}
+const char* userrec::GetIPString(char* buf)
+{
+ static char temp[1024];
+
+ if (this->ip == NULL)
+ {
+ *buf = 0;
+ return buf;
+ }
+
+ switch (this->GetProtocolFamily())
+ {
+#ifdef SUPPORT_IP6LINKS
+ case AF_INET6:
+ {
+ 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));
+ *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:
+ log(DEBUG,"Ut oh, '%s' has an unknown protocol family!",this->nick);
+ break;
+ }
+ return "";
+}
+