From: Martin Johansson Date: Sat, 25 Feb 2012 00:14:23 +0000 (+0100) Subject: Admin user role first shot + ban and kick. X-Git-Url: http://git.code-monkey.de/?p=umurmur.git;a=commitdiff_plain;h=1f6407aa1a69c734dfeb202a967609c99403f947 Admin user role first shot + ban and kick. --- diff --git a/src/ban.c b/src/ban.c new file mode 100644 index 0000000..043cbc1 --- /dev/null +++ b/src/ban.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2009-2011, Martin Johansson + Copyright (C) 2005-2011, Thorvald Natvig + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Developers nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "log.h" +#include "list.h" +#include "ban.h" +#include "conf.h" +#include "ssl.h" + +declare_list(banlist); +static int bancount; /* = 0 */ + +void Ban_UserBan(client_t *client, char *reason) +{ + ban_t *ban; + char hexhash[41]; + + ban = malloc(sizeof(ban_t)); + memcpy(ban->hash, client->hash, 20); + memcpy(&ban->address, &client->remote_tcp.sin_addr, sizeof(in_addr_t)); + ban->reason = strdup(reason); + ban->name = strdup(client->username); + Timer_init(&ban->startTime); + list_add_tail(&ban->node, &banlist); + + SSLi_hash2hex(ban->hash, hexhash); + Log_info("User %s kickbanned. Reason: '%s' Hash: %s IP: %s Banned for: %d seconds", + ban->name, ban->reason, hexhash, inet_ntoa(*((struct in_addr *)&ban->address)), + getIntConf(BAN_LENGTH)); +} + + +void Ban_pruneBanned() +{ + struct dlist *itr; + static int64_t bantime = 0; + ban_t *ban; + char hexhash[41]; + + if (bantime == 0) { + bantime = getIntConf(BAN_LENGTH) * 1000000LL; + } + + list_iterate(itr, &banlist) { + ban = list_get_entry(itr, ban_t, node); + if (Timer_isElapsed(&ban->startTime, bantime)) { + + free(ban->name); + free(ban->reason); + list_del(&ban->node); + free(ban); + } +#ifdef DEBUG + SSLi_hash2hex(ban->hash, hexhash); + Log_debug("BL: User %s Reason: '%s' Hash: %s IP: %s", + ban->name, ban->reason, hexhash, inet_ntoa(*((struct in_addr *)&ban->address))); +#endif + } +} + +bool_t Ban_isBanned(client_t *client) +{ + struct dlist *itr; + ban_t *ban; + list_iterate(itr, &banlist) { + ban = list_get_entry(itr, ban_t, node); + if (memcmp(ban->hash, client->hash, 20) == 0) + return true; + } + return false; + +} + +bool_t Ban_isBannedAddr(in_addr_t *addr) +{ + struct dlist *itr; + ban_t *ban; + list_iterate(itr, &banlist) { + ban = list_get_entry(itr, ban_t, node); + if (memcmp(&ban->address, addr, sizeof(in_addr_t)) == 0) + return true; + } + return false; +} + diff --git a/src/ban.h b/src/ban.h new file mode 100644 index 0000000..dbc97d3 --- /dev/null +++ b/src/ban.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2009-2011, Martin Johansson + Copyright (C) 2005-2011, Thorvald Natvig + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Developers nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef BAN_H_679468247 +#define BAN_H_679468247 + +#include "client.h" +#include "list.h" +#include "timer.h" + +typedef struct { + uint8_t hash[20]; + in_addr_t address; + char *reason; + char *name; + etimer_t startTime; + struct dlist node; +} ban_t; + +void Ban_UserBan(client_t *client, char *reason); +void Ban_pruneBanned(); +bool_t Ban_isBanned(client_t *client); +bool_t Ban_isBannedAddr(in_addr_t *addr); + +#endif diff --git a/src/client.c b/src/client.c index e4936e2..81269b6 100644 --- a/src/client.c +++ b/src/client.c @@ -45,6 +45,7 @@ #include "channel.h" #include "version.h" #include "voicetarget.h" +#include "ban.h" extern char system_string[], version_string[]; @@ -106,6 +107,7 @@ void Client_janitor() Client_free(c); } } + Ban_pruneBanned(); } void Client_codec_add(client_t *client, int codec) @@ -288,7 +290,11 @@ int Client_add(int fd, struct sockaddr_in *remote) { client_t *newclient; message_t *sendmsg; - + + if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) { + Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr)); + return -1; + } newclient = malloc(sizeof(client_t)); if (newclient == NULL) Log_fatal("Out of memory"); diff --git a/src/client.h b/src/client.h index 0e5e135..78d45fc 100644 --- a/src/client.h +++ b/src/client.h @@ -89,6 +89,8 @@ typedef struct { struct dlist voicetargets; struct dlist tokens; int tokencount; + uint8_t hash[20]; + bool_t isAdmin; float UDPPingAvg, UDPPingVar, TCPPingAvg, TCPPingVar; uint32_t UDPPackets, TCPPackets; } client_t; diff --git a/src/messagehandler.c b/src/messagehandler.c index 1b94204..0b7c232 100644 --- a/src/messagehandler.c +++ b/src/messagehandler.c @@ -122,20 +122,16 @@ void Mh_handle_message(client_t *client, message_t *msg) if (msg->payload.authenticate->n_tokens > 0) { Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username, msg->payload.authenticate->n_tokens); - addTokens(client, msg); - - /* Check if admin PW among tokens */ - if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 && - Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) { - client->isAdmin = true; - Log_info("User is admin"); - } + addTokens(client, msg); } break; } - client->authenticated = true; SSLi_getSHA1Hash(client->ssl, client->hash); + if (Ban_isBanned(client)) + goto disconnect; + + client->authenticated = true; client_itr = NULL; while (Client_iterate(&client_itr) != NULL) { @@ -826,8 +822,7 @@ void Mh_handle_message(client_t *client, message_t *msg) msg->payload.userRemove->actor = client->sessionId; if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) { - Log_info("User banned for %d seconds", getIntConf(BAN_LENGTH)); - /* Put reason, IP, hash, name etc in a list ---> msg->payload.userRemove->reason */ + Ban_UserBan(target, msg->payload.userRemove->reason); } else { Log_info("User kicked"); }