mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2024-09-21 10:27:19 +00:00
sec-mod/main: eliminate mem leaks related to vhost transition
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
parent
9af953383e
commit
cf8304cadf
29
src/config.c
29
src/config.c
@ -1048,9 +1048,13 @@ static int cfg_ini_handler(void *_ctx, const char *section, const char *name, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
CFG_FLAG_RELOAD = (1<<0),
|
||||
CFG_FLAG_SECMOD = (1<<1)
|
||||
};
|
||||
|
||||
static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
|
||||
unsigned reload)
|
||||
unsigned flags)
|
||||
{
|
||||
int ret;
|
||||
struct cfg_st *config;
|
||||
@ -1060,7 +1064,7 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.file = file;
|
||||
ctx.reload = reload;
|
||||
ctx.reload = (flags&CFG_FLAG_RELOAD)?1:0;
|
||||
ctx.head = head;
|
||||
|
||||
/* parse configuration
|
||||
@ -1109,11 +1113,14 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
|
||||
defvhost = NULL;
|
||||
|
||||
/* this check copies mandatory fields from default vhost if needed */
|
||||
check_cfg(vhost, defvhost, reload);
|
||||
check_cfg(vhost, defvhost, ctx.reload);
|
||||
|
||||
tls_load_files(NULL, vhost);
|
||||
tls_load_prio(NULL, vhost);
|
||||
tls_reload_crl(NULL, vhost, 1);
|
||||
/* the following are only useful in main process */
|
||||
if (!(flags & CFG_FLAG_SECMOD)) {
|
||||
tls_load_files(NULL, vhost);
|
||||
tls_load_prio(NULL, vhost);
|
||||
tls_reload_crl(NULL, vhost, 1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
if (vhost->urlfw_size > 0) {
|
||||
@ -1550,12 +1557,16 @@ static void print_version(void)
|
||||
}
|
||||
|
||||
|
||||
void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive)
|
||||
void reload_cfg_file(void *pool, struct list_head *configs, unsigned sec_mod)
|
||||
{
|
||||
struct vhost_cfg_st* vhost = NULL;
|
||||
unsigned flags = CFG_FLAG_RELOAD;
|
||||
|
||||
if (sec_mod)
|
||||
flags |= CFG_FLAG_SECMOD;
|
||||
|
||||
/* Archive or clear any non-permanent configs */
|
||||
if (archive)
|
||||
if (!sec_mod)
|
||||
archive_cfg(configs);
|
||||
else
|
||||
clear_cfg(configs);
|
||||
@ -1567,7 +1578,7 @@ void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive)
|
||||
}
|
||||
|
||||
/* parse the config again */
|
||||
parse_cfg_file(pool, cfg_file, configs, 1);
|
||||
parse_cfg_file(pool, cfg_file, configs, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -675,6 +675,16 @@ void secmod_socket_file_name(struct perm_cfg_st *perm_config, char *name, unsign
|
||||
perm_config->socket_file_prefix, (unsigned)getpid());
|
||||
}
|
||||
|
||||
static void clear_unneeded_mem(struct list_head *vconfig)
|
||||
{
|
||||
vhost_cfg_st *vhost = NULL;
|
||||
|
||||
/* deinitialize certificate credentials etc. */
|
||||
list_for_each_rev(vconfig, vhost, list) {
|
||||
tls_vhost_deinit(vhost);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns two file descriptors to be used for communication with sec-mod.
|
||||
* The sync_fd is used by main to send synchronous commands- commands which
|
||||
* expect a reply immediately.
|
||||
@ -728,6 +738,7 @@ int run_sec_mod(main_server_st *s, int *sync_fd)
|
||||
close(sfd[1]);
|
||||
set_cloexec_flag (fd[0], 1);
|
||||
set_cloexec_flag (sfd[0], 1);
|
||||
clear_unneeded_mem(s->vconfig);
|
||||
sec_mod_server(s->main_pool, s->config_pool, s->vconfig, p, fd[0], sfd[0]);
|
||||
exit(0);
|
||||
} else if (pid > 0) { /* parent */
|
||||
|
@ -1033,7 +1033,7 @@ static void reload_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revent
|
||||
* That's because of a test that the certificate matches the
|
||||
* used key. */
|
||||
ms_sleep(1500);
|
||||
reload_cfg_file(s->config_pool, s->vconfig, 1);
|
||||
reload_cfg_file(s->config_pool, s->vconfig, 0);
|
||||
}
|
||||
|
||||
static void cmd_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
|
@ -626,13 +626,13 @@ static void check_other_work(sec_mod_st *sec)
|
||||
sec_mod_client_db_deinit(sec);
|
||||
tls_cache_deinit(&sec->tls_db);
|
||||
talloc_free(sec->config_pool);
|
||||
talloc_free(sec);
|
||||
talloc_free(sec->sec_mod_pool);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (need_reload) {
|
||||
seclog(sec, LOG_DEBUG, "reloading configuration");
|
||||
reload_cfg_file(sec, sec->vconfig, 0);
|
||||
reload_cfg_file(sec, sec->vconfig, 1);
|
||||
load_keys(sec, 0);
|
||||
|
||||
list_for_each(sec->vconfig, vhost, list) {
|
||||
@ -918,6 +918,7 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
|
||||
|
||||
sec->vconfig = vconfig;
|
||||
sec->config_pool = config_pool;
|
||||
sec->sec_mod_pool = sec_mod_pool;
|
||||
|
||||
tls_cache_init(sec, &sec->tls_db);
|
||||
sup_config_init(sec);
|
||||
|
@ -35,6 +35,7 @@
|
||||
typedef struct sec_mod_st {
|
||||
struct list_head *vconfig;
|
||||
void *config_pool;
|
||||
void *sec_mod_pool;
|
||||
|
||||
struct htable *client_db;
|
||||
int cmd_fd;
|
||||
|
@ -816,7 +816,7 @@ int load_cert_files(main_server_st *s, struct vhost_cfg_st *vhost)
|
||||
}
|
||||
|
||||
pcert_list_size = 8;
|
||||
pcert_list = gnutls_malloc(sizeof(pcert_list[0])*pcert_list_size);
|
||||
pcert_list = talloc_size(vhost->pool, sizeof(pcert_list[0])*pcert_list_size);
|
||||
if (pcert_list == NULL) {
|
||||
mslog(s, NULL, LOG_ERR, "error allocating memory");
|
||||
return -1;
|
||||
@ -1038,6 +1038,9 @@ void tls_load_prio(main_server_st *s, struct vhost_cfg_st *vhost)
|
||||
int ret;
|
||||
const char* perr;
|
||||
|
||||
if (vhost->creds.cprio != NULL)
|
||||
gnutls_priority_deinit(vhost->creds.cprio);
|
||||
|
||||
ret = gnutls_priority_init(&vhost->creds.cprio, vhost->perm_config.config->priorities, &perr);
|
||||
if (ret == GNUTLS_E_PARSING_ERROR)
|
||||
mslog(s, NULL, LOG_ERR, "error in TLS priority string: %s", perr);
|
||||
|
@ -427,7 +427,7 @@ enum option_types { OPTION_NUMERIC, OPTION_STRING, OPTION_BOOLEAN, OPTION_MULTI_
|
||||
|
||||
#include <ip-util.h>
|
||||
|
||||
void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive);
|
||||
void reload_cfg_file(void *pool, struct list_head *configs, unsigned sec_mod);
|
||||
void clear_old_configs(struct list_head *configs);
|
||||
void write_pid_file(void);
|
||||
void remove_pid_file(void);
|
||||
|
Loading…
Reference in New Issue
Block a user