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:
@@ -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.
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user