From: Daniel Lenski Date: Thu, 15 Apr 2021 05:54:22 +0000 (-0700) Subject: Parse Pulse error/termination packets and print error codes and strings X-Git-Tag: v8.20~266^2~2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f1540c9d05ae0ffcc5d69981194d2fbb5c299aa7;p=users%2Fdwmw2%2Fopenconnect.git Parse Pulse error/termination packets and print error codes and strings The error string is URL-encoded, so urldecode_inplace() is moved to http.c and made a global internal function. Signed-off-by: Daniel Lenski --- diff --git a/auth-globalprotect.c b/auth-globalprotect.c index 06913267..ac7e183e 100644 --- a/auth-globalprotect.c +++ b/auth-globalprotect.c @@ -243,26 +243,6 @@ static int challenge_cb(struct openconnect_info *vpninfo, char *prompt, char *in return -EAGAIN; } -static int urldecode_inplace(char *p) -{ - char *q; - if (!p) - return -EINVAL; - - for (q = p; *p; p++, q++) { - if (*p == '+') { - *q = ' '; - } else if (*p == '%' && isxdigit((int)(unsigned char)p[1]) && - isxdigit((int)(unsigned char)p[2])) { - *q = unhex(p + 1); - p += 2; - } else - *q = *p; - } - *q = 0; - return 0; -} - /* Parse gateway login response (POST /ssl-vpn/login.esp) * * Extracts the relevant arguments from the XML (...) diff --git a/http.c b/http.c index 1fd1e5b9..26a3c38b 100644 --- a/http.c +++ b/http.c @@ -436,6 +436,26 @@ int internal_split_cookies(struct openconnect_info *vpninfo, int replace, const return 0; } +int urldecode_inplace(char *p) +{ + char *q; + if (!p) + return -EINVAL; + + for (q = p; *p; p++, q++) { + if (*p == '+') { + *q = ' '; + } else if (*p == '%' && isxdigit((int)(unsigned char)p[1]) && + isxdigit((int)(unsigned char)p[2])) { + *q = unhex(p + 1); + p += 2; + } else + *q = *p; + } + *q = 0; + return 0; +} + /* Read one HTTP header line into hdrbuf, potentially allowing for * continuation lines. Will never leave a character in 'nextchar' when * an empty line (signifying end of headers) is received. Will only diff --git a/openconnect-internal.h b/openconnect-internal.h index e3a8a758..3580f2b7 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -1251,6 +1251,7 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method, int http_add_cookie(struct openconnect_info *vpninfo, const char *option, const char *value, int replace); int internal_split_cookies(struct openconnect_info *vpninfo, int replace, const char *def_cookie); +int urldecode_inplace(char *p); int process_http_response(struct openconnect_info *vpninfo, int connect, int (*header_cb)(struct openconnect_info *, char *, char *), struct oc_text_buf *body); diff --git a/pulse.c b/pulse.c index 553f0c1c..48dc7efc 100644 --- a/pulse.c +++ b/pulse.c @@ -2712,6 +2712,29 @@ int pulse_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) print_esp_keys(vpninfo, _("new outgoing"), &vpninfo->esp_out); continue; + case 0x93: { + /* Expected contents are "errorType=%d errorString=%s\n". Known values: + * 6: "agentd error" (another session started and kicked this one off) + * 7: "session has been terminated" (by client) + * 8: "session timed out" (idle timeout) + */ + if (payload_len < 12 || strncmp("errorType=", (const char *)pkt->data, 10)) + goto unknown_pkt; + pkt->data[payload_len - 1] = '\0'; /* overwrite final '\n' */ + + char *endp; + unsigned long reason = strtol((const char *)pkt->data + 10, &endp, 10); + if (strncmp(" errorString=", endp, 13)) + goto unknown_pkt; + + urldecode_inplace(endp+1); + + vpn_progress(vpninfo, PRG_ERR, _("Pulse fatal error (reason: %ld): %s\n"), + reason, endp+13); + vpninfo->quit_reason = strdup(endp+13); + return -EPIPE; + } + case 0x96: /* It sends the licence information once the connection is set up. For * now, abuse this to deal with the race condition in ESP setup — it looks