rtsp: Parse WWW-Authenticate headers correctly.
authorPeter Kjellerstedt <pkj@axis.com>
Thu, 20 Aug 2009 12:12:09 +0000 (14:12 +0200)
committerPeter Kjellerstedt <pkj@axis.com>
Mon, 24 Aug 2009 11:19:45 +0000 (13:19 +0200)
Due to the odd syntax for WWW-Authenticate (and Proxy-Authenticate) which
allows commas both to separate between multiple challenges, and within the
challenges themself, we need to take some extra care to split these headers
correctly.

gst-libs/gst/rtsp/gstrtspconnection.c

index b569455..54b0d4c 100644 (file)
@@ -1598,6 +1598,7 @@ parse_line (guint8 * buffer, GstRTSPMessage * msg)
   /* split up the value in multiple key:value pairs if it contains comma(s) */
   while (*value != '\0') {
     gchar *next_value;
+    gchar *comma = NULL;
     gboolean quoted = FALSE;
     guint comment = 0;
 
@@ -1617,8 +1618,37 @@ parse_line (guint8 * buffer, GstRTSPMessage * msg)
         comment++;
       else if (comment != 0 && *next_value == ')')
         comment--;
-      else if (!quoted && comment == 0 && *next_value == ',')
-        break;
+      else if (!quoted && comment == 0) {
+        /* To quote RFC 2068: "User agents MUST take special care in parsing
+         * the WWW-Authenticate field value if it contains more than one
+         * challenge, or if more than one WWW-Authenticate header field is
+         * provided, since the contents of a challenge may itself contain a
+         * comma-separated list of authentication parameters."
+         *
+         * What this means is that we cannot just look for an unquoted comma
+         * when looking for multiple values in Proxy-Authenticate and
+         * WWW-Authenticate headers. Instead we need to look for the sequence
+         * "comma [space] token space token" before we can split after the
+         * comma...
+         */
+        if (field == GST_RTSP_HDR_PROXY_AUTHENTICATE ||
+            field == GST_RTSP_HDR_WWW_AUTHENTICATE) {
+          if (*next_value == ',') {
+            if (next_value[1] == ' ') {
+              /* skip any space following the comma so we do not mistake it for
+               * separating between two tokens */
+              next_value++;
+            }
+            comma = next_value;
+          } else if (*next_value == ' ' && next_value[1] != ',' &&
+              next_value[1] != '=' && comma != NULL) {
+            next_value = comma;
+            comma = NULL;
+            break;
+          }
+        } else if (*next_value == ',')
+          break;
+      }
 
       next_value++;
     }