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 defined (OPENCONNECT_GNUTLS)
36 #include <gnutls/gnutls.h>
37 #include <gnutls/x509.h>
39 #include <trousers/tss.h>
40 #include <trousers/trousers.h>
46 #include <sys/socket.h>
47 #include <sys/select.h>
49 #include <sys/types.h>
59 #define _(s) dgettext("openconnect", s)
68 /****************************************************************************/
80 struct vpn_option *next;
86 #define KA_KEEPALIVE 3
89 struct keepalive_info {
99 struct split_include {
101 struct split_include *next;
105 struct pin_cache *next;
110 #define RECONNECT_INTERVAL_MIN 10
111 #define RECONNECT_INTERVAL_MAX 100
113 #define CERT_TYPE_UNKNOWN 0
114 #define CERT_TYPE_PEM 1
115 #define CERT_TYPE_PKCS12 2
116 #define CERT_TYPE_TPM 3
118 struct openconnect_info {
128 char *csd_scriptname;
131 pxProxyFactory *proxy_factory;
137 const char *localname;
141 int cert_expire_warning;
147 const char *servercert;
148 const char *xmlconfig;
149 char xmlsha1[(SHA1_SIZE * 2) + 1];
158 int no_http_keepalive;
160 OPENCONNECT_X509 *peer_cert;
162 char *cookie; /* Pointer to within cookies list */
163 struct vpn_option *cookies;
164 struct vpn_option *cstp_options;
165 struct vpn_option *dtls_options;
167 #if defined(OPENCONNECT_OPENSSL)
171 #elif defined(OPENCONNECT_GNUTLS)
172 gnutls_session_t https_sess;
173 gnutls_certificate_credentials_t https_cred;
174 struct pin_cache *pin_cache;
176 TSS_HCONTEXT tpm_context;
178 TSS_HPOLICY srk_policy;
180 TSS_HPOLICY tpm_key_policy;
183 struct keepalive_info ssl_times;
184 int owe_ssl_dpd_response;
185 struct pkt *deflate_pkt;
186 struct pkt *current_ssl_pkt;
187 struct pkt *pending_deflated_pkt;
189 z_stream inflate_strm;
190 uint32_t inflate_adler32;
191 z_stream deflate_strm;
192 uint32_t deflate_adler32;
195 int reconnect_timeout;
196 int reconnect_interval;
197 int dtls_attempt_period;
198 time_t new_dtls_started;
199 #if defined(DTLS_OPENSSL)
203 SSL_SESSION *dtls_session;
204 #elif defined(DTLS_GNUTLS)
205 /* Call these *_ssl rather than *_sess because they're just
206 pointers, and generic code (in mainloop.c for example)
207 wants to check if they're NULL or not. No point in being
208 differently named to the OpenSSL variant, and forcing us to
209 have ifdefs or accessor macros for them. */
210 gnutls_session_t dtls_ssl;
211 gnutls_session_t new_dtls_ssl;
213 struct keepalive_info dtls_times;
214 unsigned char dtls_session_id[32];
215 unsigned char dtls_secret[48];
218 const char *vpnc_script;
224 const char *vpn_addr;
225 const char *vpn_netmask;
226 const char *vpn_addr6;
227 const char *vpn_netmask6;
228 const char *vpn_dns[3];
229 const char *vpn_nbns[3];
230 const char *vpn_domain;
231 const char *vpn_proxy_pac;
232 struct split_include *split_dns;
233 struct split_include *split_includes;
234 struct split_include *split_excludes;
251 struct pkt *incoming_queue;
252 struct pkt *outgoing_queue;
256 socklen_t peer_addrlen;
257 struct sockaddr *peer_addr;
258 struct sockaddr *dtls_addr;
263 const char *quit_reason;
266 openconnect_validate_peer_cert_vfn validate_peer_cert;
267 openconnect_write_new_config_vfn write_new_config;
268 openconnect_process_auth_form_vfn process_auth_form;
269 openconnect_progress_vfn progress;
272 #if (defined (DTLS_OPENSSL) && defined (SSL_OP_CISCO_ANYCONNECT)) || \
273 (defined (DTLS_GNUTLS) && defined (HAVE_GNUTLS_SESSION_SET_PREMASTER))
279 #define AC_PKT_DATA 0 /* Uncompressed data */
280 #define AC_PKT_DPD_OUT 3 /* Dead Peer Detection */
281 #define AC_PKT_DPD_RESP 4 /* DPD response */
282 #define AC_PKT_DISCONN 5 /* Client disconnection notice */
283 #define AC_PKT_KEEPALIVE 7 /* Keepalive */
284 #define AC_PKT_COMPRESSED 8 /* Compressed data */
285 #define AC_PKT_TERM_SERVER 9 /* Server kick */
289 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
290 #define method_const const
296 #define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__)
298 /****************************************************************************/
299 /* Oh Solaris how we hate thee! */
301 #define time(x) openconnect__time(x)
302 time_t openconnect__time(time_t *t);
304 #ifndef HAVE_ASPRINTF
305 #define asprintf openconnect__asprintf
306 int openconnect__asprintf(char **strp, const char *fmt, ...);
309 #define getline openconnect__getline
310 ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream);
313 /****************************************************************************/
316 int setup_tun(struct openconnect_info *vpninfo);
317 int tun_mainloop(struct openconnect_info *vpninfo, int *timeout);
318 void shutdown_tun(struct openconnect_info *vpninfo);
319 int script_config_tun (struct openconnect_info *vpninfo, const char *reason);
322 unsigned char unhex(const char *data);
323 int setup_dtls(struct openconnect_info *vpninfo);
324 int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
325 int dtls_try_handshake(struct openconnect_info *vpninfo);
326 int connect_dtls_socket(struct openconnect_info *vpninfo);
329 int make_cstp_connection(struct openconnect_info *vpninfo);
330 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout);
331 int cstp_bye(struct openconnect_info *vpninfo, const char *reason);
332 int cstp_reconnect(struct openconnect_info *vpninfo);
335 int connect_https_socket(struct openconnect_info *vpninfo);
336 int request_passphrase(struct openconnect_info *vpninfo,
337 char **response, const char *fmt, ...);
338 int __attribute__ ((format (printf, 2, 3)))
339 openconnect_SSL_printf(struct openconnect_info *vpninfo, const char *fmt, ...);
340 #if defined(OPENCONNECT_OPENSSL) || defined (DTLS_OPENSSL)
341 void openconnect_report_ssl_errors(struct openconnect_info *vpninfo);
344 /* ${SSL_LIBRARY}.c */
345 int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len);
346 int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len);
347 int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len);
348 int openconnect_open_https(struct openconnect_info *vpninfo);
349 void openconnect_close_https(struct openconnect_info *vpninfo, int final);
350 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo, OPENCONNECT_X509 *cert,
352 int openconnect_sha1(unsigned char *result, void *data, int len);
353 int openconnect_random(void *bytes, int len);
354 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
358 int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events);
359 int vpn_mainloop(struct openconnect_info *vpninfo);
360 int queue_new_packet(struct pkt **q, void *buf, int len);
361 void queue_packet(struct pkt **q, struct pkt *new);
362 int keepalive_action(struct keepalive_info *ka, int *timeout);
363 int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout);
368 int config_lookup_host(struct openconnect_info *vpninfo, const char *host);
371 int parse_xml_response(struct openconnect_info *vpninfo, char *response,
372 char *request_body, int req_len, const char **method,
373 const char **request_body_type);
376 char *openconnect_create_useragent(const char *base);
377 int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
378 int internal_parse_url(char *url, char **res_proto, char **res_host,
379 int *res_port, char **res_path, int default_port);
382 int set_openssl_ui(void);
385 int generate_securid_tokencodes(struct openconnect_info *vpninfo);
386 int add_securid_pin(char *token, char *pin);
389 extern const char *openconnect_version_str;
391 #endif /* __OPENCONNECT_INTERNAL_H__ */