ACL now working again.

master
Nicolas Favre-Felix 14 years ago
parent 41388a5196
commit 4a9918d313

29
cmd.c

@ -41,6 +41,8 @@ cmd_authorized(struct conf *cfg, struct evhttp_request *rq, const char *verb, si
char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD", "SUBSCRIBE", "PSUBSCRIBE"}; char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD", "SUBSCRIBE", "PSUBSCRIBE"};
unsigned int i; unsigned int i;
int authorized = 1;
struct acl *a;
char *client_ip; char *client_ip;
u_short client_port; u_short client_port;
@ -53,30 +55,31 @@ cmd_authorized(struct conf *cfg, struct evhttp_request *rq, const char *verb, si
} }
} }
/* find client's address */ /* find client's address */
evhttp_connection_get_peer(rq->evcon, &client_ip, &client_port); evhttp_connection_get_peer(rq->evcon, &client_ip, &client_port);
client_addr = ntohl(inet_addr(client_ip)); client_addr = ntohl(inet_addr(client_ip));
return 1; /* go through permissions */
#if 0 for(a = cfg->perms; a; a = a->next) {
for(dc = cfg->disabled; dc; dc = dc->next) {
/* CIDR test */ if(!acl_match(a, &client_addr)) continue; /* match client */
if((client_addr & dc->mask) != (dc->subnet & dc->mask)) { /* go through authorized commands */
continue; for(i = 0; i < a->enabled.count; ++i) {
if(strncasecmp(a->enabled.commands[i], verb, verb_len) == 0) {
authorized = 1;
}
} }
/* matched an ip */ /* go through unauthorized commands */
for(i = 0; i < dc->count; ++i) { for(i = 0; i < a->disabled.count; ++i) {
if(strncasecmp(dc->commands[i], verb, verb_len) == 0) { if(strncasecmp(a->disabled.commands[i], verb, verb_len) == 0) {
return 0; authorized = 0;
} }
} }
} }
#endif
return 1; return authorized;
} }
int int

@ -46,7 +46,7 @@ conf_read(const char *filename) {
conf->http_host = strdup(json_string_value(jtmp)); conf->http_host = strdup(json_string_value(jtmp));
} else if(strcmp(json_object_iter_key(kv), "http_port") == 0 && json_typeof(jtmp) == JSON_INTEGER) { } else if(strcmp(json_object_iter_key(kv), "http_port") == 0 && json_typeof(jtmp) == JSON_INTEGER) {
conf->http_port = (short)json_integer_value(jtmp); conf->http_port = (short)json_integer_value(jtmp);
} else if(strcmp(json_object_iter_key(kv), "acl") == 0 && json_typeof(jtmp) == JSON_OBJECT) { } else if(strcmp(json_object_iter_key(kv), "acl") == 0 && json_typeof(jtmp) == JSON_ARRAY) {
conf->perms = conf_parse_acls(jtmp); conf->perms = conf_parse_acls(jtmp);
} }
} }
@ -100,7 +100,6 @@ conf_parse_acl(json_t *j) {
if((jcidr = json_object_get(j, "ip")) && json_typeof(jcidr) == JSON_STRING) { if((jcidr = json_object_get(j, "ip")) && json_typeof(jcidr) == JSON_STRING) {
const char *s; const char *s;
char *p, *ip; char *p, *ip;
a->cidr.enabled = 1;
s = json_string_value(jcidr); s = json_string_value(jcidr);
p = strchr(s, '/'); p = strchr(s, '/');
@ -111,6 +110,7 @@ conf_parse_acl(json_t *j) {
memcpy(ip, s, (size_t)(p - s)); memcpy(ip, s, (size_t)(p - s));
mask_bits = (unsigned short)atoi(p+1); mask_bits = (unsigned short)atoi(p+1);
} }
a->cidr.enabled = 1;
a->cidr.mask = (mask_bits == 0 ? 0 : (0xffffffff << (32 - mask_bits))); a->cidr.mask = (mask_bits == 0 ? 0 : (0xffffffff << (32 - mask_bits)));
a->cidr.subnet = ntohl(inet_addr(ip)) & a->cidr.mask; a->cidr.subnet = ntohl(inet_addr(ip)) & a->cidr.mask;
free(ip); free(ip);
@ -123,13 +123,13 @@ conf_parse_acl(json_t *j) {
} }
/* parse enabled commands */ /* parse enabled commands */
if((jlist = json_object_get(j, "enable")) && json_typeof(jlist) == JSON_ARRAY) { if((jlist = json_object_get(j, "enabled")) && json_typeof(jlist) == JSON_ARRAY) {
acl_read_commands(jlist, &a->enable); acl_read_commands(jlist, &a->enabled);
} }
/* parse disabled commands */ /* parse disabled commands */
if((jlist = json_object_get(j, "disable")) && json_typeof(jlist) == JSON_ARRAY) { if((jlist = json_object_get(j, "disabled")) && json_typeof(jlist) == JSON_ARRAY) {
acl_read_commands(jlist, &a->disable); acl_read_commands(jlist, &a->disabled);
} }
return a; return a;
@ -138,18 +138,39 @@ conf_parse_acl(json_t *j) {
struct acl * struct acl *
conf_parse_acls(json_t *jtab) { conf_parse_acls(json_t *jtab) {
struct acl *root = NULL, *tmp = NULL; struct acl *head = NULL, *tail = NULL, *tmp;
void *kv; unsigned int i;
for(kv = json_object_iter(jtab); kv; kv = json_object_iter_next(jtab, kv)) { for(i = 0; i < json_array_size(jtab); ++i) {
json_t *val = json_object_iter_value(kv); json_t *val = json_array_get(jtab, i);
tmp = conf_parse_acl(val); tmp = conf_parse_acl(val);
if(root) root->next = tmp; if(head == NULL && tail == NULL) {
root = tmp; head = tail = tmp;
} else {
tail->next = tmp;
tail = tmp;
}
}
return head;
}
int
acl_match(struct acl *a, in_addr_t *ip) {
/* TODO: add HTTP Basic Auth */
if(a->cidr.enabled == 0) { /* none given, all match */
return 1;
}
/* CIDR check. */
if(((*ip) & a->cidr.mask) == (a->cidr.subnet & a->cidr.mask)) {
return 1;
} }
return root; return 0;
} }

@ -20,8 +20,8 @@ struct acl {
char *http_basic_auth; char *http_basic_auth;
/* commands that have been enabled or disabled */ /* commands that have been enabled or disabled */
struct acl_commands enable; struct acl_commands enabled;
struct acl_commands disable; struct acl_commands disabled;
struct acl *next; struct acl *next;
}; };
@ -44,4 +44,7 @@ conf_read(const char *filename);
void void
conf_free(struct conf *conf); conf_free(struct conf *conf);
int
acl_match(struct acl *a, in_addr_t *ip);
#endif /* CONF_H */ #endif /* CONF_H */

@ -7,29 +7,31 @@
"http_host": "0.0.0.0", "http_host": "0.0.0.0",
"http_port": 7379, "http_port": 7379,
"disable": {
"0.0.0.0/0": ["DEBUG", "FLUSHDB", "FLUSHALL"]
},
"acl": [ "acl": [
{ {
"basic_auth": "user:password", "basic_auth": "user:password",
"disable": ["DEBUG", "FLUSHDB", "FLUSHALL"], "disabled": ["DEBUG", "FLUSHDB", "FLUSHALL"],
"enable": ["SET"] "enabled": ["SET"]
}, },
{ {
"ip": "192.168.10.0/24", "ip": "192.168.10.0/24",
"disable": ["SET", "FLUSHDB", "FLUSHALL"], "disabled": ["SET", "FLUSHDB", "FLUSHALL"],
"enable": ["*"] "enabled": ["*"]
}, },
{ {
"basic_auth": "user:password", "basic_auth": "user:password",
"ip": "192.168.10.0/24", "ip": "192.168.10.0/24",
"disable": ["FLUSHDB", "FLUSHALL"], "disabled": ["FLUSHDB", "FLUSHALL"],
"enable": ["SET", "*"] "enabled": ["SET", "*"]
},
{
"ip": "0.0.0.0/0",
"disabled": ["SET"],
"enabled": ["SET"]
} }
] ]
} }

Loading…
Cancel
Save