Add a new public function, openconnect_get_supported_protocols(), which returns a list of protocols supported by the client. Each supported protocol has a short name (as accepted by the --protocol command-line option), description, and list of flags. 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) Description of anyconnect protocol adjusted to match IETF draft standard for openconnect VPN (https://tools.ietf.org/html/draft-mavrogiannopoulos-openconnect-00). Signed-off-by: Daniel Lenski <dlenski at gmail.com> --- libopenconnect.map.in | 6 ++++++ library.c | 32 ++++++++++++++++++++++++++++++++ openconnect-internal.h | 3 +++ openconnect.h | 27 +++++++++++++++++++++++++-- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 44eea34..04b8ed5 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 58ccf93..86b524a 100644 --- a/library.c +++ b/library.c @@ -109,6 +109,9 @@ err: const struct vpn_proto openconnect_protos[] = { { .name = "anyconnect", + .pretty_name = "Cisco AnyConnect or openconnect", + .description = "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 = "Juniper Network Connect", + .description = "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 = oncp_bye, .tcp_connect = oncp_connect, .tcp_mainloop = oncp_mainloop, @@ -137,6 +143,9 @@ const struct vpn_proto openconnect_protos[] = { #endif }, { .name = "gp", + .pretty_name = "Palo Alto Networks GlobalProtect", + .description = "Compatible with Palo Alto Networks (PAN) GlobalProtect SSL VPN", + .flags = OC_PROTO_PROXY | OC_PROTO_AUTH_CERT, .vpn_close_session = gpst_bye, .tcp_connect = gpst_setup, .tcp_mainloop = gpst_mainloop, @@ -154,6 +163,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 0; +} + +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 ee4edbd..67a122f 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -258,6 +258,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 fc23c3c..a2fbd43 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 @@ -408,7 +429,7 @@ int openconnect_init_ssl(void); const char *openconnect_get_cstp_cipher(struct openconnect_info *); const char *openconnect_get_dtls_cipher(struct openconnect_info *); -/* These return a descriptive string of the compression algorithm +/* These return a descriptive string of the compression algorithm * in use (LZS, LZ4, ...). If no compression then NULL is returned. */ const char *openconnect_get_cstp_compression(struct openconnect_info *); const char *openconnect_get_dtls_compression(struct openconnect_info *); @@ -640,6 +661,8 @@ int openconnect_has_oath_support(void); int openconnect_has_yubioath_support(void); int openconnect_has_system_key_support(void); +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; -- 2.7.4