mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 05:31:44 +00:00
added credentials support to the tuntap router
This commit is contained in:
+34
-12
@@ -3,7 +3,7 @@
|
||||
extern struct uwsgi_tuntap utt;
|
||||
|
||||
// create a new peer
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *uttr, int fd) {
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *uttr, int fd, int is_router) {
|
||||
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_calloc(sizeof(struct uwsgi_tuntap_peer));
|
||||
uttp->fd = fd;
|
||||
@@ -21,6 +21,19 @@ struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *u
|
||||
uttr->peers_tail = uttp;
|
||||
}
|
||||
|
||||
if (!is_router && utt.use_credentials) {
|
||||
uwsgi_log_verbose("[uwsgi-tuntap] waiting for privileges drop...\n");
|
||||
for(;;) {
|
||||
if (getuid() > 0) break;
|
||||
sleep(1);
|
||||
}
|
||||
uwsgi_log_verbose("[uwsgi-tuntap] privileges dropped\n");
|
||||
if (uwsgi_pass_cred(fd, "uwsgi-tuntap", 12)) {
|
||||
// better to exit
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return uttp;
|
||||
}
|
||||
|
||||
@@ -159,6 +172,24 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
int uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp) {
|
||||
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uwsgi_tuntap_peer_get_by_addr(uttr, uttp->addr);
|
||||
char ip[INET_ADDRSTRLEN + 1];
|
||||
memset(ip, 0, INET_ADDRSTRLEN + 1);
|
||||
if (!inet_ntop(AF_INET, &uttp->addr, ip, INET_ADDRSTRLEN)) {
|
||||
uwsgi_error("uwsgi_tuntap_register_addr()/inet_ntop()");
|
||||
return -1;
|
||||
}
|
||||
if (uttp != tmp_uttp) {
|
||||
uwsgi_log("[tuntap-router] detected ip collision for %s\n", ip);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
}
|
||||
uwsgi_log("[tuntap-router] registered new peer %s (fd: %d)\n", ip, uttp->fd);
|
||||
memcpy(uttp->ip, ip, INET_ADDRSTRLEN + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// receive a packet from the client
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tuntap_peer *uttp, int is_router) {
|
||||
// get body
|
||||
@@ -192,19 +223,10 @@ int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *uttr, struct uwsgi_tun
|
||||
if (!uttp->addr)
|
||||
return -1;
|
||||
|
||||
struct uwsgi_tuntap_peer *tmp_uttp = uwsgi_tuntap_peer_get_by_addr(uttr, uttp->addr);
|
||||
char ip[INET_ADDRSTRLEN + 1];
|
||||
memset(ip, 0, INET_ADDRSTRLEN + 1);
|
||||
if (!inet_ntop(AF_INET, &uttp->addr, ip, INET_ADDRSTRLEN)) {
|
||||
uwsgi_error("inet_ntop()");
|
||||
if (uwsgi_tuntap_register_addr(uttr, uttp)) {
|
||||
return -1;
|
||||
}
|
||||
if (uttp != tmp_uttp) {
|
||||
uwsgi_log("[tuntap-router] detected ip collision for %s\n", ip);
|
||||
uwsgi_tuntap_peer_destroy(uttr, tmp_uttp);
|
||||
}
|
||||
uwsgi_log("[tuntap-router] registered new peer %s (fd: %d)\n", ip, uttp->fd);
|
||||
memcpy(uttp->ip, ip, INET_ADDRSTRLEN + 1);
|
||||
|
||||
}
|
||||
|
||||
enqueue:
|
||||
|
||||
@@ -33,6 +33,10 @@ struct uwsgi_tuntap_peer {
|
||||
uint64_t tx;
|
||||
uint64_t rx;
|
||||
uint64_t dropped;
|
||||
uint8_t sent_credentials;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
struct uwsgi_tuntap_firewall_rule {
|
||||
@@ -65,6 +69,8 @@ struct uwsgi_tuntap {
|
||||
struct uwsgi_tuntap_firewall_rule *fw_in;
|
||||
struct uwsgi_tuntap_firewall_rule *fw_out;
|
||||
char *stats_server;
|
||||
char *use_credentials;
|
||||
uint32_t (*addr_by_credentials)(pid_t, uid_t, gid_t);
|
||||
};
|
||||
|
||||
int uwsgi_tuntap_peer_dequeue(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *, int);
|
||||
@@ -73,10 +79,11 @@ void uwsgi_tuntap_enqueue(struct uwsgi_tuntap_router *);
|
||||
|
||||
int uwsgi_tuntap_firewall_check(struct uwsgi_tuntap_firewall_rule *, char *, uint16_t);
|
||||
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *, int);
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_create(struct uwsgi_tuntap_router *, int, int);
|
||||
struct uwsgi_tuntap_peer *uwsgi_tuntap_peer_get_by_addr(struct uwsgi_tuntap_router *,uint32_t);
|
||||
void uwsgi_tuntap_peer_destroy(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
|
||||
|
||||
int uwsgi_tuntap_device(char *);
|
||||
|
||||
void uwsgi_tuntap_opt_firewall(char *, char *, void *);
|
||||
int uwsgi_tuntap_register_addr(struct uwsgi_tuntap_router *, struct uwsgi_tuntap_peer *);
|
||||
|
||||
+46
-2
@@ -59,6 +59,7 @@ struct uwsgi_tuntap utt;
|
||||
static struct uwsgi_option uwsgi_tuntap_options[] = {
|
||||
{"tuntap-router", required_argument, 0, "run the tuntap router (syntax: <device> <socket> [stats])", uwsgi_opt_add_string_list, &utt.routers, 0},
|
||||
{"tuntap-device", required_argument, 0, "add a tuntap device to the instance (syntax: <device>[ <socket>])", uwsgi_opt_add_string_list, &utt.devices, 0},
|
||||
{"tuntap-use-credentials", optional_argument, 0, "enable check of SCM_CREDENTIALS for tuntap client/server", uwsgi_opt_set_str, &utt.use_credentials, 0},
|
||||
{"tuntap-router-firewall-in", required_argument, 0, "add a firewall rule to the tuntap router (syntax: <action> <src/mask> <dst/mask>)", uwsgi_tuntap_opt_firewall, &utt.fw_in, 0},
|
||||
{"tuntap-router-firewall-out", required_argument, 0, "add a firewall rule to the tuntap router (syntax: <action> <src/mask> <dst/mask>)", uwsgi_tuntap_opt_firewall, &utt.fw_out, 0},
|
||||
{"tuntap-router-stats", required_argument, 0, "run the tuntap router stats server", uwsgi_opt_set_str, &utt.stats_server, 0},
|
||||
@@ -95,7 +96,7 @@ static void *uwsgi_tuntap_loop(void *arg) {
|
||||
|
||||
uwsgi_socket_nb(uttr->server_fd);
|
||||
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, uttr->server_fd);
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, uttr->server_fd, 0);
|
||||
|
||||
for (;;) {
|
||||
int interesting_fd = -1;
|
||||
@@ -270,7 +271,13 @@ void uwsgi_tuntap_router_loop(int id, void *arg) {
|
||||
uwsgi_error("uwsgi_tuntap_server_loop()/accept()");
|
||||
continue;
|
||||
}
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, client_fd);
|
||||
if (utt.use_credentials) {
|
||||
if (uwsgi_socket_passcred(client_fd)) {
|
||||
close(client_fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
struct uwsgi_tuntap_peer *uttp = uwsgi_tuntap_peer_create(uttr, client_fd, 1);
|
||||
if (event_queue_add_fd_read(uttr->queue, uttp->fd)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
}
|
||||
@@ -287,6 +294,33 @@ void uwsgi_tuntap_router_loop(int id, void *arg) {
|
||||
if (interesting_fd == uttp->fd) {
|
||||
// read from the client
|
||||
if (event_queue_interesting_fd_is_read(events, i)) {
|
||||
if (utt.use_credentials) {
|
||||
if (uttp->addr == 0) {
|
||||
if (!uttp->sent_credentials) {
|
||||
if (uwsgi_recv_cred(uttp->fd, "uwsgi-tuntap", 12, &uttp->pid, &uttp->uid, &uttp->gid)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
if (utt.addr_by_credentials) {
|
||||
uttp->addr = utt.addr_by_credentials(uttp->pid, uttp->uid, uttp->gid);
|
||||
if (!uttp->addr) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
if (uwsgi_tuntap_register_addr(uttr, uttp)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_tuntap_peer_dequeue(uttr, uttp, 1)) {
|
||||
uwsgi_tuntap_peer_destroy(uttr, uttp);
|
||||
break;
|
||||
@@ -319,6 +353,16 @@ static void uwsgi_tuntap_router() {
|
||||
if (!utt.buffer_size)
|
||||
utt.buffer_size = 8192;
|
||||
|
||||
if (utt.use_credentials) {
|
||||
if (utt.use_credentials[0] != 0) {
|
||||
utt.addr_by_credentials = (uint32_t (*)(pid_t, uid_t, gid_t)) dlsym(RTLD_DEFAULT, utt.use_credentials);
|
||||
if (!utt.addr_by_credentials) {
|
||||
uwsgi_log("[uwsgi-tuntap] unable to find symbol %s\n", utt.use_credentials);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct uwsgi_string_list *usl;
|
||||
uwsgi_foreach(usl, utt.routers) {
|
||||
char *space = strchr(usl->value, ' ');
|
||||
|
||||
Reference in New Issue
Block a user