mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
rtsp: Add gst_rtsp_generate_digest_auth_response() to calculate digest auth response
https://bugzilla.gnome.org/show_bug.cgi?id=774416
This commit is contained in:
parent
5b4010c7b5
commit
828c8604dd
5 changed files with 103 additions and 59 deletions
|
@ -1514,6 +1514,7 @@ gst_rtsp_options_as_text
|
||||||
gst_rtsp_options_from_text
|
gst_rtsp_options_from_text
|
||||||
gst_rtsp_find_header_field
|
gst_rtsp_find_header_field
|
||||||
gst_rtsp_find_method
|
gst_rtsp_find_method
|
||||||
|
gst_rtsp_generate_digest_auth_response
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GST_TYPE_RTSP_AUTH_METHOD
|
GST_TYPE_RTSP_AUTH_METHOD
|
||||||
GST_TYPE_RTSP_EVENT
|
GST_TYPE_RTSP_EVENT
|
||||||
|
|
|
@ -981,57 +981,6 @@ tunneling_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
auth_digest_compute_hex_urp (const gchar * username,
|
|
||||||
const gchar * realm, const gchar * password, gchar hex_urp[33])
|
|
||||||
{
|
|
||||||
GChecksum *md5_context = g_checksum_new (G_CHECKSUM_MD5);
|
|
||||||
const gchar *digest_string;
|
|
||||||
|
|
||||||
g_checksum_update (md5_context, (const guchar *) username, strlen (username));
|
|
||||||
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
|
||||||
g_checksum_update (md5_context, (const guchar *) realm, strlen (realm));
|
|
||||||
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
|
||||||
g_checksum_update (md5_context, (const guchar *) password, strlen (password));
|
|
||||||
digest_string = g_checksum_get_string (md5_context);
|
|
||||||
|
|
||||||
memset (hex_urp, 0, 33);
|
|
||||||
memcpy (hex_urp, digest_string, strlen (digest_string));
|
|
||||||
|
|
||||||
g_checksum_free (md5_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
auth_digest_compute_response (const gchar * method,
|
|
||||||
const gchar * uri, const gchar * hex_a1, const gchar * nonce,
|
|
||||||
gchar response[33])
|
|
||||||
{
|
|
||||||
char hex_a2[33] = { 0, };
|
|
||||||
GChecksum *md5_context = g_checksum_new (G_CHECKSUM_MD5);
|
|
||||||
const gchar *digest_string;
|
|
||||||
|
|
||||||
/* compute A2 */
|
|
||||||
g_checksum_update (md5_context, (const guchar *) method, strlen (method));
|
|
||||||
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
|
||||||
g_checksum_update (md5_context, (const guchar *) uri, strlen (uri));
|
|
||||||
digest_string = g_checksum_get_string (md5_context);
|
|
||||||
memcpy (hex_a2, digest_string, strlen (digest_string));
|
|
||||||
|
|
||||||
/* compute KD */
|
|
||||||
g_checksum_reset (md5_context);
|
|
||||||
g_checksum_update (md5_context, (const guchar *) hex_a1, strlen (hex_a1));
|
|
||||||
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
|
||||||
g_checksum_update (md5_context, (const guchar *) nonce, strlen (nonce));
|
|
||||||
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
|
||||||
|
|
||||||
g_checksum_update (md5_context, (const guchar *) hex_a2, 32);
|
|
||||||
digest_string = g_checksum_get_string (md5_context);
|
|
||||||
memset (response, 0, 33);
|
|
||||||
memcpy (response, digest_string, strlen (digest_string));
|
|
||||||
|
|
||||||
g_checksum_free (md5_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
|
add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
|
||||||
{
|
{
|
||||||
|
@ -1056,7 +1005,7 @@ add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_RTSP_AUTH_DIGEST:{
|
case GST_RTSP_AUTH_DIGEST:{
|
||||||
gchar response[33], hex_urp[33];
|
gchar *response;
|
||||||
gchar *auth_string, *auth_string2;
|
gchar *auth_string, *auth_string2;
|
||||||
gchar *realm;
|
gchar *realm;
|
||||||
gchar *nonce;
|
gchar *nonce;
|
||||||
|
@ -1075,18 +1024,17 @@ add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
|
||||||
if (realm == NULL || nonce == NULL)
|
if (realm == NULL || nonce == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auth_digest_compute_hex_urp (conn->username, realm, conn->passwd,
|
|
||||||
hex_urp);
|
|
||||||
|
|
||||||
method = gst_rtsp_method_as_text (message->type_data.request.method);
|
method = gst_rtsp_method_as_text (message->type_data.request.method);
|
||||||
uri = message->type_data.request.uri;
|
uri = message->type_data.request.uri;
|
||||||
|
|
||||||
/* Assume no qop, algorithm=md5, stale=false */
|
response =
|
||||||
/* For algorithm MD5, a1 = urp. */
|
gst_rtsp_generate_digest_auth_response (NULL, method, realm,
|
||||||
auth_digest_compute_response (method, uri, hex_urp, nonce, response);
|
conn->username, conn->passwd, uri, nonce);
|
||||||
auth_string = g_strdup_printf ("Digest username=\"%s\", "
|
auth_string =
|
||||||
|
g_strdup_printf ("Digest username=\"%s\", "
|
||||||
"realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
|
"realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
|
||||||
conn->username, realm, nonce, uri, response);
|
conn->username, realm, nonce, uri, response);
|
||||||
|
g_free (response);
|
||||||
|
|
||||||
opaque = (gchar *) g_hash_table_lookup (conn->auth_params, "opaque");
|
opaque = (gchar *) g_hash_table_lookup (conn->auth_params, "opaque");
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
|
|
|
@ -48,7 +48,12 @@
|
||||||
* Provides common defines for the RTSP library.
|
* Provides common defines for the RTSP library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "gstrtspdefs.h"
|
#include "gstrtspdefs.h"
|
||||||
|
|
||||||
|
@ -518,3 +523,84 @@ gst_rtsp_header_allow_multiple (GstRTSPHeaderField field)
|
||||||
else
|
else
|
||||||
return rtsp_headers[field - 1].multiple;
|
return rtsp_headers[field - 1].multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See RFC2069, 2.1.2 */
|
||||||
|
static gchar *
|
||||||
|
auth_digest_compute_response_md5 (const gchar * method, const gchar * realm,
|
||||||
|
const gchar * username, const gchar * password, const gchar * uri,
|
||||||
|
const gchar * nonce)
|
||||||
|
{
|
||||||
|
gchar hex_a1[33] = { 0, };
|
||||||
|
gchar hex_a2[33] = { 0, };
|
||||||
|
GChecksum *md5_context = g_checksum_new (G_CHECKSUM_MD5);
|
||||||
|
const gchar *digest_string;
|
||||||
|
gchar *response;
|
||||||
|
|
||||||
|
/* Compute A1 */
|
||||||
|
g_checksum_update (md5_context, (const guchar *) username, strlen (username));
|
||||||
|
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
||||||
|
g_checksum_update (md5_context, (const guchar *) realm, strlen (realm));
|
||||||
|
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
||||||
|
g_checksum_update (md5_context, (const guchar *) password, strlen (password));
|
||||||
|
digest_string = g_checksum_get_string (md5_context);
|
||||||
|
memcpy (hex_a1, digest_string, strlen (digest_string));
|
||||||
|
g_checksum_reset (md5_context);
|
||||||
|
|
||||||
|
/* compute A2 */
|
||||||
|
g_checksum_update (md5_context, (const guchar *) method, strlen (method));
|
||||||
|
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
||||||
|
g_checksum_update (md5_context, (const guchar *) uri, strlen (uri));
|
||||||
|
digest_string = g_checksum_get_string (md5_context);
|
||||||
|
memcpy (hex_a2, digest_string, strlen (digest_string));
|
||||||
|
|
||||||
|
/* compute KD */
|
||||||
|
g_checksum_reset (md5_context);
|
||||||
|
g_checksum_update (md5_context, (const guchar *) hex_a1, strlen (hex_a1));
|
||||||
|
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
||||||
|
g_checksum_update (md5_context, (const guchar *) nonce, strlen (nonce));
|
||||||
|
g_checksum_update (md5_context, (const guchar *) ":", 1);
|
||||||
|
|
||||||
|
g_checksum_update (md5_context, (const guchar *) hex_a2, 32);
|
||||||
|
response = g_strdup (g_checksum_get_string (md5_context));
|
||||||
|
g_checksum_free (md5_context);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_generate_digest_auth_response:
|
||||||
|
* @algorithm: (allow-none): Hash algorithm to use, or %NULL for MD5
|
||||||
|
* @method: Request method, e.g. PLAY
|
||||||
|
* @realm: Realm
|
||||||
|
* @username: Username
|
||||||
|
* @password: Password
|
||||||
|
* @uri: Original request URI
|
||||||
|
* @nonce: Nonce
|
||||||
|
*
|
||||||
|
* Calculates the digest auth response from the values given by the server and
|
||||||
|
* the username and password. See RFC2069 for details.
|
||||||
|
*
|
||||||
|
* Currently only supported algorithm "md5".
|
||||||
|
*
|
||||||
|
* Returns: Authentication response or %NULL if unsupported
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
gst_rtsp_generate_digest_auth_response (const gchar * algorithm,
|
||||||
|
const gchar * method, const gchar * realm, const gchar * username,
|
||||||
|
const gchar * password, const gchar * uri, const gchar * nonce)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (method != NULL, NULL);
|
||||||
|
g_return_val_if_fail (realm != NULL, NULL);
|
||||||
|
g_return_val_if_fail (username != NULL, NULL);
|
||||||
|
g_return_val_if_fail (password != NULL, NULL);
|
||||||
|
g_return_val_if_fail (uri != NULL, NULL);
|
||||||
|
g_return_val_if_fail (nonce != NULL, NULL);
|
||||||
|
|
||||||
|
if (algorithm == NULL || g_ascii_strcasecmp (algorithm, "md5") == 0)
|
||||||
|
return auth_digest_compute_response_md5 (method, realm, username, password,
|
||||||
|
uri, nonce);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -405,6 +405,14 @@ GstRTSPMethod gst_rtsp_find_method (const gchar *method);
|
||||||
|
|
||||||
gboolean gst_rtsp_header_allow_multiple (GstRTSPHeaderField field);
|
gboolean gst_rtsp_header_allow_multiple (GstRTSPHeaderField field);
|
||||||
|
|
||||||
|
gchar * gst_rtsp_generate_digest_auth_response (const gchar *algorithm,
|
||||||
|
const gchar *method,
|
||||||
|
const gchar *realm,
|
||||||
|
const gchar *username,
|
||||||
|
const gchar *password,
|
||||||
|
const gchar *uri,
|
||||||
|
const gchar *nonce);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_RTSP_DEFS_H__ */
|
#endif /* __GST_RTSP_DEFS_H__ */
|
||||||
|
|
|
@ -54,6 +54,7 @@ EXPORTS
|
||||||
gst_rtsp_family_get_type
|
gst_rtsp_family_get_type
|
||||||
gst_rtsp_find_header_field
|
gst_rtsp_find_header_field
|
||||||
gst_rtsp_find_method
|
gst_rtsp_find_method
|
||||||
|
gst_rtsp_generate_digest_auth_response
|
||||||
gst_rtsp_header_allow_multiple
|
gst_rtsp_header_allow_multiple
|
||||||
gst_rtsp_header_as_text
|
gst_rtsp_header_as_text
|
||||||
gst_rtsp_header_field_get_type
|
gst_rtsp_header_field_get_type
|
||||||
|
|
Loading…
Reference in a new issue