Skip to content

Commit 2743cd5

Browse files
committed
Add ACL check to HTTP server
1 parent e8336fd commit 2743cd5

File tree

6 files changed

+20
-6
lines changed

6 files changed

+20
-6
lines changed

fossa.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
13341334
/*
13351335
* Verify given IP address against the ACL.
13361336
*
1337-
* `remote_ip` - an IPv4 address to check, in network byte order
1337+
* `remote_ip` - an IPv4 address to check, in host byte order
13381338
* `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
13391339
* Each subnet is
13401340
* prepended by either a - or a + sign. A plus sign means allow, where a
@@ -3259,6 +3259,7 @@ void ns_serve_http(struct ns_connection *nc, struct http_message *hm,
32593259
char path[NS_MAX_PATH], tmp[NS_MAX_PATH];
32603260
ns_stat_t st;
32613261
int stat_result, is_directory;
3262+
uint32_t remote_ip = ntohl(*(uint32_t *) &nc->sa.sin.sin_addr);
32623263

32633264
snprintf(tmp, sizeof(tmp), "%s/%.*s", opts.document_root, (int) hm->uri.len,
32643265
hm->uri.p);
@@ -3267,7 +3268,10 @@ void ns_serve_http(struct ns_connection *nc, struct http_message *hm,
32673268
stat_result = ns_stat(path, &st);
32683269
is_directory = !stat_result && S_ISDIR(st.st_mode);
32693270

3270-
if (!is_authorized(hm, path, is_directory, &opts)) {
3271+
if (ns_check_ip_acl(opts.ip_acl, remote_ip) != 1) {
3272+
/* Not allowed to connect */
3273+
nc->flags |= NSF_CLOSE_IMMEDIATELY;
3274+
} else if (!is_authorized(hm, path, is_directory, &opts)) {
32713275
ns_printf(nc,
32723276
"HTTP/1.1 401 Unauthorized\r\n"
32733277
"WWW-Authenticate: Digest qop=\"auth\", "

fossa.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ struct ns_serve_http_opts {
653653

654654
/* SSI files suffix. By default is NULL, SSI is disabled */
655655
const char *ssi_suffix;
656+
657+
/* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
658+
const char *ip_acl;
656659
};
657660
void ns_serve_http(struct ns_connection *, struct http_message *,
658661
struct ns_serve_http_opts);

src/http.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,7 @@ void ns_serve_http(struct ns_connection *nc, struct http_message *hm,
13811381
char path[NS_MAX_PATH], tmp[NS_MAX_PATH];
13821382
ns_stat_t st;
13831383
int stat_result, is_directory;
1384+
uint32_t remote_ip = ntohl(*(uint32_t *) &nc->sa.sin.sin_addr);
13841385

13851386
snprintf(tmp, sizeof(tmp), "%s/%.*s", opts.document_root, (int) hm->uri.len,
13861387
hm->uri.p);
@@ -1389,7 +1390,10 @@ void ns_serve_http(struct ns_connection *nc, struct http_message *hm,
13891390
stat_result = ns_stat(path, &st);
13901391
is_directory = !stat_result && S_ISDIR(st.st_mode);
13911392

1392-
if (!is_authorized(hm, path, is_directory, &opts)) {
1393+
if (ns_check_ip_acl(opts.ip_acl, remote_ip) != 1) {
1394+
/* Not allowed to connect */
1395+
nc->flags |= NSF_CLOSE_IMMEDIATELY;
1396+
} else if (!is_authorized(hm, path, is_directory, &opts)) {
13931397
ns_printf(nc,
13941398
"HTTP/1.1 401 Unauthorized\r\n"
13951399
"WWW-Authenticate: Digest qop=\"auth\", "

src/http.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ struct ns_serve_http_opts {
127127

128128
/* SSI files suffix. By default is NULL, SSI is disabled */
129129
const char *ssi_suffix;
130+
131+
/* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
132+
const char *ip_acl;
130133
};
131134
void ns_serve_http(struct ns_connection *, struct http_message *,
132135
struct ns_serve_http_opts);

src/net.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
11661166
/*
11671167
* Verify given IP address against the ACL.
11681168
*
1169-
* `remote_ip` - an IPv4 address to check, in network byte order
1169+
* `remote_ip` - an IPv4 address to check, in host byte order
11701170
* `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
11711171
* Each subnet is
11721172
* prepended by either a - or a + sign. A plus sign means allow, where a

test/unit_test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,13 @@ static const char *test_to64(void) {
230230
}
231231

232232
static const char *test_check_ip_acl(void) {
233-
uint32_t ip = htonl(0x01010101);
233+
uint32_t ip = 0x01020304;
234234
ASSERT(ns_check_ip_acl(NULL, ip) == 1);
235235
ASSERT(ns_check_ip_acl("", ip) == 1);
236236
ASSERT(ns_check_ip_acl("invalid", ip) == -1);
237237
ASSERT(ns_check_ip_acl("-0.0.0.0/0", ip) == 0);
238238
ASSERT(ns_check_ip_acl("-0.0.0.0/0,+1.0.0.0/8", ip) == 1);
239-
ASSERT(ns_check_ip_acl("-0.0.0.0/0,+1.1.1.1", ip) == 1);
239+
ASSERT(ns_check_ip_acl("-0.0.0.0/0,+1.2.3.4", ip) == 1);
240240
ASSERT(ns_check_ip_acl("-0.0.0.0/0,+1.0.0.0/16", ip) == 0);
241241
return NULL;
242242
}

0 commit comments

Comments
 (0)