From 969e684960f0eff51f7adc7200f4154514ea4ca5 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 9 May 2014 12:00:34 +0200 Subject: [PATCH] Use talloc() for all allocations to reduce the possibility of memory leaks. --- configure.ac | 27 +++--- src/Makefile.am | 4 +- src/common.c | 51 +++++++---- src/common.h | 17 +++- src/config.c | 152 +++++++++++++++--------------- src/group-config.c | 39 ++++---- src/html.c | 15 +-- src/html.h | 6 +- src/ip-lease.c | 35 ++++--- src/ip-lease.h | 4 + src/main-auth.c | 6 +- src/main-auth.h | 2 +- src/main-ctl-dbus.c | 6 +- src/main-ctl-unix.c | 197 +++++++++++++++++++-------------------- src/main-misc.c | 87 +++++++++++------- src/main-resume.c | 6 +- src/main.c | 218 +++++++++++++++++++++++++------------------- src/main.h | 22 +++-- src/occtl-cache.c | 16 ++-- src/occtl-dbus.c | 63 +++++++------ src/occtl-unix.c | 42 ++++----- src/occtl.c | 34 ++++--- src/occtl.h | 11 ++- src/pam.c | 16 ++-- src/plain.c | 10 +- src/script-list.h | 4 +- src/str.c | 16 +--- src/str.h | 5 +- src/tlslib.c | 69 +++++++------- src/tlslib.h | 24 ++--- src/worker-auth.c | 49 +++++----- src/worker-resume.c | 5 +- src/worker-vpn.c | 16 ++-- src/worker.h | 2 +- 34 files changed, 694 insertions(+), 582 deletions(-) diff --git a/configure.ac b/configure.ac index f81939f0..b5c6a58c 100644 --- a/configure.ac +++ b/configure.ac @@ -83,7 +83,8 @@ PKG_CHECK_MODULES([LIBPROTOBUF_C], [libprotobuf-c],, AC_MSG_WARN([[*** *** libprotobuf-c was not found. ***]]) - AC_SUBST([LIBPROTOBUF_C_CFLAGS], [-Iprotobuf/]) + FLAGS='-Iprotobuf' + AC_SUBST([LIBPROTOBUF_C_CFLAGS], [$FLAGS]) with_local_protobuf_c=yes fi ] @@ -93,28 +94,32 @@ fi AM_CONDITIONAL(LOCAL_PROTOBUF_C, test "x$with_local_protobuf_c" != xno) -AC_ARG_WITH(talloc, - AS_HELP_STRING([--without-talloc], [use the included talloc library]), - test_for_talloc=$withval, - test_for_talloc=yes) +AC_ARG_WITH(local-talloc, + AS_HELP_STRING([--with-local-talloc], [use the included talloc library]), + no_test_for_talloc=$withval, + no_test_for_talloc=no) -with_local_talloc=no -if test "$test_for_talloc" = yes;then -PKG_CHECK_MODULES([LIBPROTOBUF_C], [libtalloc-c],, +with_local_talloc=yes +if test "$no_test_for_talloc" != yes;then +PKG_CHECK_MODULES([LIBTALLOC], [talloc],, [AC_LIB_HAVE_LINKFLAGS(talloc,, [#include ], [talloc_size(0,0);]) if test x$ac_cv_libtalloc = xyes; then AC_SUBST([LIBTALLOC_LIBS], [$LIBTALLOC]) + with_local_talloc=no else AC_MSG_WARN([[*** -*** libtalloc-c was not found. +*** libtalloc was not found. ***]]) - AC_SUBST([LIBTALLOC_CFLAGS], [-Iccan/talloc/ -Iccan/typedef_cb/ -Iccan/compiler/]) - with_local_talloc=yes fi ] ) fi +if test "$with_local_talloc" != no;then +FLAGS='-Iccan/talloc/ -Iccan/typedef_cb/ -Iccan/compiler/' +AC_SUBST([LIBTALLOC_CFLAGS], [$FLAGS]) +fi + AM_CONDITIONAL(LOCAL_TALLOC, test "x$with_local_talloc" != xno) diff --git a/src/Makefile.am b/src/Makefile.am index 9b39b01d..b0fbc2d7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -96,9 +96,9 @@ ocpasswd-args.c: $(srcdir)/ocpasswd-args.def ocpasswd-args.h: ocpasswd-args.c occtl_SOURCES = occtl.c occtl-pager.c occtl.h occtl-time.c occtl-cache.c \ - occtl-nl.c ctl.h common.h common.c ctl.pb-c.c ctl.pb-c.h + occtl-nl.c ctl.h common.h common.c ctl.pb-c.c ctl.pb-c.h $(CCAN_SOURCES) occtl_LDADD = ../gl/libgnu.a $(LIBREADLINE_LIBS) \ - $(LIBNL3_LIBS) $(LIBPROTOBUF_C_LIBS) + $(LIBNL3_LIBS) $(LIBPROTOBUF_C_LIBS) $(LIBTALLOC_LIBS) if HAVE_DBUS ocserv_SOURCES += main-ctl-dbus.c diff --git a/src/common.c b/src/common.c index fca15f6d..02f00bfd 100644 --- a/src/common.c +++ b/src/common.c @@ -164,32 +164,32 @@ int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2, /* returns an allocated string with the mask to apply for the prefix */ -char* ipv6_prefix_to_mask(unsigned prefix) +char* ipv6_prefix_to_mask(void *pool, unsigned prefix) { switch (prefix) { case 16: - return strdup("ffff::"); + return talloc_strdup(pool, "ffff::"); case 32: - return strdup("ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff::"); case 48: - return strdup("ffff:ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff:ffff::"); case 64: - return strdup("ffff:ffff:ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff:ffff:ffff::"); case 80: - return strdup("ffff:ffff:ffff:ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff:ffff:ffff:ffff::"); case 96: - return strdup("ffff:ffff:ffff:ffff:ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff:ffff:ffff:ffff:ffff::"); case 112: - return strdup("ffff:ffff:ffff:ffff:ffff:ffff:ffff::"); + return talloc_strdup(pool, "ffff:ffff:ffff:ffff:ffff:ffff:ffff::"); case 128: - return strdup("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + return talloc_strdup(pool, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); default: return NULL; } } /* Sends message + socketfd */ -int send_socket_msg(int fd, uint8_t cmd, +int send_socket_msg(void *pool, int fd, uint8_t cmd, int socketfd, const void* msg, pack_size_func get_size, pack_func pack) { @@ -218,7 +218,7 @@ int send_socket_msg(int fd, uint8_t cmd, hdr.msg_iovlen = 2; if (length > 0) { - packed = malloc(length); + packed = talloc_size(pool, length); if (packed == NULL) { syslog(LOG_ERR, "%s:%u: memory error", __FILE__, __LINE__); return -1; @@ -255,18 +255,18 @@ int send_socket_msg(int fd, uint8_t cmd, } cleanup: - free(packed); + talloc_free(packed); return ret; } -int send_msg(int fd, uint8_t cmd, +int send_msg(void *pool, int fd, uint8_t cmd, const void* msg, pack_size_func get_size, pack_func pack) { - return send_socket_msg(fd, cmd, -1, msg, get_size, pack); + return send_socket_msg(pool, fd, cmd, -1, msg, get_size, pack); } -int recv_socket_msg(int fd, uint8_t cmd, +int recv_socket_msg(void *pool, int fd, uint8_t cmd, int* socketfd, void** msg, unpack_func unpack) { struct iovec iov[3]; @@ -280,6 +280,7 @@ int recv_socket_msg(int fd, uint8_t cmd, } control_un; struct cmsghdr *cmptr; int ret; + PROTOBUF_ALLOCATOR(pa, pool); iov[0].iov_base = &rcmd; iov[0].iov_len = 1; @@ -327,7 +328,7 @@ int recv_socket_msg(int fd, uint8_t cmd, } if (length > 0) { - data = malloc(length); + data = talloc_size(pool, length); if (data == NULL) { ret = ERR_MEM; goto cleanup; @@ -341,7 +342,7 @@ int recv_socket_msg(int fd, uint8_t cmd, goto cleanup; } - *msg = unpack(NULL, length, data); + *msg = unpack(&pa, length, data); if (*msg == NULL) { syslog(LOG_ERR, "%s:%u: unpacking error", __FILE__, __LINE__); ret = ERR_MEM; @@ -352,14 +353,24 @@ int recv_socket_msg(int fd, uint8_t cmd, ret = 0; cleanup: - free(data); + talloc_free(data); if (ret < 0 && socketfd != NULL && *socketfd != -1) close(*socketfd); return ret; } -int recv_msg(int fd, uint8_t cmd, +int recv_msg(void *pool, int fd, uint8_t cmd, void** msg, unpack_func unpack) { - return recv_socket_msg(fd, cmd, NULL, msg, unpack); + return recv_socket_msg(pool, fd, cmd, NULL, msg, unpack); +} + +void _talloc_free2(void *ctx, void *ptr) +{ + talloc_free(ptr); +} + +void *_talloc_size2(void *ctx, size_t size) +{ + return talloc_size(ctx, size); } diff --git a/src/common.h b/src/common.h index a810cb98..a3149a82 100644 --- a/src/common.h +++ b/src/common.h @@ -23,12 +23,19 @@ #include #include +#include + +void _talloc_free2(void *ctx, void *ptr); +void *_talloc_size2(void *ctx, size_t size); + +#define PROTOBUF_ALLOCATOR(name, pool) \ + ProtobufCAllocator name = {.alloc = _talloc_size2, .free = _talloc_free2, .allocator_data = pool} ssize_t force_write(int sockfd, const void *buf, size_t len); ssize_t force_read(int sockfd, void *buf, size_t len); ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec); int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2, size_t n); -char* ipv6_prefix_to_mask(unsigned prefix); +char* ipv6_prefix_to_mask(void *pool, unsigned prefix); typedef size_t (*pack_func)(const void*, uint8_t *); typedef size_t (*pack_size_func)(const void*); @@ -37,17 +44,17 @@ typedef void* (*unpack_func)(ProtobufCAllocator *allocator, size_t len, const uint8_t *data); -int send_msg(int fd, uint8_t cmd, +int send_msg(void *pool, int fd, uint8_t cmd, const void* msg, pack_size_func get_size, pack_func pack); -int send_socket_msg(int fd, uint8_t cmd, +int send_socket_msg(void *pool, int fd, uint8_t cmd, int socketfd, const void* msg, pack_size_func get_size, pack_func pack); -int recv_msg(int fd, uint8_t cmd, +int recv_msg(void *pool, int fd, uint8_t cmd, void** msg, unpack_func); -int recv_socket_msg(int fd, uint8_t cmd, +int recv_socket_msg(void *pool, int fd, uint8_t cmd, int *socketfd, void** msg, unpack_func); const char* cmd_request_to_str(unsigned cmd); diff --git a/src/config.c b/src/config.c index bdcb560b..5f9b1df9 100644 --- a/src/config.c +++ b/src/config.c @@ -144,12 +144,12 @@ unsigned j; if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ if (s_name == NULL) { \ num = 0; \ - s_name = malloc(sizeof(char*)*MAX_CONFIG_ENTRIES); \ + s_name = talloc_size(config, sizeof(char*)*MAX_CONFIG_ENTRIES); \ } \ do { \ if (val && !strcmp(val->pzName, name)==0) \ continue; \ - s_name[num] = strdup(val->v.strVal); \ + s_name[num] = talloc_strdup(config, val->v.strVal); \ num++; \ if (num>=MAX_CONFIG_ENTRIES) \ break; \ @@ -163,7 +163,7 @@ unsigned j; #define READ_STRING(name, s_name) \ val = get_option(name, &mand); \ if (val != NULL && val->valType == OPARG_TYPE_STRING) \ - s_name = strdup(val->v.strVal); \ + s_name = talloc_strdup(config, val->v.strVal); \ else if (mand != 0) { \ fprintf(stderr, "Configuration option %s is mandatory.\n", name); \ exit(1); \ @@ -188,7 +188,7 @@ unsigned j; else \ s_name = 0; \ } \ - free(tmp_tf); \ + talloc_free(tmp_tf); \ } #define READ_NUMERIC(name, s_name) \ @@ -301,7 +301,7 @@ unsigned force_cert_auth; exit(1); } - config->plain_passwd = strdup(auth[j]+6); + config->plain_passwd = talloc_strdup(config, auth[j]+6); p = strchr(config->plain_passwd, ']'); if (p == NULL) { fprintf(stderr, "Format error in %s\n", auth[j]); @@ -315,9 +315,9 @@ unsigned force_cert_auth; fprintf(stderr, "Unknown auth method: %s\n", auth[j]); exit(1); } - free(auth[j]); + talloc_free(auth[j]); } - free(auth); + talloc_free(auth); /* When adding allocated data, remember to modify * reload_cfg_file(); @@ -413,7 +413,7 @@ unsigned force_cert_auth; fprintf(stderr, "Unknown rekey method '%s'\n", tmp); exit(1); } - free(tmp); tmp = NULL; + talloc_free(tmp); tmp = NULL; READ_NUMERIC("auth-timeout", config->auth_timeout); READ_NUMERIC("idle-timeout", config->idle_timeout); @@ -457,7 +457,7 @@ unsigned force_cert_auth; READ_NUMERIC("ipv6-prefix", prefix); if (prefix > 0) { - config->network.ipv6_netmask = ipv6_prefix_to_mask(prefix); + config->network.ipv6_netmask = ipv6_prefix_to_mask(config, prefix); config->network.ipv6_prefix = prefix; if (config->network.ipv6_netmask == NULL) { @@ -508,7 +508,7 @@ unsigned force_cert_auth; /* sanity checks on config */ -static void check_cfg( struct cfg_st *config) +static void check_cfg(struct cfg_st *config) { if (config->network.ipv4 == NULL && config->network.ipv6 == NULL) { fprintf(stderr, "No ipv4-network or ipv6-network options set.\n"); @@ -551,16 +551,16 @@ static void check_cfg( struct cfg_st *config) #ifdef ANYCONNECT_CLIENT_COMPAT if (config->cert) { - config->cert_hash = calc_sha1_hash(config->cert[0], 1); + config->cert_hash = calc_sha1_hash(config, config->cert[0], 1); } if (config->xml_config_file) { - config->xml_config_hash = calc_sha1_hash(config->xml_config_file, 0); + config->xml_config_hash = calc_sha1_hash(config, config->xml_config_file, 0); if (config->xml_config_hash == NULL && config->chroot_dir != NULL) { char path[_POSIX_PATH_MAX]; snprintf(path, sizeof(path), "%s/%s", config->chroot_dir, config->xml_config_file); - config->xml_config_hash = calc_sha1_hash(path, 0); + config->xml_config_hash = calc_sha1_hash(config, path, 0); if (config->xml_config_hash == NULL) { fprintf(stderr, "Cannot open file '%s'\n", path); @@ -584,21 +584,21 @@ static void check_cfg( struct cfg_st *config) config->priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT"; } -int cmd_parser (int argc, char **argv, struct cfg_st* config) +int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config) { - memset(config, 0, sizeof(*config)); + *config = talloc_zero(pool, struct cfg_st); optionProcess( &ocservOptions, argc, argv); if (HAVE_OPT(FOREGROUND)) - config->foreground = 1; + (*config)->foreground = 1; if (HAVE_OPT(PID_FILE)) pid_file = OPT_ARG(PID_FILE); if (HAVE_OPT(DEBUG)) - config->debug = OPT_VALUE_DEBUG; + (*config)->debug = OPT_VALUE_DEBUG; if (HAVE_OPT(CONFIG)) { cfg_file = OPT_ARG(CONFIG); @@ -607,85 +607,85 @@ int cmd_parser (int argc, char **argv, struct cfg_st* config) exit(1); } - parse_cfg_file(cfg_file, config); + parse_cfg_file(cfg_file, *config); - check_cfg(config); + check_cfg(*config); return 0; } -#define DEL(x) {free(x);x=NULL;} -void clear_cfg_file(struct cfg_st* config) +#define DEL(x) {talloc_free(x);x=NULL;} +void clear_cfg_file(struct cfg_st** config) { unsigned i; #ifdef ANYCONNECT_CLIENT_COMPAT - DEL(config->xml_config_file); - DEL(config->xml_config_hash); - DEL(config->cert_hash); + DEL((*config)->xml_config_file); + DEL((*config)->xml_config_hash); + DEL((*config)->cert_hash); #endif - DEL(config->cgroup); - DEL(config->route_add_cmd); - DEL(config->route_del_cmd); - DEL(config->per_user_dir); - DEL(config->per_group_dir); - DEL(config->socket_file_prefix); - DEL(config->default_domain); - DEL(config->plain_passwd); - DEL(config->ocsp_response); - DEL(config->banner); - DEL(config->dh_params_file); - DEL(config->name); - DEL(config->pin_file); - DEL(config->srk_pin_file); - DEL(config->ca); - DEL(config->crl); - DEL(config->cert_user_oid); - DEL(config->cert_group_oid); - DEL(config->priorities); - DEL(config->chroot_dir); - DEL(config->connect_script); - DEL(config->disconnect_script); + DEL((*config)->cgroup); + DEL((*config)->route_add_cmd); + DEL((*config)->route_del_cmd); + DEL((*config)->per_user_dir); + DEL((*config)->per_group_dir); + DEL((*config)->socket_file_prefix); + DEL((*config)->default_domain); + DEL((*config)->plain_passwd); + DEL((*config)->ocsp_response); + DEL((*config)->banner); + DEL((*config)->dh_params_file); + DEL((*config)->name); + DEL((*config)->pin_file); + DEL((*config)->srk_pin_file); + DEL((*config)->ca); + DEL((*config)->crl); + DEL((*config)->cert_user_oid); + DEL((*config)->cert_group_oid); + DEL((*config)->priorities); + DEL((*config)->chroot_dir); + DEL((*config)->connect_script); + DEL((*config)->disconnect_script); - DEL(config->network.ipv4); - DEL(config->network.ipv4_netmask); - DEL(config->network.ipv6); - DEL(config->network.ipv6_netmask); - for (i=0;inetwork.routes_size;i++) - DEL(config->network.routes[i]); - DEL(config->network.routes); - for (i=0;inetwork.dns_size;i++) - DEL(config->network.dns[i]); - DEL(config->network.dns); - for (i=0;inetwork.nbns_size;i++) - DEL(config->network.nbns[i]); - DEL(config->network.nbns); - for (i=0;ikey_size;i++) - DEL(config->key[i]); - DEL(config->key); - for (i=0;icert_size;i++) - DEL(config->cert[i]); - DEL(config->cert); - for (i=0;icustom_header_size;i++) - DEL(config->custom_header[i]); - DEL(config->custom_header); - for (i=0;isplit_dns_size;i++) - DEL(config->split_dns[i]); - DEL(config->split_dns); + DEL((*config)->network.ipv4); + DEL((*config)->network.ipv4_netmask); + DEL((*config)->network.ipv6); + DEL((*config)->network.ipv6_netmask); + for (i=0;i<(*config)->network.routes_size;i++) + DEL((*config)->network.routes[i]); + DEL((*config)->network.routes); + for (i=0;i<(*config)->network.dns_size;i++) + DEL((*config)->network.dns[i]); + DEL((*config)->network.dns); + for (i=0;i<(*config)->network.nbns_size;i++) + DEL((*config)->network.nbns[i]); + DEL((*config)->network.nbns); + for (i=0;i<(*config)->key_size;i++) + DEL((*config)->key[i]); + DEL((*config)->key); + for (i=0;i<(*config)->cert_size;i++) + DEL((*config)->cert[i]); + DEL((*config)->cert); + for (i=0;i<(*config)->custom_header_size;i++) + DEL((*config)->custom_header[i]); + DEL((*config)->custom_header); + for (i=0;i<(*config)->split_dns_size;i++) + DEL((*config)->split_dns[i]); + DEL((*config)->split_dns); + talloc_free(*config); + *config = NULL; return; } -void reload_cfg_file(struct cfg_st* config) +void reload_cfg_file(void *pool, struct cfg_st** config) { clear_cfg_file(config); - memset(config, 0, sizeof(*config)); + parse_cfg_file(cfg_file, *config); - parse_cfg_file(cfg_file, config); - - check_cfg(config); + check_cfg(*config); return; } diff --git a/src/group-config.c b/src/group-config.c index b9505c22..5e7cd7f4 100644 --- a/src/group-config.c +++ b/src/group-config.c @@ -63,14 +63,14 @@ static struct cfg_options available_options[] = { if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ if (s_name == NULL) { \ num = 0; \ - s_name = malloc(sizeof(char*)*MAX_CONFIG_ENTRIES); \ + s_name = talloc_size(proc, sizeof(char*)*MAX_CONFIG_ENTRIES); \ } \ do { \ if (num >= MAX_CONFIG_ENTRIES) \ break; \ if (val && !strcmp(val->pzName, name)==0) \ continue; \ - s_name[num] = strdup(val->v.strVal); \ + s_name[num] = talloc_strdup(proc, val->v.strVal); \ num++; \ } while((val = optionNextValue(pov, val)) != NULL); \ s_name[num] = NULL; \ @@ -80,8 +80,8 @@ static struct cfg_options available_options[] = { val = optionGetValue(pov, name); \ if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ if (s_name != NULL) \ - free(s_name); \ - s_name = strdup(val->v.strVal); \ + talloc_free(s_name); \ + s_name = talloc_strdup(proc, val->v.strVal); \ } #define READ_RAW_NUMERIC(name, s_name) \ @@ -125,11 +125,12 @@ unsigned j; * config. The provided config must either be memset to zero, or be * already allocated using this function. */ -int parse_group_cfg_file(main_server_st* s, const char* file, struct group_cfg_st *config) +int parse_group_cfg_file(main_server_st* s, struct proc_st *proc, const char* file) { tOptionValue const * pov; const tOptionValue* val, *prev; unsigned prefix = 0; +struct group_cfg_st *config = &proc->config; pov = configFileLoad(file); if (pov == NULL) { @@ -174,7 +175,7 @@ unsigned prefix = 0; READ_RAW_NUMERIC("ipv6-prefix", prefix); if (prefix > 0) { - config->ipv6_netmask = ipv6_prefix_to_mask(prefix); + config->ipv6_netmask = ipv6_prefix_to_mask(proc, prefix); config->ipv6_prefix = prefix; if (config->ipv6_netmask == NULL) { @@ -201,29 +202,29 @@ void del_additional_config(struct group_cfg_st* config) unsigned i; for(i=0;iroutes_size;i++) { - free(config->routes[i]); + talloc_free(config->routes[i]); } - free(config->routes); + talloc_free(config->routes); for(i=0;iiroutes_size;i++) { - free(config->iroutes[i]); + talloc_free(config->iroutes[i]); } - free(config->iroutes); + talloc_free(config->iroutes); for(i=0;idns_size;i++) { - free(config->dns[i]); + talloc_free(config->dns[i]); } - free(config->dns); + talloc_free(config->dns); for(i=0;inbns_size;i++) { - free(config->nbns[i]); + talloc_free(config->nbns[i]); } - free(config->nbns); + talloc_free(config->nbns); - free(config->cgroup); - free(config->ipv4_network); - free(config->ipv6_network); - free(config->ipv4_netmask); - free(config->ipv6_netmask); + talloc_free(config->cgroup); + talloc_free(config->ipv4_network); + talloc_free(config->ipv6_network); + talloc_free(config->ipv4_netmask); + talloc_free(config->ipv6_netmask); memset(config, 0, sizeof(*config)); } diff --git a/src/html.c b/src/html.c index 356f30ab..0e68e369 100644 --- a/src/html.c +++ b/src/html.c @@ -22,18 +22,19 @@ #include #include #include +#include #include #include #include "html.h" -char *unescape_html(const char *html, unsigned len, unsigned *out_len) +char *unescape_html(void *pool, const char *html, unsigned len, unsigned *out_len) { char *msg; int pos; unsigned i; - msg = malloc(len + 1); + msg = talloc_size(pool, len + 1); if (msg == NULL) return NULL; @@ -70,13 +71,13 @@ char *unescape_html(const char *html, unsigned len, unsigned *out_len) return msg; } -char *unescape_url(const char *url, unsigned len, unsigned *out_len) +char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len) { char *msg; int pos; unsigned i; - msg = malloc(len + 1); + msg = talloc_size(pool, len + 1); if (msg == NULL) return NULL; @@ -90,7 +91,7 @@ char *unescape_url(const char *url, unsigned len, unsigned *out_len) b[2] = 0; if (sscanf(b, "%02x", &u) <= 0) { - free(msg); + talloc_free(msg); syslog(LOG_ERR, "%s: error parsing URL: %s", __func__, url); return NULL; } @@ -108,13 +109,13 @@ char *unescape_url(const char *url, unsigned len, unsigned *out_len) return msg; } -char *escape_url(const char *url, unsigned len, unsigned *out_len) +char *escape_url(void *pool, const char *url, unsigned len, unsigned *out_len) { char *msg; int pos; unsigned i; - msg = malloc(3*len + 1); + msg = talloc_size(pool, 3*len + 1); if (msg == NULL) return NULL; diff --git a/src/html.h b/src/html.h index f4a830de..4627700b 100644 --- a/src/html.h +++ b/src/html.h @@ -21,8 +21,8 @@ #ifndef OC_HTML_H # define OC_HTML_H -char* unescape_html(const char *html, unsigned len, unsigned *out_len); -char *unescape_url(const char *url, unsigned len, unsigned *out_len); -char *escape_url(const char *url, unsigned len, unsigned *out_len); +char* unescape_html(void *pool, const char *html, unsigned len, unsigned *out_len); +char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len); +char *escape_url(void *pool, const char *url, unsigned len, unsigned *out_len); #endif diff --git a/src/ip-lease.c b/src/ip-lease.c index 379e26ec..111df6a6 100644 --- a/src/ip-lease.c +++ b/src/ip-lease.c @@ -55,7 +55,7 @@ struct htable_iter iter; cache = htable_first(&db->ht, &iter); while(cache != NULL) { - free(cache); + talloc_free(cache); cache = htable_next(&db->ht, &iter); } @@ -102,6 +102,11 @@ struct ip_lease_st t; return 0; } +void steal_ip_leases(struct proc_st* proc, struct proc_st *thief) +{ + thief->ipv4 = talloc_move(thief, &proc->ipv4); + thief->ipv6 = talloc_move(thief, &proc->ipv6); +} #define MAX_IP_TRIES 16 @@ -141,9 +146,10 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc) return -1; } - proc->ipv4 = calloc(1, sizeof(*proc->ipv4)); + proc->ipv4 = talloc_zero(proc, struct ip_lease_st); if (proc->ipv4 == NULL) return ERR_MEM; + proc->ipv4->db = &s->ip_leases; /* mask the network (just in case it is wrong) */ for (i=0;iipv4); + talloc_free(proc->ipv4); proc->ipv4 = NULL; return ret; @@ -277,9 +283,10 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc) return -1; } - proc->ipv6 = calloc(1, sizeof(*proc->ipv6)); + proc->ipv6 = talloc_zero(proc, struct ip_lease_st); if (proc->ipv6 == NULL) return ERR_MEM; + proc->ipv6->db = &s->ip_leases; /* mask the network */ for (i=0;iipv6); + talloc_free(proc->ipv6); proc->ipv6 = NULL; return ret; } +static +int unref_ip_lease(struct ip_lease_st * lease) +{ + htable_del(&lease->db->ht, rehash(lease, NULL), lease); + return 0; +} + int get_ip_leases(main_server_st* s, struct proc_st* proc) { int ret; @@ -391,6 +405,7 @@ char buf[128]; mslog(s, proc, LOG_ERR, "could not add IPv4 lease to hash table."); return -1; } + talloc_set_destructor(proc->ipv4, unref_ip_lease); } } @@ -404,6 +419,7 @@ char buf[128]; mslog(s, proc, LOG_ERR, "could not add IPv6 lease to hash table."); return -1; } + talloc_set_destructor(proc->ipv6, unref_ip_lease); } } @@ -426,19 +442,16 @@ char buf[128]; void remove_ip_leases(main_server_st* s, struct proc_st* proc) { if (proc->ipv4) { - htable_del(&s->ip_leases.ht, rehash(proc->ipv4, NULL), proc->ipv4); - free(proc->ipv4); + talloc_free(proc->ipv4); proc->ipv4 = NULL; } if (proc->ipv6) { - htable_del(&s->ip_leases.ht, rehash(proc->ipv6, NULL), proc->ipv6); - free(proc->ipv6); + talloc_free(proc->ipv6); proc->ipv6 = NULL; } } void remove_ip_lease(main_server_st* s, struct ip_lease_st * lease) { - htable_del(&s->ip_leases.ht, rehash(lease, NULL), lease); - free(lease); + talloc_free(lease); } diff --git a/src/ip-lease.h b/src/ip-lease.h index 4f27f65b..5e596ccf 100644 --- a/src/ip-lease.h +++ b/src/ip-lease.h @@ -33,11 +33,15 @@ struct ip_lease_st { struct sockaddr_storage lip; socklen_t lip_len; + + struct ip_lease_db_st* db; }; void ip_lease_deinit(struct ip_lease_db_st* db); void ip_lease_init(struct ip_lease_db_st* db); +void steal_ip_leases(struct proc_st* proc, struct proc_st *thief); + int get_ip_leases(struct main_server_st* s, struct proc_st* proc); void remove_ip_leases(struct main_server_st* s, struct proc_st* proc); void remove_ip_lease(main_server_st* s, struct ip_lease_st * lease); diff --git a/src/main-auth.c b/src/main-auth.c index 07a19c24..db22443b 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -293,7 +293,7 @@ const char* ip; if (s->config->auth_types & AUTH_TYPE_USERNAME_PASS) { /* req->username is non-null at this point */ - ret = module->auth_init(&proc->auth_ctx, req->user_name, ip, s->auth_extra); + ret = module->auth_init(&proc->auth_ctx, proc, req->user_name, ip, s->auth_extra); if (ret < 0) return ret; @@ -413,9 +413,7 @@ unsigned int entries = 1; /* that one */ mslog(s, ctmp, LOG_DEBUG, "disconnecting '%s' due to new cookie connection", ctmp->username); /* steal its leases */ - proc->ipv4 = ctmp->ipv4; - proc->ipv6 = ctmp->ipv6; - ctmp->leases_in_use = 1; + steal_ip_leases(ctmp, proc); kill(ctmp->pid, SIGTERM); } else if (strcmp(proc->username, ctmp->username) == 0) { diff --git a/src/main-auth.h b/src/main-auth.h index 1d2159d8..3d32bf3e 100644 --- a/src/main-auth.h +++ b/src/main-auth.h @@ -27,7 +27,7 @@ struct auth_mod_st { unsigned int type; - int (*auth_init)(void** ctx, const char* username, const char* ip, void* additional); + int (*auth_init)(void** ctx, void *pool, const char* username, const char* ip, void* additional); int (*auth_msg)(void* ctx, char* msg, size_t msg_size); int (*auth_pass)(void* ctx, const char* pass, unsigned pass_len); int (*auth_group)(void* ctx, char *groupname, int groupname_size); diff --git a/src/main-ctl-dbus.c b/src/main-ctl-dbus.c index 6067c088..7cb2fb62 100644 --- a/src/main-ctl-dbus.c +++ b/src/main-ctl-dbus.c @@ -160,7 +160,7 @@ static void add_ctl_fd(struct dbus_ctx *ctx, int fd, void *watch, unsigned type) { struct ctl_handler_st *tmp; - tmp = malloc(sizeof(*tmp)); + tmp = talloc_zero(ctx, struct ctl_handler_st); if (tmp == NULL) return; @@ -209,7 +209,7 @@ static void remove_watch(DBusWatch * watch, void *data) btmp->fd); list_del(&btmp->list); - free(btmp); + talloc_free(btmp); return; } } @@ -1128,7 +1128,7 @@ int ctl_handler_init(main_server_st * s) if (s->config->use_dbus == 0) return 0; - ctx = calloc(1, sizeof(struct dbus_ctx)); + ctx = talloc_zero(s, struct dbus_ctx); if (ctx == NULL) return ERR_CTL; diff --git a/src/main-ctl-unix.c b/src/main-ctl-unix.c index 8a899d54..fbb6c0d7 100644 --- a/src/main-ctl-unix.c +++ b/src/main-ctl-unix.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -37,24 +36,29 @@ #include #include -static void method_status(main_server_st * s, int cfd, uint8_t * msg, +typedef struct method_ctx { + main_server_st *s; + void *pool; +} method_ctx; + +static void method_status(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_list_users(main_server_st * s, int cfd, uint8_t * msg, +static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_disconnect_user_name(main_server_st * s, int cfd, +static void method_disconnect_user_name(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_disconnect_user_id(main_server_st * s, int cfd, +static void method_disconnect_user_id(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_stop(main_server_st * s, int cfd, uint8_t * msg, +static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_reload(main_server_st * s, int cfd, uint8_t * msg, +static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_user_info(main_server_st * s, int cfd, uint8_t * msg, +static void method_user_info(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -static void method_id_info(main_server_st * s, int cfd, uint8_t * msg, +static void method_id_info(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); -typedef void (*method_func) (main_server_st * s, int cfd, uint8_t * msg, +typedef void (*method_func) (method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size); typedef struct { @@ -142,75 +146,75 @@ int ctl_handler_init(main_server_st * s) return sd; } -static void method_status(main_server_st * s, int cfd, uint8_t * msg, +static void method_status(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { StatusRep rep = STATUS_REP__INIT; int ret; - mslog(s, NULL, LOG_DEBUG, "ctl: status"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: status"); rep.status = 1; rep.pid = getpid(); - rep.sec_mod_pid = s->sec_mod_pid; - rep.active_clients = s->active_clients; + rep.sec_mod_pid = ctx->s->sec_mod_pid; + rep.active_clients = ctx->s->active_clients; - ret = send_msg(cfd, CTL_CMD_STATUS_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_STATUS_REP, &rep, (pack_size_func) status_rep__get_packed_size, (pack_func) status_rep__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } return; } -static void method_reload(main_server_st * s, int cfd, uint8_t * msg, +static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { BoolMsg rep = BOOL_MSG__INIT; int ret; - mslog(s, NULL, LOG_DEBUG, "ctl: reload"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: reload"); request_reload(0); rep.status = 1; - ret = send_msg(cfd, CTL_CMD_RELOAD_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_RELOAD_REP, &rep, (pack_size_func) bool_msg__get_packed_size, (pack_func) bool_msg__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } return; } -static void method_stop(main_server_st * s, int cfd, uint8_t * msg, +static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { BoolMsg rep = BOOL_MSG__INIT; int ret; - mslog(s, NULL, LOG_DEBUG, "ctl: stop"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: stop"); request_stop(0); rep.status = 1; - ret = send_msg(cfd, CTL_CMD_STOP_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_STOP_REP, &rep, (pack_size_func) bool_msg__get_packed_size, (pack_func) bool_msg__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } return; } #define IPBUF_SIZE 64 -static int append_user_info(main_server_st * s, void *pool, +static int append_user_info(method_ctx *ctx, UserListRep * list, struct proc_st *ctmp, unsigned single) { @@ -220,11 +224,11 @@ static int append_user_info(main_server_st * s, void *pool, UserInfoRep *rep; list->user = - talloc_realloc(pool, list->user, UserInfoRep *, (1 + list->n_user)); + talloc_realloc(ctx->pool, list->user, UserInfoRep *, (1 + list->n_user)); if (list->user == NULL) return -1; - rep = list->user[list->n_user] = talloc(pool, UserInfoRep); + rep = list->user[list->n_user] = talloc(ctx->pool, UserInfoRep); if (rep == NULL) return -1; list->n_user++; @@ -236,7 +240,7 @@ static int append_user_info(main_server_st * s, void *pool, rep->username = ctmp->username; rep->groupname = ctmp->groupname; - ipbuf = talloc_size(pool, IPBUF_SIZE); + ipbuf = talloc_size(ctx->pool, IPBUF_SIZE); if (ipbuf == NULL) return -1; @@ -249,7 +253,7 @@ static int append_user_info(main_server_st * s, void *pool, rep->tun = ctmp->tun_lease.name; - ipbuf = talloc_size(pool, IPBUF_SIZE); + ipbuf = talloc_size(ctx->pool, IPBUF_SIZE); if (ipbuf == NULL) return -1; @@ -262,7 +266,7 @@ static int append_user_info(main_server_st * s, void *pool, strtmp = ""; rep->local_ip = strtmp; - ipbuf = talloc_size(pool, IPBUF_SIZE); + ipbuf = talloc_size(ctx->pool, IPBUF_SIZE); if (ipbuf == NULL) return -1; @@ -277,7 +281,7 @@ static int append_user_info(main_server_st * s, void *pool, /* IPv6 */ - ipbuf = talloc_size(pool, IPBUF_SIZE); + ipbuf = talloc_size(ctx->pool, IPBUF_SIZE); if (ipbuf == NULL) return -1; @@ -290,7 +294,7 @@ static int append_user_info(main_server_st * s, void *pool, strtmp = ""; rep->local_ip6 = strtmp; - ipbuf = talloc_size(pool, IPBUF_SIZE); + ipbuf = talloc_size(ctx->pool, IPBUF_SIZE); if (ipbuf == NULL) return -1; @@ -330,14 +334,14 @@ static int append_user_info(main_server_st * s, void *pool, if (ctmp->config.rx_per_sec > 0) tmp = ctmp->config.rx_per_sec; else - tmp = s->config->rx_per_sec; + tmp = ctx->s->config->rx_per_sec; tmp *= 1000; rep->rx_per_sec = tmp; if (ctmp->config.tx_per_sec > 0) tmp = ctmp->config.tx_per_sec; else - tmp = s->config->tx_per_sec; + tmp = ctx->s->config->tx_per_sec; tmp *= 1000; rep->tx_per_sec = tmp; @@ -345,24 +349,24 @@ static int append_user_info(main_server_st * s, void *pool, rep->dns = ctmp->config.dns; rep->n_dns = ctmp->config.dns_size; } else { - rep->dns = s->config->network.dns; - rep->n_dns = s->config->network.dns_size; + rep->dns = ctx->s->config->network.dns; + rep->n_dns = ctx->s->config->network.dns_size; } if (ctmp->config.nbns_size > 0) { rep->nbns = ctmp->config.nbns; rep->n_nbns = ctmp->config.nbns_size; } else { - rep->nbns = s->config->network.nbns; - rep->n_nbns = s->config->network.nbns_size; + rep->nbns = ctx->s->config->network.nbns; + rep->n_nbns = ctx->s->config->network.nbns_size; } if (ctmp->config.routes_size > 0) { rep->routes = ctmp->config.routes; rep->n_routes = ctmp->config.routes_size; } else { - rep->routes = s->config->network.routes; - rep->n_routes = s->config->network.routes_size; + rep->routes = ctx->s->config->network.routes; + rep->n_routes = ctx->s->config->network.routes_size; } if (ctmp->config.iroutes_size > 0) { @@ -374,63 +378,50 @@ static int append_user_info(main_server_st * s, void *pool, return 0; } -static void method_list_users(main_server_st * s, int cfd, uint8_t * msg, +static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { UserListRep rep = USER_LIST_REP__INIT; struct proc_st *ctmp = NULL; int ret; - void *pool = talloc_init("list-users"); - mslog(s, NULL, LOG_DEBUG, "ctl: list-users"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: list-users"); - if (pool == NULL) { - mslog(s, NULL, LOG_ERR, "memory allocation error"); - return; - } - list_for_each(&s->proc_list.head, ctmp, list) { - ret = append_user_info(s, pool, &rep, ctmp, 0); + list_for_each(&ctx->s->proc_list.head, ctmp, list) { + ret = append_user_info(ctx, &rep, ctmp, 0); if (ret < 0) { - mslog(s, NULL, LOG_ERR, + mslog(ctx->s, NULL, LOG_ERR, "error appending user info to reply"); goto error; } } - ret = send_msg(cfd, CTL_CMD_LIST_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep, (pack_size_func) user_list_rep__get_packed_size, (pack_func) user_list_rep__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } error: - talloc_free(pool); - return; } -static void single_info_common(main_server_st * s, int cfd, uint8_t * msg, +static void single_info_common(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size, const char *user, unsigned id) { UserListRep rep = USER_LIST_REP__INIT; int ret; unsigned found_user = 0; struct proc_st *ctmp = NULL; - void *pool = talloc_init("info-common"); if (user != NULL) - mslog(s, NULL, LOG_INFO, "providing info for user '%s'", user); + mslog(ctx->s, NULL, LOG_INFO, "providing info for user '%s'", user); else - mslog(s, NULL, LOG_INFO, "providing info for ID '%u'", id); + mslog(ctx->s, NULL, LOG_INFO, "providing info for ID '%u'", id); - if (pool == NULL) { - mslog(s, NULL, LOG_ERR, "memory allocation error"); - return; - } - - list_for_each(&s->proc_list.head, ctmp, list) { + list_for_each(&ctx->s->proc_list.head, ctmp, list) { if (user == NULL) { /* id */ if (id == 0 || id == -1 || id != ctmp->pid) { continue; @@ -441,9 +432,9 @@ static void single_info_common(main_server_st * s, int cfd, uint8_t * msg, } } - ret = append_user_info(s, pool, &rep, ctmp, 1); + ret = append_user_info(ctx, &rep, ctmp, 1); if (ret < 0) { - mslog(s, NULL, LOG_ERR, + mslog(ctx->s, NULL, LOG_ERR, "error appending user info to reply"); goto error; } @@ -456,64 +447,62 @@ static void single_info_common(main_server_st * s, int cfd, uint8_t * msg, if (found_user == 0) { if (user != NULL) - mslog(s, NULL, LOG_INFO, "could not find user '%s'", + mslog(ctx->s, NULL, LOG_INFO, "could not find user '%s'", user); else - mslog(s, NULL, LOG_INFO, "could not find ID '%u'", id); + mslog(ctx->s, NULL, LOG_INFO, "could not find ID '%u'", id); } - ret = send_msg(cfd, CTL_CMD_LIST_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep, (pack_size_func) user_list_rep__get_packed_size, (pack_func) user_list_rep__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } error: - talloc_free(pool); - return; } -static void method_user_info(main_server_st * s, int cfd, uint8_t * msg, +static void method_user_info(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { UsernameReq *req; - mslog(s, NULL, LOG_DEBUG, "ctl: user_info (name)"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: user_info (name)"); req = username_req__unpack(NULL, msg_size, msg); if (req == NULL) { - mslog(s, NULL, LOG_ERR, "error parsing user_info request"); + mslog(ctx->s, NULL, LOG_ERR, "error parsing user_info request"); return; } - single_info_common(s, cfd, msg, msg_size, req->username, 0); + single_info_common(ctx, cfd, msg, msg_size, req->username, 0); username_req__free_unpacked(req, NULL); return; } -static void method_id_info(main_server_st * s, int cfd, uint8_t * msg, +static void method_id_info(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { IdReq *req; - mslog(s, NULL, LOG_DEBUG, "ctl: user_info (id)"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: user_info (id)"); req = id_req__unpack(NULL, msg_size, msg); if (req == NULL) { - mslog(s, NULL, LOG_ERR, "error parsing id_info request"); + mslog(ctx->s, NULL, LOG_ERR, "error parsing id_info request"); return; } - single_info_common(s, cfd, msg, msg_size, NULL, req->id); + single_info_common(ctx, cfd, msg, msg_size, NULL, req->id); id_req__free_unpacked(req, NULL); return; } -static void method_disconnect_user_name(main_server_st * s, +static void method_disconnect_user_name(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { @@ -523,36 +512,36 @@ static void method_disconnect_user_name(main_server_st * s, struct proc_st *ctmp = NULL; int ret; - mslog(s, NULL, LOG_DEBUG, "ctl: disconnect_name"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: disconnect_name"); req = username_req__unpack(NULL, msg_size, msg); if (req == NULL) { - mslog(s, NULL, LOG_ERR, + mslog(ctx->s, NULL, LOG_ERR, "error parsing disconnect_name request"); return; } /* got the name. Try to disconnect */ - list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) { + list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list) { if (strcmp(ctmp->username, req->username) == 0) { - remove_proc(s, ctmp, 1); + remove_proc(ctx->s, ctmp, 1); rep.status = 1; } } username_req__free_unpacked(req, NULL); - ret = send_msg(cfd, CTL_CMD_DISCONNECT_NAME_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_NAME_REP, &rep, (pack_size_func) bool_msg__get_packed_size, (pack_func) bool_msg__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } return; } -static void method_disconnect_user_id(main_server_st * s, int cfd, +static void method_disconnect_user_id(method_ctx *ctx, int cfd, uint8_t * msg, unsigned msg_size) { IdReq *req; @@ -561,18 +550,18 @@ static void method_disconnect_user_id(main_server_st * s, int cfd, struct proc_st *ctmp = NULL; int ret; - mslog(s, NULL, LOG_DEBUG, "ctl: disconnect_id"); + mslog(ctx->s, NULL, LOG_DEBUG, "ctl: disconnect_id"); req = id_req__unpack(NULL, msg_size, msg); if (req == NULL) { - mslog(s, NULL, LOG_ERR, "error parsing disconnect_id request"); + mslog(ctx->s, NULL, LOG_ERR, "error parsing disconnect_id request"); return; } /* got the ID. Try to disconnect */ - list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) { + list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list) { if (ctmp->pid == req->id) { - remove_proc(s, ctmp, 1); + remove_proc(ctx->s, ctmp, 1); rep.status = 1; if (req->id != -1) break; @@ -582,11 +571,11 @@ static void method_disconnect_user_id(main_server_st * s, int cfd, /* reply */ id_req__free_unpacked(req, NULL); - ret = send_msg(cfd, CTL_CMD_DISCONNECT_ID_REP, &rep, + ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_ID_REP, &rep, (pack_size_func) bool_msg__get_packed_size, (pack_func) bool_msg__pack); if (ret < 0) { - mslog(s, NULL, LOG_ERR, "error sending ctl reply"); + mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply"); } return; @@ -594,13 +583,23 @@ static void method_disconnect_user_id(main_server_st * s, int cfd, static void ctl_handle_commands(main_server_st * s) { - int cfd, e, ret; + int cfd = -1, e, ret; unsigned i; struct sockaddr_un sa; socklen_t sa_len; 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; + } + + ctx.s = s; + ctx.pool = pool; sa_len = sizeof(sa); cfd = accept(s->ctl_fd, (struct sockaddr *)&sa, &sa_len); @@ -608,7 +607,7 @@ static void ctl_handle_commands(main_server_st * s) e = errno; mslog(s, NULL, LOG_ERR, "error accepting control connection: %s", strerror(e)); - return; + goto cleanup; } ret = check_upeer_id("ctl", cfd, 0, 0); @@ -647,12 +646,14 @@ static void ctl_handle_commands(main_server_st * s) (unsigned)buffer[0]); break; } else if (methods[i].cmd == buffer[0]) { - methods[i].func(s, cfd, buffer + 3, buffer_size); + methods[i].func(&ctx, cfd, buffer + 3, buffer_size); break; } } cleanup: - close(cfd); + talloc_free(pool); + if (cfd != -1) + close(cfd); } int ctl_handler_set_fds(main_server_st * s, fd_set * rd_set, fd_set * wr_set) diff --git a/src/main-misc.c b/src/main-misc.c index 72fa8956..c42c6070 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -141,7 +141,7 @@ static int read_additional_config_file(main_server_st * s, struct proc_st *proc, mslog(s, proc, LOG_DEBUG, "Loading %s configuration '%s'", type, file); - ret = parse_group_cfg_file(s, file, &proc->config); + ret = parse_group_cfg_file(s, proc, file); if (ret < 0) return ERR_READ_CONFIG; } else { @@ -185,6 +185,32 @@ static int read_additional_config(struct main_server_st *s, return 0; } +struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd, + struct sockaddr_storage *remote_addr, socklen_t remote_addr_len, + uint8_t *sid, size_t sid_size) +{ +struct proc_st *ctmp; + + ctmp = talloc_zero(s, struct proc_st); + if (ctmp == NULL) + return NULL; + + ctmp->pid = pid; + ctmp->tun_lease.fd = -1; + ctmp->fd = cmd_fd; + set_cloexec_flag (cmd_fd, 1); + + memcpy(&ctmp->remote_addr, remote_addr, remote_addr_len); + ctmp->remote_addr_len = remote_addr_len; + memcpy(ctmp->sid, sid, sid_size); + + list_add(&s->proc_list.head, &(ctmp->list)); + put_into_cgroup(s, s->config->cgroup, pid); + s->active_clients++; + + return ctmp; +} + /* k: whether to kill the process */ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k) @@ -213,12 +239,10 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k) if (proc->auth_ctx != NULL) proc_auth_deinit(s, proc); - if (!proc->leases_in_use) { - if (proc->ipv4 || proc->ipv6) - remove_ip_leases(s, proc); - } + if (proc->ipv4 || proc->ipv6) + remove_ip_leases(s, proc); - free(proc); + talloc_free(proc); } void proc_to_zombie(main_server_st * s, struct proc_st *proc) @@ -372,6 +396,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) uint16_t length; uint8_t *raw; int ret, raw_len, e; + PROTOBUF_ALLOCATOR(pa, proc); iov[0].iov_base = &cmd; iov[0].iov_len = 1; @@ -405,7 +430,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) mslog(s, proc, LOG_DEBUG, "main received message '%s' of %u bytes\n", cmd_request_to_str(cmd), (unsigned)length); - raw = malloc(length); + raw = talloc_size(proc, length); if (raw == NULL) { mslog(s, proc, LOG_ERR, "memory error"); return ERR_MEM; @@ -432,7 +457,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) goto cleanup; } - tmsg = tun_mtu_msg__unpack(NULL, raw_len, raw); + tmsg = tun_mtu_msg__unpack(&pa, raw_len, raw); if (tmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -441,7 +466,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) set_tun_mtu(s, proc, tmsg->mtu); - tun_mtu_msg__free_unpacked(tmsg, NULL); + tun_mtu_msg__free_unpacked(tmsg, &pa); } break; @@ -455,7 +480,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) goto cleanup; } - tmsg = cli_stats_msg__unpack(NULL, raw_len, raw); + tmsg = cli_stats_msg__unpack(&pa, raw_len, raw); if (tmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -465,14 +490,14 @@ int handle_commands(main_server_st * s, struct proc_st *proc) proc->bytes_in = tmsg->bytes_in; proc->bytes_out = tmsg->bytes_out; - cli_stats_msg__free_unpacked(tmsg, NULL); + cli_stats_msg__free_unpacked(tmsg, &pa); } break; case CMD_SESSION_INFO:{ SessionInfoMsg *tmsg; - tmsg = session_info_msg__unpack(NULL, raw_len, raw); + tmsg = session_info_msg__unpack(&pa, raw_len, raw); if (tmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -492,7 +517,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) sizeof(proc->user_agent), "%s", tmsg->user_agent); - session_info_msg__free_unpacked(tmsg, NULL); + session_info_msg__free_unpacked(tmsg, &pa); } @@ -501,7 +526,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) SessionResumeStoreReqMsg *smsg; smsg = - session_resume_store_req_msg__unpack(NULL, raw_len, + session_resume_store_req_msg__unpack(&pa, raw_len, raw); if (smsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); @@ -511,7 +536,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_resume_store_req(s, proc, smsg); - session_resume_store_req_msg__free_unpacked(smsg, NULL); + session_resume_store_req_msg__free_unpacked(smsg, &pa); if (ret < 0) { mslog(s, proc, LOG_DEBUG, @@ -525,7 +550,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) SessionResumeFetchMsg *fmsg; fmsg = - session_resume_fetch_msg__unpack(NULL, raw_len, + session_resume_fetch_msg__unpack(&pa, raw_len, raw); if (fmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); @@ -535,7 +560,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_resume_delete_req(s, proc, fmsg); - session_resume_fetch_msg__free_unpacked(fmsg, NULL); + session_resume_fetch_msg__free_unpacked(fmsg, &pa); if (ret < 0) { mslog(s, proc, LOG_DEBUG, @@ -551,7 +576,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) SessionResumeFetchMsg *fmsg; fmsg = - session_resume_fetch_msg__unpack(NULL, raw_len, + session_resume_fetch_msg__unpack(&pa, raw_len, raw); if (fmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); @@ -561,7 +586,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_resume_fetch_req(s, proc, fmsg, &msg); - session_resume_fetch_msg__free_unpacked(fmsg, NULL); + session_resume_fetch_msg__free_unpacked(fmsg, &pa); if (ret < 0) { msg.reply = @@ -600,7 +625,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) goto cleanup; } - auth_init = auth_init_msg__unpack(NULL, raw_len, raw); + auth_init = auth_init_msg__unpack(&pa, raw_len, raw); if (auth_init == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -609,7 +634,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_auth_init(s, proc, auth_init); - auth_init_msg__free_unpacked(auth_init, NULL); + auth_init_msg__free_unpacked(auth_init, &pa); proc->status = PS_AUTH_INIT; @@ -629,7 +654,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) goto cleanup; } - auth_reinit = auth_reinit_msg__unpack(NULL, raw_len, raw); + auth_reinit = auth_reinit_msg__unpack(&pa, raw_len, raw); if (auth_reinit == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -639,7 +664,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) /* note that it may replace proc on success */ ret = handle_auth_reinit(s, &proc, auth_reinit); - auth_reinit_msg__free_unpacked(auth_reinit, NULL); + auth_reinit_msg__free_unpacked(auth_reinit, &pa); proc->status = PS_AUTH_INIT; @@ -670,7 +695,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) goto cleanup; } - auth_req = auth_request_msg__unpack(NULL, raw_len, raw); + auth_req = auth_request_msg__unpack(&pa, raw_len, raw); if (auth_req == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -679,7 +704,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_auth_req(s, proc, auth_req); - auth_request_msg__free_unpacked(auth_req, NULL); + auth_request_msg__free_unpacked(auth_req, &pa); proc->status = PS_AUTH_INIT; @@ -699,7 +724,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) } auth_cookie_req = - auth_cookie_request_msg__unpack(NULL, raw_len, raw); + auth_cookie_request_msg__unpack(&pa, raw_len, raw); if (auth_cookie_req == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; @@ -708,7 +733,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = handle_auth_cookie_req(s, proc, auth_cookie_req); - auth_cookie_request_msg__free_unpacked(auth_cookie_req, NULL); + auth_cookie_request_msg__free_unpacked(auth_cookie_req, &pa); ret = handle_auth_res(s, proc, cmd, ret); if (ret < 0) { @@ -725,7 +750,7 @@ int handle_commands(main_server_st * s, struct proc_st *proc) ret = 0; cleanup: - free(raw); + talloc_free(raw); return ret; } @@ -743,7 +768,7 @@ int check_if_banned(main_server_st * s, struct sockaddr_storage *addr, if (now - btmp->failed_time > s->config->min_reauth_time) { /* invalid entry. Clean it up */ list_del(&btmp->list); - free(btmp); + talloc_free(btmp); } else { if (SA_IN_SIZE(btmp->addr_len) == SA_IN_SIZE(addr_len) && @@ -770,7 +795,7 @@ void expire_banned(main_server_st * s) if (now - btmp->failed_time > s->config->min_reauth_time) { /* invalid entry. Clean it up */ list_del(&btmp->list); - free(btmp); + talloc_free(btmp); } } @@ -785,7 +810,7 @@ void add_to_ip_ban_list(main_server_st * s, struct sockaddr_storage *addr, if (s->config->min_reauth_time == 0) return; - btmp = malloc(sizeof(*btmp)); + btmp = talloc(s, struct banned_st); if (btmp == NULL) return; diff --git a/src/main-resume.c b/src/main-resume.c index c27a3673..13eae825 100644 --- a/src/main-resume.c +++ b/src/main-resume.c @@ -57,7 +57,7 @@ int handle_resume_delete_req(main_server_st * s, struct proc_st *proc, cache->session_id_size = 0; htable_delval(&s->tls_db->ht, &iter); - free(cache); + talloc_free(cache); s->tls_db->entries--; return 0; } @@ -138,7 +138,7 @@ int handle_resume_store_req(main_server_st * s, struct proc_st *proc, key = hash_any(req->session_id.data, req->session_id.len, 0); - cache = malloc(sizeof(*cache)); + cache = talloc(s, tls_cache_st); if (cache == NULL) return -1; @@ -183,7 +183,7 @@ void expire_tls_sessions(main_server_st * s) cache->session_id_size = 0; htable_delval(&s->tls_db->ht, &iter); - free(cache); + talloc_free(cache); s->tls_db->entries--; } cache = htable_next(&s->tls_db->ht, &iter); diff --git a/src/main.c b/src/main.c index f30c9cc7..74b30cd7 100644 --- a/src/main.c +++ b/src/main.c @@ -77,13 +77,13 @@ static void ms_sleep(unsigned ms) nanosleep(&tv, NULL); } -static void add_listener(struct listen_list_st *list, +static void add_listener(void *pool, struct listen_list_st *list, int fd, int family, int socktype, int protocol, struct sockaddr* addr, socklen_t addr_len) { struct listener_st *tmp; - tmp = calloc(1, sizeof(struct listener_st)); + tmp = talloc_zero(pool, struct listener_st); tmp->fd = fd; tmp->family = family; tmp->socktype = socktype; @@ -130,7 +130,8 @@ int val; } static -int _listen_ports(struct cfg_st* config, struct addrinfo *res, struct listen_list_st *list) +int _listen_ports(void *pool, struct cfg_st* config, + struct addrinfo *res, struct listen_list_st *list) { struct addrinfo *ptr; int s, y; @@ -197,7 +198,7 @@ int _listen_ports(struct cfg_st* config, struct addrinfo *res, struct listen_lis set_common_socket_options(s); - add_listener(list, s, ptr->ai_family, ptr->ai_socktype, + add_listener(pool, list, s, ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol, ptr->ai_addr, ptr->ai_addrlen); } @@ -210,7 +211,8 @@ int _listen_ports(struct cfg_st* config, struct addrinfo *res, struct listen_lis /* Returns 0 on success or negative value on error. */ static int -listen_ports(struct cfg_st* config, struct listen_list_st *list, const char *node) +listen_ports(void *pool, struct cfg_st* config, + struct listen_list_st *list) { struct addrinfo hints, *res; char portname[6]; @@ -274,7 +276,7 @@ listen_ports(struct cfg_st* config, struct listen_list_st *list, const char *nod config->udp_port = ntohs(((struct sockaddr_in6*)&tmp_sock)->sin6_port); } - add_listener(list, fd, family, type, 0, (struct sockaddr*)&tmp_sock, tmp_sock_len); + add_listener(pool, list, fd, family, type, 0, (struct sockaddr*)&tmp_sock, tmp_sock_len); } if (list->total == 0) { @@ -304,14 +306,14 @@ listen_ports(struct cfg_st* config, struct listen_list_st *list, const char *nod #endif ; - ret = getaddrinfo(node, portname, &hints, &res); + ret = getaddrinfo(config->name, portname, &hints, &res); if (ret != 0) { fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(ret)); return -1; } - ret = _listen_ports(config, res, list); + ret = _listen_ports(pool, config, res, list); if (ret < 0) { return -1; } @@ -334,14 +336,14 @@ listen_ports(struct cfg_st* config, struct listen_list_st *list, const char *nod #endif ; - ret = getaddrinfo(node, portname, &hints, &res); + ret = getaddrinfo(config->name, portname, &hints, &res); if (ret != 0) { fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(ret)); return -1; } - ret = _listen_ports(config, res, list); + ret = _listen_ports(pool, config, res, list); if (ret < 0) { return -1; } @@ -431,7 +433,7 @@ struct script_wait_st *stmp = NULL, *spos; if (ret < 0) { remove_proc(s, stmp->proc, 1); } else { - free(stmp); + talloc_free(stmp); } break; } @@ -555,7 +557,7 @@ void clear_lists(main_server_st *s) list_for_each_safe(&s->listen_list.head, ltmp, lpos, list) { close(ltmp->fd); list_del(<mp->list); - free(ltmp); + talloc_free(ltmp); s->listen_list.total--; } @@ -568,18 +570,18 @@ void clear_lists(main_server_st *s) proc_auth_deinit(s, ctmp); list_del(&ctmp->list); memset(ctmp, 0, sizeof(*ctmp)); - free(ctmp); + talloc_free(ctmp); s->proc_list.total--; } list_for_each_safe(&s->ban_list.head, btmp, bpos, list) { list_del(&btmp->list); - free(btmp); + talloc_free(btmp); } list_for_each_safe(&s->script_list.head, script_tmp, script_pos, list) { list_del(&script_tmp->list); - free(script_tmp); + talloc_free(script_tmp); } tls_cache_deinit(s->tls_db); @@ -751,8 +753,8 @@ unsigned total = 10; if (reload_conf != 0) { mslog(s, NULL, LOG_INFO, "reloading configuration"); - reload_cfg_file(s->config); - tls_reload_crl(s); + reload_cfg_file(s->main_pool, &s->config); + tls_reload_crl(s, s->creds); reload_conf = 0; } @@ -779,8 +781,10 @@ unsigned total = 10; * for memory leaks. */ clear_lists(s); - tls_global_deinit(s); - clear_cfg_file(s->config); + tls_global_deinit(s->creds); + clear_cfg_file(&s->config); + talloc_free(s->worker_pool); + talloc_free(s->main_pool); closelog(); exit(0); } @@ -827,19 +831,50 @@ int main(int argc, char** argv) struct timeval ts; #endif int cmd_fd[2]; - struct worker_st ws; - struct cfg_st config; + struct worker_st *ws; + void *worker_pool; + void *main_pool; unsigned set; - main_server_st s; + main_server_st *s; sigset_t emptyset, blockset; + /* tls credentials */ + struct tls_st creds; - memset(&s, 0, sizeof(s)); + memset(&creds, 0, sizeof(creds)); - list_head_init(&s.proc_list.head); - list_head_init(&s.ban_list.head); - list_head_init(&s.script_list.head); - tls_cache_init(&s.tls_db); - ip_lease_init(&s.ip_leases); + worker_pool = talloc_init("worker"); + if (worker_pool == NULL) { + fprintf(stderr, "talloc init error\n"); + exit(1); + } + + /* main pool */ + main_pool = talloc_init("main"); + if (main_pool == NULL) { + fprintf(stderr, "talloc init error\n"); + exit(1); + } + + ws = talloc_zero(worker_pool, struct worker_st); + if (ws == NULL) { + fprintf(stderr, "memory error\n"); + exit(1); + } + + s = talloc_zero(main_pool, main_server_st); + if (s == NULL) { + fprintf(stderr, "memory error\n"); + exit(1); + } + s->main_pool = main_pool; + s->worker_pool = worker_pool; + s->creds = &creds; + + list_head_init(&s->proc_list.head); + list_head_init(&s->ban_list.head); + list_head_init(&s->script_list.head); + tls_cache_init(s, &s->tls_db); + ip_lease_init(&s->ip_leases); sigemptyset(&blockset); sigemptyset(&emptyset); @@ -857,16 +892,16 @@ int main(int argc, char** argv) ocsignal(SIGALRM, handle_alarm); /* Initialize GnuTLS */ - tls_global_init(&s); + tls_global_init(&creds); - ret = gnutls_rnd(GNUTLS_RND_RANDOM, s.cookie_key, sizeof(s.cookie_key)); + ret = gnutls_rnd(GNUTLS_RND_RANDOM, s->cookie_key, sizeof(s->cookie_key)); if (ret < 0) { fprintf(stderr, "Error in cookie key generation\n"); exit(1); } /* load configuration */ - ret = cmd_parser(argc, argv, &config); + ret = cmd_parser(main_pool, argc, argv, &s->config); if (ret < 0) { fprintf(stderr, "Error in arguments\n"); exit(1); @@ -879,12 +914,10 @@ int main(int argc, char** argv) exit(1); } - s.config = &config; - - main_auth_init(&s); + main_auth_init(s); /* Listen to network ports */ - ret = listen_ports(&config, &s.listen_list, config.name); + ret = listen_ports(s, s->config, &s->listen_list); if (ret < 0) { fprintf(stderr, "Cannot listen to specified ports\n"); exit(1); @@ -892,7 +925,7 @@ int main(int argc, char** argv) flags = LOG_PID|LOG_NDELAY; #ifdef LOG_PERROR - if (config.debug != 0) + if (s->config->debug != 0) flags |= LOG_PERROR; #endif openlog("ocserv", flags, LOG_DAEMON); @@ -902,7 +935,7 @@ int main(int argc, char** argv) deny_severity = LOG_DAEMON|LOG_WARNING; #endif - if (config.foreground == 0) { + if (s->config->foreground == 0) { if (daemon(0, 0) == -1) { e = errno; fprintf(stderr, "daemon failed: %s\n", strerror(e)); @@ -912,44 +945,44 @@ int main(int argc, char** argv) write_pid_file(); - run_sec_mod(&s); + run_sec_mod(s); /* Initialize certificates */ - tls_load_certs(&s); + tls_load_certs(s, &creds); - mslog(&s, NULL, LOG_INFO, "initialized %s", PACKAGE_STRING); + mslog(s, NULL, LOG_INFO, "initialized %s", PACKAGE_STRING); - ret = ctl_handler_init(&s); + ret = ctl_handler_init(s); if (ret < 0) { fprintf(stderr, "Cannot create command handler\n"); exit(1); } sigprocmask(SIG_BLOCK, &blockset, NULL); - alarm(MAINTAINANCE_TIME(&s)); + alarm(MAINTAINANCE_TIME(s)); for (;;) { - check_other_work(&s); + check_other_work(s); /* initialize select */ FD_ZERO(&rd_set); FD_ZERO(&wr_set); - list_for_each(&s.listen_list.head, ltmp, list) { + list_for_each(&s->listen_list.head, ltmp, list) { if (ltmp->fd == -1) continue; FD_SET(ltmp->fd, &rd_set); n = MAX(n, ltmp->fd); } - list_for_each(&s.proc_list.head, ctmp, list) { + list_for_each(&s->proc_list.head, ctmp, list) { if (ctmp->fd > 0) { FD_SET(ctmp->fd, &rd_set); n = MAX(n, ctmp->fd); } } - ret = ctl_handler_set_fds(&s, &rd_set, &wr_set); + ret = ctl_handler_set_fds(s, &rd_set, &wr_set); n = MAX(n, ret); #ifdef HAVE_PSELECT @@ -968,59 +1001,59 @@ int main(int argc, char** argv) if (ret < 0) { e = errno; - mslog(&s, NULL, LOG_ERR, "Error in pselect(): %s", + mslog(s, NULL, LOG_ERR, "Error in pselect(): %s", strerror(e)); exit(1); } /* Check for new connections to accept */ - list_for_each(&s.listen_list.head, ltmp, list) { + list_for_each(&s->listen_list.head, ltmp, list) { set = FD_ISSET(ltmp->fd, &rd_set); if (set && ltmp->socktype == SOCK_STREAM) { /* connection on TCP port */ - memset(&ws, 0, sizeof(ws)); + memset(ws, 0, sizeof(*ws)); - ws.remote_addr_len = sizeof(ws.remote_addr); - fd = accept(ltmp->fd, (void*)&ws.remote_addr, &ws.remote_addr_len); + ws->remote_addr_len = sizeof(ws->remote_addr); + fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len); if (fd < 0) { - mslog(&s, NULL, LOG_ERR, + mslog(s, NULL, LOG_ERR, "Error in accept(): %s", strerror(errno)); continue; } set_cloexec_flag (fd, 1); - ret = gnutls_rnd(GNUTLS_RND_RANDOM, ws.sid, sizeof(ws.sid)); + ret = gnutls_rnd(GNUTLS_RND_RANDOM, ws->sid, sizeof(ws->sid)); if (ret < 0) { close(fd); - mslog(&s, NULL, LOG_ERR, "Error generating SID"); + mslog(s, NULL, LOG_ERR, "Error generating SID"); break; } /* Check if the client is on the banned list */ - ret = check_if_banned(&s, &ws.remote_addr, ws.remote_addr_len); + ret = check_if_banned(s, &ws->remote_addr, ws->remote_addr_len); if (ret < 0) { /* banned */ close(fd); - mslog(&s, NULL, LOG_INFO, "dropping client connection due to a previous failed authentication attempt"); + mslog(s, NULL, LOG_INFO, "dropping client connection due to a previous failed authentication attempt"); break; } - if (config.max_clients > 0 && s.active_clients >= config.max_clients) { + if (s->config->max_clients > 0 && s->active_clients >= s->config->max_clients) { close(fd); - mslog(&s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", s.active_clients); + mslog(s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", s->active_clients); break; } if (check_tcp_wrapper(fd) < 0) { close(fd); - mslog(&s, NULL, LOG_INFO, "TCP wrappers rejected the connection (see /etc/hosts.[allow|deny])"); + mslog(s, NULL, LOG_INFO, "TCP wrappers rejected the connection (see /etc/hosts->[allow|deny])"); break; } /* Create a command socket */ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd); if (ret < 0) { - mslog(&s, NULL, LOG_ERR, "Error creating command socket"); + mslog(s, NULL, LOG_ERR, "Error creating command socket"); close(fd); break; } @@ -1031,82 +1064,75 @@ int main(int argc, char** argv) * sensitive data before running the worker */ close(cmd_fd[0]); - clear_lists(&s); + clear_lists(s); setproctitle(PACKAGE_NAME"-worker"); kill_on_parent_kill(SIGTERM); - ws.config = &config; - ws.cmd_fd = cmd_fd[1]; - ws.tun_fd = -1; - ws.udp_fd = -1; - ws.conn_fd = fd; - ws.creds = &s.creds; + ws->config = s->config; + ws->cmd_fd = cmd_fd[1]; + ws->tun_fd = -1; + ws->udp_fd = -1; + ws->conn_fd = fd; + ws->creds = &creds; /* Drop privileges after this point */ sigprocmask(SIG_UNBLOCK, &blockset, NULL); - drop_privileges(&s); + drop_privileges(s); - vpn_server(&ws); + /* creds and config are not allocated + * under s. + */ + talloc_free(s); + + vpn_server(ws); exit(0); } else if (pid == -1) { fork_failed: close(cmd_fd[0]); } else { /* parent */ /* add_proc */ - ctmp = calloc(1, sizeof(struct proc_st)); + ctmp = new_proc(s, pid, cmd_fd[0], + &ws->remote_addr, ws->remote_addr_len, + ws->sid, sizeof(ws->sid)); if (ctmp == NULL) { kill(pid, SIGTERM); goto fork_failed; } - memcpy(&ctmp->remote_addr, &ws.remote_addr, ws.remote_addr_len); - ctmp->remote_addr_len = ws.remote_addr_len; - memcpy(&ctmp->sid, &ws.sid, sizeof(ws.sid)); - ctmp->pid = pid; - ctmp->tun_lease.fd = -1; - ctmp->conn_time = time(0); - ctmp->fd = cmd_fd[0]; - set_cloexec_flag (cmd_fd[0], 1); - - list_add(&s.proc_list.head, &(ctmp->list)); - - put_into_cgroup(&s, s.config->cgroup, pid); - - s.active_clients++; } close(cmd_fd[1]); close(fd); - if (config.rate_limit_ms > 0) - ms_sleep(config.rate_limit_ms); + if (s->config->rate_limit_ms > 0) + ms_sleep(s->config->rate_limit_ms); } else if (set && ltmp->socktype == SOCK_DGRAM) { /* connection on UDP port */ - ret = forward_udp_to_owner(&s, ltmp); + ret = forward_udp_to_owner(s, ltmp); if (ret < 0) { - mslog(&s, NULL, LOG_INFO, "could not determine the owner of received UDP packet"); + mslog(s, NULL, LOG_INFO, "could not determine the owner of received UDP packet"); } - if (config.rate_limit_ms > 0) - ms_sleep(config.rate_limit_ms); + if (s->config->rate_limit_ms > 0) + ms_sleep(s->config->rate_limit_ms); } } /* Check for any pending commands */ - list_for_each_safe(&s.proc_list.head, ctmp, cpos, list) { + list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) { if (ctmp->fd >= 0 && FD_ISSET(ctmp->fd, &rd_set)) { - ret = handle_commands(&s, ctmp); + ret = handle_commands(s, ctmp); if (ret == ERR_WORKER_TERMINATED && ctmp->status == PS_AUTH_INIT && - s.config->cisco_client_compat != 0) { - proc_to_zombie(&s, ctmp); + s->config->cisco_client_compat != 0) { + proc_to_zombie(s, ctmp); } else if (ret < 0) { - remove_proc(&s, ctmp, (ret!=ERR_WORKER_TERMINATED)?1:0); + remove_proc(s, ctmp, (ret!=ERR_WORKER_TERMINATED)?1:0); } } } /* Check for pending control commands */ - ctl_handler_run_pending(&s, &rd_set, &wr_set); + ctl_handler_run_pending(s, &rd_set, &wr_set); } return 0; diff --git a/src/main.h b/src/main.h index 2b3ecac9..f34b5add 100644 --- a/src/main.h +++ b/src/main.h @@ -31,9 +31,9 @@ #include #include -int cmd_parser (int argc, char **argv, struct cfg_st* config); -void reload_cfg_file(struct cfg_st* config); -void clear_cfg_file(struct cfg_st* config); +int cmd_parser (void *pool, int argc, char **argv, struct cfg_st** config); +void reload_cfg_file(void *pool, struct cfg_st** config); +void clear_cfg_file(struct cfg_st** config); void write_pid_file(void); void remove_pid_file(void); @@ -167,12 +167,10 @@ typedef struct main_server_st { struct ip_lease_db_st ip_leases; hash_db_st *tls_db; + tls_st *creds; uint8_t cookie_key[16]; - /* tls credentials */ - struct tls_st creds; - struct listen_list_st listen_list; struct proc_list_st proc_list; struct script_list_st script_list; @@ -190,6 +188,8 @@ typedef struct main_server_st { #else int ctl_fd; #endif + void *main_pool; /* talloc main pool */ + void *worker_pool; /* talloc worker pool */ } main_server_st; void clear_lists(main_server_st *s); @@ -258,9 +258,13 @@ int handle_script_exit(main_server_st *s, struct proc_st* proc, int code, unsign void run_sec_mod(main_server_st * s); -int parse_group_cfg_file(main_server_st* s, const char* file, struct group_cfg_st *config); +int parse_group_cfg_file(main_server_st* s, struct proc_st *proc, const char* file); void del_additional_config(struct group_cfg_st* config); + +struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd, + struct sockaddr_storage *remote_addr, socklen_t remote_addr_len, + uint8_t *sid, size_t sid_size); void remove_proc(main_server_st* s, struct proc_st *proc, unsigned k); void proc_to_zombie(main_server_st* s, struct proc_st *proc); @@ -271,7 +275,7 @@ int send_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd, const void* msg, pack_size_func get_size, pack_func pack) { mslog(s, proc, LOG_DEBUG, "sending message '%s' to worker", cmd_request_to_str(cmd)); - return send_msg(proc->fd, cmd, msg, get_size, pack); + return send_msg(proc, proc->fd, cmd, msg, get_size, pack); } inline static @@ -279,7 +283,7 @@ int send_socket_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t c int socketfd, const void* msg, pack_size_func get_size, pack_func pack) { mslog(s, proc, LOG_DEBUG, "sending (socket) message %u to worker", (unsigned)cmd); - return send_socket_msg(proc->fd, cmd, socketfd, msg, get_size, pack); + return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size, pack); } void request_reload(int signo); diff --git a/src/occtl-cache.c b/src/occtl-cache.c index 2e38e703..ced4dbc4 100644 --- a/src/occtl-cache.c +++ b/src/occtl-cache.c @@ -43,20 +43,20 @@ void entries_clear(void) unsigned i; for (i=0;i max_entries_size) { max_entries_size += 128; - entries = realloc(entries, sizeof(uid_entries_st)*max_entries_size); + entries = talloc_realloc_size(pool, entries, sizeof(uid_entries_st)*max_entries_size); } - entries[entries_size].user = strdup(user); + entries[entries_size].user = talloc_strdup(pool, user); entries[entries_size].user_size = user_size; entries[entries_size].id_size = snprintf(entries[entries_size].id, sizeof(entries[entries_size].id), "%u", id); @@ -66,7 +66,7 @@ void entries_add(const char* user, unsigned user_size, unsigned id) return; } -char* search_for_user(unsigned idx, const char* match, int match_size) +char* search_for_user(void *pool, unsigned idx, const char* match, int match_size) { unsigned i; @@ -76,14 +76,14 @@ unsigned i; for (i=idx;i #include +typedef struct dbus_ctx { + DBusConnection *conn; +} dbus_ctx; + /* sends a message and returns the reply */ -DBusMessage *send_dbus_cmd(DBusConnection * conn, +DBusMessage *send_dbus_cmd(dbus_ctx *ctx, const char *bus_name, const char *path, const char *interface, const char *method, unsigned type, const void *arg) @@ -52,14 +56,14 @@ DBusMessage *send_dbus_cmd(DBusConnection * conn, } if (!dbus_connection_send_with_reply - (conn, msg, &pending, DEFAULT_TIMEOUT)) { + (ctx->conn, msg, &pending, DEFAULT_TIMEOUT)) { goto error; } if (pending == NULL) goto error; - dbus_connection_flush(conn); + dbus_connection_flush(ctx->conn); dbus_message_unref(msg); /* wait for reply */ @@ -79,7 +83,7 @@ DBusMessage *send_dbus_cmd(DBusConnection * conn, } -int handle_status_cmd(DBusConnection * conn, const char *arg) +int handle_status_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -88,7 +92,7 @@ int handle_status_cmd(DBusConnection * conn, const char *arg) dbus_uint32_t sec_mod_pid; dbus_uint32_t clients; - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "status", 0, NULL); if (msg == NULL) { @@ -154,13 +158,13 @@ int handle_status_cmd(DBusConnection * conn, const char *arg) return 1; } -int handle_reload_cmd(DBusConnection * conn, const char *arg) +int handle_reload_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; dbus_bool_t status; - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "reload", 0, NULL); if (msg == NULL) { @@ -199,7 +203,7 @@ int handle_reload_cmd(DBusConnection * conn, const char *arg) return 1; } -int handle_stop_cmd(DBusConnection * conn, const char *arg) +int handle_stop_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -210,7 +214,7 @@ int handle_stop_cmd(DBusConnection * conn, const char *arg) return 1; } - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "stop", 0, NULL); if (msg == NULL) { @@ -249,7 +253,7 @@ int handle_stop_cmd(DBusConnection * conn, const char *arg) return 1; } -int handle_disconnect_user_cmd(DBusConnection * conn, const char *arg) +int handle_disconnect_user_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -260,7 +264,7 @@ int handle_disconnect_user_cmd(DBusConnection * conn, const char *arg) return 1; } - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "disconnect_name", DBUS_TYPE_STRING, &arg); @@ -293,7 +297,7 @@ int handle_disconnect_user_cmd(DBusConnection * conn, const char *arg) return 1; } -int handle_disconnect_id_cmd(DBusConnection * conn, const char *arg) +int handle_disconnect_id_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -309,7 +313,7 @@ int handle_disconnect_id_cmd(DBusConnection * conn, const char *arg) return 1; } - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "disconnect_id", DBUS_TYPE_UINT32, &id); @@ -344,7 +348,7 @@ int handle_disconnect_id_cmd(DBusConnection * conn, const char *arg) return 1; } -int handle_list_users_cmd(DBusConnection * conn, const char *arg) +int handle_list_users_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args, suba, subs; @@ -369,7 +373,7 @@ int handle_list_users_cmd(DBusConnection * conn, const char *arg) out = pager_start(); - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "list", 0, NULL); if (msg == NULL) { @@ -525,7 +529,7 @@ int handle_list_users_cmd(DBusConnection * conn, const char *arg) fprintf(out, " %14s %9s\n", "(no dtls)", auth); } - entries_add(username, strlen(username), id); + entries_add(ctx, username, strlen(username), id); if (!dbus_message_iter_next(&suba)) break; @@ -850,7 +854,7 @@ int common_info_cmd(DBusMessageIter * args) return ret; } -int handle_show_user_cmd(DBusConnection * conn, const char *arg) +int handle_show_user_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -861,7 +865,7 @@ int handle_show_user_cmd(DBusConnection * conn, const char *arg) return 1; } - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "user_info2", DBUS_TYPE_STRING, &arg); @@ -892,7 +896,7 @@ int handle_show_user_cmd(DBusConnection * conn, const char *arg) return ret; } -int handle_show_id_cmd(DBusConnection * conn, const char *arg) +int handle_show_id_cmd(dbus_ctx *ctx, const char *arg) { DBusMessage *msg; DBusMessageIter args; @@ -907,7 +911,7 @@ int handle_show_id_cmd(DBusConnection * conn, const char *arg) return 1; } - msg = send_dbus_cmd(conn, "org.infradead.ocserv", + msg = send_dbus_cmd(ctx->conn, "org.infradead.ocserv", "/org/infradead/ocserv", "org.infradead.ocserv", "id_info2", DBUS_TYPE_UINT32, &id); @@ -938,11 +942,16 @@ int handle_show_id_cmd(DBusConnection * conn, const char *arg) return ret; } -DBusConnection *conn_init(void) +dbus_ctx *conn_init(void *pool) { DBusError err; + dbus_ctx *ctx; DBusConnection *conn; + ctx = talloc(pool, dbus_ctx); + if (ctx == NULL) + return NULL; + dbus_error_init(&err); conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); @@ -954,20 +963,22 @@ DBusConnection *conn_init(void) if (conn == NULL) exit(1); - return conn; + ctx->conn = conn; + + return ctx; } -void conn_close(DBusConnection* conn) +void conn_close(dbus_ctx *ctx) { - dbus_connection_close(conn); + dbus_connection_close(ctx->conn); } -int conn_prehandle(DBusConnection *ctx) +int conn_prehandle(dbus_ctx *ctx) { return 0; } -void conn_posthandle(DBusConnection *ctx) +void conn_posthandle(dbus_ctx *ctx) { return; } diff --git a/src/occtl-unix.c b/src/occtl-unix.c index 27441777..9c761df6 100644 --- a/src/occtl-unix.c +++ b/src/occtl-unix.c @@ -63,7 +63,7 @@ struct cmd_reply_st { static void free_reply(struct cmd_reply_st *rep) { - free(rep->data); + talloc_free(rep->data); } static void init_reply(struct cmd_reply_st *rep) @@ -74,7 +74,7 @@ static void init_reply(struct cmd_reply_st *rep) /* sends a message and returns the reply */ static -int send_cmd(int fd, unsigned cmd, const void *data, +int send_cmd(struct unix_ctx *ctx, unsigned cmd, const void *data, pack_size_func get_size, pack_func pack, struct cmd_reply_st *rep) { @@ -96,7 +96,7 @@ int send_cmd(int fd, unsigned cmd, const void *data, iov[0].iov_len = 3; if (data != NULL) { - packed = malloc(length); + packed = talloc_size(ctx, length); if (packed == NULL) { fprintf(stderr, "memory error\n"); return -1; @@ -113,7 +113,7 @@ int send_cmd(int fd, unsigned cmd, const void *data, iov_len++; } - ret = writev(fd, iov, iov_len); + ret = writev(ctx->fd, iov, iov_len); if (ret < 0) { e = errno; fprintf(stderr, "writev: %s\n", strerror(e)); @@ -122,7 +122,7 @@ int send_cmd(int fd, unsigned cmd, const void *data, } if (rep != NULL) { - ret = force_read_timeout(fd, header, 3, DEFAULT_TIMEOUT); + ret = force_read_timeout(ctx->fd, header, 3, DEFAULT_TIMEOUT); if (ret == -1) { /*e = errno; fprintf(stderr, "read: %s\n", strerror(e));*/ @@ -147,17 +147,17 @@ int send_cmd(int fd, unsigned cmd, const void *data, length = (header[2] << 8) | header[1]; rep->data_size = length; - rep->data = malloc(length); + rep->data = talloc_size(ctx, length); if (rep->data == NULL) { fprintf(stderr, "memory error\n"); ret = -1; goto fail; } - ret = force_read_timeout(fd, rep->data, length, DEFAULT_TIMEOUT); + ret = force_read_timeout(ctx->fd, rep->data, length, DEFAULT_TIMEOUT); if (ret == -1) { e = errno; - free(rep->data); + talloc_free(rep->data); rep->data = NULL; fprintf(stderr, "read: %s\n", strerror(e)); ret = -1; @@ -167,7 +167,7 @@ int send_cmd(int fd, unsigned cmd, const void *data, ret = 0; fail: - free(packed); + talloc_free(packed); return ret; } @@ -212,7 +212,7 @@ int handle_status_cmd(struct unix_ctx *ctx, const char *arg) init_reply(&raw); - ret = send_cmd(ctx->fd, CTL_CMD_STATUS, NULL, NULL, NULL, &raw); + ret = send_cmd(ctx, CTL_CMD_STATUS, NULL, NULL, NULL, &raw); if (ret < 0) { goto error_status; } @@ -252,7 +252,7 @@ int handle_reload_cmd(struct unix_ctx *ctx, const char *arg) init_reply(&raw); - ret = send_cmd(ctx->fd, CTL_CMD_RELOAD, NULL, NULL, NULL, &raw); + ret = send_cmd(ctx, CTL_CMD_RELOAD, NULL, NULL, NULL, &raw); if (ret < 0) { goto error_status; } @@ -291,7 +291,7 @@ int handle_stop_cmd(struct unix_ctx *ctx, const char *arg) init_reply(&raw); - ret = send_cmd(ctx->fd, CTL_CMD_STOP, NULL, NULL, NULL, &raw); + ret = send_cmd(ctx, CTL_CMD_STOP, NULL, NULL, NULL, &raw); if (ret < 0) { goto error_status; } @@ -338,7 +338,7 @@ int handle_disconnect_user_cmd(struct unix_ctx *ctx, const char *arg) req.username = (void*)arg; - ret = send_cmd(ctx->fd, CTL_CMD_DISCONNECT_NAME, &req, + ret = send_cmd(ctx, CTL_CMD_DISCONNECT_NAME, &req, (pack_size_func)username_req__get_packed_size, (pack_func)username_req__pack, &raw); if (ret < 0) { @@ -391,7 +391,7 @@ int handle_disconnect_id_cmd(struct unix_ctx *ctx, const char *arg) req.id = id; - ret = send_cmd(ctx->fd, CTL_CMD_DISCONNECT_ID, &req, + ret = send_cmd(ctx, CTL_CMD_DISCONNECT_ID, &req, (pack_size_func)id_req__get_packed_size, (pack_func)id_req__pack, &raw); if (ret < 0) { @@ -443,7 +443,7 @@ int handle_list_users_cmd(struct unix_ctx *ctx, const char *arg) out = pager_start(); - ret = send_cmd(ctx->fd, CTL_CMD_LIST, NULL, NULL, NULL, &raw); + ret = send_cmd(ctx, CTL_CMD_LIST, NULL, NULL, NULL, &raw); if (ret < 0) { goto error; } @@ -491,7 +491,7 @@ int handle_list_users_cmd(struct unix_ctx *ctx, const char *arg) fprintf(out, " %14s %9s\n", "(no dtls)", rep->user[i]->status); } - entries_add(username, strlen(username), rep->user[i]->id); + entries_add(ctx, username, strlen(username), rep->user[i]->id); } ret = 0; @@ -666,7 +666,7 @@ int handle_show_user_cmd(struct unix_ctx *ctx, const char *arg) req.username = (void*)arg; - ret = send_cmd(ctx->fd, CTL_CMD_USER_INFO, &req, + ret = send_cmd(ctx, CTL_CMD_USER_INFO, &req, (pack_size_func)username_req__get_packed_size, (pack_func)username_req__pack, &raw); if (ret < 0) { @@ -715,7 +715,7 @@ int handle_show_id_cmd(struct unix_ctx *ctx, const char *arg) req.id = id; - ret = send_cmd(ctx->fd, CTL_CMD_ID_INFO, &req, + ret = send_cmd(ctx, CTL_CMD_ID_INFO, &req, (pack_size_func)id_req__get_packed_size, (pack_func)id_req__pack, &raw); if (ret < 0) { @@ -761,12 +761,12 @@ void conn_posthandle(struct unix_ctx *ctx) } } -struct unix_ctx *conn_init(void) +struct unix_ctx *conn_init(void *pool) { - return calloc(1, sizeof(struct unix_ctx)); + return talloc_zero(pool, struct unix_ctx); } void conn_close(struct unix_ctx* conn) { - free(conn); + talloc_free(conn); } diff --git a/src/occtl.c b/src/occtl.c index 15120483..94a23f11 100644 --- a/src/occtl.c +++ b/src/occtl.c @@ -33,6 +33,9 @@ static int handle_reset_cmd(CONN_TYPE * conn, const char *arg); static int handle_help_cmd(CONN_TYPE * conn, const char *arg); static int handle_exit_cmd(CONN_TYPE * conn, const char *arg); +/* global talloc pool */ +static void *gl_pool = NULL; + typedef struct { char *name; unsigned name_size; @@ -178,7 +181,7 @@ char *rl_gets(char *line_read) /* If the buffer has already been allocated, return the memory to the free pool. */ if (line_read) { - free(line_read); + talloc_free(line_read); } /* Get a line from the user. */ @@ -254,7 +257,7 @@ unsigned check_cmd(const char *cmd, const char *input, len = strlen(input); - t = malloc(len + 1); + t = talloc_size(conn, len + 1); if (t == NULL) return 0; @@ -289,7 +292,7 @@ unsigned check_cmd(const char *cmd, const char *input, } cleanup: - free(t); + talloc_free(t); return ret; } @@ -345,7 +348,7 @@ int handle_cmd(CONN_TYPE * conn, char *line) return 1; } -char *merge_args(int argc, char **argv) +char *merge_args(void *pool, int argc, char **argv) { unsigned size = 0; char *data, *p; @@ -355,7 +358,8 @@ char *merge_args(int argc, char **argv) size += strlen(argv[i]) + 1; } size++; - data = malloc(size); + + data = talloc_size(pool, size); if (data == NULL) { fprintf(stderr, "memory error\n"); exit(1); @@ -413,11 +417,11 @@ static char *command_generator(const char *text, int state) ret = NULL; if (strcmp(arg, "[NAME]") == 0) ret = - search_for_user(entries_idx, + search_for_user(gl_pool, entries_idx, text, len); else if (strcmp(arg, "[ID]") == 0) ret = - search_for_id(entries_idx, + search_for_id(gl_pool, entries_idx, text, len); if (ret != NULL) { entries_idx++; @@ -439,7 +443,7 @@ static char *command_generator(const char *text, int state) name += cmd_start; if (c_strncasecmp(name, text, len) == 0) { - return (strdup(name)); + return (talloc_strdup(gl_pool, name)); } } @@ -466,7 +470,7 @@ void handle_sigint(int signo) void initialize_readline(void) { rl_readline_name = "occtl"; - rl_attempted_completion_function = occtl_completion; + rl_attempted_completion_function = (CPPFunction*)occtl_completion; rl_completion_entry_function = command_generator; rl_completion_query_items = 20; #ifdef HAVE_ORIG_READLINE @@ -480,9 +484,15 @@ int main(int argc, char **argv) char *line = NULL; CONN_TYPE *conn; + gl_pool = talloc_init("occtl"); + if (gl_pool == NULL) { + fprintf(stderr, "talloc init error\n"); + exit(1); + } + signal(SIGPIPE, SIG_IGN); - conn = conn_init(); + conn = conn_init(gl_pool); if (argc > 1) { int ret; @@ -497,10 +507,10 @@ int main(int argc, char **argv) exit(0); } - line = merge_args(argc, argv); + line = merge_args(conn, argc, argv); ret = handle_cmd(conn, line); - free(line); + talloc_free(line); return ret; } diff --git a/src/occtl.h b/src/occtl.h index 44c30f59..f4cf9a7b 100644 --- a/src/occtl.h +++ b/src/occtl.h @@ -3,6 +3,7 @@ #include #include +#include "common.h" #ifdef HAVE_ORIG_READLINE # include @@ -19,9 +20,9 @@ void print_iface_stats(const char *iface, time_t since, FILE * out); void bytes2human(unsigned long bytes, char* output, unsigned output_size, const char* suffix); -char* search_for_id(unsigned idx, const char* match, int match_size); -char* search_for_user(unsigned idx, const char* match, int match_size); -void entries_add(const char* user, unsigned user_size, unsigned id); +char* search_for_id(void *pool, unsigned idx, const char* match, int match_size); +char* search_for_user(void *pool, unsigned idx, const char* match, int match_size); +void entries_add(void *pool, const char* user, unsigned user_size, unsigned id); void entries_clear(void); #define DEFAULT_TIMEOUT (10*1000) @@ -35,12 +36,12 @@ unsigned check_cmd_help(const char *line); #ifdef HAVE_DBUS # include -# define CONN_TYPE DBusConnection +# define CONN_TYPE struct dbus_ctx #else # define CONN_TYPE struct unix_ctx #endif -CONN_TYPE *conn_init(void); +CONN_TYPE *conn_init(void *pool); void conn_close(CONN_TYPE*); int conn_prehandle(CONN_TYPE *ctx); diff --git a/src/pam.c b/src/pam.c index 1d4e455f..cb4b40a8 100644 --- a/src/pam.c +++ b/src/pam.c @@ -77,7 +77,7 @@ unsigned i; if (msg_size == 0) return PAM_SUCCESS; - pctx->replies = calloc(1, msg_size*sizeof(*pctx->replies)); + pctx->replies = talloc_zero_size(pctx, msg_size*sizeof(*pctx->replies)); if (pctx->replies == NULL) return PAM_BUF_ERR; @@ -104,7 +104,7 @@ unsigned i; co_resume(); pctx->state = PAM_S_INIT; - pctx->replies[i].resp = strdup(pctx->password); + pctx->replies[i].resp = talloc_strdup(pctx, pctx->password); pctx->sent_msg = 0; break; } @@ -151,7 +151,7 @@ wait: } } -static int pam_auth_init(void** ctx, const char* user, const char* ip, void* additional) +static int pam_auth_init(void** ctx, void *pool, const char* user, const char* ip, void* additional) { int pret; struct pam_ctx_st * pctx; @@ -159,11 +159,11 @@ struct pam_ctx_st * pctx; if (user == NULL) return -1; - pctx = calloc(1, sizeof(*pctx)); + pctx = talloc_zero(pool, struct pam_ctx_st); if (pctx == NULL) return -1; - str_init(&pctx->msg); + str_init(&pctx->msg, pctx); pctx->dc.conv = ocserv_conv; pctx->dc.appdata_ptr = pctx; @@ -189,7 +189,7 @@ struct pam_ctx_st * pctx; fail2: pam_end(pctx->ph, pret); fail1: - free(pctx); + talloc_free(pctx); return -1; } @@ -307,11 +307,11 @@ static void pam_auth_deinit(void* ctx) struct pam_ctx_st * pctx = ctx; pam_end(pctx->ph, pctx->cr_ret); - free(pctx->replies); + talloc_free(pctx->replies); str_clear(&pctx->msg); if (pctx->cr != NULL) co_delete(pctx->cr); - free(pctx); + talloc_free(pctx); } const struct auth_mod_st pam_auth_funcs = { diff --git a/src/plain.c b/src/plain.c index 1656fd43..e4e7fc8e 100644 --- a/src/plain.c +++ b/src/plain.c @@ -101,17 +101,17 @@ static int read_auth_pass(struct plain_ctx_st *pctx) ret = 0; exit: fclose(fp); - free(line); + free(line); /* no talloc_free, as it is provided by getline */ return ret; } -static int plain_auth_init(void **ctx, const char *username, const char *ip, +static int plain_auth_init(void **ctx, void *pool, const char *username, const char *ip, void *additional) { struct plain_ctx_st *pctx; int ret; - pctx = malloc(sizeof(*pctx)); + pctx = talloc_zero(pool, struct plain_ctx_st); if (pctx == NULL) return ERR_AUTH_FAIL; @@ -124,7 +124,7 @@ static int plain_auth_init(void **ctx, const char *username, const char *ip, ret = read_auth_pass(pctx); if (ret < 0) { - free(pctx); + talloc_free(pctx); return ERR_AUTH_FAIL; } @@ -180,7 +180,7 @@ static int plain_auth_msg(void *ctx, char *msg, size_t msg_size) static void plain_auth_deinit(void *ctx) { - free(ctx); + talloc_free(ctx); } const struct auth_mod_st plain_auth_funcs = { diff --git a/src/script-list.h b/src/script-list.h index 2f62fe3a..da41abf2 100644 --- a/src/script-list.h +++ b/src/script-list.h @@ -28,7 +28,7 @@ void add_to_script_list(main_server_st* s, pid_t pid, unsigned up, struct proc_s { struct script_wait_st *stmp; - stmp = malloc(sizeof(*stmp)); + stmp = talloc(s, struct script_wait_st); if (stmp == NULL) return; @@ -46,7 +46,7 @@ struct script_wait_st *stmp = NULL, *spos; list_for_each_safe(&s->script_list.head, stmp, spos, list) { if (stmp->proc == proc) { list_del(&stmp->list); - free(stmp); + talloc_free(stmp); break; } } diff --git a/src/str.c b/src/str.c index d644fdb7..ebb55e50 100644 --- a/src/str.c +++ b/src/str.c @@ -35,25 +35,13 @@ void str_clear(str_st * str) { if (str == NULL || str->allocd == NULL) return; - free(str->allocd); + talloc_free(str->allocd); str->data = str->allocd = NULL; str->max_length = 0; str->length = 0; } -void *safe_realloc(void *ptr, size_t size) -{ - void* tmp, *ret; - - tmp = ptr; - ret = realloc(ptr, size); - if (ret == NULL) { - free(tmp); - } - return ret; -} - #define MIN_CHUNK 64 /* This function makes sure there is an additional byte in dest; */ @@ -82,7 +70,7 @@ int str_append_size(str_st * dest, size_t data_size) MAX(data_size, MIN_CHUNK) + MAX(dest->max_length, MIN_CHUNK); - dest->allocd = safe_realloc(dest->allocd, new_len+1); + dest->allocd = talloc_realloc_size(dest->pool, dest->allocd, new_len+1); if (dest->allocd == NULL) return ERR_MEM; dest->max_length = new_len; diff --git a/src/str.h b/src/str.h index 5001b515..fa0d5a77 100644 --- a/src/str.h +++ b/src/str.h @@ -31,14 +31,16 @@ typedef struct { uint8_t *data; /* API: pointer to data to copy from */ size_t max_length; size_t length; /* API: current length */ + void *pool; } str_st; /* Initialize a buffer */ -inline static void str_init(str_st * str) +inline static void str_init(str_st * str, void *pool) { str->data = str->allocd = NULL; str->max_length = 0; str->length = 0; + str->pool = pool; } /* Free the data in a buffer */ @@ -55,7 +57,6 @@ int str_append_str(str_st *, const char *str); int str_append_data(str_st *, const void *data, size_t data_size); int str_append_size(str_st *, size_t data_size); int str_append_data_prefix1(str_st *, const void *data, size_t data_size); -void *safe_realloc(void *ptr, size_t size); #define str_append_str_prefix1(s, str) (((str)==NULL)?str_append_data_prefix1(s, NULL, 0):str_append_data_prefix1(s, str, strlen(str))) diff --git a/src/tlslib.c b/src/tlslib.c index 21030f79..a3a20eb8 100644 --- a/src/tlslib.c +++ b/src/tlslib.c @@ -181,11 +181,11 @@ const tls_cache_st *e = _e; return hash_any(e->session_id, e->session_id_size, 0); } -void tls_cache_init(hash_db_st** _db) +void tls_cache_init(void *pool, hash_db_st** _db) { hash_db_st * db; - db = malloc(sizeof(*db)); + db = talloc(pool, hash_db_st); if (db == NULL) exit(1); @@ -207,13 +207,13 @@ struct htable_iter iter; cache->session_data_size = 0; cache->session_id_size = 0; } - free(cache); + talloc_free(cache); cache = htable_next(&db->ht, &iter); } htable_clear(&db->ht); db->entries = 0; - free(db); + talloc_free(db); return; } @@ -292,7 +292,7 @@ fail: } -void tls_global_init(main_server_st* s) +void tls_global_init(tls_st *creds) { int ret; @@ -304,12 +304,12 @@ int ret; return; } -void tls_global_deinit(main_server_st* s) +void tls_global_deinit(tls_st *creds) { - if (s->creds.xcred != NULL) - gnutls_certificate_free_credentials(s->creds.xcred); - if (s->creds.cprio != NULL) - gnutls_priority_deinit(s->creds.cprio); + if (creds->xcred != NULL) + gnutls_certificate_free_credentials(creds->xcred); + if (creds->cprio != NULL) + gnutls_priority_deinit(creds->cprio); gnutls_global_deinit(); @@ -362,24 +362,24 @@ cleanup: return; } -static void set_dh_params(main_server_st* s, gnutls_certificate_credentials_t cred) +static void set_dh_params(main_server_st* s, tls_st *creds) { gnutls_datum_t data; int ret; if (s->config->dh_params_file != NULL) { - ret = gnutls_dh_params_init (&s->creds.dh_params); + ret = gnutls_dh_params_init (&creds->dh_params); GNUTLS_FATAL_ERR(ret); ret = gnutls_load_file(s->config->dh_params_file, &data); GNUTLS_FATAL_ERR(ret); - ret = gnutls_dh_params_import_pkcs3(s->creds.dh_params, &data, GNUTLS_X509_FMT_PEM); + ret = gnutls_dh_params_import_pkcs3(creds->dh_params, &data, GNUTLS_X509_FMT_PEM); GNUTLS_FATAL_ERR(ret); gnutls_free(data.data); - gnutls_certificate_set_dh_params(cred, s->creds.dh_params); + gnutls_certificate_set_dh_params(creds->xcred, creds->dh_params); } } @@ -479,11 +479,11 @@ static int key_cb_decrypt_func(gnutls_privkey_t key, void* userdata, const gnutl static void key_cb_deinit_func(gnutls_privkey_t key, void* userdata) { - free(userdata); + talloc_free(userdata); } static -int load_cert_files(main_server_st *s) +int load_cert_files(main_server_st *s, tls_st *creds) { int ret; gnutls_pcert_st *pcert_list; @@ -521,7 +521,10 @@ struct key_cb_data * cdata; ret = gnutls_privkey_init(&key); GNUTLS_FATAL_ERR(ret); - cdata = malloc(sizeof(*cdata)); + /* use use the main pool rather than main, to allow usage of the credentials + * after freeing s. + */ + cdata = talloc(s->main_pool, struct key_cb_data); if (cdata == NULL) { mslog(s, NULL, LOG_ERR, "error allocating memory"); return -1; @@ -540,7 +543,7 @@ struct key_cb_data * cdata; key_cb_deinit_func, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); GNUTLS_FATAL_ERR(ret); - ret = gnutls_certificate_set_key(s->creds.xcred, NULL, 0, pcert_list, + ret = gnutls_certificate_set_key(creds->xcred, NULL, 0, pcert_list, pcert_list_size, key); GNUTLS_FATAL_ERR(ret); } @@ -549,7 +552,7 @@ struct key_cb_data * cdata; } /* reload key files etc. */ -void tls_load_certs(main_server_st* s) +void tls_load_certs(main_server_st *s, tls_st *creds) { int ret; const char* perr; @@ -559,13 +562,13 @@ const char* perr; gnutls_global_set_log_level(9); } - if (s->creds.xcred != NULL) - gnutls_certificate_free_credentials(s->creds.xcred); + if (creds->xcred != NULL) + gnutls_certificate_free_credentials(creds->xcred); - ret = gnutls_certificate_allocate_credentials(&s->creds.xcred); + ret = gnutls_certificate_allocate_credentials(&creds->xcred); GNUTLS_FATAL_ERR(ret); - set_dh_params(s, s->creds.xcred); + set_dh_params(s, creds); if (s->config->key_size == 0 || s->config->cert_size == 0) { mslog(s, NULL, LOG_ERR, "no certificate or key files were specified"); @@ -574,7 +577,7 @@ const char* perr; certificate_check(s); - ret = load_cert_files(s); + ret = load_cert_files(s, creds); if (ret < 0) { mslog(s, NULL, LOG_ERR, "error loading the certificate or key file"); exit(1); @@ -583,7 +586,7 @@ const char* perr; if (s->config->cert_req != GNUTLS_CERT_IGNORE) { if (s->config->ca != NULL) { ret = - gnutls_certificate_set_x509_trust_file(s->creds.xcred, + gnutls_certificate_set_x509_trust_file(creds->xcred, s->config->ca, GNUTLS_X509_FMT_PEM); if (ret < 0) { @@ -595,19 +598,19 @@ const char* perr; mslog(s, NULL, LOG_INFO, "processed %d CA certificate(s)", ret); } - tls_reload_crl(s); + tls_reload_crl(s, creds); - gnutls_certificate_set_verify_function(s->creds.xcred, + gnutls_certificate_set_verify_function(creds->xcred, verify_certificate_cb); } - ret = gnutls_priority_init(&s->creds.cprio, s->config->priorities, &perr); + ret = gnutls_priority_init(&creds->cprio, s->config->priorities, &perr); if (ret == GNUTLS_E_PARSING_ERROR) mslog(s, NULL, LOG_ERR, "error in TLS priority string: %s", perr); GNUTLS_FATAL_ERR(ret); if (s->config->ocsp_response != NULL) { - ret = gnutls_certificate_set_ocsp_status_request_file(s->creds.xcred, + ret = gnutls_certificate_set_ocsp_status_request_file(creds->xcred, s->config->ocsp_response, 0); GNUTLS_FATAL_ERR(ret); } @@ -615,13 +618,13 @@ const char* perr; return; } -void tls_reload_crl(main_server_st* s) +void tls_reload_crl(main_server_st* s, tls_st *creds) { int ret; if (s->config->cert_req != GNUTLS_CERT_IGNORE && s->config->crl != NULL) { ret = - gnutls_certificate_set_x509_crl_file(s->creds.xcred, + gnutls_certificate_set_x509_crl_file(creds->xcred, s->config->crl, GNUTLS_X509_FMT_PEM); if (ret < 0) { @@ -648,7 +651,7 @@ int tls_uncork(gnutls_session_t session) return gnutls_record_uncork(session, GNUTLS_RECORD_WAIT); } -void *calc_sha1_hash(char* file, unsigned cert) +void *calc_sha1_hash(void *pool, char* file, unsigned cert) { int ret; gnutls_datum_t data; @@ -687,7 +690,7 @@ unsigned i; } size_t ret_size = sizeof(digest)*2+1; - retval = malloc(ret_size); + retval = talloc_size(pool, ret_size); if (retval == NULL) { fprintf(stderr, "memory error"); exit(1); diff --git a/src/tlslib.h b/src/tlslib.h index 4551e066..357f13fe 100644 --- a/src/tlslib.h +++ b/src/tlslib.h @@ -41,10 +41,16 @@ ssize_t tls_send_nb(gnutls_session_t session, const void *data, void tls_cork(gnutls_session_t session); int tls_uncork(gnutls_session_t session); -void tls_reload_crl(struct main_server_st* s); -void tls_global_init(struct main_server_st* s); -void tls_global_deinit(struct main_server_st* s); -void tls_load_certs(struct main_server_st* s); +typedef struct tls_st { + gnutls_certificate_credentials_t xcred; + gnutls_priority_t cprio; + gnutls_dh_params_t dh_params; +} tls_st; + +void tls_reload_crl(struct main_server_st* s, struct tls_st *creds); +void tls_global_init(struct tls_st *creds); +void tls_global_deinit(struct tls_st *creds); +void tls_load_certs(struct main_server_st* s, struct tls_st *creds); ssize_t tls_send_file(gnutls_session_t session, const char *file); size_t tls_get_overhead(gnutls_protocol_t, gnutls_cipher_algorithm_t, gnutls_mac_algorithm_t); @@ -87,12 +93,6 @@ unsigned tls_has_session_cert(struct worker_st * ws); void tls_fatal_close(gnutls_session_t session, gnutls_alert_description_t a); -struct tls_st { - gnutls_certificate_credentials_t xcred; - gnutls_priority_t cprio; - gnutls_dh_params_t dh_params; -}; - typedef struct { /* does not allow resumption from different address @@ -110,8 +110,8 @@ typedef struct #define TLS_SESSION_EXPIRATION_TIME 600 #define DEFAULT_MAX_CACHED_TLS_SESSIONS 64 -void tls_cache_init(hash_db_st** db); +void tls_cache_init(void *pool, hash_db_st** db); void tls_cache_deinit(hash_db_st* db); -void *calc_sha1_hash(char* file, unsigned cert); +void *calc_sha1_hash(void *pool, char* file, unsigned cert); #endif diff --git a/src/worker-auth.c b/src/worker-auth.c index 2877a58f..becd8a21 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -217,8 +217,9 @@ static int recv_auth_reply(worker_st * ws, char *txt, size_t max_txt_size) int ret; int socketfd = -1; AuthReplyMsg *msg = NULL; + PROTOBUF_ALLOCATOR(pa, ws); - ret = recv_socket_msg(ws->cmd_fd, AUTH_REP, &socketfd, + ret = recv_socket_msg(ws, ws->cmd_fd, AUTH_REP, &socketfd, (void *)&msg, (unpack_func) auth_reply_msg__unpack); if (ret < 0) { @@ -275,48 +276,48 @@ static int recv_auth_reply(worker_st * ws, char *txt, size_t max_txt_size) msg->session_id.len); if (msg->ipv4 != NULL) { - free(ws->vinfo.ipv4); + talloc_free(ws->vinfo.ipv4); if (strcmp(msg->ipv4, "0.0.0.0") == 0) ws->vinfo.ipv4 = NULL; else - ws->vinfo.ipv4 = strdup(msg->ipv4); + ws->vinfo.ipv4 = talloc_strdup(ws, msg->ipv4); } if (msg->ipv6 != NULL) { - free(ws->vinfo.ipv6); + talloc_free(ws->vinfo.ipv6); if (strcmp(msg->ipv6, "::") == 0) ws->vinfo.ipv6 = NULL; else - ws->vinfo.ipv6 = strdup(msg->ipv6); + ws->vinfo.ipv6 = talloc_strdup(ws, msg->ipv6); } if (msg->ipv4_local != NULL) { - free(ws->vinfo.ipv4_local); + talloc_free(ws->vinfo.ipv4_local); if (strcmp(msg->ipv4_local, "0.0.0.0") == 0) ws->vinfo.ipv4_local = NULL; else - ws->vinfo.ipv4_local = strdup(msg->ipv4_local); + ws->vinfo.ipv4_local = talloc_strdup(ws, msg->ipv4_local); } if (msg->ipv6_local != NULL) { - free(ws->vinfo.ipv6_local); + talloc_free(ws->vinfo.ipv6_local); if (strcmp(msg->ipv6_local, "::") == 0) ws->vinfo.ipv6_local = NULL; else - ws->vinfo.ipv6_local = strdup(msg->ipv6_local); + ws->vinfo.ipv6_local = talloc_strdup(ws, msg->ipv6_local); } /* Read any additional data */ if (msg->ipv4_netmask != NULL) { - free(ws->config->network.ipv4_netmask); + talloc_free(ws->config->network.ipv4_netmask); ws->config->network.ipv4_netmask = - strdup(msg->ipv4_netmask); + talloc_strdup(ws, msg->ipv4_netmask); } if (msg->ipv6_netmask != NULL) { - free(ws->config->network.ipv6_netmask); + talloc_free(ws->config->network.ipv6_netmask); ws->config->network.ipv6_netmask = - strdup(msg->ipv6_netmask); + talloc_strdup(ws, msg->ipv6_netmask); } ws->config->network.ipv6_prefix = msg->ipv6_prefix; @@ -334,19 +335,19 @@ static int recv_auth_reply(worker_st * ws, char *txt, size_t max_txt_size) ws->routes_size = msg->n_routes; for (i = 0; i < ws->routes_size; i++) { - ws->routes[i] = strdup(msg->routes[i]); + ws->routes[i] = talloc_strdup(ws, msg->routes[i]); } ws->dns_size = msg->n_dns; for (i = 0; i < ws->dns_size; i++) { - ws->dns[i] = strdup(msg->dns[i]); + ws->dns[i] = talloc_strdup(ws, msg->dns[i]); } ws->nbns_size = msg->n_nbns; for (i = 0; i < ws->nbns_size; i++) { - ws->nbns[i] = strdup(msg->nbns[i]); + ws->nbns[i] = talloc_strdup(ws, msg->nbns[i]); } } else { oclog(ws, LOG_ERR, "error in received message"); @@ -366,7 +367,7 @@ static int recv_auth_reply(worker_st * ws, char *txt, size_t max_txt_size) ret = 0; cleanup: if (msg != NULL) - auth_reply_msg__free_unpacked(msg, NULL); + auth_reply_msg__free_unpacked(msg, &pa); return ret; } @@ -597,7 +598,7 @@ int read_user_pass(worker_st * ws, char *body, unsigned body_length, } *username = - unescape_html(*username, strlen(*username), NULL); + unescape_html(ws, *username, strlen(*username), NULL); } if (password != NULL) { @@ -616,7 +617,7 @@ int read_user_pass(worker_st * ws, char *body, unsigned body_length, } *password = - unescape_html(*password, strlen(*password), NULL); + unescape_html(ws, *password, strlen(*password), NULL); } } else { /* non-xml version */ @@ -657,7 +658,7 @@ int read_user_pass(worker_st * ws, char *body, unsigned body_length, } *username = - unescape_url(*username, strlen(*username), NULL); + unescape_url(ws, *username, strlen(*username), NULL); } if (password != NULL) { @@ -671,7 +672,7 @@ int read_user_pass(worker_st * ws, char *body, unsigned body_length, } *password = - unescape_url(*password, strlen(*password), NULL); + unescape_url(ws, *password, strlen(*password), NULL); } } @@ -738,7 +739,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver) ret = send_msg_to_main(ws, AUTH_REINIT, &rreq, (pack_size_func)auth_reinit_msg__get_packed_size, (pack_func)auth_reinit_msg__pack); - free(username); + talloc_free(username); if (ret < 0) { oclog(ws, LOG_ERR, @@ -755,7 +756,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver) } snprintf(tmp_user, sizeof(tmp_user), "%s", username); - free(username); + talloc_free(username); ireq.user_name = tmp_user; } @@ -814,7 +815,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver) (pack_func) auth_request_msg__pack); - free(password); + talloc_free(password); if (ret < 0) { oclog(ws, LOG_ERR, diff --git a/src/worker-resume.c b/src/worker-resume.c index b526a6ef..a0223eac 100644 --- a/src/worker-resume.c +++ b/src/worker-resume.c @@ -45,8 +45,9 @@ static int recv_resume_fetch_reply(worker_st *ws, gnutls_datum_t *sdata) { int ret; SessionResumeReplyMsg *resp; + PROTOBUF_ALLOCATOR(pa, ws); - ret = recv_msg( ws->cmd_fd, RESUME_FETCH_REP, (void*)&resp, + ret = recv_msg(ws, ws->cmd_fd, RESUME_FETCH_REP, (void*)&resp, (unpack_func)session_resume_reply_msg__unpack); if (ret < 0) { oclog(ws, LOG_ERR, "error receiving resumption reply (fetch)"); @@ -69,7 +70,7 @@ static int recv_resume_fetch_reply(worker_st *ws, gnutls_datum_t *sdata) ret = 0; cleanup: - session_resume_reply_msg__free_unpacked(resp, NULL); + session_resume_reply_msg__free_unpacked(resp, &pa); return ret; } diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 976e0db6..3a74cc2a 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -240,7 +240,7 @@ static void value_check(struct worker_st *ws, struct http_req_st *req) oclog(ws, LOG_HTTP_DEBUG, "HTTP: %.*s: %.*s", (int)req->header.length, req->header.data, (int)req->value.length, req->value.data); - value = malloc(req->value.length + 1); + value = talloc_size(ws, req->value.length + 1); if (value == NULL) return; @@ -384,7 +384,7 @@ static void value_check(struct worker_st *ws, struct http_req_st *req) } cleanup: - free(value); + talloc_free(value); } int header_field_cb(http_parser * parser, const char *at, size_t length) @@ -503,7 +503,7 @@ int body_cb(http_parser * parser, const char *at, size_t length) struct http_req_st *req = &ws->req; char *tmp; - tmp = safe_realloc(req->body, req->body_length + length + 1); + tmp = talloc_realloc_size(ws, req->body, req->body_length + length + 1); if (tmp == NULL) return 1; @@ -591,8 +591,8 @@ static int setup_dtls_connection(struct worker_st *ws) static void http_req_init(worker_st * ws) { - str_init(&ws->req.header); - str_init(&ws->req.value); + str_init(&ws->req.header, ws); + str_init(&ws->req.value, ws); } static void http_req_reset(worker_st * ws) @@ -612,7 +612,7 @@ static void http_req_deinit(worker_st * ws) http_req_reset(ws); str_clear(&ws->req.header); str_clear(&ws->req.value); - free(ws->req.body); + talloc_free(ws->req.body); ws->req.body = NULL; } @@ -1324,7 +1324,7 @@ static int connect_handler(worker_st * ws) sigaddset(&blockset, SIGTERM); ws->buffer_size = 16 * 1024; - ws->buffer = malloc(ws->buffer_size); + ws->buffer = talloc_size(ws, ws->buffer_size); if (ws->buffer == NULL) { oclog(ws, LOG_INFO, "memory error"); tls_puts(ws->session, @@ -1764,7 +1764,7 @@ static int connect_handler(worker_st * ws) "buffer size is smaller than MTU (%u < %u); adjusting", ws->buffer_size, ws->conn_mtu); ws->buffer_size = ws->conn_mtu + CSTP_OVERHEAD; - ws->buffer = safe_realloc(ws->buffer, ws->buffer_size); + ws->buffer = talloc_realloc_size(ws, ws->buffer, ws->buffer_size); if (ws->buffer == NULL) goto exit; } diff --git a/src/worker.h b/src/worker.h index e2b0d5fe..626df961 100644 --- a/src/worker.h +++ b/src/worker.h @@ -258,7 +258,7 @@ int send_msg_to_main(worker_st *ws, uint8_t cmd, const void* msg, pack_size_func get_size, pack_func pack) { oclog(ws, LOG_DEBUG, "sending message '%s' to main", cmd_request_to_str(cmd)); - return send_msg(ws->cmd_fd, cmd, msg, get_size, pack); + return send_msg(ws, ws->cmd_fd, cmd, msg, get_size, pack); } #endif