From 08d3fe856102b1374d30e8bb35cf59a00899141b Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Thu, 20 Aug 2009 14:12:09 +0200 Subject: [PATCH] rtsp: Parse WWW-Authenticate headers correctly. 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 | 34 +++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c index b56945588a..54b0d4c335 100644 --- a/gst-libs/gst/rtsp/gstrtspconnection.c +++ b/gst-libs/gst/rtsp/gstrtspconnection.c @@ -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++; }