1 /*
2  * OpenConnect (SSL + DTLS) VPN client
3  *
4  * Copyright © 2008-2016 Intel Corporation.
5  * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
6  * Copyright © 2013 John Morrissey <jwm@horde.net>
7  *
8  * Author: David Woodhouse <dwmw2@infradead.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * version 2.1, as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  */
19 
20 #ifndef __OPENCONNECT_H__
21 #define __OPENCONNECT_H__
22 
23 #include <stdint.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #ifdef _WIN32
32 #define uid_t unsigned
33 #endif
34 
35 #define OPENCONNECT_API_VERSION_MAJOR 5
36 #define OPENCONNECT_API_VERSION_MINOR 6
37 
38 /*
39  * API version 5.6 (v8.06; 2020-03-31):
40  *  - Add openconnect_set_trojan_interval()
41  *
42  * API version 5.5 (v8.00; 2019-01-05):
43  *  - add openconnect_set_version_string()
44  *  - add openconnect_set_key_password()
45  *  - Add openconnect_has_tss2_blob_support()
46  *  - Add openconnect_get_supported_protocols()
47  *  - Add openconnect_free_supported_protocols()
48  *  - Add openconnect_get_protocol()
49  *  - Add openconnect_get_idle_timeout()
50  *
51  * API version 5.4 (v7.08; 2016-12-13):
52  *  - Add openconnect_set_pass_tos()
53  *
54  * API version 5.3 (v7.07; 2016-07-11):
55  *  - Add openconnect_set_localname().
56  *  - Add openconnect_override_getaddrinfo().
57  *  - Add openconnect_get_cstp_compression().
58  *  - Add openconnect_get_dtls_compression().
59  *  - Add openconnect_disable_ipv6().
60  *  - Add ip_info->gateway_addr.
61  *  - Add openconnect_set_setup_tun_handler().
62  *  - Add openconnect_set_reconnected_handler().
63  *  - Add openconnect_get_dnsname().
64  *  - Add openconnect_get_peer_cert_chain() and
65  *        openconnect_free_peer_cert_chain().
66  *
67  * API version 5.2 (v7.05; 2015-03-10):
68  *  - Add openconnect_set_http_auth(), openconnect_set_protocol().
69  *
70  * API version 5.1 (v7.05; 2015-03-10):
71  *  - Add openconnect_set_compression_mode(), openconnect_set_loglevel()
72  *
73  *   (Note: API 5.1 and openconnect_set_compression_mode() were present in
74  *    this file in the v7.04 release on 2015-01-25, but the symbol versioning
75  *    for the new function was OPENCONNECT_5_0, and openconnect_set_loglevel()
76  *    was not yet present.)
77  *
78  * API version 5.0 (v7.00; 2014-11-27):
79  *  - Remove OPENCONNECT_X509 and openconnect_get_peer_cert().
80  *  - Change openconnect_get_cert_der() to openconnect_get_peer_cert_DER() etc.
81  *  - Add openconnect_check_peer_cert_hash().
82  *  - Remove openconnect_set_server_cert_sha1().
83  *  - Add openconnect_has_yubioath_support() and OC_TOKEN_MODE_YUBIOATH.
84  *  - Add openconnect_has_system_key_support().
85  *
86  * API version 4.1 (v7.00; 2014-11-27):
87  *  - Add openconnect_get_cstp_cipher(), openconnect_get_dtls_cipher(),
88  *    openconnect_set_system_trust(), openconnect_set_csd_environ().
89  *  - Change openconnect_init_ssl() to return int.
90  *
91  * API version 4.0 (v7.00; 2014-11-27):
92  *  - Change string handling to never transfer ownership of allocations.
93  *  - Add openconnect_set_option_value(), openconnect_free_cert_info().
94  *
95  * API version 3.4 (v7.00; 2014-11-27):
96  *  - Add openconnect_set_token_callbacks()
97  *
98  * API version 3.3 (v6.00; 2014-07-08):
99  *  - Add openconnect_set_pfs(), openconnect_set_dpd(),
100  *    openconnect_set_proxy_auth()
101  *
102  * API version 3.2 (v5.99; 2014-03-05):
103  *  - Add OC_TOKEN_MODE_HOTP and allow openconnect_has_oath_support() to
104  *    return 2 to indicate that it is present.
105  *
106  * API version 3.1 (v5.99; 2014-03-05):
107  *  - Add openconnect_setup_cmd_pipe(), openconnect_mainloop(),
108  *    openconnect_setup_tun_device(), openconnect_setup_tun_script(),
109  *    openconnect_setup_tun_fd(), openconnect_setup_dtls(),
110  *    openconnect_make_cstp_connection(), openconnect_set_server_cert_sha1(),
111  *    openconnect_get_ifname(), openconnect_set_reqmtu(),
112  *    openconnect_get_ip_info(), openconnect_set_protect_socket_handler(),
113  *    openconnect_set_mobile_info(), openconnect_set_xmlpost(),
114  *    openconnect_set_stats_handler()
115  *
116  * API version 3.0 (v5.99; 2014-03-05):
117  *  - Change oc_form_opt_select->choices to an array of pointers
118  *  - Add oc_form_opt->flags
119  *  - Add OC_FORM_RESULT_* and oc_auth_form->authgroup_*
120  *
121  * API version 2.2 (v5.00; 2013-05-16):
122  *  - Add openconnect_set_token_mode(), openconnect_has_oath_support()
123  *  - Deprecate openconnect_set_stoken_mode()
124  *
125  * API version 2.1 (v4.99; 2013-02-07):
126  *  - Add openconnect_set_reported_os()
127  *  - Add openconnect_set_stoken_mode(), openconnect_has_stoken_support()
128  *
129  * API version 2.0 (v3.99; 2012-06-13):
130  *  - OPENCONNECT_X509 is now an opaque type.
131  *  - Add openconnect_has_pkcs11_support(), openconnect_has_tss_blob_support()
132  *  - Rename openconnect_init_openssl() -> openconnect_init_ssl()
133  *  - Rename openconnect_vpninfo_new_with_cbdata() -> openconnect_vpninfo_new()
134  *    and kill the old openconnect_vpninfo_new() and its callback types.
135  *
136  * API version 1.5 (v3.99; 2012-06-13):
137  *  - Add openconnect_get_cert_details(), openconnect_get_cert_DER().
138  *
139  * API version 1.4 (v3.19; 2012-05-17):
140  *  - Add openconnect_set_cancel_fd()
141  *
142  * API version 1.3 (v3.13; 2011-09-30):
143  *  - Add openconnect_set_cert_expiry_warning() to change from default 60 days
144  *
145  * API version 1.2 (v3.10; 2011-06-30)
146  *  - Add openconnect_vpninfo_new_with_cbdata()
147  *
148  * API version 1.1 (v3.02; 2011-04-19):
149  *  - Add openconnect_vpninfo_free()
150  *
151  * API version 1.0 (v3.00; 2011-03-09):
152  *  - Initial version
153  *
154  * NEW LIBRARY FUNCTION CHECKLIST:
155  *
156  * 1) Bump the API version if the current API version has already appeared
157  *    in a release
158  * 2) Add function to the above changelog
159  * 3) Add function to libopenconnect.map.in
160  * 4) Add declaration + comments in the latter part of this file
161  * 5) Add function to jni.c, then test with ./configure --with-java && make
162  * 6) Add declaration to LibOpenConnect.java, then run "cd java && ant" to test
163  */
164 
165 /* Before API version 1.4 (OpenConnect 3.19) this macro didn't exist.
166  * Somewhat ironic, that the API version check itself needs to be
167  * conditionally used depending on the API version. A very simple way
168  * for users to handle this with an approximately correct answer is
169  *   #include <openconnect.h>
170  *   #ifndef OPENCONNECT_CHECK_VER
171  *   #define OPENCONNECT_CHECK_VER(x,y) 0
172  *   #endif
173  */
174 #define OPENCONNECT_CHECK_VER(maj, min) \
175 	(OPENCONNECT_API_VERSION_MAJOR > (maj) || \
176 	(OPENCONNECT_API_VERSION_MAJOR == (maj) && \
177 	 OPENCONNECT_API_VERSION_MINOR >= (min)))
178 
179 /****************************************************************************/
180 
181 /* Enumeration of supported VPN protocols */
182 
183 #define OC_PROTO_PROXY	(1<<0)
184 #define OC_PROTO_CSD	(1<<1)
185 #define OC_PROTO_AUTH_CERT	(1<<2)
186 #define OC_PROTO_AUTH_OTP	(1<<3)
187 #define OC_PROTO_AUTH_STOKEN	(1<<4)
188 #define OC_PROTO_PERIODIC_TROJAN	(1<<4)
189 
190 struct oc_vpn_proto {
191 	const char *name;
192 	const char *pretty_name;
193 	const char *description;
194 	unsigned int flags;
195 };
196 
197 /****************************************************************************/
198 
199 /* Authentication form processing */
200 
201 #define OC_FORM_OPT_TEXT	1
202 #define OC_FORM_OPT_PASSWORD	2
203 #define OC_FORM_OPT_SELECT	3
204 #define OC_FORM_OPT_HIDDEN	4
205 #define OC_FORM_OPT_TOKEN	5
206 
207 #define OC_FORM_RESULT_ERR		-1
208 #define OC_FORM_RESULT_OK		0
209 #define OC_FORM_RESULT_CANCELLED	1
210 #define OC_FORM_RESULT_NEWGROUP		2
211 
212 #ifdef __OPENCONNECT_PRIVATE__
213 #define OC_FORM_RESULT_LOGGEDIN		255
214 
215 #define OC_FORM_OPT_SECOND_AUTH		0x8000
216 #endif
217 
218 #define OC_FORM_OPT_IGNORE		0x0001
219 #define OC_FORM_OPT_NUMERIC		0x0002
220 
221 /* char * fields are static (owned by XML parser) and don't need to be
222    freed by the form handling code — except for value, which for TEXT
223    and PASSWORD options is allocated by openconnect_set_option_value()
224    when process_form() interacts with the user and must be freed. */
225 struct oc_form_opt {
226 	struct oc_form_opt *next;
227 	int type;
228 	char *name;
229 	char *label;
230 	char *_value; /* Use openconnect_set_option_value() to set this */
231 	unsigned int flags;
232 	void *reserved;
233 };
234 
235 /* To set the value to a form use the following function */
236 int openconnect_set_option_value(struct oc_form_opt *opt, const char *value);
237 
238 /* All fields are static, owned by the XML parser */
239 struct oc_choice {
240 	char *name;
241 	char *label;
242 	char *auth_type;
243 	char *override_name;
244 	char *override_label;
245 #ifdef __OPENCONNECT_PRIVATE__
246 	int second_auth;
247 	char *secondary_username;
248 	int secondary_username_editable;
249 	int noaaa;
250 #endif
251 };
252 
253 struct oc_form_opt_select {
254 	struct oc_form_opt form;
255 	int nr_choices;
256 	struct oc_choice **choices;
257 };
258 
259 /* All char * fields are static, owned by the XML parser */
260 struct oc_auth_form {
261 	char *banner;
262 	char *message;
263 	char *error;
264 	char *auth_id;
265 	char *method;
266 	char *action;
267 	struct oc_form_opt *opts;
268 	struct oc_form_opt_select *authgroup_opt;
269 	int authgroup_selection;
270 };
271 
272 struct oc_split_include {
273 	const char *route;
274 	struct oc_split_include *next;
275 };
276 
277 struct oc_ip_info {
278 	const char *addr;
279 	const char *netmask;
280 	const char *addr6;
281 	const char *netmask6;
282 	const char *dns[3];
283 	const char *nbns[3];
284 	const char *domain;
285 	const char *proxy_pac;
286 	int mtu;
287 
288 	struct oc_split_include *split_dns;
289 	struct oc_split_include *split_includes;
290 	struct oc_split_include *split_excludes;
291 
292 	/* The elements above this line come from server-provided CSTP headers,
293 	 * so they should be handled with caution.  gateway_addr is generated
294 	 * locally from getnameinfo(). */
295 	char *gateway_addr;
296 };
297 
298 struct oc_vpn_option {
299 	char *option;
300 	char *value;
301 	struct oc_vpn_option *next;
302 };
303 
304 struct oc_stats {
305 	uint64_t tx_pkts;
306 	uint64_t tx_bytes;
307 	uint64_t rx_pkts;
308 	uint64_t rx_bytes;
309 };
310 
311 struct oc_cert {
312 	int der_len;
313 	unsigned char *der_data;
314 	void *reserved;
315 };
316 
317 /****************************************************************************/
318 
319 #define PRG_ERR		0
320 #define PRG_INFO	1
321 #define PRG_DEBUG	2
322 #define PRG_TRACE	3
323 
324 /* Byte commands to write into the cmd_fd:
325  *
326  *  CANCEL closes network connections, logs off the session (cookie)
327  *    and shuts down the tun device.
328  *  PAUSE closes network connections and returns. The caller is expected
329  *    to call openconnect_mainloop() again soon.
330  *  DETACH closes network connections and shuts down the tun device.
331  *    It is not legal to call openconnect_mainloop() again after this,
332  *    but a new instance of openconnect can be started using the same
333  *    cookie.
334  *  STATS calls the stats_handler.
335  */
336 #define OC_CMD_CANCEL		'x'
337 #define OC_CMD_PAUSE		'p'
338 #define OC_CMD_DETACH		'd'
339 #define OC_CMD_STATS		's'
340 
341 #define RECONNECT_INTERVAL_MIN	10
342 #define RECONNECT_INTERVAL_MAX	100
343 
344 struct openconnect_info;
345 
346 typedef enum {
347 	OC_TOKEN_MODE_NONE,
348 	OC_TOKEN_MODE_STOKEN,
349 	OC_TOKEN_MODE_TOTP,
350 	OC_TOKEN_MODE_HOTP,
351 	OC_TOKEN_MODE_YUBIOATH,
352 	OC_TOKEN_MODE_OIDC,
353 } oc_token_mode_t;
354 
355 typedef enum {
356 	OC_COMPRESSION_MODE_NONE,
357 	OC_COMPRESSION_MODE_STATELESS,
358 	OC_COMPRESSION_MODE_ALL,
359 } oc_compression_mode_t;
360 
361 /* All strings are UTF-8. If operating in a legacy environment where
362    nl_langinfo(CODESET) returns anything other than UTF-8, or on Windows,
363    the library will take appropriate steps to convert back to the legacy
364    character set (or UTF-16) for file handling and wherever else it is
365    appropriate to do so. Library functions may (but probably don't yet)
366    return -EILSEQ if passed invalid UTF-8 strings. */
367 
368 /* Unlike previous versions of openconnect, no functions will take ownership
369    of the provided strings. */
370 
371 
372 /* Provide environment variables to be set in the CSD trojan environment
373    before spawning it. Some callers may need to set $TMPDIR, $PATH and
374    other such things if not running from a standard UNIX-like environment.
375    To ensure that a variable is unset, pass its name with value==NULL.
376    To clear all settings and allow the CSD trojan to inherit an unmodified
377    environment, call with name==NULL. */
378 
379 int openconnect_set_csd_environ(struct openconnect_info *vpninfo,
380 				const char *name, const char *value);
381 
382 /* This string is static, valid only while the connection lasts. If you
383  * are going to cache this to remember which certs the user has accepted,
384  * make sure you also store the host/port for which it was accepted and
385  * don't just accept this cert from *anywhere*. Also use use the check
386  * function below instead of manually comparing. When this function
387  * returns a string which *doesn't* match the previously-stored hash
388  * matched with openconnect_check_peer_cert_hash(), you should store
389  * the new result from this function in place of the old. It means
390  * we have upgraded to a better hash function. */
391 const char *openconnect_get_peer_cert_hash(struct openconnect_info *vpninfo);
392 
393 /* Check if the current peer certificate matches a hash previously
394  * obtained from openconect_get_peer_cert_hash(). Clients should not
395  * attempt to do this using strcmp() and the *current* result of
396  * openconnect_get_peer_cert_hash() because it might use
397  * a different hash function today. This function will get it right.
398  * Returns 0 on match; 1 on mismatch, -errno on failure. */
399 int openconnect_check_peer_cert_hash(struct openconnect_info *vpninfo,
400 				     const char *old_hash);
401 
402 /* The buffers returned by these two functions must be freed with
403    openconnect_free_cert_info(), especially on Windows. */
404 char *openconnect_get_peer_cert_details(struct openconnect_info *vpninfo);
405 
406 /* Returns the length of the created DER output, in a newly-allocated buffer
407    that will need to be freed by openconnect_free_cert_info(). */
408 int openconnect_get_peer_cert_DER(struct openconnect_info *vpninfo,
409 				  unsigned char **buf);
410 void openconnect_free_cert_info(struct openconnect_info *vpninfo,
411 				void *buf);
412 
413 /* Creates a list of all certs in the peer's chain, returning the
414    number of certs in the chain (or <0 on error). Only valid inside the
415    validate_peer_cert callback. The caller should free the chain,
416    but should not modify the contents. */
417 int openconnect_get_peer_cert_chain(struct openconnect_info *vpninfo,
418 				    struct oc_cert **chain);
419 void openconnect_free_peer_cert_chain(struct openconnect_info *vpninfo,
420 				      struct oc_cert *chain);
421 
422 /* Contains a comma-separated list of authentication methods to enabled.
423    Currently supported: Negotiate,NTLM,Digest,Basic */
424 int openconnect_set_http_auth(struct openconnect_info *vpninfo,
425 			      const char *methods);
426 int openconnect_set_proxy_auth(struct openconnect_info *vpninfo,
427 			       const char *methods);
428 int openconnect_set_http_proxy(struct openconnect_info *vpninfo,
429 			       const char *proxy);
430 int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo);
431 int openconnect_obtain_cookie(struct openconnect_info *vpninfo);
432 int openconnect_init_ssl(void);
433 
434 /* These are strictly cosmetic. The strings differ depending on
435  * whether OpenSSL or GnuTLS is being used. And even depending on the
436  * version of GnuTLS. Do *not* attempt to do anything meaningful based
437  * on matching these strings; if you want to do something like that then
438  * ask for an API that *does* offer you what you need. */
439 const char *openconnect_get_cstp_cipher(struct openconnect_info *);
440 const char *openconnect_get_dtls_cipher(struct openconnect_info *);
441 
442 /* These return a descriptive string of the compression algorithm
443  * in use (LZS, LZ4, ...). If no compression then NULL is returned. */
444 const char *openconnect_get_cstp_compression(struct openconnect_info *);
445 const char *openconnect_get_dtls_compression(struct openconnect_info *);
446 
447 /* Returns the IP address of the exact host to which the connection
448  * was made. In --cookieonly mode or in any other scenario involving
449  * a "two stage" connection, it is important to reconnect by IP because
450  * the server side may be using DNS trickery for load balancing.
451  *
452  * If the IP address is unavailable due to the use of a proxy, this will
453  * fall back to returning the DNS name. */
454 const char *openconnect_get_hostname(struct openconnect_info *);
455 
456 /* Returns the hostname parsed out of the server name URL. This is
457  * intended to be used by the validate_peer_cert callback to check that
458  * the certificate matches the server name. */
459 const char *openconnect_get_dnsname(struct openconnect_info *);
460 
461 int openconnect_set_hostname(struct openconnect_info *, const char *);
462 char *openconnect_get_urlpath(struct openconnect_info *);
463 int openconnect_set_urlpath(struct openconnect_info *, const char *);
464 int openconnect_set_localname(struct openconnect_info *, const char *);
465 
466 /* Some software tokens, such as HOTP tokens, include a counter which
467  * needs to be stored in persistent storage.
468  *
469  * For such tokens, the lock function is first invoked to obtain a lock
470  * on the storage because we're about to generate a new code. It is
471  * permitted to call openconnect_set_token_mode() from the lock function,
472  * if the token storage has been updated since it was first loaded. The
473  * token mode must not change; only the token secret.
474  *
475  * The unlock function is called when a token code has been generated,
476  * with a new token secret to be written to the persistent storage. The
477  * secret will be in the same format as it was originally received by
478  * openconnect_set_token_mode(). The new token may be NULL if an error
479  * was encountered generating the code, in which case it is only
480  * necessary for the callback function to unlock the storage.
481  */
482 typedef int (*openconnect_lock_token_vfn)(void *tokdata);
483 typedef int (*openconnect_unlock_token_vfn)(void *tokdata, const char *new_tok);
484 int openconnect_set_token_callbacks(struct openconnect_info *, void *tokdata,
485 				    openconnect_lock_token_vfn,
486 				    openconnect_unlock_token_vfn);
487 
488 int openconnect_set_token_mode(struct openconnect_info *,
489 			       oc_token_mode_t, const char *token_str);
490 /* Legacy stoken-only function; do not use */
491 int openconnect_set_stoken_mode(struct openconnect_info *, int, const char *);
492 
493 int openconnect_set_compression_mode(struct openconnect_info *,
494 				     oc_compression_mode_t);
495 
496 /* The size must be 41 bytes, since that's the size of a 20-byte SHA1
497    represented as hex with a trailing NUL. */
498 void openconnect_set_xmlsha1(struct openconnect_info *, const char *, int size);
499 
500 int openconnect_set_cafile(struct openconnect_info *, const char *);
501 
502 /* call this function to disable the system trust from being used to
503  * verify the server certificate. @val is a boolean value.
504  *
505  * For backwards compatibility reasons this is enabled by default.
506  */
507 void openconnect_set_system_trust(struct openconnect_info *vpninfo, unsigned val);
508 
509 int openconnect_setup_csd(struct openconnect_info *, uid_t, int silent, const char *wrapper);
510 void openconnect_set_xmlpost(struct openconnect_info *, int enable);
511 
512 /* Valid choices are: "linux", "linux-64", "win", "mac-intel",
513    "android", and "apple-ios". This also selects the corresponding CSD
514    trojan binary. */
515 int openconnect_set_reported_os(struct openconnect_info *, const char *os);
516 
517 int openconnect_set_version_string(struct openconnect_info *vpninfo,
518 				   const char *version_string);
519 int openconnect_set_mobile_info(struct openconnect_info *vpninfo,
520 				const char *mobile_platform_version,
521 				const char *mobile_device_type,
522 				const char *mobile_device_uniqueid);
523 int openconnect_set_client_cert(struct openconnect_info *, const char *cert,
524 				const char *sslkey);
525 int openconnect_set_key_password(struct openconnect_info *vpninfo, const char *pass);
526 const char *openconnect_get_ifname(struct openconnect_info *);
527 void openconnect_set_reqmtu(struct openconnect_info *, int reqmtu);
528 void openconnect_set_dpd(struct openconnect_info *, int min_seconds);
529 void openconnect_set_trojan_interval(struct openconnect_info *, int seconds);
530 int openconnect_get_idle_timeout(struct openconnect_info *);
531 
532 /* The returned structures are owned by the library and may be freed/replaced
533    due to rekey or reconnect. Assume that once the mainloop starts, the
534    pointers are no longer valid. For similar reasons, it is unsafe to call
535    this function from another thread. */
536 int openconnect_get_ip_info(struct openconnect_info *,
537 			    const struct oc_ip_info **info,
538 			    const struct oc_vpn_option **cstp_options,
539 			    const struct oc_vpn_option **dtls_options);
540 
541 int openconnect_get_port(struct openconnect_info *);
542 const char *openconnect_get_cookie(struct openconnect_info *);
543 void openconnect_clear_cookie(struct openconnect_info *);
544 
545 void openconnect_disable_ipv6(struct openconnect_info *vpninfo);
546 void openconnect_reset_ssl(struct openconnect_info *vpninfo);
547 int openconnect_parse_url(struct openconnect_info *vpninfo, const char *url);
548 void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo,
549 					 int seconds);
550 void openconnect_set_pfs(struct openconnect_info *vpninfo, unsigned val);
551 
552 /* If this is set, then openconnect_obtain_cookie() will abort and return
553    failure if the file descriptor is readable. Typically a user may create
554    a pair of pipes with the pipe(2) system call, hand the readable one to
555    this function, and then write a byte to the other end if it ever wants
556    to cancel the connection. This way, a multi-threaded UI (which will be
557    running openconnect_obtain_cookie() in a separate thread since it blocks)
558    has the ability to cancel that call, reap its thread and free the
559    vpninfo structure (or retry). An 'fd' argument of -1 will render the
560    cancellation mechanism inactive. */
561 void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd);
562 
563 /* Create a nonblocking pipe used to send cancellations and other commands
564    to the library. This returns a file descriptor to the write side of
565    the pipe. Both sides will be closed by openconnect_vpninfo_free().
566    This replaces openconnect_set_cancel_fd(). */
567 #ifdef _WIN32
568 SOCKET
569 #else
570 int
571 #endif
572 openconnect_setup_cmd_pipe(struct openconnect_info *vpninfo);
573 
574 const char *openconnect_get_version(void);
575 
576 /* Open CSTP connection; on success, IP information will be available. */
577 int openconnect_make_cstp_connection(struct openconnect_info *vpninfo);
578 
579 /* Create a tun device through the OS kernel (typical use case). Both
580    strings are optional and can be NULL if desired. */
581 int openconnect_setup_tun_device(struct openconnect_info *vpninfo,
582 				 const char *vpnc_script, const char *ifname);
583 
584 /* Pass traffic to a script program (no tun device). */
585 int openconnect_setup_tun_script(struct openconnect_info *vpninfo,
586 				 const char *tun_script);
587 
588 #ifdef _WIN32
589 /* Caller will provide an overlap-capable handle for the tunnel traffic. */
590 int openconnect_setup_tun_fd(struct openconnect_info *vpninfo, intptr_t tun_fd);
591 #else
592 /* Caller will provide a file descriptor for the tunnel traffic. */
593 int openconnect_setup_tun_fd(struct openconnect_info *vpninfo, int tun_fd);
594 #endif
595 /* Optional call to enable DTLS on the connection. */
596 int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_period);
597 
598 /* Start the main loop; exits if OC_CMD_CANCEL is received on cmd_fd or
599    the remote site aborts. */
600 int openconnect_mainloop(struct openconnect_info *vpninfo,
601 			 int reconnect_timeout,
602 			 int reconnect_interval);
603 
604 /* The first (privdata) argument to each of these functions is either
605    the privdata argument provided to openconnect_vpninfo_new_with_cbdata(),
606    or if that argument was NULL then it'll be the vpninfo itself. */
607 
608 /* When the server's certificate fails validation via the normal means,
609    this function is called with the offending certificate along with
610    a textual reason for the failure (which may not be translated, if
611    it comes directly from OpenSSL, but will be if it is rejected for
612    "certificate does not match hostname", because that check is done
613    in OpenConnect and *is* translated). The function shall return zero
614    if the certificate is (or has in the past been) explicitly accepted
615    by the user, and non-zero to abort the connection. */
616 typedef int (*openconnect_validate_peer_cert_vfn) (void *privdata,
617 						   const char *reason);
618 /* On a successful connection, the server may provide us with a new XML
619    configuration file. This contains the list of servers that can be
620    chosen by the user to connect to, amongst other stuff that we mostly
621    ignore. By "new", we mean that the SHA1 indicated by the server does
622    not match the SHA1 set with the openconnect_set_xmlsha1() above. If
623    they don't match, or openconnect_set_xmlsha1() has not been called,
624    then the new XML is downloaded and this function is invoked. */
625 typedef int (*openconnect_write_new_config_vfn) (void *privdata, const char *buf,
626 						int buflen);
627 /* Handle an authentication form, requesting input from the user.
628  * Return value:
629  *  < 0, on error
630  *  = 0, when form was parsed and POST required
631  *  = 1, when response was cancelled by user
632  */
633 typedef int (*openconnect_process_auth_form_vfn) (void *privdata,
634 						 struct oc_auth_form *form);
635 /* Logging output which the user *may* want to see. */
636 typedef void __attribute__ ((format(printf, 3, 4)))
637 		(*openconnect_progress_vfn) (void *privdata, int level,
638 					    const char *fmt, ...);
639 struct openconnect_info *openconnect_vpninfo_new(const char *useragent,
640 						 openconnect_validate_peer_cert_vfn,
641 						 openconnect_write_new_config_vfn,
642 						 openconnect_process_auth_form_vfn,
643 						 openconnect_progress_vfn,
644 						 void *privdata);
645 void openconnect_vpninfo_free(struct openconnect_info *vpninfo);
646 
647 /* Callback to allow binding a newly created socket's file descriptor to
648    a specific interface, e.g. with SO_BINDTODEVICE. This tells the kernel
649    not to route the traffic in question over the VPN tunnel. */
650 typedef void (*openconnect_protect_socket_vfn) (void *privdata, int fd);
651 void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo,
652 					    openconnect_protect_socket_vfn protect_socket);
653 
654 void openconnect_set_loglevel(struct openconnect_info *vpninfo, int level);
655 
656 void openconnect_set_pass_tos(struct openconnect_info *vpninfo, int enable);
657 
658 /* Callback for obtaining traffic stats via OC_CMD_STATS.
659  */
660 typedef void (*openconnect_stats_vfn) (void *privdata, const struct oc_stats *stats);
661 void openconnect_set_stats_handler(struct openconnect_info *vpninfo,
662 				   openconnect_stats_vfn stats_handler);
663 
664 /* SSL certificate capabilities. openconnect_has_pkcs11_support() means that we
665    can accept PKCS#11 URLs in place of filenames, for the certificate and key. */
666 int openconnect_has_pkcs11_support(void);
667 
668 /* The OpenSSL TPM ENGINE stores keys in a PEM file labelled with the string
669    -----BEGIN TSS KEY BLOB-----. */
670 int openconnect_has_tss_blob_support(void);
671 int openconnect_has_tss2_blob_support(void);
672 
673 /* Software token capabilities. */
674 int openconnect_has_stoken_support(void);
675 int openconnect_has_oath_support(void);
676 int openconnect_has_yubioath_support(void);
677 int openconnect_has_system_key_support(void);
678 
679 /* Query and select from among supported protocols */
680 int openconnect_get_supported_protocols(struct oc_vpn_proto **protos);
681 void openconnect_free_supported_protocols(struct oc_vpn_proto *protos);
682 const char *openconnect_get_protocol(struct openconnect_info *vpninfo);
683 int openconnect_set_protocol(struct openconnect_info *vpninfo, const char *protocol);
684 
685 struct addrinfo;
686 typedef int (*openconnect_getaddrinfo_vfn) (void *privdata, const char *node, const char *service,
687 					    const struct addrinfo *hints, struct addrinfo **res);
688 void openconnect_override_getaddrinfo(struct openconnect_info *vpninfo, openconnect_getaddrinfo_vfn gai_fn);
689 
690 /* Callback for configuring the interface after MTU detection finishes. */
691 typedef void (*openconnect_setup_tun_vfn) (void *privdata);
692 void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo,
693 				       openconnect_setup_tun_vfn setup_tun);
694 
695 /* Callback for indicating that a TCP reconnection succeeded. */
696 typedef void (*openconnect_reconnected_vfn) (void *privdata);
697 void openconnect_set_reconnected_handler(struct openconnect_info *vpninfo,
698 				         openconnect_reconnected_vfn reconnected_fn);
699 
700 #ifdef __cplusplus
701 }
702 #endif
703 
704 #endif /* __OPENCONNECT_H__ */
705