Skip to content
Browse files

ACL refactoring.

  • Loading branch information...
1 parent 17669d9 commit a7bf6f76e99815e4383b0505fb7a97ded26278f9 @nicolasff committed Jan 1, 2011
Showing with 125 additions and 108 deletions.
  1. +1 −1 Makefile
  2. +82 −0 acl.c
  3. +39 −0 acl.h
  4. +2 −53 cmd.c
  5. +1 −24 conf.c
  6. +0 −30 conf.h
View
2 Makefile
@@ -2,7 +2,7 @@ OUT=webdis
HIREDIS_OBJ=hiredis/hiredis.o hiredis/sds.o hiredis/net.o hiredis/async.o hiredis/dict.o
JANSSON_OBJ=jansson/src/dump.o jansson/src/error.o jansson/src/hashtable.o jansson/src/load.o jansson/src/strbuffer.o jansson/src/utf.o jansson/src/value.o jansson/src/variadic.o
FORMAT_OBJS=formats/json.o formats/raw.o formats/common.o
-OBJS=webdis.o conf.o $(FORMAT_OBJS) cmd.o server.o $(HIREDIS_OBJ) $(JANSSON_OBJ) libb64/cencode.o
+OBJS=webdis.o conf.o $(FORMAT_OBJS) cmd.o server.o $(HIREDIS_OBJ) $(JANSSON_OBJ) libb64/cencode.o acl.o
CFLAGS=-O3 -Wall -Wextra -I. -Ijansson/src
LDFLAGS=-levent
View
82 acl.c
@@ -0,0 +1,82 @@
+#include "acl.h"
+#include "cmd.h"
+#include "conf.h"
+
+#include <string.h>
+#include <evhttp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+acl_match_client(struct acl *a, struct evhttp_request *rq, in_addr_t *ip) {
+
+ /* check HTTP Basic Auth */
+ const char *auth;
+ auth = evhttp_find_header(rq->input_headers, "Authorization");
+ if(auth && a->http_basic_auth && strncasecmp(auth, "Basic ", 6) == 0) { /* sent auth */
+ if(strcmp(auth + 6, a->http_basic_auth) != 0) { /* wrong */
+ return 0;
+ }
+ }
+
+ /* CIDR check. */
+ if(a->cidr.enabled == 0) { /* none given, all match */
+ return 1;
+ }
+ if(((*ip) & a->cidr.mask) == (a->cidr.subnet & a->cidr.mask)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq) {
+
+ char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD"};
+
+ unsigned int i;
+ int authorized = 1;
+ struct acl *a;
+
+ char *client_ip;
+ u_short client_port;
+ in_addr_t client_addr;
+
+ const char *cmd_name = cmd->argv[0];
+ size_t cmd_len = cmd->argv_len[0];
+
+ /* some commands are always disabled, regardless of the config file. */
+ for(i = 0; i < sizeof(always_off) / sizeof(always_off[0]); ++i) {
+ if(strncasecmp(always_off[i], cmd_name, cmd_len) == 0) {
+ return 0;
+ }
+ }
+
+ /* find client's address */
+ evhttp_connection_get_peer(rq->evcon, &client_ip, &client_port);
+ client_addr = ntohl(inet_addr(client_ip));
+
+ /* go through permissions */
+ for(a = cfg->perms; a; a = a->next) {
+
+ if(!acl_match_client(a, rq, &client_addr)) continue; /* match client */
+
+ /* go through authorized commands */
+ for(i = 0; i < a->enabled.count; ++i) {
+ if(strncasecmp(a->enabled.commands[i], cmd_name, cmd_len) == 0) {
+ authorized = 1;
+ }
+ }
+
+ /* go through unauthorized commands */
+ for(i = 0; i < a->disabled.count; ++i) {
+ if(strncasecmp(a->disabled.commands[i], cmd_name, cmd_len) == 0) {
+ authorized = 0;
+ }
+ }
+ }
+
+ return authorized;
+}
+
View
39 acl.h
@@ -0,0 +1,39 @@
+#ifndef ACL_H
+#define ACL_H
+
+#include <netinet/in.h>
+
+struct evhttp_request;
+struct cmd;
+struct conf;
+
+struct acl_commands {
+ unsigned int count;
+ char **commands;
+};
+
+struct acl {
+
+ /* CIDR subnet + mask */
+ struct {
+ int enabled;
+ in_addr_t subnet;
+ in_addr_t mask;
+ } cidr;
+
+ char *http_basic_auth;
+
+ /* commands that have been enabled or disabled */
+ struct acl_commands enabled;
+ struct acl_commands disabled;
+
+ struct acl *next;
+};
+
+int
+acl_match_client(struct acl *a, struct evhttp_request *rq, in_addr_t *ip);
+
+int
+acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq);
+
+#endif
View
55 cmd.c
@@ -1,15 +1,14 @@
#include "cmd.h"
#include "server.h"
#include "conf.h"
+#include "acl.h"
#include "formats/json.h"
#include "formats/raw.h"
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
struct cmd *
cmd_new(struct evhttp_request *rq, int count) {
@@ -55,56 +54,6 @@ void on_http_disconnect(struct evhttp_connection *evcon, void *ctx) {
}
int
-cmd_authorized(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq) {
-
- char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD"};
-
- unsigned int i;
- int authorized = 1;
- struct acl *a;
-
- char *client_ip;
- u_short client_port;
- in_addr_t client_addr;
-
- const char *cmd_name = cmd->argv[0];
- size_t cmd_len = cmd->argv_len[0];
-
- /* some commands are always disabled, regardless of the config file. */
- for(i = 0; i < sizeof(always_off) / sizeof(always_off[0]); ++i) {
- if(strncasecmp(always_off[i], cmd_name, cmd_len) == 0) {
- return 0;
- }
- }
-
- /* find client's address */
- evhttp_connection_get_peer(rq->evcon, &client_ip, &client_port);
- client_addr = ntohl(inet_addr(client_ip));
-
- /* go through permissions */
- for(a = cfg->perms; a; a = a->next) {
-
- if(!acl_match(a, rq, &client_addr)) continue; /* match client */
-
- /* go through authorized commands */
- for(i = 0; i < a->enabled.count; ++i) {
- if(strncasecmp(a->enabled.commands[i], cmd_name, cmd_len) == 0) {
- authorized = 1;
- }
- }
-
- /* go through unauthorized commands */
- for(i = 0; i < a->disabled.count; ++i) {
- if(strncasecmp(a->disabled.commands[i], cmd_name, cmd_len) == 0) {
- authorized = 0;
- }
- }
- }
-
- return authorized;
-}
-
-int
cmd_run(struct server *s, struct evhttp_request *rq,
const char *uri, size_t uri_len) {
@@ -145,7 +94,7 @@ cmd_run(struct server *s, struct evhttp_request *rq,
/* check that the client is able to run this command */
- if(!cmd_authorized(cmd, s->cfg, rq)) {
+ if(!acl_allow_command(cmd, s->cfg, rq)) {
return -1;
}
View
25 conf.c
@@ -8,6 +8,7 @@
#include <evhttp.h>
#include <libb64/cencode.h>
#include "conf.h"
+#include "acl.h"
static struct acl *
conf_parse_acls(json_t *jtab);
@@ -174,30 +175,6 @@ conf_parse_acls(json_t *jtab) {
return head;
}
-int
-acl_match(struct acl *a, struct evhttp_request *rq, in_addr_t *ip) {
-
- /* check HTTP Basic Auth */
- const char *auth;
- auth = evhttp_find_header(rq->input_headers, "Authorization");
- if(auth && a->http_basic_auth && strncasecmp(auth, "Basic ", 6) == 0) { /* sent auth */
- if(strcmp(auth + 6, a->http_basic_auth) != 0) { /* wrong */
- return 0;
- }
- }
-
- /* CIDR check. */
- if(a->cidr.enabled == 0) { /* none given, all match */
- return 1;
- }
- if(((*ip) & a->cidr.mask) == (a->cidr.subnet & a->cidr.mask)) {
- return 1;
- }
-
- return 0;
-}
-
-
void
conf_free(struct conf *conf) {
View
30 conf.h
@@ -1,33 +1,6 @@
#ifndef CONF_H
#define CONF_H
-#include <netinet/in.h>
-
-struct evhttp_request;
-
-struct acl_commands {
- unsigned int count;
- char **commands;
-};
-
-struct acl {
-
- /* CIDR subnet + mask */
- struct {
- int enabled;
- in_addr_t subnet;
- in_addr_t mask;
- } cidr;
-
- char *http_basic_auth;
-
- /* commands that have been enabled or disabled */
- struct acl_commands enabled;
- struct acl_commands disabled;
-
- struct acl *next;
-};
-
struct conf {
char *redis_host;
@@ -46,7 +19,4 @@ conf_read(const char *filename);
void
conf_free(struct conf *conf);
-int
-acl_match(struct acl *a, struct evhttp_request *rq, in_addr_t *ip);
-
#endif /* CONF_H */

0 comments on commit a7bf6f7

Please sign in to comment.
Something went wrong with that request. Please try again.