mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
gst/rtsp/gstrtspsrc.c: Support Digest authentication. Fixes #532065.
Original commit message from CVS: Based on patch by: Wouter Cloetens <wouter at mind be> * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init), (gst_rtspsrc_skip_lws), (gst_rtspsrc_unskip_lws), (gst_rtspsrc_skip_commas), (gst_rtspsrc_skip_item), (gst_rtsp_decode_quoted_string), (gst_rtspsrc_parse_digest_challenge), (gst_rtspsrc_parse_auth_hdr), (gst_rtspsrc_setup_auth): Support Digest authentication. Fixes #532065.
This commit is contained in:
parent
a0369011e7
commit
5506fbfc48
2 changed files with 139 additions and 6 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2008-05-08 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
Based on patch by: Wouter Cloetens <wouter at mind be>
|
||||||
|
|
||||||
|
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init),
|
||||||
|
(gst_rtspsrc_skip_lws), (gst_rtspsrc_unskip_lws),
|
||||||
|
(gst_rtspsrc_skip_commas), (gst_rtspsrc_skip_item),
|
||||||
|
(gst_rtsp_decode_quoted_string),
|
||||||
|
(gst_rtspsrc_parse_digest_challenge), (gst_rtspsrc_parse_auth_hdr),
|
||||||
|
(gst_rtspsrc_setup_auth):
|
||||||
|
Support Digest authentication. Fixes #532065.
|
||||||
|
|
||||||
2008-05-08 Stefan Kost <ensonic@users.sf.net>
|
2008-05-08 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* gst/level/gstlevel.c:
|
* gst/level/gstlevel.c:
|
||||||
|
|
|
@ -2973,19 +2973,136 @@ gst_rtsp_auth_method_to_string (GstRTSPAuthMethod method)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_rtspsrc_skip_lws (const gchar * s)
|
||||||
|
{
|
||||||
|
while (g_ascii_isspace (*s))
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_rtspsrc_unskip_lws (const gchar * s, const gchar * start)
|
||||||
|
{
|
||||||
|
while (s > start && g_ascii_isspace (*(s - 1)))
|
||||||
|
s--;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_rtspsrc_skip_commas (const gchar * s)
|
||||||
|
{
|
||||||
|
/* The grammar allows for multiple commas */
|
||||||
|
while (g_ascii_isspace (*s) || *s == ',')
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
gst_rtspsrc_skip_item (const gchar * s)
|
||||||
|
{
|
||||||
|
gboolean quoted = FALSE;
|
||||||
|
const gchar *start = s;
|
||||||
|
|
||||||
|
/* A list item ends at the last non-whitespace character
|
||||||
|
* before a comma which is not inside a quoted-string. Or at
|
||||||
|
* the end of the string.
|
||||||
|
*/
|
||||||
|
while (*s) {
|
||||||
|
if (*s == '"')
|
||||||
|
quoted = !quoted;
|
||||||
|
else if (quoted) {
|
||||||
|
if (*s == '\\' && *(s + 1))
|
||||||
|
s++;
|
||||||
|
} else {
|
||||||
|
if (*s == ',')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gst_rtspsrc_unskip_lws (s, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtsp_decode_quoted_string (gchar * quoted_string)
|
||||||
|
{
|
||||||
|
gchar *src, *dst;
|
||||||
|
|
||||||
|
src = quoted_string + 1;
|
||||||
|
dst = quoted_string;
|
||||||
|
while (*src && *src != '"') {
|
||||||
|
if (*src == '\\' && *(src + 1))
|
||||||
|
src++;
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
*dst = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract the authentication tokens that the server provided for each method
|
||||||
|
* into an array of structures and give those to the connection object.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_rtspsrc_parse_digest_challenge (GstRTSPConnection * conn,
|
||||||
|
const gchar * header)
|
||||||
|
{
|
||||||
|
GSList *list = NULL, *iter;
|
||||||
|
const gchar *end;
|
||||||
|
gchar *item, *eq, *name_end, *value;
|
||||||
|
|
||||||
|
gst_rtsp_connection_clear_auth_params (conn);
|
||||||
|
|
||||||
|
/* Parse a header whose content is described by RFC2616 as
|
||||||
|
* "#something", where "something" does not itself contain commas,
|
||||||
|
* except as part of quoted-strings, into a list of allocated strings.
|
||||||
|
*/
|
||||||
|
header = gst_rtspsrc_skip_commas (header);
|
||||||
|
while (*header) {
|
||||||
|
end = gst_rtspsrc_skip_item (header);
|
||||||
|
list = g_slist_prepend (list, g_strndup (header, end - header));
|
||||||
|
header = gst_rtspsrc_skip_commas (end);
|
||||||
|
}
|
||||||
|
if (!list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list = g_slist_reverse (list);
|
||||||
|
for (iter = list; iter; iter = iter->next) {
|
||||||
|
item = iter->data;
|
||||||
|
|
||||||
|
eq = strchr (item, '=');
|
||||||
|
if (eq) {
|
||||||
|
name_end = (gchar *) gst_rtspsrc_unskip_lws (eq, item);
|
||||||
|
if (name_end == item) {
|
||||||
|
/* That's no good... */
|
||||||
|
g_free (item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*name_end = '\0';
|
||||||
|
|
||||||
|
value = (gchar *) gst_rtspsrc_skip_lws (eq + 1);
|
||||||
|
if (*value == '"')
|
||||||
|
gst_rtsp_decode_quoted_string (value);
|
||||||
|
} else
|
||||||
|
value = NULL;
|
||||||
|
|
||||||
|
gst_rtsp_connection_set_auth_param (conn, item, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (list);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a WWW-Authenticate Response header and determine the
|
/* Parse a WWW-Authenticate Response header and determine the
|
||||||
* available authentication methods
|
* available authentication methods
|
||||||
* FIXME: To implement digest or other auth types, we should extract
|
|
||||||
* the authentication tokens that the server provided for each method
|
|
||||||
* into an array of structures and give those to the connection object.
|
|
||||||
*
|
*
|
||||||
* This code should also cope with the fact that each WWW-Authenticate
|
* This code should also cope with the fact that each WWW-Authenticate
|
||||||
* header can contain multiple challenge methods + tokens
|
* header can contain multiple challenge methods + tokens
|
||||||
*
|
*
|
||||||
* At the moment, we just do a minimal check for Basic auth and don't
|
* At the moment, for Basic auth, we just do a minimal check and don't
|
||||||
* even parse out the realm */
|
* even parse out the realm */
|
||||||
static void
|
static void
|
||||||
gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods)
|
gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods,
|
||||||
|
GstRTSPConnection * conn)
|
||||||
{
|
{
|
||||||
gchar *start;
|
gchar *start;
|
||||||
|
|
||||||
|
@ -2997,6 +3114,10 @@ gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods)
|
||||||
|
|
||||||
if (g_ascii_strncasecmp (start, "basic", 5) == 0)
|
if (g_ascii_strncasecmp (start, "basic", 5) == 0)
|
||||||
*methods |= GST_RTSP_AUTH_BASIC;
|
*methods |= GST_RTSP_AUTH_BASIC;
|
||||||
|
else if (g_ascii_strncasecmp (start, "digest ", 7) == 0) {
|
||||||
|
*methods |= GST_RTSP_AUTH_DIGEST;
|
||||||
|
gst_rtspsrc_parse_digest_challenge (conn, &start[7]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3026,7 +3147,7 @@ gst_rtspsrc_setup_auth (GstRTSPSrc * src, GstRTSPMessage * response)
|
||||||
/* Identify the available auth methods and see if any are supported */
|
/* Identify the available auth methods and see if any are supported */
|
||||||
if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_WWW_AUTHENTICATE,
|
if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_WWW_AUTHENTICATE,
|
||||||
&hdr, 0) == GST_RTSP_OK) {
|
&hdr, 0) == GST_RTSP_OK) {
|
||||||
gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods);
|
gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods, src->connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avail_methods == GST_RTSP_AUTH_NONE)
|
if (avail_methods == GST_RTSP_AUTH_NONE)
|
||||||
|
|
Loading…
Reference in a new issue