2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2012 Intel Corporation.
6 * Authors: David Woodhouse <dwmw2@infradead.org>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * version 2.1, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to:
20 * Free Software Foundation, Inc.
21 * 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
30 #include LIBSTOKEN_HDR
33 #include "openconnect-internal.h"
35 struct openconnect_info *openconnect_vpninfo_new (char *useragent,
36 openconnect_validate_peer_cert_vfn validate_peer_cert,
37 openconnect_write_new_config_vfn write_new_config,
38 openconnect_process_auth_form_vfn process_auth_form,
39 openconnect_progress_vfn progress,
42 struct openconnect_info *vpninfo = calloc (sizeof(*vpninfo), 1);
45 vpninfo->cert_expire_warning = 60 * 86400;
46 vpninfo->useragent = openconnect_create_useragent (useragent);
47 vpninfo->validate_peer_cert = validate_peer_cert;
48 vpninfo->write_new_config = write_new_config;
49 vpninfo->process_auth_form = process_auth_form;
50 vpninfo->progress = progress;
51 vpninfo->cbdata = privdata?:vpninfo;
52 vpninfo->cancel_fd = -1;
54 vpninfo->csd_xmltag = "csdMac";
56 vpninfo->csd_xmltag = "csdLinux";
60 bindtextdomain("openconnect", LOCALEDIR);
66 static void free_optlist (struct vpn_option *opt)
68 struct vpn_option *next;
70 for (; opt; opt = next) {
78 void openconnect_vpninfo_free (struct openconnect_info *vpninfo)
80 openconnect_close_https(vpninfo, 1);
81 free(vpninfo->peer_addr);
82 free_optlist(vpninfo->cookies);
83 free_optlist(vpninfo->cstp_options);
84 free_optlist(vpninfo->dtls_options);
85 free(vpninfo->hostname);
86 free(vpninfo->urlpath);
87 free(vpninfo->redirect_url);
88 free(vpninfo->proxy_type);
90 if (vpninfo->csd_scriptname) {
91 unlink(vpninfo->csd_scriptname);
92 free(vpninfo->csd_scriptname);
94 free(vpninfo->csd_stuburl);
95 /* These are const in openconnect itself, but for consistency of
96 the library API we do take ownership of the strings we're given,
97 and thus we have to free them too. */
98 free((void *)vpninfo->cafile);
99 if (vpninfo->cert != vpninfo->sslkey)
100 free((void *)vpninfo->sslkey);
101 free((void *)vpninfo->cert);
102 if (vpninfo->peer_cert) {
103 #if defined (OPENCONNECT_OPENSSL)
104 X509_free(vpninfo->peer_cert);
105 #elif defined (OPENCONNECT_GNUTLS)
106 gnutls_x509_crt_deinit(vpninfo->peer_cert);
108 vpninfo->peer_cert = NULL;
110 free(vpninfo->useragent);
112 if (vpninfo->stoken_pin)
113 free(vpninfo->stoken_pin);
114 if (vpninfo->stoken_ctx)
115 stoken_destroy(vpninfo->stoken_ctx);
117 /* No need to free deflate streams; they weren't initialised */
121 char *openconnect_get_hostname (struct openconnect_info *vpninfo)
123 return vpninfo->hostname;
126 void openconnect_set_hostname (struct openconnect_info *vpninfo, char *hostname)
128 vpninfo->hostname = hostname;
131 char *openconnect_get_urlpath (struct openconnect_info *vpninfo)
133 return vpninfo->urlpath;
136 void openconnect_set_urlpath (struct openconnect_info *vpninfo, char *urlpath)
138 vpninfo->urlpath = urlpath;
141 void openconnect_set_xmlsha1 (struct openconnect_info *vpninfo, const char *xmlsha1, int size)
143 if (size != sizeof (vpninfo->xmlsha1))
146 memcpy (&vpninfo->xmlsha1, xmlsha1, size);
149 void openconnect_set_cafile (struct openconnect_info *vpninfo, char *cafile)
151 vpninfo->cafile = cafile;
154 void openconnect_setup_csd (struct openconnect_info *vpninfo, uid_t uid, int silent, char *wrapper)
156 vpninfo->uid_csd = uid;
157 vpninfo->uid_csd_given = silent?2:1;
158 vpninfo->csd_wrapper = wrapper;
161 void openconnect_set_client_cert (struct openconnect_info *vpninfo, char *cert, char *sslkey)
163 vpninfo->cert = cert;
165 vpninfo->sslkey = sslkey;
167 vpninfo->sslkey = cert;
170 OPENCONNECT_X509 *openconnect_get_peer_cert (struct openconnect_info *vpninfo)
172 return vpninfo->peer_cert;
175 int openconnect_get_port (struct openconnect_info *vpninfo)
177 return vpninfo->port;
180 char *openconnect_get_cookie (struct openconnect_info *vpninfo)
182 return vpninfo->cookie;
185 void openconnect_clear_cookie (struct openconnect_info *vpninfo)
188 memset(vpninfo->cookie, 0, strlen(vpninfo->cookie));
191 void openconnect_reset_ssl (struct openconnect_info *vpninfo)
193 openconnect_close_https(vpninfo, 0);
194 if (vpninfo->peer_addr) {
195 free(vpninfo->peer_addr);
196 vpninfo->peer_addr = NULL;
200 int openconnect_parse_url (struct openconnect_info *vpninfo, char *url)
205 if (vpninfo->peer_addr) {
206 free(vpninfo->peer_addr);
207 vpninfo->peer_addr = NULL;
210 free(vpninfo->hostname);
211 vpninfo->hostname = NULL;
212 free(vpninfo->urlpath);
213 vpninfo->urlpath = NULL;
215 ret = internal_parse_url (url, &scheme, &vpninfo->hostname,
216 &vpninfo->port, &vpninfo->urlpath, 443);
219 vpn_progress(vpninfo, PRG_ERR,
220 _("Failed to parse server URL '%s'\n"),
224 if (scheme && strcmp(scheme, "https")) {
225 vpn_progress(vpninfo, PRG_ERR,
226 _("Only https:// permitted for server URL\n"));
233 void openconnect_set_cert_expiry_warning (struct openconnect_info *vpninfo,
236 vpninfo->cert_expire_warning = seconds;
239 void openconnect_set_cancel_fd (struct openconnect_info *vpninfo, int fd)
241 vpninfo->cancel_fd = fd;
244 const char *openconnect_get_version (void)
246 return openconnect_version_str;
249 int openconnect_has_pkcs11_support(void)
251 #if defined (OPENCONNECT_GNUTLS) && defined (HAVE_P11KIT)
258 #if defined (OPENCONNECT_OPENSSL) && defined (HAVE_ENGINE)
259 #include <openssl/engine.h>
261 int openconnect_has_tss_blob_support(void)
263 #if defined (OPENCONNECT_OPENSSL) && defined (HAVE_ENGINE)
266 ENGINE_load_builtin_engines();
268 e = ENGINE_by_id("tpm");
273 #elif defined (OPENCONNECT_GNUTLS) && defined (HAVE_TROUSERS)
279 int openconnect_has_stoken_support(void)
289 * Enable software token generation if use_stoken == 1.
291 * If token_str is not NULL, try to parse the string. Otherwise, try to read
292 * the token data from ~/.stokenrc
295 * = -EOPNOTSUPP, if libstoken is not available
296 * = -EINVAL, if the token string is invalid (token_str was provided)
297 * = -ENOENT, if ~/.stokenrc is missing (token_str was NULL)
298 * = -EIO, for other libstoken failures
301 int openconnect_set_stoken_mode (struct openconnect_info *vpninfo,
302 int use_stoken, const char *token_str)
307 vpninfo->use_stoken = 0;
311 if (!vpninfo->stoken_ctx) {
312 vpninfo->stoken_ctx = stoken_new();
313 if (!vpninfo->stoken_ctx)
318 stoken_import_string(vpninfo->stoken_ctx, token_str) :
319 stoken_import_rcfile(vpninfo->stoken_ctx, NULL);
323 vpninfo->use_stoken = 1;