master
Nicolas Favre-Felix 14 years ago
parent e08af9149d
commit 9ffc5197fb

14
acl.c

@ -1,6 +1,7 @@
#include "acl.h" #include "acl.h"
#include "cmd.h" #include "cmd.h"
#include "conf.h" #include "conf.h"
#include "http.h"
#include <string.h> #include <string.h>
#include <evhttp.h> #include <evhttp.h>
@ -8,11 +9,11 @@
#include <arpa/inet.h> #include <arpa/inet.h>
int int
acl_match_client(struct acl *a, struct evhttp_request *rq, in_addr_t *ip) { acl_match_client(struct acl *a, struct http_client *client, in_addr_t *ip) {
/* check HTTP Basic Auth */ /* check HTTP Basic Auth */
const char *auth; const char *auth;
auth = evhttp_find_header(rq->input_headers, "Authorization"); auth = client->header_authorization.s;
if(auth && a->http_basic_auth && strncasecmp(auth, "Basic ", 6) == 0) { /* sent auth */ if(auth && a->http_basic_auth && strncasecmp(auth, "Basic ", 6) == 0) { /* sent auth */
if(strcmp(auth + 6, a->http_basic_auth) != 0) { /* wrong */ if(strcmp(auth + 6, a->http_basic_auth) != 0) { /* wrong */
return 0; return 0;
@ -31,7 +32,7 @@ acl_match_client(struct acl *a, struct evhttp_request *rq, in_addr_t *ip) {
} }
int int
acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq) { acl_allow_command(struct cmd *cmd, struct conf *cfg, struct http_client *client) {
char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD"}; char *always_off[] = {"MULTI", "EXEC", "WATCH", "DISCARD"};
@ -39,8 +40,6 @@ acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq)
int authorized = 1; int authorized = 1;
struct acl *a; struct acl *a;
char *client_ip;
u_short client_port;
in_addr_t client_addr; in_addr_t client_addr;
const char *cmd_name = cmd->argv[0]; const char *cmd_name = cmd->argv[0];
@ -54,13 +53,12 @@ acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq)
} }
/* find client's address */ /* find client's address */
evhttp_connection_get_peer(rq->evcon, &client_ip, &client_port); client_addr = ntohl(client->addr);
client_addr = ntohl(inet_addr(client_ip));
/* go through permissions */ /* go through permissions */
for(a = cfg->perms; a; a = a->next) { for(a = cfg->perms; a; a = a->next) {
if(!acl_match_client(a, rq, &client_addr)) continue; /* match client */ if(!acl_match_client(a, client, &client_addr)) continue; /* match client */
/* go through authorized commands */ /* go through authorized commands */
for(i = 0; i < a->enabled.count; ++i) { for(i = 0; i < a->enabled.count; ++i) {

@ -3,7 +3,7 @@
#include <netinet/in.h> #include <netinet/in.h>
struct evhttp_request; struct http_client;
struct cmd; struct cmd;
struct conf; struct conf;
@ -31,9 +31,9 @@ struct acl {
}; };
int int
acl_match_client(struct acl *a, struct evhttp_request *rq, in_addr_t *ip); acl_match_client(struct acl *a, struct http_client *client, in_addr_t *ip);
int int
acl_allow_command(struct cmd *cmd, struct conf *cfg, struct evhttp_request *rq); acl_allow_command(struct cmd *cmd, struct conf *cfg, struct http_client *client);
#endif #endif

@ -131,12 +131,10 @@ cmd_run(struct server *s, struct http_client *client,
cmd->argv_len[0] = cmd_len; cmd->argv_len[0] = cmd_len;
/* FIXME: check that the client is able to run this command */ /* check that the client is able to run this command */
/* if(!acl_allow_command(cmd, s->cfg, client)) {
if(!acl_allow_command(cmd, s->cfg, rq)) {
return -1; return -1;
} }
*/
/* FIXME:check if we have to split the connection */ /* FIXME:check if we have to split the connection */
/* /*

@ -77,6 +77,9 @@ http_client_cleanup(struct http_client *c) {
free(c->header_if_none_match.s); free(c->header_if_none_match.s);
memset(&c->header_if_none_match, 0, sizeof(str_t)); memset(&c->header_if_none_match, 0, sizeof(str_t));
free(c->header_authorization.s);
memset(&c->header_authorization, 0, sizeof(str_t));
free(c->out_content_type.s); free(c->out_content_type.s);
memset(&c->out_content_type, 0, sizeof(str_t)); memset(&c->out_content_type, 0, sizeof(str_t));
@ -256,12 +259,23 @@ http_on_complete(http_parser *p) {
default: default:
slog(c->s, WEBDIS_DEBUG, "405"); slog(c->s, WEBDIS_DEBUG, "405");
/* evhttp_send_reply(rq, 405, "Method Not Allowed", NULL); */ http_send_error(c, 405, "Method Not Allowed");
return 0; return 0;
} }
if(ret < 0) {
http_send_error(c, 403, "Forbidden");
}
return ret; return ret;
} }
void
http_send_error(struct http_client *c, short code, const char *msg) {
http_send_reply(c, code, msg, NULL, 0);
}
void void
http_send_reply(struct http_client *c, short code, const char *msg, http_send_reply(struct http_client *c, short code, const char *msg,
const char *body, size_t body_len) { const char *body, size_t body_len) {
@ -345,6 +359,10 @@ http_on_header_value(http_parser *p, const char *at, size_t length) {
c->header_if_none_match.s = calloc(length+1, 1); c->header_if_none_match.s = calloc(length+1, 1);
memcpy(c->header_if_none_match.s, at, length); memcpy(c->header_if_none_match.s, at, length);
c->header_if_none_match.sz = length; c->header_if_none_match.sz = length;
} else if(strncmp("Authorization", c->last_header_name.s, c->last_header_name.sz) == 0) {
c->header_authorization.s = calloc(length+1, 1);
memcpy(c->header_authorization.s, at, length);
c->header_authorization.sz = length;
} }
free(c->last_header_name.s); free(c->last_header_name.s);

@ -2,6 +2,7 @@
#define HTTP_H #define HTTP_H
#include <event.h> #include <event.h>
#include <arpa/inet.h>
#include "http-parser/http_parser.h" #include "http-parser/http_parser.h"
typedef struct { typedef struct {
@ -13,6 +14,7 @@ struct http_client {
/* socket and server reference */ /* socket and server reference */
int fd; int fd;
in_addr_t addr;
struct event ev; struct event ev;
struct server *s; struct server *s;
int executing; int executing;
@ -31,6 +33,7 @@ struct http_client {
str_t body; str_t body;
str_t header_connection; str_t header_connection;
str_t header_if_none_match; str_t header_if_none_match;
str_t header_authorization;
/* response headers */ /* response headers */
str_t out_content_type; str_t out_content_type;
@ -92,6 +95,9 @@ void
http_send_reply(struct http_client *c, short code, const char *msg, http_send_reply(struct http_client *c, short code, const char *msg,
const char *body, size_t body_len); const char *body, size_t body_len);
void
http_send_error(struct http_client *c, short code, const char *msg);
/* HTTP response */ /* HTTP response */
void void
http_response_init(struct http_response *r, int code, const char *msg); http_response_init(struct http_response *r, int code, const char *msg);

@ -169,6 +169,7 @@ on_possible_accept(int fd, short event, void *ctx) {
client_fd = accept(fd, (struct sockaddr*)&addr, &addr_sz); client_fd = accept(fd, (struct sockaddr*)&addr, &addr_sz);
c = http_client_new(client_fd, s); c = http_client_new(client_fd, s);
c->addr = addr.sin_addr.s_addr;
http_client_serve(c); http_client_serve(c);
} }
@ -189,11 +190,6 @@ server_start(struct server *s) {
event_base_set(s->base, &s->ev); event_base_set(s->base, &s->ev);
event_add(&s->ev, NULL); event_add(&s->ev, NULL);
/*
evhttp_set_cb(s->http, "/crossdomain.xml", on_flash_request, s);
evhttp_set_gencb(s->http, on_request, s);
*/
/* drop privileges */ /* drop privileges */
slog(s, WEBDIS_INFO, "Dropping Privileges"); slog(s, WEBDIS_INFO, "Dropping Privileges");
setuid(s->cfg->user); setuid(s->cfg->user);

Loading…
Cancel
Save