Admin user role first shot + ban and kick.
authorMartin Johansson <martin@fatbob.nu>
Sat, 25 Feb 2012 00:14:23 +0000 (01:14 +0100)
committerMartin Johansson <martin@fatbob.nu>
Sat, 25 Feb 2012 00:14:23 +0000 (01:14 +0100)
src/ban.c [new file with mode: 0644]
src/ban.h [new file with mode: 0644]
src/client.c
src/client.h
src/messagehandler.c

diff --git a/src/ban.c b/src/ban.c
new file mode 100644 (file)
index 0000000..043cbc1
--- /dev/null
+++ b/src/ban.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 2009-2011, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
+
+   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 <stdlib.h>
+#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 (file)
index 0000000..dbc97d3
--- /dev/null
+++ b/src/ban.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 2009-2011, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
+
+   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
index e4936e2419ef15f6091ceaa6bddd73ab25e5e9d6..81269b6134bfb8a70b250d2d178d4c9c9e69f5ff 100644 (file)
@@ -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");
index 0e5e1353300fdb2e1fdd3e48fab9151f7b536b0c..78d45fc0cf52e3e8542d854dc16beb3fde8e7df3 100644 (file)
@@ -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;
index 1b94204294e4393fc877ef1fcd55669e053f69d1..0b7c2328db534da0c83ee69fe1b025ad2303a4d4 100644 (file)
@@ -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");
                }