mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
main: allow multiple clients in control channel (occtl)
This commit is contained in:
committed by
Nikos Mavrogiannopoulos
parent
0e604b8a9f
commit
12bc8955bd
@@ -28,12 +28,14 @@
|
||||
#include <sys/un.h>
|
||||
#include <main.h>
|
||||
#include <vpn.h>
|
||||
#include <cloexec.h>
|
||||
#include <ip-lease.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <system.h>
|
||||
#include <main-ctl.h>
|
||||
#include <main-ban.h>
|
||||
#include <ccan/container_of/container_of.h>
|
||||
|
||||
#include <ctl.pb-c.h>
|
||||
#include <str.h>
|
||||
@@ -691,43 +693,28 @@ static void method_disconnect_user_id(method_ctx *ctx, int cfd,
|
||||
return;
|
||||
}
|
||||
|
||||
static void ctl_handle_commands(main_server_st * s)
|
||||
struct ctl_watcher_st {
|
||||
int fd;
|
||||
struct ev_io ctl_cmd_io;
|
||||
};
|
||||
|
||||
static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
int cfd = -1, e, ret;
|
||||
unsigned i;
|
||||
struct sockaddr_un sa;
|
||||
socklen_t sa_len;
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
int ret, e;
|
||||
uint16_t length;
|
||||
uint8_t buffer[256];
|
||||
unsigned buffer_size;
|
||||
method_ctx ctx;
|
||||
void *pool = talloc_new(s);
|
||||
|
||||
if (pool == NULL) {
|
||||
mslog(s, NULL, LOG_ERR, "memory allocation error");
|
||||
return;
|
||||
}
|
||||
struct ctl_watcher_st *wst = container_of(w, struct ctl_watcher_st, ctl_cmd_io);
|
||||
unsigned i;
|
||||
|
||||
ctx.s = s;
|
||||
ctx.pool = pool;
|
||||
|
||||
sa_len = sizeof(sa);
|
||||
cfd = accept(s->ctl_fd, (struct sockaddr *)&sa, &sa_len);
|
||||
if (cfd == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error accepting control connection: %s", strerror(e));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = check_upeer_id("ctl", s->perm_config->debug, cfd, 0, 0, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection");
|
||||
goto cleanup;
|
||||
}
|
||||
ctx.pool = wst;
|
||||
|
||||
/* read request */
|
||||
ret = recv(cfd, buffer, sizeof(buffer), 0);
|
||||
ret = recv(wst->fd, buffer, sizeof(buffer), 0);
|
||||
|
||||
if (ret < 3) {
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
@@ -737,7 +724,7 @@ static void ctl_handle_commands(main_server_st * s)
|
||||
mslog(s, NULL, LOG_ERR, "received ctl data: %d bytes",
|
||||
ret);
|
||||
}
|
||||
goto cleanup;
|
||||
goto fail;
|
||||
}
|
||||
memcpy(&length, &buffer[1], 2);
|
||||
buffer_size = ret - 3;
|
||||
@@ -746,7 +733,7 @@ static void ctl_handle_commands(main_server_st * s)
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"received data length doesn't match received data (%d/%d)",
|
||||
buffer_size, (int)length);
|
||||
goto cleanup;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0;; i++) {
|
||||
@@ -756,12 +743,54 @@ static void ctl_handle_commands(main_server_st * s)
|
||||
(unsigned)buffer[0]);
|
||||
break;
|
||||
} else if (methods[i].cmd == buffer[0]) {
|
||||
methods[i].func(&ctx, cfd, buffer + 3, buffer_size);
|
||||
methods[i].func(&ctx, wst->fd, buffer + 3, buffer_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
talloc_free(pool);
|
||||
|
||||
return;
|
||||
fail:
|
||||
close(wst->fd);
|
||||
ev_io_stop(EV_A_ w);
|
||||
talloc_free(wst);
|
||||
return;
|
||||
}
|
||||
|
||||
static void ctl_handle_commands(main_server_st * s)
|
||||
{
|
||||
int cfd = -1, e, ret;
|
||||
struct sockaddr_un sa;
|
||||
socklen_t sa_len;
|
||||
struct ctl_watcher_st *wst;
|
||||
|
||||
sa_len = sizeof(sa);
|
||||
cfd = accept(s->ctl_fd, (struct sockaddr *)&sa, &sa_len);
|
||||
if (cfd == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error accepting control connection: %s", strerror(e));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = check_upeer_id("ctl", s->perm_config->debug, cfd, 0, 0, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
set_cloexec_flag(cfd, 1);
|
||||
|
||||
wst = talloc(s, struct ctl_watcher_st);
|
||||
if (wst == NULL)
|
||||
goto fail;
|
||||
|
||||
wst->fd = cfd;
|
||||
|
||||
ev_io_init(&wst->ctl_cmd_io, ctl_cmd_wacher_cb, wst->fd, EV_READ);
|
||||
ev_io_start(loop, &wst->ctl_cmd_io);
|
||||
|
||||
return;
|
||||
fail:
|
||||
if (cfd != -1)
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ static int handle_cookie_auth_res(main_server_st *s, struct proc_st *proc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int handle_commands(main_server_st * s, struct proc_st *proc)
|
||||
int handle_worker_commands(main_server_st * s, struct proc_st *proc)
|
||||
{
|
||||
struct iovec iov[3];
|
||||
uint8_t cmd;
|
||||
|
||||
@@ -902,7 +902,7 @@ static void cmd_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
int ret;
|
||||
|
||||
/* Check for any pending commands */
|
||||
ret = handle_commands(s, ctmp);
|
||||
ret = handle_worker_commands(s, ctmp);
|
||||
if (ret < 0) {
|
||||
remove_proc(s, ctmp, (ret!=ERR_WORKER_TERMINATED)?RPROC_KILL:0);
|
||||
}
|
||||
|
||||
@@ -223,11 +223,8 @@ typedef struct main_server_st {
|
||||
/* This one is on worker pool */
|
||||
struct worker_st *ws;
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
void * ctl_ctx;
|
||||
#else
|
||||
int ctl_fd;
|
||||
#endif
|
||||
|
||||
int sec_mod_fd; /* messages are sent and received async */
|
||||
int sec_mod_fd_sync; /* messages are send in a sync order (ping-pong). Only main sends. */
|
||||
void *main_pool; /* talloc main pool */
|
||||
@@ -235,7 +232,7 @@ typedef struct main_server_st {
|
||||
|
||||
void clear_lists(main_server_st *s);
|
||||
|
||||
int handle_commands(main_server_st *s, struct proc_st* cur);
|
||||
int handle_worker_commands(main_server_st *s, struct proc_st* cur);
|
||||
int handle_sec_mod_commands(main_server_st *s);
|
||||
|
||||
int user_connected(main_server_st *s, struct proc_st* cur);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
int handle_worker_commands(struct worker_st *ws)
|
||||
int handle_commands_from_main(struct worker_st *ws)
|
||||
{
|
||||
struct iovec iov[3];
|
||||
uint8_t cmd;
|
||||
|
||||
@@ -1974,7 +1974,7 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
/* read commands from command fd */
|
||||
if (FD_ISSET(ws->cmd_fd, &rfds)) {
|
||||
ret = handle_worker_commands(ws);
|
||||
ret = handle_commands_from_main(ws);
|
||||
if (ret == ERR_NO_CMD_FD) {
|
||||
terminate_reason = REASON_ERROR;
|
||||
goto terminate;
|
||||
|
||||
@@ -328,7 +328,7 @@ int complete_vpn_info(worker_st * ws,
|
||||
struct vpn_st* vinfo);
|
||||
|
||||
int send_tun_mtu(worker_st *ws, unsigned int mtu);
|
||||
int handle_worker_commands(struct worker_st *ws);
|
||||
int handle_commands_from_main(struct worker_st *ws);
|
||||
int disable_system_calls(struct worker_st *ws);
|
||||
void ocsigaltstack(struct worker_st *ws);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user