2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2012 Intel Corporation.
5 * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
7 * Author: David Woodhouse <dwmw2@infradead.org>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1, as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to:
21 * Free Software Foundation, Inc.
22 * 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA
26 #ifndef __OPENCONNECT_INTERNAL_H__
27 #define __OPENCONNECT_INTERNAL_H__
29 #include "openconnect.h"
31 #if defined (OPENCONNECT_OPENSSL) || defined(DTLS_OPENSSL)
32 #include <openssl/ssl.h>
33 #include <openssl/err.h>
35 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
36 #define method_const const
42 #if defined (OPENCONNECT_GNUTLS)
43 #include <gnutls/gnutls.h>
44 #include <gnutls/abstract.h>
45 #include <gnutls/x509.h>
47 #include <trousers/tss.h>
48 #include <trousers/trousers.h>
54 #include <sys/socket.h>
55 #include <sys/select.h>
57 #include <sys/types.h>
65 #include LIBSTOKEN_HDR
71 #define _(s) dgettext("openconnect", s)
77 #include <libxml/tree.h>
82 /****************************************************************************/
94 struct vpn_option *next;
100 #define KA_KEEPALIVE 3
103 struct keepalive_info {
113 struct split_include {
115 struct split_include *next;
119 struct pin_cache *next;
124 #define RECONNECT_INTERVAL_MIN 10
125 #define RECONNECT_INTERVAL_MAX 100
127 #define CERT_TYPE_UNKNOWN 0
128 #define CERT_TYPE_PEM 1
129 #define CERT_TYPE_PKCS12 2
130 #define CERT_TYPE_TPM 3
132 #define REDIR_TYPE_NONE 0
133 #define REDIR_TYPE_NEWHOST 1
134 #define REDIR_TYPE_LOCAL 2
136 struct openconnect_info {
140 const char *csd_xmltag;
141 const char *platname;
149 char *csd_scriptname;
150 xmlNode *opaque_srvdata;
153 pxProxyFactory *proxy_factory;
159 const char *localname;
163 int cert_expire_warning;
169 const char *servercert;
170 const char *xmlconfig;
171 char xmlsha1[(SHA1_SIZE * 2) + 1];
180 int no_http_keepalive;
183 struct stoken_ctx *stoken_ctx;
191 OPENCONNECT_X509 *peer_cert;
193 char *cookie; /* Pointer to within cookies list */
194 struct vpn_option *cookies;
195 struct vpn_option *cstp_options;
196 struct vpn_option *dtls_options;
198 #if defined(OPENCONNECT_OPENSSL)
202 #elif defined(OPENCONNECT_GNUTLS)
203 gnutls_session_t https_sess;
204 gnutls_certificate_credentials_t https_cred;
205 struct pin_cache *pin_cache;
207 TSS_HCONTEXT tpm_context;
209 TSS_HPOLICY srk_policy;
211 TSS_HPOLICY tpm_key_policy;
213 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
215 gnutls_pkcs11_privkey_t my_p11key;
217 gnutls_privkey_t my_pkey;
218 gnutls_x509_crt_t *my_certs;
219 unsigned int nr_my_certs;
221 #endif /* OPENCONNECT_GNUTLS */
222 struct keepalive_info ssl_times;
223 int owe_ssl_dpd_response;
224 struct pkt *deflate_pkt;
225 struct pkt *current_ssl_pkt;
226 struct pkt *pending_deflated_pkt;
228 z_stream inflate_strm;
229 uint32_t inflate_adler32;
230 z_stream deflate_strm;
231 uint32_t deflate_adler32;
234 int reconnect_timeout;
235 int reconnect_interval;
236 int dtls_attempt_period;
237 time_t new_dtls_started;
238 #if defined(DTLS_OPENSSL)
242 SSL_SESSION *dtls_session;
243 #elif defined(DTLS_GNUTLS)
244 /* Call these *_ssl rather than *_sess because they're just
245 pointers, and generic code (in mainloop.c for example)
246 wants to check if they're NULL or not. No point in being
247 differently named to the OpenSSL variant, and forcing us to
248 have ifdefs or accessor macros for them. */
249 gnutls_session_t dtls_ssl;
250 gnutls_session_t new_dtls_ssl;
252 struct keepalive_info dtls_times;
253 unsigned char dtls_session_id[32];
254 unsigned char dtls_secret[48];
257 const char *vpnc_script;
264 const char *vpn_addr;
265 const char *vpn_netmask;
266 const char *vpn_addr6;
267 const char *vpn_netmask6;
268 const char *vpn_dns[3];
269 const char *vpn_nbns[3];
270 const char *vpn_domain;
271 const char *vpn_proxy_pac;
272 struct split_include *split_dns;
273 struct split_include *split_includes;
274 struct split_include *split_excludes;
291 struct pkt *incoming_queue;
292 struct pkt *outgoing_queue;
296 socklen_t peer_addrlen;
297 struct sockaddr *peer_addr;
298 struct sockaddr *dtls_addr;
305 const char *quit_reason;
308 openconnect_validate_peer_cert_vfn validate_peer_cert;
309 openconnect_write_new_config_vfn write_new_config;
310 openconnect_process_auth_form_vfn process_auth_form;
311 openconnect_progress_vfn progress;
314 #if (defined (DTLS_OPENSSL) && defined (SSL_OP_CISCO_ANYCONNECT)) || \
315 (defined (DTLS_GNUTLS) && defined (HAVE_GNUTLS_SESSION_SET_PREMASTER))
321 #define AC_PKT_DATA 0 /* Uncompressed data */
322 #define AC_PKT_DPD_OUT 3 /* Dead Peer Detection */
323 #define AC_PKT_DPD_RESP 4 /* DPD response */
324 #define AC_PKT_DISCONN 5 /* Client disconnection notice */
325 #define AC_PKT_KEEPALIVE 7 /* Keepalive */
326 #define AC_PKT_COMPRESSED 8 /* Compressed data */
327 #define AC_PKT_TERM_SERVER 9 /* Server kick */
329 #define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__)
331 /****************************************************************************/
332 /* Oh Solaris how we hate thee! */
334 #define time(x) openconnect__time(x)
335 time_t openconnect__time(time_t *t);
337 #ifndef HAVE_ASPRINTF
338 #define asprintf openconnect__asprintf
339 int openconnect__asprintf(char **strp, const char *fmt, ...);
342 #define getline openconnect__getline
343 ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream);
345 #ifndef HAVE_STRCASESTR
346 #define strcasestr openconnect__strcasestr
347 char *openconnect__strcasestr(const char *haystack, const char *needle);
350 /****************************************************************************/
353 int setup_tun(struct openconnect_info *vpninfo);
354 int tun_mainloop(struct openconnect_info *vpninfo, int *timeout);
355 void shutdown_tun(struct openconnect_info *vpninfo);
356 int script_config_tun (struct openconnect_info *vpninfo, const char *reason);
359 unsigned char unhex(const char *data);
360 int setup_dtls(struct openconnect_info *vpninfo);
361 int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
362 int dtls_try_handshake(struct openconnect_info *vpninfo);
363 int connect_dtls_socket(struct openconnect_info *vpninfo);
366 int make_cstp_connection(struct openconnect_info *vpninfo);
367 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout);
368 int cstp_bye(struct openconnect_info *vpninfo, const char *reason);
369 int cstp_reconnect(struct openconnect_info *vpninfo);
372 int connect_https_socket(struct openconnect_info *vpninfo);
373 int request_passphrase(struct openconnect_info *vpninfo, const char *label,
374 char **response, const char *fmt, ...);
375 int __attribute__ ((format (printf, 2, 3)))
376 openconnect_SSL_printf(struct openconnect_info *vpninfo, const char *fmt, ...);
377 int openconnect_print_err_cb(const char *str, size_t len, void *ptr);
378 #define openconnect_report_ssl_errors(v) ERR_print_errors_cb(openconnect_print_err_cb, (v))
379 #ifdef FAKE_ANDROID_KEYSTORE
380 #define ANDROID_KEYSTORE
382 #ifdef ANDROID_KEYSTORE
383 char *keystore_strerror(int err);
384 int keystore_fetch(const char *key, unsigned char **result);
387 /* ${SSL_LIBRARY}.c */
388 int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len);
389 int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len);
390 int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len);
391 int openconnect_open_https(struct openconnect_info *vpninfo);
392 void openconnect_close_https(struct openconnect_info *vpninfo, int final);
393 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo, OPENCONNECT_X509 *cert,
395 int openconnect_sha1(unsigned char *result, void *data, int len);
396 int openconnect_random(void *bytes, int len);
397 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
401 int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events);
402 int vpn_mainloop(struct openconnect_info *vpninfo);
403 int queue_new_packet(struct pkt **q, void *buf, int len);
404 void queue_packet(struct pkt **q, struct pkt *new);
405 int keepalive_action(struct keepalive_info *ka, int *timeout);
406 int ka_stalled_action(struct keepalive_info *ka, int *timeout);
411 int config_lookup_host(struct openconnect_info *vpninfo, const char *host);
414 int parse_xml_response(struct openconnect_info *vpninfo, char *response, struct oc_auth_form **form);
415 int handle_auth_form(struct openconnect_info *vpninfo, struct oc_auth_form *form,
416 char *request_body, int req_len, const char **method,
417 const char **request_body_type, int xmlpost);
418 void free_auth_form(struct oc_auth_form *form);
419 int xmlpost_initial_req(struct openconnect_info *vpninfo, char *request_body, int req_len);
420 int prepare_stoken(struct openconnect_info *vpninfo);
423 char *openconnect_create_useragent(const char *base);
424 int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
425 int internal_parse_url(char *url, char **res_proto, char **res_host,
426 int *res_port, char **res_path, int default_port);
429 int set_openssl_ui(void);
432 extern const char *openconnect_version_str;
434 #endif /* __OPENCONNECT_INTERNAL_H__ */