Skip to content

Commit

Permalink
library: Add support for mobile headers
Browse files Browse the repository at this point in the history
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 <cernekee@gmail.com>
  • Loading branch information
cernekee committed Jan 15, 2014
1 parent 9483a20 commit 1c90e4d
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 3 deletions.
13 changes: 11 additions & 2 deletions auth.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions http.c
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions libopenconnect.map.in
Expand Up @@ -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 {
Expand Down
20 changes: 19 additions & 1 deletion library.c
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions main.c
Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions openconnect-internal.h
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions openconnect.h
Expand Up @@ -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 *);
Expand Down

0 comments on commit 1c90e4d

Please sign in to comment.