- Share some similar/duplicate code between the http and the dccp sender.
- Generic access control lists for paraslash senders.
+ - Access control for the dccp sender.
- Update to gengetopt-2.22
- fix a bug in the "off" command of the http sender.
- fix some fd and memory leaks.
*
* \return One if \a fd belongs to \a acl, zero otherwise.
*/
-int acl_lookup(int fd, struct list_head *acl)
+static int acl_lookup(int fd, struct list_head *acl)
{
struct access_info *ai, *tmp;
struct sockaddr_storage ss;
* \param addr The address to add.
* \param netmask The netmask to use for this entry.
*/
-void acl_add_entry(struct list_head *acl, struct in_addr addr,
+static void acl_add_entry(struct list_head *acl, struct in_addr addr,
int netmask)
{
struct access_info *ai = para_malloc(sizeof(struct access_info));
* \param addr The address to delete.
* \param netmask The netmask of the entry to be removed from the list.
*/
-void acl_del_entry(struct list_head *acl, struct in_addr addr,
+static void acl_del_entry(struct list_head *acl, struct in_addr addr,
int netmask)
{
struct access_info *ai, *tmp;
}
}
+
+/**
+ * Check whether the peer name of a given fd is allowed by an acl.
+ *
+ * \param fd File descriptor.
+ * \param acl The access control list.
+ * \param default_deny Whether \a acl is a whitelist.
+ *
+ * \return Positive if the peer of \a fd is permitted by \a acl, \p -E_ACL_PERM
+ * otherwise.
+ */
+int acl_check_access(int fd, struct list_head *acl, int default_deny)
+{
+ int match = acl_lookup(fd, acl);
+
+ return (!match || default_deny) && (match || !default_deny)?
+ 1 : -E_ACL_PERM;
+}
+
+/**
+ * Permit access for a range of IP addresses.
+ *
+ * \param addr The address to permit.
+ * \param netmask The netmask of the entry to be permitted.
+ * \param acl The access control list.
+ * \param default_deny Whether \a acl is a whitelist.
+ */
+void acl_allow(struct in_addr addr, int netmask,
+ struct list_head *acl, int default_deny)
+{
+ if (default_deny)
+ acl_add_entry(acl, addr, netmask);
+ else
+ acl_del_entry(acl, addr, netmask);
+}
+
+/**
+ * Deny access for a range of IP addresses.
+ *
+ * \param addr The address to permit.
+ * \param netmask The netmask of the entry to be permitted.
+ * \param acl The access control list.
+ * \param default_deny Whether \a acl is a whitelist.
+ */
+void acl_deny(struct in_addr addr, int netmask,
+ struct list_head *acl, int default_deny)
+{
+ acl_allow(addr, netmask, acl, !default_deny);
+}
/** \file acl.h Exported functions of acl.c. */
void acl_init(struct list_head *acl, char * const *acl_info, int num);
-int acl_lookup(int fd, struct list_head *acl);
-void acl_add_entry(struct list_head *acl, struct in_addr addr,
- int netmask);
-void acl_del_entry(struct list_head *acl, struct in_addr addr,
- int netmask);
char *acl_get_contents(struct list_head *acl);
+int acl_check_access(int fd, struct list_head *acl, int default_deny);
+void acl_allow(struct in_addr addr, int netmask,
+ struct list_head *acl, int default_deny);
+void acl_deny(struct in_addr addr, int netmask,
+ struct list_head *acl, int default_deny);
#include "close_on_fork.h"
#include "chunk_queue.h"
#include "server.cmdline.h"
+#include "acl.h"
/** the list of connected clients **/
static struct list_head clients;
+/** The whitelist/blacklist. */
+static struct list_head dccp_acl;
static int listen_fd = -1;
/** Maximal number of bytes in a chunk queue. */
goto err;
}
ret = mark_fd_nonblocking(fd);
+ if (ret < 0)
+ goto err;
+ ret = acl_check_access(fd, &dccp_acl, conf.dccp_default_deny_given);
if (ret < 0)
goto err;
sc = para_calloc(sizeof(*sc));
shutdown_client(sc);
}
+static int dccp_com_deny(struct sender_command_data *scd)
+{
+ acl_deny(scd->addr, scd->netmask, &dccp_acl,
+ conf.dccp_default_deny_given);
+ return 1;
+}
+
+static int dccp_com_allow(struct sender_command_data *scd)
+{
+ acl_allow(scd->addr, scd->netmask, &dccp_acl,
+ conf.dccp_default_deny_given);
+ return 1;
+}
+
static char *dccp_info(void)
{
int num_clients = 0;
s->help = dccp_help;
s->client_cmds[SENDER_ON] = NULL;
s->client_cmds[SENDER_OFF] = NULL;
- s->client_cmds[SENDER_DENY] = NULL;
- s->client_cmds[SENDER_ALLOW] = NULL;
+ s->client_cmds[SENDER_DENY] = dccp_com_deny;
+ s->client_cmds[SENDER_ALLOW] = dccp_com_allow;
s->client_cmds[SENDER_ADD] = NULL;
s->client_cmds[SENDER_DELETE] = NULL;
+ acl_init(&dccp_acl, conf.dccp_access_arg, conf.dccp_access_given);
ret = open_sender(IPPROTO_DCCP, conf.dccp_port_arg);
if (ret < 0)
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
#define AFH_COMMON_ERRORS
#define RBTREE_ERRORS
#define RECV_ERRORS
-#define ACL_ERRORS
#define SEND_COMMON_ERRORS
extern const char **para_errlist[];
+#define ACL_ERRORS \
+ PARA_ERROR(ACL_PERM, "access denied by acl"), \
+
+
#define FSCK_ERRORS \
PARA_ERROR(FSCK_SYNTAX, "fsck syntax error"), \
PARA_ERROR(RANGE_VIOLATION, "range violation detected, very bad"), \
#define HTTP_SEND_ERRORS \
PARA_ERROR(WRITE_OK, "can not check whether fd is writable"), \
PARA_ERROR(MAX_CLIENTS, "maximal number of clients exceeded"), \
- PARA_ERROR(ACL_PERM, "access denied by acl"), \
#define COMMAND_ERRORS \
static void http_post_select(fd_set *rfds, __a_unused fd_set *wfds)
{
- int ret, fd, match;
+ int ret, fd;
struct sender_client *sc, *tmp;
struct private_http_sender_data *phsd;
ret = mark_fd_nonblocking(fd);
if (ret < 0)
goto err_out;
- match = acl_lookup(fd, &http_acl);
- PARA_DEBUG_LOG("acl lookup returned %d\n", match);
- ret = -E_ACL_PERM;
- if ((match && !conf.http_default_deny_given) ||
- (!match && conf.http_default_deny_given))
+ ret = acl_check_access(fd, &http_acl, conf.http_default_deny_given);
+ if (ret < 0)
goto err_out;
numclients++;
sc = para_calloc(sizeof(*sc));
static int http_com_deny(struct sender_command_data *scd)
{
- if (conf.http_default_deny_given)
- acl_del_entry(&http_acl, scd->addr, scd->netmask);
- else
- acl_add_entry(&http_acl, scd->addr, scd->netmask);
+ acl_deny(scd->addr, scd->netmask, &http_acl,
+ conf.http_default_deny_given);
return 1;
}
static int http_com_allow(struct sender_command_data *scd)
{
- if (conf.http_default_deny_given)
- acl_add_entry(&http_acl, scd->addr, scd->netmask);
- else
- acl_del_entry(&http_acl, scd->addr, scd->netmask);
+ acl_allow(scd->addr, scd->netmask, &http_acl,
+ conf.http_default_deny_given);
return 1;
}
default="8000"
optional
+option "dccp_default_deny" -
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"See http_default_deny"
+
+ flag off
+option "dccp_access" -
+#~~~~~~~~~~~~~~~~~~~~~
+"See http_access"
+ string typestr="a.b.c.d/n"
+ optional
+ multiple
section "ortp sender"
#~~~~~~~~~~~~~~~~~~~~