mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-23 04:11:53 +00:00
bug fixes to ban logic, partial ipv4 addresses work for bans, ban with reasons (ex. ban 192.168.0.0/16 "I hate people on LANs"), addip/removeip/listip can use the same format as ban (and now work for ipv6/ipx), writeip removed and will be fixed/replaced later
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2295 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c19474d271
commit
116faaf0c9
5 changed files with 275 additions and 191 deletions
|
@ -580,7 +580,7 @@ qboolean NET_StringToAdr (char *s, netadr_t *a)
|
||||||
// (bits < 0 will always fill all bits)
|
// (bits < 0 will always fill all bits)
|
||||||
void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
qbyte *n;
|
qbyte *n;
|
||||||
|
|
||||||
memset (amask, 0, sizeof(*amask));
|
memset (amask, 0, sizeof(*amask));
|
||||||
|
@ -608,7 +608,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
||||||
// fill last bit
|
// fill last bit
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
i = (~((1 << i) - 1)) & 0xFF;
|
i = 8 - i;
|
||||||
|
i = 255 - ((1 << i) - 1);
|
||||||
*n = i;
|
*n = i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -628,7 +629,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
||||||
// fill last bit
|
// fill last bit
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
i = (~((1 << i) - 1)) & 0xFF;
|
i = 8 - i;
|
||||||
|
i = 255 - ((1 << i) - 1);
|
||||||
*n = i;
|
*n = i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -647,13 +649,62 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
||||||
// fill last bit
|
// fill last bit
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
i = (~((1 << i) - 1)) & 0xFF;
|
i = 8 - i;
|
||||||
|
i = 255 - ((1 << i) - 1);
|
||||||
*n = i;
|
*n = i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParsePartialIPv4: check string to see if it is a partial IPv4 address and
|
||||||
|
// return bits to mask and set netadr_t or 0 if not an address
|
||||||
|
int ParsePartialIPv4(char *s, netadr_t *a)
|
||||||
|
{
|
||||||
|
char *colon = NULL;
|
||||||
|
char *address = a->address.ip;
|
||||||
|
int bits = 8;
|
||||||
|
|
||||||
|
if (!*s)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset (a, 0, sizeof(*a));
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == ':')
|
||||||
|
{
|
||||||
|
if (colon) // only 1 colon
|
||||||
|
return 0;
|
||||||
|
colon = s + 1;
|
||||||
|
}
|
||||||
|
else if (*s == '.')
|
||||||
|
{
|
||||||
|
if (colon) // no colons before periods (probably invalid anyway)
|
||||||
|
return 0;
|
||||||
|
else if (bits >= 32) // only 32 bits in ipv4
|
||||||
|
return 0;
|
||||||
|
else if (*(s+1) == '.')
|
||||||
|
return 0;
|
||||||
|
else if (*(s+1) == '\0')
|
||||||
|
break; // don't add more bits to the mask for x.x., etc
|
||||||
|
bits += 8;
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
else if (*s >= '0' && *s <= '9')
|
||||||
|
*address = ((*address)*10) + (*s-'0');
|
||||||
|
else
|
||||||
|
return 0; // invalid character
|
||||||
|
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->type = NA_IP;
|
||||||
|
if (colon)
|
||||||
|
a->port = atoi(colon);
|
||||||
|
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
// NET_StringToAdrMasked: extension to NET_StringToAdr to handle IP addresses
|
// NET_StringToAdrMasked: extension to NET_StringToAdr to handle IP addresses
|
||||||
// with masks or integers representing the bit masks
|
// with masks or integers representing the bit masks
|
||||||
qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
||||||
|
@ -669,12 +720,12 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
||||||
// we have a slash in the address so split and resolve separately
|
// we have a slash in the address so split and resolve separately
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
i = spoint - s;
|
i = (int)(spoint - s) + 1;
|
||||||
if (i + 1 > sizeof(t))
|
if (i > sizeof(t))
|
||||||
i = sizeof(t);
|
i = sizeof(t);
|
||||||
|
|
||||||
Q_strncpyz(t, s, i);
|
Q_strncpyz(t, s, i);
|
||||||
if (!NET_StringToAdr(t, a))
|
if (!ParsePartialIPv4(t, a) && !NET_StringToAdr(t, a))
|
||||||
return false;
|
return false;
|
||||||
spoint++;
|
spoint++;
|
||||||
|
|
||||||
|
@ -693,7 +744,7 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == NULL) // we have an address so resolve it and return
|
if (c == NULL) // we have an address so resolve it and return
|
||||||
return NET_StringToAdr(spoint, amask);
|
return ParsePartialIPv4(spoint, amask) || NET_StringToAdr(spoint, amask);
|
||||||
|
|
||||||
// otherwise generate mask for given bits
|
// otherwise generate mask for given bits
|
||||||
i = atoi(spoint);
|
i = atoi(spoint);
|
||||||
|
@ -702,13 +753,17 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// we don't have a slash, resolve and fill with a full mask
|
// we don't have a slash, resolve and fill with a full mask
|
||||||
if (!NET_StringToAdr(s, a))
|
i = ParsePartialIPv4(s, a);
|
||||||
|
if (!i && !NET_StringToAdr(s, a))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memset (amask, 0, sizeof(*amask));
|
memset (amask, 0, sizeof(*amask));
|
||||||
amask->type = a->type;
|
amask->type = a->type;
|
||||||
|
|
||||||
NET_IntegerToMask(a, amask, -1);
|
if (i)
|
||||||
|
NET_IntegerToMask(a, amask, i);
|
||||||
|
else
|
||||||
|
NET_IntegerToMask(a, amask, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -774,7 +829,7 @@ int UniformMaskedBits(netadr_t mask)
|
||||||
{
|
{
|
||||||
int bits;
|
int bits;
|
||||||
int b;
|
int b;
|
||||||
int bs;
|
unsigned int bs;
|
||||||
qboolean bitenc = false;
|
qboolean bitenc = false;
|
||||||
|
|
||||||
switch (mask.type)
|
switch (mask.type)
|
||||||
|
@ -788,7 +843,7 @@ int UniformMaskedBits(netadr_t mask)
|
||||||
bitenc = true;
|
bitenc = true;
|
||||||
else if (mask.address.ip[b])
|
else if (mask.address.ip[b])
|
||||||
{
|
{
|
||||||
bs = ~mask.address.ip[b];
|
bs = (~mask.address.ip[b]) & 0xFF;
|
||||||
while (bs)
|
while (bs)
|
||||||
{
|
{
|
||||||
if (bs & 1)
|
if (bs & 1)
|
||||||
|
@ -818,7 +873,7 @@ int UniformMaskedBits(netadr_t mask)
|
||||||
bitenc = true;
|
bitenc = true;
|
||||||
else if (mask.address.ip6[b])
|
else if (mask.address.ip6[b])
|
||||||
{
|
{
|
||||||
bs = ~mask.address.ip6[b];
|
bs = (~mask.address.ip6[b]) & 0xFF;
|
||||||
while (bs)
|
while (bs)
|
||||||
{
|
{
|
||||||
if (bs & 1)
|
if (bs & 1)
|
||||||
|
@ -849,7 +904,7 @@ int UniformMaskedBits(netadr_t mask)
|
||||||
bitenc = true;
|
bitenc = true;
|
||||||
else if (mask.address.ipx[b])
|
else if (mask.address.ipx[b])
|
||||||
{
|
{
|
||||||
bs = ~mask.address.ipx[b];
|
bs = (~mask.address.ipx[b]) & 0xFF;
|
||||||
while (bs)
|
while (bs)
|
||||||
{
|
{
|
||||||
if (bs & 1)
|
if (bs & 1)
|
||||||
|
@ -887,7 +942,13 @@ char *NET_AdrToStringMasked (netadr_t a, netadr_t amask)
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
sprintf(s, "%s/%i", NET_AdrToString(a), i);
|
sprintf(s, "%s/%i", NET_AdrToString(a), i);
|
||||||
else
|
else
|
||||||
sprintf(s, "%s/%s", NET_AdrToString(a), NET_AdrToString(amask));
|
{
|
||||||
|
// has to be done this way due to NET_AdrToString returning a
|
||||||
|
// static address
|
||||||
|
Q_strncatz(s, NET_AdrToString(a), sizeof(s));
|
||||||
|
Q_strncatz(s, "/", sizeof(s));
|
||||||
|
Q_strncatz(s, NET_AdrToString(amask), sizeof(s));
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -651,8 +651,15 @@ typedef struct bannedips_s {
|
||||||
struct bannedips_s *next;
|
struct bannedips_s *next;
|
||||||
netadr_t adr;
|
netadr_t adr;
|
||||||
netadr_t adrmask;
|
netadr_t adrmask;
|
||||||
|
char reason[1];
|
||||||
} bannedips_t;
|
} bannedips_t;
|
||||||
|
|
||||||
|
typedef struct filteredip_s {
|
||||||
|
struct filteredip_s *next;
|
||||||
|
netadr_t adr;
|
||||||
|
netadr_t adrmask;
|
||||||
|
} filteredips_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
|
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
|
||||||
GT_QUAKE2, //q2 servers run from a q2 game dll
|
GT_QUAKE2, //q2 servers run from a q2 game dll
|
||||||
|
@ -711,6 +718,7 @@ typedef struct
|
||||||
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
||||||
|
|
||||||
bannedips_t *bannedips;
|
bannedips_t *bannedips;
|
||||||
|
filteredips_t *filteredips;
|
||||||
|
|
||||||
char progsnames[MAX_PROGS][32];
|
char progsnames[MAX_PROGS][32];
|
||||||
progsnum_t progsnum[MAX_PROGS];
|
progsnum_t progsnum[MAX_PROGS];
|
||||||
|
|
|
@ -638,13 +638,21 @@ void SV_BanName_f (void)
|
||||||
{
|
{
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
int clnum=-1;
|
int clnum=-1;
|
||||||
|
char *reason = NULL;
|
||||||
|
int reasonsize = 0;
|
||||||
|
|
||||||
if (Cmd_Argc() < 2)
|
if (Cmd_Argc() < 2)
|
||||||
{
|
{
|
||||||
Con_Printf("%s userid|nick\n", Cmd_Argv(0));
|
Con_Printf("%s userid|nick [reason]\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Cmd_Argc() > 2)
|
||||||
|
{
|
||||||
|
reason = Cmd_Argv(2);
|
||||||
|
reasonsize = strlen(reason);
|
||||||
|
}
|
||||||
|
|
||||||
while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum)))
|
while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum)))
|
||||||
if (cl)
|
if (cl)
|
||||||
{
|
{
|
||||||
|
@ -656,13 +664,15 @@ void SV_BanName_f (void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nb = Z_Malloc(sizeof(bannedips_t));
|
nb = Z_Malloc(sizeof(bannedips_t)+reasonsize);
|
||||||
nb->next = svs.bannedips;
|
nb->next = svs.bannedips;
|
||||||
nb->adr = cl->netchan.remote_address;
|
nb->adr = cl->netchan.remote_address;
|
||||||
NET_IntegerToMask(&nb->adr, &nb->adrmask, -1); // fill mask
|
NET_IntegerToMask(&nb->adr, &nb->adrmask, -1); // fill mask
|
||||||
if (*Cmd_Argv(2)) //explicit blocking of all ports of a client ip
|
if (*Cmd_Argv(2)) //explicit blocking of all ports of a client ip
|
||||||
nb->adr.port = 0;
|
nb->adr.port = 0;
|
||||||
svs.bannedips = nb;
|
svs.bannedips = nb;
|
||||||
|
if (reasonsize)
|
||||||
|
Q_strcpy(nb->reason, reason);
|
||||||
|
|
||||||
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTWASBANNED, cl->name);
|
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTWASBANNED, cl->name);
|
||||||
// print directly, because the dropped client won't get the
|
// print directly, because the dropped client won't get the
|
||||||
|
@ -682,10 +692,12 @@ void SV_BanIP_f (void)
|
||||||
int i;
|
int i;
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
bannedips_t *nb;
|
bannedips_t *nb;
|
||||||
|
char *reason = NULL;
|
||||||
|
int reasonsize = 0;
|
||||||
|
|
||||||
if (Cmd_Argc() < 2)
|
if (Cmd_Argc() < 2)
|
||||||
{
|
{
|
||||||
Con_Printf("%s address/mask|adress/maskbits\n", Cmd_Argv(0));
|
Con_Printf("%s address/mask|adress/maskbits [reason]\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,6 +713,12 @@ void SV_BanIP_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Cmd_Argc() > 2)
|
||||||
|
{
|
||||||
|
reason = Cmd_Argv(2);
|
||||||
|
reasonsize = strlen(reason);
|
||||||
|
}
|
||||||
|
|
||||||
// loop through clients and kick the ones that match
|
// loop through clients and kick the ones that match
|
||||||
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||||
{
|
{
|
||||||
|
@ -719,11 +737,58 @@ void SV_BanIP_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add IP and mask to ban list
|
// add IP and mask to ban list
|
||||||
nb = Z_Malloc(sizeof(bannedips_t));
|
nb = Z_Malloc(sizeof(bannedips_t)+reasonsize);
|
||||||
nb->next = svs.bannedips;
|
nb->next = svs.bannedips;
|
||||||
nb->adr = banadr;
|
nb->adr = banadr;
|
||||||
nb->adrmask = banmask;
|
nb->adrmask = banmask;
|
||||||
svs.bannedips = nb;
|
svs.bannedips = nb;
|
||||||
|
if (reasonsize)
|
||||||
|
Q_strcpy(nb->reason, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SV_FilterIP_f (void)
|
||||||
|
{
|
||||||
|
netadr_t banadr;
|
||||||
|
netadr_t banmask;
|
||||||
|
int i;
|
||||||
|
client_t *cl;
|
||||||
|
filteredips_t *nb;
|
||||||
|
extern cvar_t filterban;
|
||||||
|
|
||||||
|
if (Cmd_Argc() < 2)
|
||||||
|
{
|
||||||
|
Con_Printf("%s address/mask|adress/maskbits\n", Cmd_Argv(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NET_StringToAdrMasked(Cmd_Argv(1), &banadr, &banmask))
|
||||||
|
{
|
||||||
|
Con_Printf("invalid address or mask\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NET_IsLoopBackAddress(banadr))
|
||||||
|
{
|
||||||
|
Con_Printf("You're not allowed to filter loopback!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through clients and kick the ones that match
|
||||||
|
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||||
|
{
|
||||||
|
if (cl->state<=cs_zombie)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (filterban.value && NET_CompareAdrMasked(cl->netchan.remote_address, banadr, banmask))
|
||||||
|
SV_DropClient (cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add IP and mask to filter list
|
||||||
|
nb = Z_Malloc(sizeof(filteredips_t));
|
||||||
|
nb->next = svs.filteredips;
|
||||||
|
nb->adr = banadr;
|
||||||
|
nb->adrmask = banmask;
|
||||||
|
svs.filteredips = nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SV_BanList_f (void)
|
void SV_BanList_f (void)
|
||||||
|
@ -733,7 +798,10 @@ void SV_BanList_f (void)
|
||||||
|
|
||||||
while (nb)
|
while (nb)
|
||||||
{
|
{
|
||||||
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
if (nb->reason[0])
|
||||||
|
Con_Printf("%s, %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask), nb->reason);
|
||||||
|
else
|
||||||
|
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||||
bancount++;
|
bancount++;
|
||||||
nb = nb->next;
|
nb = nb->next;
|
||||||
}
|
}
|
||||||
|
@ -741,6 +809,21 @@ void SV_BanList_f (void)
|
||||||
Con_Printf("%i total entries in ban list\n", bancount);
|
Con_Printf("%i total entries in ban list\n", bancount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SV_FilterList_f (void)
|
||||||
|
{
|
||||||
|
int filtercount = 0;
|
||||||
|
filteredips_t *nb = svs.filteredips;
|
||||||
|
|
||||||
|
while (nb)
|
||||||
|
{
|
||||||
|
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||||
|
filtercount++;
|
||||||
|
nb = nb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con_Printf("%i total entries in filter list\n", filtercount);
|
||||||
|
}
|
||||||
|
|
||||||
void SV_Unban_f (void)
|
void SV_Unban_f (void)
|
||||||
{
|
{
|
||||||
qboolean all = false;
|
qboolean all = false;
|
||||||
|
@ -766,7 +849,7 @@ void SV_Unban_f (void)
|
||||||
while (nb)
|
while (nb)
|
||||||
{
|
{
|
||||||
nbnext = nb->next;
|
nbnext = nb->next;
|
||||||
if (NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
if (all || NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
||||||
{
|
{
|
||||||
if (!all)
|
if (!all)
|
||||||
Con_Printf("unbanned %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
Con_Printf("unbanned %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||||
|
@ -779,6 +862,44 @@ void SV_Unban_f (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SV_Unfilter_f (void)
|
||||||
|
{
|
||||||
|
qboolean all = false;
|
||||||
|
filteredips_t *nb = svs.filteredips;
|
||||||
|
filteredips_t *nbnext;
|
||||||
|
netadr_t unbanadr = {0};
|
||||||
|
netadr_t unbanmask = {0};
|
||||||
|
|
||||||
|
if (Cmd_Argc() < 2)
|
||||||
|
{
|
||||||
|
Con_Printf("%s address/mask|address/maskbits|all\n", Cmd_Argv(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Q_strcasecmp(Cmd_Argv(1), "all"))
|
||||||
|
all = true;
|
||||||
|
else if (!NET_StringToAdrMasked(Cmd_Argv(1), &unbanadr, &unbanmask))
|
||||||
|
{
|
||||||
|
Con_Printf("invalid address or mask\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nb)
|
||||||
|
{
|
||||||
|
nbnext = nb->next;
|
||||||
|
if (all || NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
||||||
|
{
|
||||||
|
if (!all)
|
||||||
|
Con_Printf("unfiltered %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||||
|
if (svs.filteredips == nb)
|
||||||
|
svs.filteredips = nbnext;
|
||||||
|
Z_Free(nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
nb = nbnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SV_ForceName_f (void)
|
void SV_ForceName_f (void)
|
||||||
{
|
{
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
|
@ -1807,6 +1928,16 @@ void SV_InitOperatorCommands (void)
|
||||||
// Cmd_AddCommand ("ban", SV_BanName_f);
|
// Cmd_AddCommand ("ban", SV_BanName_f);
|
||||||
Cmd_AddCommand ("status", SV_Status_f);
|
Cmd_AddCommand ("status", SV_Status_f);
|
||||||
|
|
||||||
|
Cmd_AddCommand ("addip", SV_FilterIP_f);
|
||||||
|
Cmd_AddCommand ("removeip", SV_Unfilter_f);
|
||||||
|
Cmd_AddCommand ("listip", SV_FilterList_f);
|
||||||
|
|
||||||
|
// Cmd_AddCommand ("filterip", SV_FilterIP_f);
|
||||||
|
// Cmd_AddCommand ("unfilter", SV_Unfilter_f);
|
||||||
|
// Cmd_AddCommand ("filterlist", SV_FilterList_f);
|
||||||
|
|
||||||
|
// Cmd_AddCommand ("writeip", SV_WriteIP_f);
|
||||||
|
|
||||||
Cmd_AddCommand ("sv", SV_SendGameCommand_f);
|
Cmd_AddCommand ("sv", SV_SendGameCommand_f);
|
||||||
|
|
||||||
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
||||||
|
|
|
@ -196,6 +196,7 @@ void SV_FixupName(char *in, char *out);
|
||||||
void SV_AcceptClient (netadr_t adr, int userid, char *userinfo);
|
void SV_AcceptClient (netadr_t adr, int userid, char *userinfo);
|
||||||
void Master_Shutdown (void);
|
void Master_Shutdown (void);
|
||||||
void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
|
void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
|
||||||
|
bannedips_t *SV_BannedAddress (netadr_t *a);
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
@ -1757,18 +1758,16 @@ client_t *SVC_DirectConnect(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
bannedips_t *banip;
|
bannedips_t *banip = SV_BannedAddress(&adr);
|
||||||
for (banip = svs.bannedips; banip; banip=banip->next)
|
if (banip)
|
||||||
{
|
{
|
||||||
if (NET_CompareAdrMasked(adr, banip->adr, banip->adrmask))
|
if (banip->reason[0])
|
||||||
{
|
SV_RejectMessage (protocol, "You were banned.\nReason: %s\n", banip->reason);
|
||||||
SV_RejectMessage (protocol, "You were banned.\nContact the administrator to complain.\n");
|
else
|
||||||
return NULL;
|
SV_RejectMessage (protocol, "You were banned.\n");
|
||||||
}
|
return NULL;
|
||||||
}
|
}
|
||||||
//yay, a legit client who we havn't banned yet.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
edictnum = (newcl-svs.clients)+1;
|
edictnum = (newcl-svs.clients)+1;
|
||||||
|
@ -2091,6 +2090,15 @@ void SVC_RemoteCommand (void)
|
||||||
int i;
|
int i;
|
||||||
char remaining[1024];
|
char remaining[1024];
|
||||||
|
|
||||||
|
{
|
||||||
|
bannedips_t *banip = SV_BannedAddress(&net_from);
|
||||||
|
if (banip)
|
||||||
|
{
|
||||||
|
Con_Printf ("Rcon from banned ip %s\n", NET_AdrToString (net_from));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Rcon_Validate ())
|
if (!Rcon_Validate ())
|
||||||
{
|
{
|
||||||
#ifdef SVRANKING
|
#ifdef SVRANKING
|
||||||
|
@ -2362,136 +2370,8 @@ If 0, then only addresses matching the list will be allowed. This lets you easi
|
||||||
==============================================================================
|
==============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned mask;
|
|
||||||
unsigned compare;
|
|
||||||
} ipfilter_t;
|
|
||||||
|
|
||||||
#define MAX_IPFILTERS 1024
|
|
||||||
|
|
||||||
ipfilter_t ipfilters[MAX_IPFILTERS];
|
|
||||||
int numipfilters;
|
|
||||||
|
|
||||||
cvar_t filterban = SCVAR("filterban", "1");
|
cvar_t filterban = SCVAR("filterban", "1");
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
StringToFilter
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
qboolean StringToFilter (char *s, ipfilter_t *f)
|
|
||||||
{
|
|
||||||
char num[128];
|
|
||||||
int i, j;
|
|
||||||
qbyte b[4];
|
|
||||||
qbyte m[4];
|
|
||||||
|
|
||||||
for (i=0 ; i<4 ; i++)
|
|
||||||
{
|
|
||||||
b[i] = 0;
|
|
||||||
m[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0 ; i<4 ; i++)
|
|
||||||
{
|
|
||||||
if (*s < '0' || *s > '9')
|
|
||||||
{
|
|
||||||
Con_Printf ("Bad filter address: %s\n", s);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
while (*s >= '0' && *s <= '9')
|
|
||||||
{
|
|
||||||
num[j++] = *s++;
|
|
||||||
}
|
|
||||||
num[j] = 0;
|
|
||||||
b[i] = atoi(num);
|
|
||||||
if (b[i] != 0)
|
|
||||||
m[i] = 255;
|
|
||||||
|
|
||||||
if (!*s)
|
|
||||||
break;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
f->mask = *(unsigned *)m;
|
|
||||||
f->compare = *(unsigned *)b;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
SV_AddIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SV_AddIP_f (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
|
||||||
if (ipfilters[i].compare == 0xffffffff)
|
|
||||||
break; // free spot
|
|
||||||
if (i == numipfilters)
|
|
||||||
{
|
|
||||||
if (numipfilters == MAX_IPFILTERS)
|
|
||||||
{
|
|
||||||
Con_Printf ("IP filter list is full\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
numipfilters++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StringToFilter (Cmd_Argv(1), &ipfilters[i]))
|
|
||||||
ipfilters[i].compare = 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
SV_RemoveIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SV_RemoveIP_f (void)
|
|
||||||
{
|
|
||||||
ipfilter_t f;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (!StringToFilter (Cmd_Argv(1), &f))
|
|
||||||
return;
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
|
||||||
if (ipfilters[i].mask == f.mask
|
|
||||||
&& ipfilters[i].compare == f.compare)
|
|
||||||
{
|
|
||||||
for (j=i+1 ; j<numipfilters ; j++)
|
|
||||||
ipfilters[j-1] = ipfilters[j];
|
|
||||||
numipfilters--;
|
|
||||||
Con_Printf ("Removed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Con_Printf ("Didn't find %s.\n", Cmd_Argv(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
SV_ListIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SV_ListIP_f (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
qbyte b[4];
|
|
||||||
|
|
||||||
Con_Printf ("Filter list:\n");
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
|
||||||
{
|
|
||||||
*(unsigned *)b = ipfilters[i].compare;
|
|
||||||
Con_Printf ("%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
SV_WriteIP_f
|
SV_WriteIP_f
|
||||||
|
@ -2499,6 +2379,8 @@ SV_WriteIP_f
|
||||||
*/
|
*/
|
||||||
void SV_WriteIP_f (void)
|
void SV_WriteIP_f (void)
|
||||||
{
|
{
|
||||||
|
// TODO: function needs to be rewritten to handle new banning and filtering logic
|
||||||
|
/*
|
||||||
vfsfile_t *f;
|
vfsfile_t *f;
|
||||||
char name[MAX_OSPATH];
|
char name[MAX_OSPATH];
|
||||||
qbyte b[4];
|
qbyte b[4];
|
||||||
|
@ -2524,23 +2406,7 @@ void SV_WriteIP_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS_CLOSE (f);
|
VFS_CLOSE (f);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
SV_SendBan
|
|
||||||
=================
|
|
||||||
*/
|
*/
|
||||||
void SV_SendBan (void)
|
|
||||||
{
|
|
||||||
char data[128];
|
|
||||||
|
|
||||||
data[0] = data[1] = data[2] = data[3] = 0xff;
|
|
||||||
data[4] = A2C_PRINT;
|
|
||||||
data[5] = 0;
|
|
||||||
strcat (data, "\nbanned.\n");
|
|
||||||
|
|
||||||
NET_SendPacket (NS_SERVER, strlen(data), data, net_from);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2548,20 +2414,34 @@ void SV_SendBan (void)
|
||||||
SV_FilterPacket
|
SV_FilterPacket
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
qboolean SV_FilterPacket (void)
|
qboolean SV_FilterPacket (netadr_t *a)
|
||||||
{
|
{
|
||||||
int i;
|
filteredips_t *banip;
|
||||||
unsigned in;
|
|
||||||
|
|
||||||
in = *(unsigned *)net_from.address.ip;
|
if (NET_IsLoopBackAddress(*a))
|
||||||
|
return 0; // never filter loopback
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
for (banip = svs.filteredips; banip; banip=banip->next)
|
||||||
if ( (in & ipfilters[i].mask) == ipfilters[i].compare)
|
{
|
||||||
|
if (NET_CompareAdrMasked(*a, banip->adr, banip->adrmask))
|
||||||
return filterban.value;
|
return filterban.value;
|
||||||
|
}
|
||||||
return !filterban.value;
|
return !filterban.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SV_BannedAdress, run through ban address list and return corresponding bannedips_t
|
||||||
|
// pointer, otherwise return NULL if not in the list
|
||||||
|
bannedips_t *SV_BannedAddress (netadr_t *a)
|
||||||
|
{
|
||||||
|
bannedips_t *banip;
|
||||||
|
for (banip = svs.bannedips; banip; banip=banip->next)
|
||||||
|
{
|
||||||
|
if (NET_CompareAdrMasked(*a, banip->adr, banip->adrmask))
|
||||||
|
return banip;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//send a network packet to a new non-connected client.
|
//send a network packet to a new non-connected client.
|
||||||
//this is to combat tunneling
|
//this is to combat tunneling
|
||||||
void SV_OpenRoute_f(void)
|
void SV_OpenRoute_f(void)
|
||||||
|
@ -2598,11 +2478,8 @@ void SV_ReadPackets (void)
|
||||||
good = false;
|
good = false;
|
||||||
while (SV_GetPacket ())
|
while (SV_GetPacket ())
|
||||||
{
|
{
|
||||||
if (SV_FilterPacket ())
|
if (SV_FilterPacket (&net_from))
|
||||||
{
|
|
||||||
SV_SendBan (); // tell them we aren't listening...
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// check for connectionless packet (0xffffffff) first
|
// check for connectionless packet (0xffffffff) first
|
||||||
if (*(int *)net_message.data == -1)
|
if (*(int *)net_message.data == -1)
|
||||||
|
@ -3235,11 +3112,6 @@ void SV_InitLocal (void)
|
||||||
|
|
||||||
Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
|
Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
|
||||||
|
|
||||||
Cmd_AddCommand ("addip", SV_AddIP_f);
|
|
||||||
Cmd_AddCommand ("removeip", SV_RemoveIP_f);
|
|
||||||
Cmd_AddCommand ("listip", SV_ListIP_f);
|
|
||||||
Cmd_AddCommand ("writeip", SV_WriteIP_f);
|
|
||||||
|
|
||||||
Cmd_AddCommand ("sv_impulse", SV_Impulse_f);
|
Cmd_AddCommand ("sv_impulse", SV_Impulse_f);
|
||||||
|
|
||||||
Cmd_AddCommand ("openroute", SV_OpenRoute_f);
|
Cmd_AddCommand ("openroute", SV_OpenRoute_f);
|
||||||
|
|
|
@ -2911,6 +2911,7 @@ void SVQ3_HandleClient(void)
|
||||||
SVQ3_ParseClientMessage(&svs.clients[i]);
|
SVQ3_ParseClientMessage(&svs.clients[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bannedips_t *SV_BannedAddress (netadr_t *a);
|
||||||
void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and let the gamecode know of it.
|
void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and let the gamecode know of it.
|
||||||
{
|
{
|
||||||
char *reason;
|
char *reason;
|
||||||
|
@ -2919,6 +2920,7 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
|
||||||
int ret;
|
int ret;
|
||||||
int challenge;
|
int challenge;
|
||||||
int qport;
|
int qport;
|
||||||
|
bannedips_t *banip;
|
||||||
|
|
||||||
if (net_message.cursize < 13)
|
if (net_message.cursize < 13)
|
||||||
return;
|
return;
|
||||||
|
@ -2934,7 +2936,17 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
|
||||||
if (!cl)
|
if (!cl)
|
||||||
cl = SVQ3_FindEmptyPlayerSlot();
|
cl = SVQ3_FindEmptyPlayerSlot();
|
||||||
|
|
||||||
if (!cl)
|
banip = SV_BannedAddress(&net_from);
|
||||||
|
|
||||||
|
if (banip)
|
||||||
|
{
|
||||||
|
if (banip->reason[0])
|
||||||
|
reason = banip->reason;
|
||||||
|
else
|
||||||
|
reason = "Banned.";
|
||||||
|
userinfo = NULL;
|
||||||
|
}
|
||||||
|
else if (!cl)
|
||||||
{
|
{
|
||||||
reason = "Server is full.";
|
reason = "Server is full.";
|
||||||
userinfo = NULL;
|
userinfo = NULL;
|
||||||
|
|
Loading…
Reference in a new issue