]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Parse Pulse error/termination packets and print error codes and strings
authorDaniel Lenski <dlenski@gmail.com>
Thu, 15 Apr 2021 05:54:22 +0000 (22:54 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Thu, 15 Apr 2021 06:11:35 +0000 (23:11 -0700)
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 <dlenski@gmail.com>
auth-globalprotect.c
http.c
openconnect-internal.h
pulse.c

index 06913267c8f2c66d236c3bc84676814ccf806529..ac7e183e685f798ea07d816158c2856270e0511e 100644 (file)
@@ -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 (<jnlp><application-desc><argument>...</argument></application-desc></jnlp>)
diff --git a/http.c b/http.c
index 1fd1e5b9820b4ef56993558ec7f44e7a003e5837..26a3c38b81e156eff87d45a19e58937e2952be1e 100644 (file)
--- 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
index e3a8a758be1e5d74e7b32bb2701669f2b5243425..3580f2b75b7ed0af7ae154caf018255a5764fa2e 100644 (file)
@@ -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 553f0c1c8e8a72b28aef506e4841345999db3155..48dc7efcbe0657099c8af8d57068d5b6a7ac8496 100644 (file)
--- 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