From e2f574a5f5f06a2364ff65f7a13721f79bf4beef Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Sun, 25 Nov 2018 10:53:37 -0500 Subject: [PATCH] GlobalProtect: apparently, the parameter `clientos=Linux` value is not just allowed, but necessary, for some VPNs. * Previously, I had received at least two reports of servers where `clientos=Windows` was required for the VPN to work correctly. * Per https://github.com/dlenski/openconnect/issues/126, there is at least one report where *not* setting `clientos=Windows` was required for the VPN to work. * The truly maddening part is not only the pointless and inconsistent behavior of the GlobalProtect servers, but also the fact that the servers give such misleading and irrelevant error messages ("Incorrect username or password" or "Unable to assign private IP address", etc.) rather than something that makes sense like "Unknown clientos value." This patch makes `clientos=Linux` the default behavior when `vpninfo->platname` is `linux-64` or `android`, while still allowing it to be overridden with `--os=win` etc. Signed-off-by: Daniel Lenski --- auth-globalprotect.c | 19 +++++++++++++++++-- gpst.c | 8 +++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/auth-globalprotect.c b/auth-globalprotect.c index f0247608..61f0fbe8 100644 --- a/auth-globalprotect.c +++ b/auth-globalprotect.c @@ -447,9 +447,18 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal, struct login /* Ask the user to fill in the auth form; repeat as necessary */ for (;;) { + const char *clientos; + if (!strcmp(vpninfo->platname, "mac-intel") || !strcmp(vpninfo->platname, "apple-ios")) + clientos = "Mac"; + else if (!strcmp(vpninfo->platname, "linux-64") || !strcmp(vpninfo->platname, "android")) + clientos = "Linux"; + else + clientos = "Windows"; + /* submit prelogin request to get form */ orig_path = vpninfo->urlpath; - vpninfo->urlpath = strdup(portal ? "global-protect/prelogin.esp?tmp=tmp&clientVer=4100&clientos=Windows" : "ssl-vpn/prelogin.esp"); + asprintf(&vpninfo->urlpath, "%s/prelogin.esp?tmp=tmp&clientVer=4100&clientos=%s", + portal ? "global-protect" : "ssl-vpn", clientos); result = do_https_request(vpninfo, "POST", NULL, NULL, &xml_buf, 0); free(vpninfo->urlpath); vpninfo->urlpath = orig_path; @@ -476,7 +485,13 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal, struct login /* submit gateway login (ssl-vpn/login.esp) or portal config (global-protect/getconfig.esp) request */ buf_truncate(request_body); - buf_append(request_body, "jnlpReady=jnlpReady&ok=Login&direct=yes&clientVer=4100&prot=https:&clientos=Windows"); + buf_append(request_body, "jnlpReady=jnlpReady&ok=Login&direct=yes&clientVer=4100&prot=https:"); + if (!strcmp(vpninfo->platname, "mac-intel") || !strcmp(vpninfo->platname, "apple-ios")) + append_opt(request_body, "clientos", "Mac"); + else if (!strcmp(vpninfo->platname, "linux-64") || !strcmp(vpninfo->platname, "android")) + append_opt(request_body, "clientos", "Linux"); + else + append_opt(request_body, "clientos", "Windows"); append_opt(request_body, "os-version", vpninfo->platname); append_opt(request_body, "server", vpninfo->hostname); append_opt(request_body, "computer", vpninfo->localname); diff --git a/gpst.c b/gpst.c index cae4e4f8..5fa2fc40 100644 --- a/gpst.c +++ b/gpst.c @@ -581,7 +581,13 @@ static int gpst_get_config(struct openconnect_info *vpninfo) char *xml_buf=NULL; /* submit getconfig request */ - buf_append(request_body, "client-type=1&protocol-version=p1&app-version=3.0.1-10&clientos=Windows"); + buf_append(request_body, "client-type=1&protocol-version=p1&app-version=3.0.1-10"); + if (!strcmp(vpninfo->platname, "mac-intel") || !strcmp(vpninfo->platname, "apple-ios")) + append_opt(request_body, "clientos", "Mac"); + else if (!strcmp(vpninfo->platname, "linux-64") || !strcmp(vpninfo->platname, "android")) + append_opt(request_body, "clientos", "Linux"); + else + append_opt(request_body, "clientos", "Windows"); append_opt(request_body, "os-version", vpninfo->platname); append_opt(request_body, "hmac-algo", "sha1,md5"); append_opt(request_body, "enc-algo", "aes-128-cbc,aes-256-cbc"); -- 2.50.1