http: Record the last redirection type
[platform/upstream/openconnect.git] / openconnect-internal.h
1 /*
2  * OpenConnect (SSL + DTLS) VPN client
3  *
4  * Copyright © 2008-2012 Intel Corporation.
5  * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
6  *
7  * Author: David Woodhouse <dwmw2@infradead.org>
8  *
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.
12  *
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.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to:
20  *
21  *   Free Software Foundation, Inc.
22  *   51 Franklin Street, Fifth Floor,
23  *   Boston, MA 02110-1301 USA
24  */
25
26 #ifndef __OPENCONNECT_INTERNAL_H__
27 #define __OPENCONNECT_INTERNAL_H__
28
29 #include "openconnect.h"
30
31 #if defined (OPENCONNECT_OPENSSL) || defined(DTLS_OPENSSL)
32 #include <openssl/ssl.h>
33 #include <openssl/err.h>
34 /* Ick */
35 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
36 #define method_const const
37 #else
38 #define method_const
39 #endif
40 #endif /* OPENSSL */
41
42 #if defined (OPENCONNECT_GNUTLS)
43 #include <gnutls/gnutls.h>
44 #include <gnutls/abstract.h>
45 #include <gnutls/x509.h>
46 #ifdef HAVE_TROUSERS
47 #include <trousers/tss.h>
48 #include <trousers/trousers.h>
49 #endif
50 #endif
51
52 #include <zlib.h>
53 #include <stdint.h>
54 #include <sys/socket.h>
55 #include <sys/select.h>
56 #include <sys/time.h>
57 #include <sys/types.h>
58 #include <unistd.h>
59
60 #ifdef LIBPROXY_HDR
61 #include LIBPROXY_HDR
62 #endif
63
64 #ifdef LIBSTOKEN_HDR
65 #include LIBSTOKEN_HDR
66 #endif
67
68 #ifdef ENABLE_NLS
69 #include <locale.h>
70 #include <libintl.h>
71 #define _(s) dgettext("openconnect", s)
72 #else
73 #define _(s) s
74 #endif
75 #define N_(s) s
76
77 #include <libxml/tree.h>
78
79 #define SHA1_SIZE 20
80 #define MD5_SIZE 16
81
82 /****************************************************************************/
83
84 struct pkt {
85         int len;
86         struct pkt *next;
87         unsigned char hdr[8];
88         unsigned char data[];
89 };
90
91 struct vpn_option {
92         char *option;
93         char *value;
94         struct vpn_option *next;
95 };
96
97 #define KA_NONE         0
98 #define KA_DPD          1
99 #define KA_DPD_DEAD     2
100 #define KA_KEEPALIVE    3
101 #define KA_REKEY        4
102
103 struct keepalive_info {
104         int dpd;
105         int keepalive;
106         int rekey;
107         time_t last_rekey;
108         time_t last_tx;
109         time_t last_rx;
110         time_t last_dpd;
111 };
112
113 struct split_include {
114         char *route;
115         struct split_include *next;
116 };
117
118 struct pin_cache {
119         struct pin_cache *next;
120         char *token;
121         char *pin;
122 };
123
124 #define RECONNECT_INTERVAL_MIN  10
125 #define RECONNECT_INTERVAL_MAX  100
126
127 #define CERT_TYPE_UNKNOWN       0
128 #define CERT_TYPE_PEM           1
129 #define CERT_TYPE_PKCS12        2
130 #define CERT_TYPE_TPM           3
131
132 #define REDIR_TYPE_NONE         0
133 #define REDIR_TYPE_NEWHOST      1
134 #define REDIR_TYPE_LOCAL        2
135
136 struct openconnect_info {
137         char *redirect_url;
138         int redirect_type;
139
140         const char *csd_xmltag;
141         const char *platname;
142         char *csd_token;
143         char *csd_ticket;
144         char *csd_stuburl;
145         char *csd_starturl;
146         char *csd_waiturl;
147         char *csd_preurl;
148
149         char *csd_scriptname;
150         xmlNode *opaque_srvdata;
151
152 #ifdef LIBPROXY_HDR
153         pxProxyFactory *proxy_factory;
154 #endif
155         char *proxy_type;
156         char *proxy;
157         int proxy_port;
158
159         const char *localname;
160         char *hostname;
161         int port;
162         char *urlpath;
163         int cert_expire_warning;
164         const char *cert;
165         const char *sslkey;
166         int cert_type;
167         char *cert_password;
168         const char *cafile;
169         const char *servercert;
170         const char *xmlconfig;
171         char xmlsha1[(SHA1_SIZE * 2) + 1];
172         char *username;
173         char *password;
174         char *authgroup;
175         int nopasswd;
176         char *dtls_ciphers;
177         uid_t uid_csd;
178         char *csd_wrapper;
179         int uid_csd_given;
180         int no_http_keepalive;
181
182 #ifdef LIBSTOKEN_HDR
183         struct stoken_ctx *stoken_ctx;
184 #endif
185         int use_stoken;
186         int stoken_bypassed;
187         int stoken_tries;
188         time_t stoken_time;
189         char *stoken_pin;
190
191         OPENCONNECT_X509 *peer_cert;
192
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;
197
198 #if defined(OPENCONNECT_OPENSSL)
199         X509 *cert_x509;
200         SSL_CTX *https_ctx;
201         SSL *https_ssl;
202 #elif defined(OPENCONNECT_GNUTLS)
203         gnutls_session_t https_sess;
204         gnutls_certificate_credentials_t https_cred;
205         struct pin_cache *pin_cache;
206 #ifdef HAVE_TROUSERS
207         TSS_HCONTEXT tpm_context;
208         TSS_HKEY srk;
209         TSS_HPOLICY srk_policy;
210         TSS_HKEY tpm_key;
211         TSS_HPOLICY tpm_key_policy;
212 #endif
213 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
214 #ifdef HAVE_P11KIT
215         gnutls_pkcs11_privkey_t my_p11key;
216 #endif
217         gnutls_privkey_t my_pkey;
218         gnutls_x509_crt_t *my_certs;
219         unsigned int nr_my_certs;
220 #endif
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;
227
228         z_stream inflate_strm;
229         uint32_t inflate_adler32;
230         z_stream deflate_strm;
231         uint32_t deflate_adler32;
232
233         int disable_ipv6;
234         int reconnect_timeout;
235         int reconnect_interval;
236         int dtls_attempt_period;
237         time_t new_dtls_started;
238 #if defined(DTLS_OPENSSL)
239         SSL_CTX *dtls_ctx;
240         SSL *dtls_ssl;
241         SSL *new_dtls_ssl;
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;
251 #endif
252         struct keepalive_info dtls_times;
253         unsigned char dtls_session_id[32];
254         unsigned char dtls_secret[48];
255
256         char *dtls_cipher;
257         const char *vpnc_script;
258         int script_tun;
259         char *ifname;
260
261         int actual_mtu;
262         int reqmtu, basemtu;
263         const char *banner;
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;
275
276         int select_nfds;
277         fd_set select_rfds;
278         fd_set select_wfds;
279         fd_set select_efds;
280
281 #ifdef __sun__
282         int ip_fd;
283         int ip6_fd;
284 #endif
285         int tun_fd;
286         int ssl_fd;
287         int dtls_fd;
288         int new_dtls_fd;
289         int cancel_fd;
290
291         struct pkt *incoming_queue;
292         struct pkt *outgoing_queue;
293         int outgoing_qlen;
294         int max_qlen;
295
296         socklen_t peer_addrlen;
297         struct sockaddr *peer_addr;
298         struct sockaddr *dtls_addr;
299
300         int dtls_local_port;
301
302         int deflate;
303         char *useragent;
304
305         const char *quit_reason;
306
307         void *cbdata;
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;
312 };
313
314 #if (defined (DTLS_OPENSSL) && defined (SSL_OP_CISCO_ANYCONNECT)) || \
315     (defined (DTLS_GNUTLS) && defined (HAVE_GNUTLS_SESSION_SET_PREMASTER))
316 #define HAVE_DTLS 1
317 #endif
318
319 /* Packet types */
320
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 */
328
329 #define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__)
330
331 /****************************************************************************/
332 /* Oh Solaris how we hate thee! */
333 #ifdef __sun__
334 #define time(x) openconnect__time(x)
335 time_t openconnect__time(time_t *t);
336 #endif
337 #ifndef HAVE_ASPRINTF
338 #define asprintf openconnect__asprintf
339 int openconnect__asprintf(char **strp, const char *fmt, ...);
340 #endif
341 #ifndef HAVE_GETLINE
342 #define getline openconnect__getline
343 ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream);
344 #endif
345 #ifndef HAVE_STRCASESTR
346 #define strcasestr openconnect__strcasestr
347 char *openconnect__strcasestr(const char *haystack, const char *needle);
348 #endif
349
350 /****************************************************************************/
351
352 /* tun.c */
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);
357
358 /* dtls.c */
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);
364
365 /* cstp.c */
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);
370
371 /* ssl.c */
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
381 #endif
382 #ifdef ANDROID_KEYSTORE
383 char *keystore_strerror(int err);
384 int keystore_fetch(const char *key, unsigned char **result);
385 #endif
386
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,
394                              char *buf);
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,
398                                char *buf);
399
400 /* mainloop.c */
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);
407
408 extern int killed;
409
410 /* xml.c */
411 int config_lookup_host(struct openconnect_info *vpninfo, const char *host);
412
413 /* auth.c */
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);
421
422 /* http.c */
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);
427
428 /* ssl_ui.c */
429 int set_openssl_ui(void);
430
431 /* version.c */
432 extern const char *openconnect_version_str;
433
434 #endif /* __OPENCONNECT_INTERNAL_H__ */