1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-07 20:43:13 +02:00

- Partially fixed bug where IPv4 addresses were randomly mishandled by the cgiirc code, resulting in the sockhost/hostmask being set to something like ::ffff:127.0.0.1, which confused the s2s protocol. Reported by tabrisnet (#0003907). Also, reject incorrectly formed hostnames from WEBIRC command.

This commit is contained in:
binki
2010-05-28 04:30:22 +00:00
parent 625102cacd
commit f1ec26a07c
6 changed files with 39 additions and 15 deletions
+4
View File
@@ -1971,3 +1971,7 @@
- Fixed bug in CVS where the ban exempt (+e) handling was reversed: if a
non-matching +e was present, one could walk through bans. Reported by
tabrisnet (#0003909). Bug was caused by chained/stacked extbans.
- Partially fixed bug where IPv4 addresses were randomly mishandled by the
cgiirc code, resulting in the sockhost/hostmask being set to something like
::ffff:127.0.0.1, which confused the s2s protocol. Reported by tabrisnet
(#0003907). Also, reject incorrectly formed hostnames from WEBIRC command.
+1
View File
@@ -256,6 +256,7 @@ extern int get_sockerr(aClient *);
extern int inetport(aClient *, char *, int);
extern void init_sys();
extern void init_modef();
extern int verify_hostname(char *name);
#ifdef NO_FDLIST
extern int read_message(time_t);
+25 -14
View File
@@ -148,8 +148,9 @@ ConfigItem_ban *bconf;
int docgiirc(aClient *cptr, char *ip, char *host)
{
#ifdef INET6
char ipbuf[64], crap[32];
char ipbuf[64];
#endif
char *sockhost;
if (IsCGIIRC(cptr))
return exit_client(cptr, cptr, &me, "Double CGI:IRC request (already identified)");
@@ -157,18 +158,20 @@ char ipbuf[64], crap[32];
if (host && !strcmp(ip, host))
host = NULL; /* host did not resolve, make it NULL */
/* STEP 1: Update cptr->ip */
#ifdef INET6
/* Transform ipv4 to ::ffff:ipv4 if needed */
if (inet_pton(AF_INET, ip, crap) != 0)
/* STEP 1: Update cptr->ip
inet_pton() returns 1 on success, 0 on bad input, -1 on bad AF */
if(inet_pton(AFINET, ip, &cptr->ip) != 1)
{
snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ip);
ip = ipbuf;
}
#endif
if (inet_pton(AFINET, ip, &cptr->ip) <= 0)
#ifndef INET6
/* then we have an invalid IP */
return exit_client(cptr, cptr, &me, "Invalid IP address");
#else
/* The address may be IPv4. We have to try ::ffff:ipv4 */
snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ip);
if(inet_pton(AFINET, ipbuf, &cptr->ip) != 1)
return exit_client(cptr, cptr, &me, "Invalid IP address");
#endif
}
/* STEP 2: Update GetIP() */
if (cptr->user)
@@ -187,11 +190,19 @@ char ipbuf[64], crap[32];
cptr->hostp = NULL;
}
/* (create new) */
if (host)
if (host && verify_hostname(host))
cptr->hostp = unreal_create_hostent(host, &cptr->ip);
/* STEP 4: Update sockhost */
strlcpy(cptr->sockhost, ip, sizeof(cptr->sockhost));
/* STEP 4: Update sockhost
Make sure that if this any IPv4 address is _not_ prefixed with
"::ffff:" by using Inet_ia2p().
*/
sockhost = Inet_ia2p(&cptr->ip);
if(!sockhost)
{
return exit_client(cptr, cptr, &me, "Error processing CGI:IRC IP address.");
}
strlcpy(cptr->sockhost, sockhost, sizeof(cptr->sockhost));
SetCGIIRC(cptr);
+5
View File
@@ -282,6 +282,11 @@ char ipv6 = r->ipv6;
#endif
}
/*
returns:
1 = good hostname
0 = bad hostname
*/
int verify_hostname(char *name)
{
char *p;
+1 -1
View File
@@ -1041,7 +1041,7 @@ void set_sock_opts(int fd, aClient *cptr)
/* We deal with both IPv4 and IPv6 in one (listen) socket.
* This used to be on by default, but FreeBSD, and much later Linux
* sometimes as well, seem to default it to IPv6 only ('1').
* We now have this new fancy option to turn it on in Unreal,
* We now have this new fancy option to turn it off in Unreal,
* instead of requiring our users to sysctl.
*/
opt = 0;
+3
View File
@@ -199,6 +199,9 @@ char *Inet_si2p(struct SOCKADDR_IN *sin)
return (Inet_si2pB(sin, buf, sizeof(buf)));
}
/*
May return NULL if inet_ntop() fails.
*/
char *Inet_ia2p(struct IN_ADDR *ia)
{
#ifndef INET6