1
0
mirror of https://github.com/lammertb/libhttp.git synced 2026-01-27 08:02:47 +03:00

Moved check_acl to own file

This commit is contained in:
Lammert Bies
2016-12-10 11:02:21 +01:00
parent df277d6934
commit 640863e02d
4 changed files with 102 additions and 54 deletions

View File

@@ -43,6 +43,7 @@ BUILD_DIRS = $(BUILD_DIR) $(BUILD_DIR)/src $(BUILD_DIR)/resources
LIB_SOURCES = src/libhttp.c \
src/httplib_accept_new_connection.c \
src/httplib_check_acl.c \
src/httplib_check_feature.c \
src/httplib_close_connection.c \
src/httplib_close_socket_gracefully.c \

68
src/httplib_check_acl.c Normal file
View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2016 Lammert Bies
* Copyright (c) 2013-2016 the Civetweb developers
* Copyright (c) 2004-2013 Sergey Lyubka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "libhttp-private.h"
/*
* int XX_httplib_check_acl( struct mg_context *ctx, uint32_t remote_ip );
*
* The function XX_httplib_check_acl() is used to check of the socket address
* of a connection is allowed according to the access control list. The
* function returns -1 if the ACL is malformed, 0 if the address is not
* allowed and 1 if the address is allowed.
*/
int XX_httplib_check_acl( struct mg_context *ctx, uint32_t remote_ip ) {
int allowed;
int flag;
uint32_t net;
uint32_t mask;
struct vec vec;
if (ctx) {
const char *list = ctx->config[ACCESS_CONTROL_LIST];
/* If any ACL is set, deny by default */
allowed = (list == NULL) ? '+' : '-';
while ((list = XX_httplib_next_option(list, &vec, NULL)) != NULL) {
flag = vec.ptr[0];
if ((flag != '+' && flag != '-') || XX_httplib_parse_net(&vec.ptr[1], &net, &mask) == 0) {
mg_cry( XX_httplib_fc(ctx), "%s: subnet must be [+|-]x.x.x.x[/x]", __func__);
return -1;
}
if (net == (remote_ip & mask)) allowed = flag;
}
return allowed == '+';
}
return -1;
} /* XX_httplib_check_acl */

View File

@@ -817,6 +817,13 @@ struct file {
#define STRUCT_FILE_INITIALIZER { (uint64_t)0, (time_t)0, (FILE *)NULL, (const char *)NULL, 0, 0 }
/* Describes a string (chunk of memory). */
struct vec {
const char *ptr;
size_t len;
};
/*
* Functions local to the server. These functions all begin with XX_httplib to
* indicate that these are private functions.
@@ -847,7 +854,9 @@ int XX_httplib_is_valid_port( unsigned long port );
int XX_httplib_join_thread( pthread_t threadid );
void * XX_httplib_load_dll( struct mg_context *ctx, const char *dll_name, struct ssl_func *sw );
void XX_httplib_log_access( const struct mg_connection *conn );
const char * XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val );
int XX_httplib_parse_http_message( char *buf, int len, struct mg_request_info *ri );
int XX_httplib_parse_net( const char *spec, uint32_t *net, uint32_t *mask );
void XX_httplib_process_new_connection( struct mg_connection *conn );
void XX_httplib_produce_socket( struct mg_context *ctx, const struct socket *sp );
int XX_httplib_read_request( FILE *fp, struct mg_connection *conn, char *buf, int bufsiz, int *nread );

View File

@@ -545,12 +545,6 @@ struct ssl_func XX_httplib_crypto_sw[] = {{"CRYPTO_num_locks", NULL},
static const char *month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
#endif /* !NO_CACHING */
/* Describes a string (chunk of memory). */
struct vec {
const char *ptr;
size_t len;
};
/* Config option name, config types, default value */
@@ -1346,7 +1340,7 @@ const char *mg_get_header( const struct mg_connection *conn, const char *name )
* Value is stored in val vector. If value has form "x=y", then eq_val
* vector is initialized to point to the "y" part, and val vector length
* is adjusted to point only to "x". */
static const char * next_option(const char *list, struct vec *val, struct vec *eq_val) {
const char *XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val ) {
int end;
@@ -1394,7 +1388,10 @@ reparse:
}
return list;
}
} /* XX_httplib_next_option */
/* A helper function for checking if a comma separated list of values contains
* the given option (case insensitvely).
@@ -1407,7 +1404,7 @@ static int header_has_option(const char *header, const char *option) {
assert(option != NULL);
assert(option[0] != '\0');
while ((header = next_option(header, &opt_vec, &eq_vec)) != NULL) {
while ((header = XX_httplib_next_option(header, &opt_vec, &eq_vec)) != NULL) {
if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0) return 1;
}
@@ -3414,7 +3411,7 @@ interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */
if (truncated) goto interpret_cleanup;
rewrite = conn->ctx->config[REWRITE];
while ((rewrite = next_option(rewrite, &a, &b)) != NULL) {
while ((rewrite = XX_httplib_next_option(rewrite, &a, &b)) != NULL) {
if ((match_len = match_prefix(a.ptr, a.len, uri)) > 0) {
XX_httplib_snprintf(conn, &truncated, filename, filename_buf_len - 1, "%.*s%s", (int)b.len, b.ptr, uri + match_len);
break;
@@ -3761,7 +3758,7 @@ static void get_mime_type(struct mg_context *ctx, const char *path, struct vec *
/* Scan user-defined mime types first, in case user wants to
* override default mime types. */
list = ctx->config[EXTRA_MIME_TYPES];
while ((list = next_option(list, &ext_vec, &mime_vec)) != NULL) {
while ((list = XX_httplib_next_option(list, &ext_vec, &mime_vec)) != NULL) {
/* ext now points to the path suffix */
ext = path + path_len - ext_vec.len;
if (mg_strncasecmp(ext, ext_vec.ptr, ext_vec.len) == 0) {
@@ -4134,7 +4131,7 @@ static int check_authorization(struct mg_connection *conn, const char *path) {
if (!conn || !conn->ctx) return 0;
list = conn->ctx->config[PROTECT_URI];
while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) {
while ((list = XX_httplib_next_option(list, &uri_vec, &filename_vec)) != NULL) {
if (!memcmp(conn->request_info.local_uri, uri_vec.ptr, uri_vec.len)) {
XX_httplib_snprintf(conn, &truncated, fname, sizeof(fname), "%.*s", (int)filename_vec.len, filename_vec.ptr);
@@ -5379,7 +5376,7 @@ static int substitute_index_file(struct mg_connection *conn, char *path, size_t
/* Traverse index files list. For each entry, append it to the given
* path and see if the file exists. If it exists, break the loop */
while ((list = next_option(list, &filename_vec, NULL)) != NULL) {
while ((list = XX_httplib_next_option(list, &filename_vec, NULL)) != NULL) {
/* Ignore too long entries that may overflow path buffer */
if (filename_vec.len > path_len - (n + 2)) continue;
@@ -5701,7 +5698,7 @@ static void prepare_cgi_environment( struct mg_connection *conn, const char *pro
/* Add user-specified variables */
s = conn->ctx->config[CGI_ENVIRONMENT];
while ((s = next_option(s, &var_vec, NULL)) != NULL) {
while ((s = XX_httplib_next_option(s, &var_vec, NULL)) != NULL) {
addenv(env, "%.*s", (int)var_vec.len, var_vec.ptr);
}
@@ -7165,9 +7162,15 @@ static int isbyte(int n) {
} /* isbyte */
static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
int XX_httplib_parse_net( const char *spec, uint32_t *net, uint32_t *mask ) {
int n, a, b, c, d, slash = 32, len = 0;
int n;
int a;
int b;
int c;
int d;
int slash = 32;
int len = 0;
if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5
|| sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) && isbyte(a)
@@ -7179,7 +7182,8 @@ static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
}
return len;
}
} /* XX_httplib_parse_net */
static int set_throttle(const char *spec, uint32_t remote_ip, const char *uri) {
@@ -7190,7 +7194,7 @@ static int set_throttle(const char *spec, uint32_t remote_ip, const char *uri) {
char mult;
double v;
while ((spec = next_option(spec, &vec, &val)) != NULL) {
while ((spec = XX_httplib_next_option(spec, &vec, &val)) != NULL) {
mult = ',';
if ((val.ptr == NULL) || (sscanf(val.ptr, "%lf%c", &v, &mult) < 1)
|| (v < 0) || ((lowercase(&mult) != 'k')
@@ -7200,7 +7204,7 @@ static int set_throttle(const char *spec, uint32_t remote_ip, const char *uri) {
v *= (lowercase(&mult) == 'k') ? 1024 : ((lowercase(&mult) == 'm') ? 1048576 : 1);
if (vec.len == 1 && vec.ptr[0] == '*') {
throttle = (int)v;
} else if (parse_net(vec.ptr, &net, &mask) > 0) {
} else if (XX_httplib_parse_net(vec.ptr, &net, &mask) > 0) {
if ((remote_ip & mask) == net) {
throttle = (int)v;
}
@@ -8053,7 +8057,7 @@ int XX_httplib_set_ports_option( struct mg_context *ctx ) {
len = sizeof(usa);
list = ctx->config[LISTENING_PORTS];
while ((list = next_option(list, &vec, NULL)) != NULL) {
while ((list = XX_httplib_next_option(list, &vec, NULL)) != NULL) {
portsTotal++;
@@ -8294,37 +8298,3 @@ void XX_httplib_log_access( const struct mg_connection *conn ) {
}
} /* XX_httplib_log_access */
/* Verify given socket address against the ACL.
* Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
*/
int XX_httplib_check_acl( struct mg_context *ctx, uint32_t remote_ip ) {
int allowed;
int flag;
uint32_t net;
uint32_t mask;
struct vec vec;
if (ctx) {
const char *list = ctx->config[ACCESS_CONTROL_LIST];
/* If any ACL is set, deny by default */
allowed = (list == NULL) ? '+' : '-';
while ((list = next_option(list, &vec, NULL)) != NULL) {
flag = vec.ptr[0];
if ((flag != '+' && flag != '-') || parse_net(&vec.ptr[1], &net, &mask) == 0) {
mg_cry( XX_httplib_fc(ctx), "%s: subnet must be [+|-]x.x.x.x[/x]", __func__);
return -1;
}
if (net == (remote_ip & mask)) allowed = flag;
}
return allowed == '+';
}
return -1;
} /* XX_httplib_check_acl */