diff --git a/http.c b/http.c index e1c3f79c..d04ef6c5 100644 --- a/http.c +++ b/http.c @@ -1077,7 +1077,7 @@ int process_proxy(struct openconnect_info *vpninfo, int ssl_sock) int openconnect_set_http_proxy(struct openconnect_info *vpninfo, char *proxy) { - char *url = strdup(proxy); + char *url = proxy; int ret; if (!url) diff --git a/library.c b/library.c index bb72b339..2611f84c 100644 --- a/library.c +++ b/library.c @@ -43,6 +43,42 @@ struct openconnect_info *openconnect_vpninfo_new (char *useragent, return vpninfo; } +static void free_optlist (struct vpn_option *opt) +{ + struct vpn_option *next; + + for (; opt; opt = next) { + next = opt->next; + free(opt->option); + free(opt->value); + free(opt); + } +} + +void openconnect_vpninfo_free (struct openconnect_info *vpninfo) +{ + openconnect_reset_ssl(vpninfo); + free_optlist(vpninfo->cookies); + free_optlist(vpninfo->cstp_options); + free_optlist(vpninfo->dtls_options); + free(vpninfo->hostname); + free(vpninfo->urlpath); + free(vpninfo->redirect_url); + free(vpninfo->proxy_type); + free(vpninfo->proxy); + free(vpninfo->csd_scriptname); + free(vpninfo->csd_stuburl); + /* These are const in openconnect itself, but for consistency of + the library API we do take ownership of the strings we're given, + and thus we have to free them too. */ + free((void *)vpninfo->cafile); + free((void *)vpninfo->cert); + if (vpninfo->cert != vpninfo->sslkey) + free((void *)vpninfo->sslkey); + /* No need to free deflate streams; they weren't initialised */ + free(vpninfo); +} + char *openconnect_get_hostname (struct openconnect_info *vpninfo) { return vpninfo->hostname; @@ -69,7 +105,6 @@ void openconnect_set_xmlsha1 (struct openconnect_info *vpninfo, char *xmlsha1, i return; memcpy (&vpninfo->xmlsha1, xmlsha1, size); - } void openconnect_set_cafile (struct openconnect_info *vpninfo, char *cafile) @@ -110,7 +145,8 @@ char *openconnect_get_cookie (struct openconnect_info *vpninfo) void openconnect_clear_cookie (struct openconnect_info *vpninfo) { - memset(vpninfo->cookie, 0, sizeof(vpninfo->cookie)); + if (vpninfo->cookie) + memset(vpninfo->cookie, 0, strlen(vpninfo->cookie)); } void openconnect_reset_ssl (struct openconnect_info *vpninfo) diff --git a/main.c b/main.c index 39064bd4..ad69d60e 100644 --- a/main.c +++ b/main.c @@ -459,7 +459,7 @@ int main(int argc, char **argv) if (autoproxy) vpninfo->proxy_factory = px_proxy_factory_new(); #endif - if (proxy && openconnect_set_http_proxy(vpninfo, proxy)) + if (proxy && openconnect_set_http_proxy(vpninfo, strdup(proxy))) exit(1); if (use_syslog) { diff --git a/openconnect-internal.h b/openconnect-internal.h index e4d3f821..622d9395 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -127,7 +127,7 @@ struct openconnect_info { int uid_csd_given; int no_http_keepalive; - char *cookie; + char *cookie; /* Pointer to within cookies list */ struct vpn_option *cookies; struct vpn_option *cstp_options; struct vpn_option *dtls_options; diff --git a/openconnect.h b/openconnect.h index f9066e2f..f2aed5a1 100644 --- a/openconnect.h +++ b/openconnect.h @@ -91,6 +91,10 @@ struct openconnect_info; /* We don't want to have to pull in OpenSSL stuff just for this */ struct x509_st; + + +/* Unless otherwise specified, all functions which set strings will take ownership of those strings + and should free them later in openconnect_vpninfo_free() */ int openconnect_get_cert_sha1(struct openconnect_info *vpninfo, struct x509_st *cert, char *buf); int openconnect_set_http_proxy(struct openconnect_info *vpninfo, char *proxy); @@ -103,7 +107,11 @@ char *openconnect_get_hostname (struct openconnect_info *); void openconnect_set_hostname (struct openconnect_info *, char *); char *openconnect_get_urlpath (struct openconnect_info *); void openconnect_set_urlpath (struct openconnect_info *, char *); + +/* This function does *not* take ownership of the string; it's copied + into a static buffer in the vpninfo */ void openconnect_set_xmlsha1 (struct openconnect_info *, char *, int size); + void openconnect_set_cafile (struct openconnect_info *, char *); void openconnect_setup_csd (struct openconnect_info *, uid_t, int silent, char *wrapper); void openconnect_set_client_cert (struct openconnect_info *, char *cert, char *sslkey); @@ -111,8 +119,6 @@ struct x509_st *openconnect_get_peer_cert (struct openconnect_info *); int openconnect_get_port (struct openconnect_info *); char *openconnect_get_cookie (struct openconnect_info *); void openconnect_clear_cookie (struct openconnect_info *); -void openconnect_clear_peer_addr (struct openconnect_info *); -void openconnect_clear_https_ctx (struct openconnect_info *); void openconnect_reset_ssl (struct openconnect_info *vpninfo); int openconnect_parse_url (struct openconnect_info *vpninfo, char *url); @@ -133,5 +139,6 @@ struct openconnect_info *openconnect_vpninfo_new (char *useragent, openconnect_write_new_config_fn, openconnect_process_auth_form_fn, openconnect_progress_fn); +void openconnect_vpninfo_free (struct openconnect_info *vpninfo); #endif /* __OPENCONNECT_H__ */