Skip to content

Commit 7a6a4d4

Browse files
committed
captcha-whitelist
1 parent 70097a5 commit 7a6a4d4

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

include/libwebsockets/lws-network-helper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,7 @@ lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len);
258258
LWS_VISIBLE LWS_EXTERN int
259259
lws_parse_mac(const char *ads, uint8_t *result_6_bytes);
260260

261+
LWS_VISIBLE LWS_EXTERN int
262+
lws_parse_cidr(const char *cidr, lws_sockaddr46 *sa46, int *len);
263+
261264
///@}

lib/core-net/network.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,3 +1175,29 @@ lws_parse_mac(const char *ads, uint8_t *result_6_bytes)
11751175

11761176
return -14;
11771177
}
1178+
1179+
int
1180+
lws_parse_cidr(const char *cidr, lws_sockaddr46 *sa46, int *len)
1181+
{
1182+
char buf[64], *p;
1183+
int n;
1184+
1185+
lws_strncpy(buf, cidr, sizeof(buf));
1186+
p = strchr(buf, '/');
1187+
1188+
if (!p) {
1189+
*len = -1; /* no mask */
1190+
} else {
1191+
*p++ = '\0';
1192+
*len = atoi(p);
1193+
}
1194+
1195+
n = lws_sa46_parse_numeric_address(buf, sa46);
1196+
if (n)
1197+
return n;
1198+
1199+
if (*len == -1)
1200+
*len = sa46->sa4.sin_family == AF_INET6 ? 128 : 32;
1201+
1202+
return 0;
1203+
}

lib/roles/http/server/interceptor.c

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626

2727

2828

29+
struct lws_interceptor_cidr {
30+
struct lws_interceptor_cidr *next;
31+
lws_sockaddr46 sa46;
32+
int len;
33+
};
34+
2935
struct vhd_interceptor {
3036
struct lws_context *context;
3137
struct lws_vhost *vhost;
@@ -53,6 +59,7 @@ struct vhd_interceptor {
5359
int always_pass;
5460

5561
lws_sorted_usec_list_t sul_stats;
62+
struct lws_interceptor_cidr *cidr_head;
5663
int stats_logging;
5764
};
5865

@@ -274,9 +281,28 @@ lws_interceptor_check(struct lws *wsi, const struct lws_protocols *prot)
274281

275282
lws_get_peer_simple(wsi, ip, sizeof(ip));
276283
if (strcmp(sub_claim, ip)) {
277-
lwsl_notice("%s: IP mismatch %s vs %s\n", __func__, sub_claim, ip);
278-
lws_interceptor_inject_header(wsi, vhd, NULL);
279-
return vhd->always_pass ? 0 : 1;
284+
struct lws_interceptor_cidr *cidr = vhd->cidr_head;
285+
lws_sockaddr46 sa46;
286+
int allow = 0;
287+
288+
lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi),
289+
NULL, 0, ip, sizeof(ip));
290+
291+
if (!lws_sa46_parse_numeric_address(ip, &sa46)) {
292+
while (cidr) {
293+
if (!lws_sa46_on_net(&sa46, &cidr->sa46, cidr->len)) {
294+
allow = 1;
295+
break;
296+
}
297+
cidr = cidr->next;
298+
}
299+
}
300+
301+
if (!allow) {
302+
lwsl_notice("%s: IP mismatch %s vs %s\n", __func__, sub_claim, ip);
303+
lws_interceptor_inject_header(wsi, vhd, NULL);
304+
return vhd->always_pass ? 0 : 1;
305+
}
280306
}
281307

282308
lwsl_notice("%s: valid JWT for %s: exp %lu, now %lu (expires in %lds)\n",
@@ -519,6 +545,7 @@ lws_callback_interceptor(struct lws *wsi, enum lws_callback_reasons reason,
519545
struct vhd_interceptor *vhd = (struct vhd_interceptor *)lws_protocol_vh_priv_get(
520546
lws_get_vhost(wsi), lws_get_protocol(wsi));
521547
struct pss_interceptor *pss = (struct pss_interceptor *)user;
548+
const struct lws_protocol_vhost_options *pvo;
522549
const char *cp;
523550

524551
switch (reason) {
@@ -588,12 +615,41 @@ lws_callback_interceptor(struct lws *wsi, enum lws_callback_reasons reason,
588615

589616
if (!lws_pvo_get_str(in, "always-pass", &cp))
590617
vhd->always_pass = !!atoi(cp);
618+
619+
pvo = lws_pvo_search(in, "cidr-allow");
620+
while (pvo) {
621+
struct lws_interceptor_cidr *cidr =
622+
malloc(sizeof(*cidr));
623+
624+
if (!cidr) {
625+
lwsl_err("%s: OOM\n", __func__);
626+
return -1;
627+
}
628+
629+
if (lws_parse_cidr(pvo->value, &cidr->sa46, &cidr->len)) {
630+
lwsl_err("%s: Bad CIDR %s\n", __func__,
631+
pvo->value);
632+
free(cidr);
633+
return -1;
634+
}
635+
636+
cidr->next = vhd->cidr_head;
637+
vhd->cidr_head = cidr;
638+
639+
pvo = lws_pvo_search(pvo->next, "cidr-allow");
640+
}
591641
break;
592642

593643
case LWS_CALLBACK_PROTOCOL_DESTROY:
594644
if (vhd) {
595645
lws_sul_cancel(&vhd->sul_stats);
596646
lws_jwk_destroy(&vhd->jwk);
647+
while (vhd->cidr_head) {
648+
struct lws_interceptor_cidr *cidr = vhd->cidr_head;
649+
650+
vhd->cidr_head = cidr->next;
651+
free(cidr);
652+
}
597653
}
598654
break;
599655

0 commit comments

Comments
 (0)