From 828c8604dd6dcd06947f80b462057a1882109f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Nov 2016 13:20:55 +0200 Subject: [PATCH] rtsp: Add gst_rtsp_generate_digest_auth_response() to calculate digest auth response https://bugzilla.gnome.org/show_bug.cgi?id=774416 --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/rtsp/gstrtspconnection.c | 66 ++------------- gst-libs/gst/rtsp/gstrtspdefs.c | 86 ++++++++++++++++++++ gst-libs/gst/rtsp/gstrtspdefs.h | 8 ++ win32/common/libgstrtsp.def | 1 + 5 files changed, 103 insertions(+), 59 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 81a37d48be..a4cb69c4a8 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -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 GST_TYPE_RTSP_AUTH_METHOD GST_TYPE_RTSP_EVENT diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c index 309421c9d1..5f3c8ba400 100644 --- a/gst-libs/gst/rtsp/gstrtspconnection.c +++ b/gst-libs/gst/rtsp/gstrtspconnection.c @@ -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) { diff --git a/gst-libs/gst/rtsp/gstrtspdefs.c b/gst-libs/gst/rtsp/gstrtspdefs.c index a27f579956..c00e32056c 100644 --- a/gst-libs/gst/rtsp/gstrtspdefs.c +++ b/gst-libs/gst/rtsp/gstrtspdefs.c @@ -48,7 +48,12 @@ * Provides common defines for the RTSP library. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include +#include #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; +} diff --git a/gst-libs/gst/rtsp/gstrtspdefs.h b/gst-libs/gst/rtsp/gstrtspdefs.h index 2a1608e6ca..dec6a1108c 100644 --- a/gst-libs/gst/rtsp/gstrtspdefs.h +++ b/gst-libs/gst/rtsp/gstrtspdefs.h @@ -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__ */ diff --git a/win32/common/libgstrtsp.def b/win32/common/libgstrtsp.def index 355a9ef8de..827517cd45 100644 --- a/win32/common/libgstrtsp.def +++ b/win32/common/libgstrtsp.def @@ -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