X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fban.c;h=84e95dc174e7a3ed881b616a70f4a75d39f573b6;hb=HEAD;hp=667bdc8ecec353114b7e8a65e9db2c2b39f45795;hpb=cb6f0e94e2fb2a513810d515526fbc3035a76bda;p=umurmur.git diff --git a/src/ban.c b/src/ban.c index 667bdc8..84e95dc 100644 --- a/src/ban.c +++ b/src/ban.c @@ -33,6 +33,7 @@ #include #include #include "log.h" +#include "memory.h" #include "list.h" #include "ban.h" #include "conf.h" @@ -70,9 +71,7 @@ void Ban_UserBan(client_t *client, char *reason) ban_t *ban; char hexhash[41]; - ban = calloc(1, sizeof(ban_t)); - if (ban == NULL) - Log_fatal("Out of memory"); + ban = Memory_safeCalloc(1, sizeof(ban_t)); memcpy(ban->hash, client->hash, 20); @@ -82,7 +81,6 @@ void Ban_UserBan(client_t *client, char *reason) ban->name = strdup(client->username); ban->time = time(NULL); ban->duration = ban_duration; - Timer_init(&ban->startTime); list_add_tail(&ban->node, &banlist); bancount++; banlist_changed = true; @@ -91,8 +89,12 @@ void Ban_UserBan(client_t *client, char *reason) SSLi_hash2hex(ban->hash, hexhash); + char *clientAddressString = Util_clientAddressToString(client); + Log_info_client(client, "User kickbanned. Reason: '%s' Hash: %s IP: %s Banned for: %d seconds", - ban->reason, hexhash, Util_clientAddressToString(client), ban->duration); + ban->reason, hexhash, clientAddressString, ban->duration); + + free(clientAddressString); } @@ -100,19 +102,20 @@ void Ban_pruneBanned() { struct dlist *itr; ban_t *ban; - uint64_t bantime_long; list_iterate(itr, &banlist) { ban = list_get_entry(itr, ban_t, node); - bantime_long = ban->duration * 1000000LL; #ifdef DEBUG + char hexhash[41]; SSLi_hash2hex(ban->hash, hexhash); + char *addressString = Util_addressToString(&ban->address); Log_debug("BL: User %s Reason: '%s' Hash: %s IP: %s Time left: %d", - ban->name, ban->reason, hexhash, Util_addressToString(&ban->address)), - bantime_long / 1000000LL - Timer_elapsed(&ban->startTime) / 1000000LL); + ban->name, ban->reason, hexhash, addressString, + ban->time + ban->duration - time(NULL)); + free(addressString); #endif /* Duration of 0 = forever */ - if (ban->duration != 0 && Timer_isElapsed(&ban->startTime, bantime_long)) { + if (ban->duration != 0 && ban->time + ban->duration - time(NULL) <= 0) { free(ban->name); free(ban->reason); list_del(&ban->node); @@ -142,41 +145,36 @@ bool_t Ban_isBannedAddr(struct sockaddr_storage *address) { struct dlist *itr; ban_t *ban; - uint64_t clientAddressBytes[2] = {0}; - uint64_t banAddressBytes[2] = {0}; - uint64_t banMaskBits[2] = {UINT64_MAX}; - - if (address->ss_family == AF_INET) { - memcpy(clientAddressBytes, &((struct sockaddr_in *)address)->sin_addr, 4); - } else { - memcpy(clientAddressBytes, &((struct sockaddr_in6 *)address)->sin6_addr, 16); - } list_iterate(itr, &banlist) { ban = list_get_entry(itr, ban_t, node); - - if(address->ss_len == ban->address.ss_family) { - if (ban->address.ss_family == AF_INET) { - memcpy(banAddressBytes, &((struct sockaddr_in *)&ban->address)->sin_addr, 4); + if (ban->address.ss_family == address->ss_family) { + if (address->ss_family == AF_INET) { + uint32_t a1, a2, mask; + mask = (ban->mask == 32) ? UINT32_MAX : (1u << ban->mask) - 1; + a1 = (uint32_t)((struct sockaddr_in *)&ban->address)->sin_addr.s_addr & mask; + a2 = (uint32_t)((struct sockaddr_in *)address)->sin_addr.s_addr & mask; + if (a1 == a2) + return true; } else { - memcpy(banAddressBytes, &((struct sockaddr_in6 *)&ban->address)->sin6_addr, 16); + uint64_t mask[2]; + uint64_t *a1 = (uint64_t *) &((struct sockaddr_in6 *)&ban->address)->sin6_addr.s6_addr; + uint64_t *a2 = (uint64_t *) &((struct sockaddr_in6 *)address)->sin6_addr.s6_addr; + + if (ban->mask == 128) + mask[0] = mask[1] = 0xffffffffffffffffULL; + else if (ban->mask > 64) { + mask[0] = 0xffffffffffffffffULL; + mask[1] = SWAPPED(~((1ULL << (128 - ban->mask)) - 1)); + } else { + mask[0] = SWAPPED(~((1ULL << (64 - ban->mask)) - 1)); + mask[1] = 0ULL; + } + if ((a1[0] & mask[0]) == (a2[0] & mask[0]) && + (a1[1] & mask[1]) == (a2[1] & mask[1])) + return true; } - - banMaskBits[0] <<= (ban->mask >= 64) ? 0 : 64 - ban->mask; - banMaskBits[1] <<= (ban->mask > 64) ? 128 - ban->mask : 64; - - clientAddressBytes[0] &= banMaskBits[0]; - clientAddressBytes[1] &= banMaskBits[1]; - - banAddressBytes[0] &= banMaskBits[0]; - banAddressBytes[1] &= banMaskBits[1]; - - if (memcmp(clientAddressBytes, banAddressBytes, 16) == 0) { - return true; - } - } - } return false; @@ -202,7 +200,7 @@ message_t *Ban_getBanList(void) list_iterate(itr, &banlist) { ban = list_get_entry(itr, ban_t, node); gmtime_r(&ban->time, ×pec); - strftime(timestr, 32, "%Y-%m-%dT%H:%M:%S", ×pec); + strftime(timestr, 32, "%Y-%m-%dT%H:%M:%SZ", ×pec); SSLi_hash2hex(ban->hash, hexhash); memset(address, 0, 16); @@ -242,12 +240,11 @@ void Ban_putBanList(message_t *msg, int n_bans) uint32_t duration, mask; uint8_t *address; char mappedBytes[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff}; + char *tz; for (i = 0; i < n_bans; i++) { Msg_banList_getEntry(msg, i, &address, &mask, &name, &hexhash, &reason, &start, &duration); - ban = malloc(sizeof(ban_t)); - if (ban == NULL) - Log_fatal("Out of memory"); + ban = Memory_safeMalloc(1, sizeof(ban_t)); SSLi_hex2hash(hexhash, ban->hash); if(memcmp(address, mappedBytes, 12) == 0) { @@ -264,9 +261,24 @@ void Ban_putBanList(message_t *msg, int n_bans) ban->mask = mask; ban->reason = strdup(reason); ban->name = strdup(name); + + /* + * Parse the timestring. We need to set TZ to UTC so that mktime() knows that the info in + * struct tm indeed is given in UTC. Otherwise it will use the current locale. There's + * apparently no other way to do this... + */ + memset(×pec, 0, sizeof(struct tm)); strptime(start, "%Y-%m-%dT%H:%M:%S", ×pec); + tz = getenv("TZ"); + setenv("TZ", "UTC", 1); + tzset(); ban->time = mktime(×pec); - ban->startTime = ban->time * 1000000LL; + if (tz) + setenv("TZ", tz, 1); + else + unsetenv("TZ"); + tzset(); + ban->duration = duration; list_add_tail(&ban->node, &banlist); bancount++; @@ -294,7 +306,9 @@ static void Ban_saveBanFile(void) ban = list_get_entry(itr, ban_t, node); SSLi_hash2hex(ban->hash, hexhash); - fprintf(file, "%s,%s,%d,%ld,%d,%s,%s\n", hexhash, Util_addressToString(&ban->address),ban->mask, (long int)ban->time, ban->duration, ban->name, ban->reason); + char *addressString = Util_addressToString(&ban->address); + fprintf(file, "%s,%s,%d,%ld,%d,%s,%s\n", hexhash, addressString,ban->mask, (long int)ban->time, ban->duration, ban->name, ban->reason); + free(addressString); } fclose(file); banlist_changed = false; @@ -337,10 +351,7 @@ static void Ban_readBanFile(void) if (p == NULL) break; reason = p; - ban = malloc(sizeof(ban_t)); - if (ban == NULL) - Log_fatal("Out of memory"); - memset(ban, 0, sizeof(ban_t)); + ban = Memory_safeCalloc(1, sizeof(ban_t)); SSLi_hex2hash(hexhash, ban->hash); if (inet_pton(AF_INET, address, &ban->address) == 0) { if (inet_pton(AF_INET6, address, &ban->address) == 0) { @@ -358,7 +369,6 @@ static void Ban_readBanFile(void) ban->time = time; ban->duration = duration; ban->mask = mask; - ban->startTime = ban->time * 1000000LL; list_add_tail(&ban->node, &banlist); bancount++; Log_debug("Banfile: H = '%s' A = '%s' M = %d U = '%s' R = '%s'", hexhash, address, ban->mask, ban->name, ban->reason);