From 40802e459873e55eefbe64f05b9475821f761b8e Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Wed, 19 Apr 2017 13:12:48 -0700 Subject: [PATCH] enumerate supported VPN protocols via openconnect_get_supported_protocols() Add two new public functions: * int openconnect_get_supported_protocols(struct oc_vpn_proto **protos) Fetches a list of protocols supported by the client. Each supported protocol has a short name (as accepted by the --protocol command-line option), pretty name, longer description, and list of flags. The return value of the function is the number of protocols supported (or negative if an error occurred). The flags indicate features that are meaningful for this protocol, to be used by tools like the Networkmanager configuration UI. Current flags: * OC_PROTO_PROXY: can connect via HTTP or SOCKS proxy * OC_PROTO_CSD: supports verification of the client via CSD trojan * OC_PROTO_AUTH_CERT: supports authentication by client certificate * OC_PROTO_AUTH_OTP: supports authentication by OATH HOTP/TOTP token * OC_PROTO_AUTH_STOKEN: supports authentication by RSA SecurID token (stoken) * void openconnect_free_supported_protocols(struct oc_vpn_proto *protos) Frees the list of protocols fetched by openconnect_get_supported_protocols() The description of the "anyconnect" protocol matches the IETF draft standard for openconnect VPN (https://tools.ietf.org/html/draft-mavrogiannopoulos-openconnect-00). Signed-off-by: Daniel Lenski Signed-off-by: David Woodhouse --- libopenconnect.map.in | 6 ++++++ library.c | 29 +++++++++++++++++++++++++++++ openconnect-internal.h | 3 +++ openconnect.h | 26 +++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 44eea34a..04b8ed5b 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -92,6 +92,12 @@ OPENCONNECT_5_4 { openconnect_set_pass_tos; } OPENCONNECT_5_3; +OPENCONNECT_5_5 { + global: + openconnect_get_supported_protocols; + openconnect_free_supported_protocols; +} OPENCONNECT_5_4; + OPENCONNECT_PRIVATE { global: @SYMVER_TIME@ @SYMVER_GETLINE@ @SYMVER_JAVA@ @SYMVER_ASPRINTF@ @SYMVER_VASPRINTF@ @SYMVER_WIN32_STRERROR@ openconnect_fopen_utf8; diff --git a/library.c b/library.c index 824338e1..59217a9e 100644 --- a/library.c +++ b/library.c @@ -109,6 +109,9 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent, const struct vpn_proto openconnect_protos[] = { { .name = "anyconnect", + .pretty_name = N_("Cisco AnyConnect or openconnect"), + .description = N_("Compatible with Cisco AnyConnect SSL VPN, as well as ocserv"), + .flags = OC_PROTO_PROXY | OC_PROTO_CSD | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_AUTH_STOKEN, .vpn_close_session = cstp_bye, .tcp_connect = cstp_connect, .tcp_mainloop = cstp_mainloop, @@ -122,6 +125,9 @@ const struct vpn_proto openconnect_protos[] = { #endif }, { .name = "nc", + .pretty_name = N_("Juniper Network Connect"), + .description = N_("Compatible with Juniper Network Connect / Pulse Secure SSL VPN"), + .flags = OC_PROTO_PROXY | OC_PROTO_CSD | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP, .vpn_close_session = NULL, .tcp_connect = oncp_connect, .tcp_mainloop = oncp_mainloop, @@ -137,6 +143,29 @@ const struct vpn_proto openconnect_protos[] = { { /* NULL */ } }; +int openconnect_get_supported_protocols(struct oc_vpn_proto **protos) +{ + struct oc_vpn_proto *pr; + const struct vpn_proto *p; + + *protos = pr = calloc(sizeof(openconnect_protos)/sizeof(*openconnect_protos), sizeof(*pr)); + if (!pr) + return -ENOMEM; + + for (p = openconnect_protos; p->name; p++, pr++) { + pr->name = p->name; + pr->pretty_name = p->pretty_name; + pr->description = p->description; + pr->flags = p->flags; + } + return (p - openconnect_protos); +} + +void openconnect_free_supported_protocols(struct oc_vpn_proto *protos) +{ + free((void *)protos); +} + int openconnect_set_protocol(struct openconnect_info *vpninfo, const char *protocol) { const struct vpn_proto *p; diff --git a/openconnect-internal.h b/openconnect-internal.h index a24a9e48..0e87268f 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -254,6 +254,9 @@ struct http_auth_state { struct vpn_proto { const char *name; + const char *pretty_name; + const char *description; + unsigned int flags; int (*vpn_close_session)(struct openconnect_info *vpninfo, const char *reason); /* This does the full authentication, calling back as appropriate */ diff --git a/openconnect.h b/openconnect.h index fc23c3ca..e97dacbc 100644 --- a/openconnect.h +++ b/openconnect.h @@ -33,9 +33,13 @@ extern "C" { #endif #define OPENCONNECT_API_VERSION_MAJOR 5 -#define OPENCONNECT_API_VERSION_MINOR 4 +#define OPENCONNECT_API_VERSION_MINOR 5 /* + * API version 5.5: + * - Add openconnect_get_supported_protocols() + * - Add openconnect_free_supported_protocols() + * * API version 5.4 (v7.08; 2016-12-13): * - Add openconnect_set_pass_tos() * @@ -166,6 +170,23 @@ extern "C" { /****************************************************************************/ +/* Enumeration of supported VPN protocols */ + +#define OC_PROTO_PROXY (1<<0) +#define OC_PROTO_CSD (1<<1) +#define OC_PROTO_AUTH_CERT (1<<2) +#define OC_PROTO_AUTH_OTP (1<<3) +#define OC_PROTO_AUTH_STOKEN (1<<4) + +struct oc_vpn_proto { + const char *name; + const char *pretty_name; + const char *description; + unsigned int flags; +}; + +/****************************************************************************/ + /* Authentication form processing */ #define OC_FORM_OPT_TEXT 1 @@ -640,6 +661,9 @@ int openconnect_has_oath_support(void); int openconnect_has_yubioath_support(void); int openconnect_has_system_key_support(void); +/* Query and select from among supported protocols */ +int openconnect_get_supported_protocols(struct oc_vpn_proto **protos); +void openconnect_free_supported_protocols(struct oc_vpn_proto *protos); int openconnect_set_protocol(struct openconnect_info *vpninfo, const char *protocol); struct addrinfo;