mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
main/sec-mod: handle sec-mod reload via synchronous communication
This eliminates race-conditions related to signal handling and potential main/sec-mod desynchronizations related to cert/key pairs. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
@@ -146,6 +146,10 @@ const char *cmd_request_to_str(unsigned _cmd)
|
||||
return "sm: ban IP";
|
||||
case CMD_SECM_BAN_IP_REPLY:
|
||||
return "sm: ban IP reply";
|
||||
case CMD_SECM_RELOAD:
|
||||
return "sm: reload";
|
||||
case CMD_SECM_RELOAD_REPLY:
|
||||
return "sm: reload reply";
|
||||
case CMD_SECM_LIST_COOKIES:
|
||||
return "sm: list cookies";
|
||||
case CMD_SECM_LIST_COOKIES_REPLY:
|
||||
@@ -682,7 +686,7 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
if (length > 0 && msg) {
|
||||
data = talloc_size(pool, length);
|
||||
if (data == NULL) {
|
||||
ret = ERR_MEM;
|
||||
|
||||
@@ -96,6 +96,8 @@ typedef enum {
|
||||
CMD_SECM_LIST_COOKIES,
|
||||
CMD_SECM_LIST_COOKIES_REPLY,
|
||||
CMD_SECM_STATS, /* sent periodically */
|
||||
CMD_SECM_RELOAD,
|
||||
CMD_SECM_RELOAD_REPLY,
|
||||
|
||||
MAX_SECM_CMD,
|
||||
} cmd_request_t;
|
||||
|
||||
@@ -668,6 +668,31 @@ int session_close(main_server_st * s, struct proc_st *proc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int secmod_reload(main_server_st * s)
|
||||
{
|
||||
int ret, e;
|
||||
|
||||
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_RELOAD));
|
||||
|
||||
ret = send_msg(s->main_pool, s->sec_mod_fd_sync, CMD_SECM_RELOAD,
|
||||
NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error sending message to sec-mod cmd socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = recv_msg(s->main_pool, s->sec_mod_fd_sync, CMD_SECM_RELOAD_REPLY,
|
||||
NULL, NULL, MAIN_SEC_MOD_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "error receiving reload reply message from sec-mod cmd socket: %s", strerror(e));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void secmod_socket_file_name(struct perm_cfg_st *perm_config, char *name, unsigned max_name_size)
|
||||
{
|
||||
/* make socket name and full socket name */
|
||||
|
||||
@@ -1026,6 +1026,7 @@ static void term_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents)
|
||||
static void reload_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
int ret;
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "reloading configuration");
|
||||
kill(s->sec_mod_pid, SIGHUP);
|
||||
@@ -1033,7 +1034,12 @@ static void reload_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revent
|
||||
/* Reload on main needs to happen later than sec-mod.
|
||||
* That's because of a test that the certificate matches the
|
||||
* used key. */
|
||||
ms_sleep(1500);
|
||||
ret = secmod_reload(s);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "could not reload sec-mod!\n");
|
||||
ev_feed_signal_event (loop, SIGTERM);
|
||||
}
|
||||
|
||||
reload_cfg_file(s->config_pool, s->vconfig, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -346,6 +346,8 @@ int send_socket_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t c
|
||||
return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size, pack);
|
||||
}
|
||||
|
||||
int secmod_reload(main_server_st * s);
|
||||
|
||||
void secmod_socket_file_name(struct perm_cfg_st *perm_config, char *name, unsigned max_name_size);
|
||||
void clear_vhosts(struct list_head *head);
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ static int need_maintainance = 0;
|
||||
static int need_reload = 0;
|
||||
static int need_exit = 0;
|
||||
|
||||
static void reload_server(sec_mod_st *sec);
|
||||
|
||||
static int load_keys(sec_mod_st *sec, unsigned force);
|
||||
|
||||
static
|
||||
@@ -496,6 +498,16 @@ int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t
|
||||
data.size = buffer_size;
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_SECM_RELOAD:
|
||||
reload_server(sec);
|
||||
|
||||
ret = send_msg(pool, fd, CMD_SECM_RELOAD_REPLY, NULL,
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
seclog(sec, LOG_ERR, "could not send reload reply to main!\n");
|
||||
return ERR_BAD_COMMAND;
|
||||
}
|
||||
break;
|
||||
case CMD_SECM_LIST_COOKIES:
|
||||
handle_secm_list_cookies_reply(pool, fd, sec);
|
||||
|
||||
@@ -561,11 +573,6 @@ static void handle_alarm(int signo)
|
||||
need_maintainance = 1;
|
||||
}
|
||||
|
||||
static void handle_sighup(int signo)
|
||||
{
|
||||
need_reload = 1;
|
||||
}
|
||||
|
||||
static void handle_sigterm(int signo)
|
||||
{
|
||||
need_exit = 1;
|
||||
@@ -608,6 +615,22 @@ static void send_stats_to_main(sec_mod_st *sec)
|
||||
return;
|
||||
}
|
||||
|
||||
static void reload_server(sec_mod_st *sec)
|
||||
{
|
||||
vhost_cfg_st *vhost = NULL;
|
||||
|
||||
seclog(sec, LOG_DEBUG, "reloading configuration");
|
||||
reload_cfg_file(sec, sec->vconfig, 1);
|
||||
load_keys(sec, 0);
|
||||
|
||||
list_for_each(sec->vconfig, vhost, list) {
|
||||
sec_auth_init(vhost);
|
||||
}
|
||||
sup_config_init(sec);
|
||||
|
||||
need_reload = 0;
|
||||
}
|
||||
|
||||
static void check_other_work(sec_mod_st *sec)
|
||||
{
|
||||
vhost_cfg_st *vhost = NULL;
|
||||
@@ -631,16 +654,7 @@ static void check_other_work(sec_mod_st *sec)
|
||||
}
|
||||
|
||||
if (need_reload) {
|
||||
seclog(sec, LOG_DEBUG, "reloading configuration");
|
||||
reload_cfg_file(sec, sec->vconfig, 1);
|
||||
load_keys(sec, 0);
|
||||
|
||||
list_for_each(sec->vconfig, vhost, list) {
|
||||
sec_auth_init(vhost);
|
||||
}
|
||||
sup_config_init(sec);
|
||||
|
||||
need_reload = 0;
|
||||
reload_server(sec);
|
||||
}
|
||||
|
||||
if (need_maintainance) {
|
||||
@@ -933,7 +947,7 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
|
||||
/* we no longer need the main pool after this point. */
|
||||
talloc_free(main_pool);
|
||||
|
||||
ocsignal(SIGHUP, handle_sighup);
|
||||
ocsignal(SIGHUP, SIG_IGN);
|
||||
ocsignal(SIGINT, handle_sigterm);
|
||||
ocsignal(SIGTERM, handle_sigterm);
|
||||
ocsignal(SIGALRM, handle_alarm);
|
||||
|
||||
Reference in New Issue
Block a user