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)
32 #include <openssl/ssl.h>
33 #elif defined (OPENCONNECT_GNUTLS)
34 #include <gnutls/gnutls.h>
35 #include <gnutls/x509.h>
40 #include <sys/socket.h>
41 #include <sys/select.h>
43 #include <sys/types.h>
53 #define _(s) dgettext("openconnect", s)
62 /****************************************************************************/
74 struct vpn_option *next;
80 #define KA_KEEPALIVE 3
83 struct keepalive_info {
93 struct split_include {
95 struct split_include *next;
98 #define RECONNECT_INTERVAL_MIN 10
99 #define RECONNECT_INTERVAL_MAX 100
101 #define CERT_TYPE_UNKNOWN 0
102 #define CERT_TYPE_PEM 1
103 #define CERT_TYPE_PKCS12 2
104 #define CERT_TYPE_TPM 3
106 struct openconnect_info {
116 char *csd_scriptname;
119 pxProxyFactory *proxy_factory;
125 const char *localname;
129 int cert_expire_warning;
135 const char *servercert;
136 const char *xmlconfig;
137 char xmlsha1[(SHA1_SIZE * 2) + 1];
146 int no_http_keepalive;
148 OPENCONNECT_X509 *peer_cert;
150 char *cookie; /* Pointer to within cookies list */
151 struct vpn_option *cookies;
152 struct vpn_option *cstp_options;
153 struct vpn_option *dtls_options;
155 #if defined(OPENCONNECT_OPENSSL)
159 #elif defined(OPENCONNECT_GNUTLS)
160 gnutls_session_t https_sess;
161 gnutls_certificate_credentials_t https_cred;
163 struct keepalive_info ssl_times;
164 int owe_ssl_dpd_response;
165 struct pkt *deflate_pkt;
166 struct pkt *current_ssl_pkt;
167 struct pkt *pending_deflated_pkt;
169 z_stream inflate_strm;
170 uint32_t inflate_adler32;
171 z_stream deflate_strm;
172 uint32_t deflate_adler32;
175 int reconnect_timeout;
176 int reconnect_interval;
177 int dtls_attempt_period;
178 time_t new_dtls_started;
179 #if defined(OPENCONNECT_OPENSSL)
183 SSL_SESSION *dtls_session;
184 #elif defined(OPENCONNECT_GNUTLS)
185 /* Call these *_ssl rather than *_sess because they're just
186 pointers, and generic code (in mainloop.c for example)
187 wants to check if they're NULL or not. No point in being
188 differently named to the OpenSSL variant, and forcing us to
189 have ifdefs or accessor macros for them. */
190 gnutls_session_t dtls_ssl;
191 gnutls_session_t new_dtls_ssl;
193 struct keepalive_info dtls_times;
194 unsigned char dtls_session_id[32];
195 unsigned char dtls_secret[48];
198 const char *vpnc_script;
204 const char *vpn_addr;
205 const char *vpn_netmask;
206 const char *vpn_addr6;
207 const char *vpn_netmask6;
208 const char *vpn_dns[3];
209 const char *vpn_nbns[3];
210 const char *vpn_domain;
211 const char *vpn_proxy_pac;
212 struct split_include *split_includes;
213 struct split_include *split_excludes;
230 struct pkt *incoming_queue;
231 struct pkt *outgoing_queue;
235 socklen_t peer_addrlen;
236 struct sockaddr *peer_addr;
237 struct sockaddr *dtls_addr;
242 const char *quit_reason;
245 openconnect_validate_peer_cert_vfn validate_peer_cert;
246 openconnect_write_new_config_vfn write_new_config;
247 openconnect_process_auth_form_vfn process_auth_form;
248 openconnect_progress_vfn progress;
251 #if (defined (OPENCONNECT_OPENSSL) && defined (SSL_OP_CISCO_ANYCONNECT)) || \
252 (defined(OPENCONNECT_GNUTLS) && defined (HAVE_GNUTLS_SESSION_SET_PREMASTER))
258 #define AC_PKT_DATA 0 /* Uncompressed data */
259 #define AC_PKT_DPD_OUT 3 /* Dead Peer Detection */
260 #define AC_PKT_DPD_RESP 4 /* DPD response */
261 #define AC_PKT_DISCONN 5 /* Client disconnection notice */
262 #define AC_PKT_KEEPALIVE 7 /* Keepalive */
263 #define AC_PKT_COMPRESSED 8 /* Compressed data */
264 #define AC_PKT_TERM_SERVER 9 /* Server kick */
267 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
268 #define method_const const
273 #define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__)
275 /****************************************************************************/
276 /* Oh Solaris how we hate thee! */
278 #define time(x) openconnect__time(x)
279 time_t openconnect__time(time_t *t);
281 #ifndef HAVE_ASPRINTF
282 #define asprintf openconnect__asprintf
283 int openconnect__asprintf(char **strp, const char *fmt, ...);
286 #define getline openconnect__getline
287 ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream);
290 /****************************************************************************/
293 int setup_tun(struct openconnect_info *vpninfo);
294 int tun_mainloop(struct openconnect_info *vpninfo, int *timeout);
295 void shutdown_tun(struct openconnect_info *vpninfo);
296 int script_config_tun (struct openconnect_info *vpninfo, const char *reason);
299 unsigned char unhex(const char *data);
300 int setup_dtls(struct openconnect_info *vpninfo);
301 int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
302 int dtls_try_handshake(struct openconnect_info *vpninfo);
303 int connect_dtls_socket(struct openconnect_info *vpninfo);
306 int make_cstp_connection(struct openconnect_info *vpninfo);
307 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout);
308 int cstp_bye(struct openconnect_info *vpninfo, const char *reason);
309 int cstp_reconnect(struct openconnect_info *vpninfo);
312 int connect_https_socket(struct openconnect_info *vpninfo);
313 int request_passphrase(struct openconnect_info *vpninfo,
314 char **response, const char *fmt, ...);
315 int __attribute__ ((format (printf, 2, 3)))
316 openconnect_SSL_printf(struct openconnect_info *vpninfo, const char *fmt, ...);
318 /* ${SSL_LIBRARY}.c */
319 int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len);
320 int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len);
321 int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len);
322 int openconnect_open_https(struct openconnect_info *vpninfo);
323 void openconnect_close_https(struct openconnect_info *vpninfo);
324 int get_cert_md5_fingerprint(struct openconnect_info *vpninfo, OPENCONNECT_X509 *cert,
326 /* This one is actually OpenSSL-specific */
327 void openconnect_report_ssl_errors(struct openconnect_info *vpninfo);
328 int openconnect_sha1(unsigned char *result, void *data, int len);
329 int openconnect_random(void *bytes, int len);
330 int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
334 int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events);
335 int vpn_mainloop(struct openconnect_info *vpninfo);
336 int queue_new_packet(struct pkt **q, void *buf, int len);
337 void queue_packet(struct pkt **q, struct pkt *new);
338 int keepalive_action(struct keepalive_info *ka, int *timeout);
339 int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout);
344 int config_lookup_host(struct openconnect_info *vpninfo, const char *host);
347 int parse_xml_response(struct openconnect_info *vpninfo, char *response,
348 char *request_body, int req_len, const char **method,
349 const char **request_body_type);
352 char *openconnect_create_useragent(const char *base);
353 int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
354 int internal_parse_url(char *url, char **res_proto, char **res_host,
355 int *res_port, char **res_path, int default_port);
358 int set_openssl_ui(void);
361 int generate_securid_tokencodes(struct openconnect_info *vpninfo);
362 int add_securid_pin(char *token, char *pin);
365 extern const char *openconnect_version_str;
367 #endif /* __OPENCONNECT_INTERNAL_H__ */