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:
Sebastian Dröge 2016-11-18 13:20:55 +02:00
parent 5b4010c7b5
commit 828c8604dd
5 changed files with 103 additions and 59 deletions

View file

@ -1514,6 +1514,7 @@ gst_rtsp_options_as_text
gst_rtsp_options_from_text
gst_rtsp_find_header_field
gst_rtsp_find_method
gst_rtsp_generate_digest_auth_response
<SUBSECTION Standard>
GST_TYPE_RTSP_AUTH_METHOD
GST_TYPE_RTSP_EVENT

View file

@ -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
add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
{
@ -1056,7 +1005,7 @@ add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
break;
}
case GST_RTSP_AUTH_DIGEST:{
gchar response[33], hex_urp[33];
gchar *response;
gchar *auth_string, *auth_string2;
gchar *realm;
gchar *nonce;
@ -1075,18 +1024,17 @@ add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
if (realm == NULL || nonce == NULL)
break;
auth_digest_compute_hex_urp (conn->username, realm, conn->passwd,
hex_urp);
method = gst_rtsp_method_as_text (message->type_data.request.method);
uri = message->type_data.request.uri;
/* Assume no qop, algorithm=md5, stale=false */
/* For algorithm MD5, a1 = urp. */
auth_digest_compute_response (method, uri, hex_urp, nonce, response);
auth_string = g_strdup_printf ("Digest username=\"%s\", "
response =
gst_rtsp_generate_digest_auth_response (NULL, method, realm,
conn->username, conn->passwd, uri, nonce);
auth_string =
g_strdup_printf ("Digest username=\"%s\", "
"realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
conn->username, realm, nonce, uri, response);
g_free (response);
opaque = (gchar *) g_hash_table_lookup (conn->auth_params, "opaque");
if (opaque) {

View file

@ -48,7 +48,12 @@
* Provides common defines for the RTSP library.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <string.h>
#include "gstrtspdefs.h"
@ -518,3 +523,84 @@ gst_rtsp_header_allow_multiple (GstRTSPHeaderField field)
else
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;
}

View file

@ -405,6 +405,14 @@ GstRTSPMethod gst_rtsp_find_method (const gchar *method);
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
#endif /* __GST_RTSP_DEFS_H__ */

View file

@ -54,6 +54,7 @@ EXPORTS
gst_rtsp_family_get_type
gst_rtsp_find_header_field
gst_rtsp_find_method
gst_rtsp_generate_digest_auth_response
gst_rtsp_header_allow_multiple
gst_rtsp_header_as_text
gst_rtsp_header_field_get_type