Merge branch 'refs/heads/t/mixer-fix'
[paraslash.git] / acl.c
diff --git a/acl.c b/acl.c
index 02df1e4..2c90052 100644 (file)
--- a/acl.c
+++ b/acl.c
@@ -1,18 +1,20 @@
-/*
- * Copyright (C) 2005-2010 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file acl.c Access control lists for paraslash senders. */
 
+#include <netinet/in.h>
+#include <sys/socket.h>
 #include <regex.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <netdb.h>
 
 #include "para.h"
 #include "error.h"
 #include "string.h"
 #include "list.h"
 #include "net.h"
+#include "acl.h"
 
 /**
  * Describes one entry in the blacklist/whitelist of a paraslash sender.
@@ -29,10 +31,12 @@ struct access_info {
 /**
  * Return true if addr_1 matches addr_2 in the first `netmask' bits.
  */
-static int v4_addr_match(uint32_t addr_1, uint32_t addr_2, uint8_t netmask)
+static bool v4_addr_match(uint32_t addr_1, uint32_t addr_2, uint8_t netmask)
 {
        uint32_t mask = ~0U;
 
+       if (netmask == 0) /* avoid 32-bit shift, which is undefined in C. */
+               return true;
        if (netmask < 32)
                mask <<= (32 - netmask);
        return (htonl(addr_1) & mask) == (htonl(addr_2) & mask);
@@ -57,7 +61,7 @@ static int acl_lookup(int fd, struct list_head *acl)
                PARA_ERROR_LOG("Can not determine peer address: %s\n", strerror(errno));
                goto no_match;
        }
-       v4_addr = extract_v4_addr(&ss);
+       extract_v4_addr(&ss, &v4_addr);
        if (!v4_addr.s_addr)
                goto no_match;
 
@@ -75,13 +79,13 @@ no_match:
  * \param addr The address to add.
  * \param netmask The netmask to use for this entry.
  */
-static void acl_add_entry(struct list_head *acl, char *addr, int netmask)
+void acl_add_entry(struct list_head *acl, char *addr, int netmask)
 {
        struct access_info *ai = para_malloc(sizeof(struct access_info));
 
        inet_pton(AF_INET, addr, &ai->addr);
        ai->netmask = netmask;
-       PARA_INFO_LOG("adding %s/%i to access list\n", addr, ai->netmask);
+       PARA_INFO_LOG("adding %s/%u to access list\n", addr, ai->netmask);
        para_list_add(&ai->node, acl);
 }
 
@@ -97,14 +101,18 @@ static void acl_del_entry(struct list_head *acl, char *addr, unsigned netmask)
        struct access_info *ai, *tmp;
        struct in_addr to_delete;
 
+       PARA_NOTICE_LOG("removing entries matching %s/%u\n", addr, netmask);
        inet_pton(AF_INET, addr, &to_delete);
 
        list_for_each_entry_safe(ai, tmp, acl, node) {
-
                if (v4_addr_match(to_delete.s_addr, ai->addr.s_addr,
                                        PARA_MIN(netmask, ai->netmask))) {
-                       PARA_NOTICE_LOG("removing %s/%i from access list\n",
-                                       addr, ai->netmask);
+                       char dst[INET_ADDRSTRLEN + 1];
+                       const char *p = inet_ntop(AF_INET, &ai->addr.s_addr,
+                               dst, sizeof(dst));
+                       if (p)
+                               PARA_INFO_LOG("removing %s/%u\n", p,
+                                       ai->netmask);
                        list_del(&ai->node);
                        free(ai);
                }
@@ -125,7 +133,7 @@ char *acl_get_contents(struct list_head *acl)
        char *ret = NULL;
 
        list_for_each_entry_safe(ai, tmp_ai, acl, node) {
-               char *tmp = make_message("%s%s/%d ", ret? ret : "",
+               char *tmp = make_message("%s%s/%u ", ret? ret : "",
                        inet_ntoa(ai->addr), ai->netmask);
                free(ret);
                ret = tmp;
@@ -133,27 +141,6 @@ char *acl_get_contents(struct list_head *acl)
        return ret;
 }
 
-/**
- * Initialize an access control list.
- *
- * \param acl The list to initialize.
- * \param acl_info An array of strings of the form ip/netmask.
- * \param num The number of strings in \a acl_info.
- */
-void acl_init(struct list_head *acl, char * const *acl_info, int num)
-{
-       char    addr[16];
-       int     mask, i;
-
-       INIT_LIST_HEAD(acl);
-       for (i = 0; i < num; i++)
-               if (parse_cidr(acl_info[i], addr, sizeof(addr), &mask) == NULL)
-                       PARA_CRIT_LOG("ACL syntax error: %s, ignoring\n",
-                                     acl_info[i]);
-               else
-                       acl_add_entry(acl, addr, mask);
-}
-
 /**
  * Check whether the peer name of a given fd is allowed by an acl.
  *