#include <time.h>
#include <string.h>
#include "log.h"
+#include "memory.h"
#include "list.h"
#include "ban.h"
#include "conf.h"
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);
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;
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);
}
{
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);
{
struct dlist *itr;
ban_t *ban;
- char* addressString = Util_addressToString(address);
list_iterate(itr, &banlist) {
ban = list_get_entry(itr, ban_t, node);
-
- if( strncmp(Util_addressToString(&ban->address), addressString, ban->mask) == 0) {
- return true;
+ 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 {
+ 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;
+ }
}
-
}
+
return false;
}
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);
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) {
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++;
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;
if (p == NULL) break;
reason = p;
- ban = malloc(sizeof(ban_t));
- if (ban == NULL)
- Log_fatal("Out of memory");
+ ban = Memory_safeMalloc(1, sizeof(ban_t));
memset(ban, 0, sizeof(ban_t));
SSLi_hex2hash(hexhash, ban->hash);
if (inet_pton(AF_INET, address, &ban->address) == 0) {
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);