From 1c90e4d0dadd84c26fbe5735a4f7e6fb6cecd4e2 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sun, 22 Sep 2013 16:29:38 -0700 Subject: [PATCH] library: Add support for mobile headers Cisco's Android and iOS clients send a couple of extra HTTP headers[1] which are necessary to enable a limited "mobile CSD" mode on the gateway[2]. Add an API allowing the caller to specify these headers. Also, skip downloading the CSD trojan on mobile devices, as it won't run anyway. [1] http://lists.infradead.org/pipermail/openconnect-devel/2013-February/000890.html [2] http://lists.infradead.org/pipermail/openconnect-devel/2013-March/000989.html Signed-off-by: Kevin Cernekee --- auth.c | 13 +++++++++++-- http.c | 12 ++++++++++++ libopenconnect.map.in | 1 + library.c | 20 +++++++++++++++++++- main.c | 7 +++++++ openconnect-internal.h | 4 ++++ openconnect.h | 4 ++++ 7 files changed, 58 insertions(+), 3 deletions(-) diff --git a/auth.c b/auth.c index efab89b2..5bf73656 100644 --- a/auth.c +++ b/auth.c @@ -506,7 +506,9 @@ static int parse_auth_node(struct openconnect_info *vpninfo, xmlNode *xml_node, xmlnode_get_prop(xml_node, "token", &vpninfo->csd_token); xmlnode_get_prop(xml_node, "ticket", &vpninfo->csd_ticket); } else if (!vpninfo->csd_scriptname && xmlnode_is_named(xml_node, vpninfo->csd_xmltag)) { - xmlnode_get_prop(xml_node, "stuburl", &vpninfo->csd_stuburl); + /* ignore the CSD trojan binary on mobile platforms */ + if (!vpninfo->csd_nostub) + xmlnode_get_prop(xml_node, "stuburl", &vpninfo->csd_stuburl); xmlnode_get_prop(xml_node, "starturl", &vpninfo->csd_starturl); xmlnode_get_prop(xml_node, "waiturl", &vpninfo->csd_waiturl); vpninfo->csd_preurl = strdup(vpninfo->urlpath); @@ -838,8 +840,15 @@ static xmlDocPtr xmlpost_new_query(struct openconnect_info *vpninfo, const char if (!xmlNewProp(node, XCAST("who"), XCAST("vpn"))) goto bad; - if (!xmlNewTextChild(root, NULL, XCAST("device-id"), XCAST(vpninfo->platname))) + node = xmlNewTextChild(root, NULL, XCAST("device-id"), XCAST(vpninfo->platname)); + if (!node) goto bad; + if (vpninfo->mobile_platform_version) { + if (!xmlNewProp(node, XCAST("platform-version"), XCAST(vpninfo->mobile_platform_version)) || + !xmlNewProp(node, XCAST("device-type"), XCAST(vpninfo->mobile_device_type)) || + !xmlNewProp(node, XCAST("unique-id"), XCAST(vpninfo->mobile_device_uniqueid))) + goto bad; + } return doc; diff --git a/http.c b/http.c index 9c1ef71a..b2c07c85 100644 --- a/http.c +++ b/http.c @@ -452,6 +452,18 @@ static void add_common_headers(struct openconnect_info *vpninfo, struct oc_text_ buf_append(buf, "X-AnyConnect-Platform: %s\r\n", vpninfo->platname); } + if (vpninfo->mobile_platform_version) { + buf_append(buf, "X-AnyConnect-Identifier-ClientVersion: %s\r\n", + openconnect_version_str); + buf_append(buf, "X-AnyConnect-Identifier-Platform: %s\r\n", + vpninfo->platname); + buf_append(buf, "X-AnyConnect-Identifier-PlatformVersion: %s\r\n", + vpninfo->mobile_platform_version); + buf_append(buf, "X-AnyConnect-Identifier-DeviceType: %s\r\n", + vpninfo->mobile_device_type); + buf_append(buf, "X-AnyConnect-Identifier-Device-UniqueID: %s\r\n", + vpninfo->mobile_device_uniqueid); + } } static int fetch_config(struct openconnect_info *vpninfo, char *fu, char *bu, diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 694dcc25..8a9d2593 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -49,6 +49,7 @@ OPENCONNECT_3.1 { openconnect_set_reqmtu; openconnect_get_ip_info; openconnect_set_protect_socket_handler; + openconnect_set_mobile_info; } OPENCONNECT_3.0; OPENCONNECT_PRIVATE { diff --git a/library.c b/library.c index c38255b7..fcf2b89a 100644 --- a/library.c +++ b/library.c @@ -88,6 +88,8 @@ int openconnect_set_reported_os(struct openconnect_info *vpninfo, const char *os if (!os) { #if defined(__APPLE__) os = "mac"; +#elif defined(__ANDROID__) + os = "android"; #else os = sizeof(long) > 4 ? "linux-64" : "linux"; #endif @@ -98,7 +100,10 @@ int openconnect_set_reported_os(struct openconnect_info *vpninfo, const char *os vpninfo->csd_xmltag = "csdMac"; else if (!strcmp(os, "linux") || !strcmp(os, "linux-64")) vpninfo->csd_xmltag = "csdLinux"; - else if (!strcmp(os, "win")) + else if (!strcmp(os, "android") || !strcmp(os, "apple-ios")) { + vpninfo->csd_xmltag = "csdLinux"; + vpninfo->csd_nostub = 1; + } else if (!strcmp(os, "win")) vpninfo->csd_xmltag = "csd"; else return -EINVAL; @@ -107,6 +112,16 @@ int openconnect_set_reported_os(struct openconnect_info *vpninfo, const char *os return 0; } +void openconnect_set_mobile_info(struct openconnect_info *vpninfo, + char *mobile_platform_version, + char *mobile_device_type, + char *mobile_device_uniqueid) +{ + vpninfo->mobile_platform_version = mobile_platform_version; + vpninfo->mobile_device_type = mobile_device_type; + vpninfo->mobile_device_uniqueid = mobile_device_uniqueid; +} + static void free_optlist(struct oc_vpn_option *opt) { struct oc_vpn_option *next; @@ -146,6 +161,9 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo) unlink(vpninfo->csd_scriptname); free(vpninfo->csd_scriptname); } + free(vpninfo->mobile_platform_version); + free(vpninfo->mobile_device_type); + free(vpninfo->mobile_device_uniqueid); free(vpninfo->csd_token); free(vpninfo->csd_ticket); free(vpninfo->csd_stuburl); diff --git a/main.c b/main.c index 55d4c715..d1992ecd 100644 --- a/main.c +++ b/main.c @@ -791,6 +791,13 @@ int main(int argc, char **argv) config_arg); exit(1); } + if (!strcmp(config_arg, "android") || !strcmp(config_arg, "apple-ios")) { + /* generic defaults */ + openconnect_set_mobile_info(vpninfo, + xstrdup("1.0"), + xstrdup(config_arg), + xstrdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); + } break; default: usage(); diff --git a/openconnect-internal.h b/openconnect-internal.h index 5c1a15cc..faa0fb87 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -130,7 +130,11 @@ struct openconnect_info { int redirect_type; const char *csd_xmltag; + int csd_nostub; const char *platname; + char *mobile_platform_version; + char *mobile_device_type; + char *mobile_device_uniqueid; char *csd_token; char *csd_ticket; char *csd_stuburl; diff --git a/openconnect.h b/openconnect.h index 6a5cb73b..e8d23163 100644 --- a/openconnect.h +++ b/openconnect.h @@ -252,6 +252,10 @@ void openconnect_set_xmlsha1(struct openconnect_info *, const char *, int size); void openconnect_set_cafile(struct openconnect_info *, char *); void openconnect_setup_csd(struct openconnect_info *, uid_t, int silent, char *wrapper); int openconnect_set_reported_os(struct openconnect_info *, const char *os); +void openconnect_set_mobile_info(struct openconnect_info *vpninfo, + char *mobile_platform_version, + char *mobile_device_type, + char *mobile_device_uniqueid); void openconnect_set_client_cert(struct openconnect_info *, char *cert, char *sslkey); void openconnect_set_server_cert_sha1(struct openconnect_info *, char *); const char *openconnect_get_ifname(struct openconnect_info *);