rtspdefs: Add gst_rtsp_generate_digest_auth_response_from_md5
authorMathieu Duponchelle <mathieu@centricular.com>
Wed, 20 Jun 2018 02:41:24 +0000 (04:41 +0200)
committerMathieu Duponchelle <mathieu@centricular.com>
Thu, 21 Jun 2018 13:32:12 +0000 (15:32 +0200)
Passwords are usually not stored in clear text, usually
the A1 section of the response is stored as is in .htdigest
files.

https://bugzilla.gnome.org/show_bug.cgi?id=796636

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/rtsp/gstrtspdefs.c
gst-libs/gst/rtsp/gstrtspdefs.h

index 04af5c4..02a0b52 100644 (file)
@@ -1704,6 +1704,7 @@ gst_rtsp_options_from_text
 gst_rtsp_find_header_field
 gst_rtsp_find_method
 gst_rtsp_generate_digest_auth_response
+gst_rtsp_generate_digest_auth_response_from_md5
 <SUBSECTION Standard>
 GST_TYPE_RTSP_AUTH_METHOD
 GST_TYPE_RTSP_EVENT
index 2645076..4b5ea6d 100644 (file)
@@ -536,27 +536,40 @@ gst_rtsp_header_allow_multiple (GstRTSPHeaderField field)
     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)
+auth_digest_compute_a1_md5 (const gchar * realm, const gchar * username,
+    const gchar * password)
 {
-  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;
+  gchar *ret;
 
-  /* 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);
-  g_assert (strlen (digest_string) == 32);
-  memcpy (hex_a1, digest_string, 32);
+  ret = g_strdup (g_checksum_get_string (md5_context));
+  g_assert (strlen (ret) == 32);
+  g_checksum_free (md5_context);
+
+  return ret;
+}
+
+/* See RFC2069, 2.1.2 */
+static gchar *
+auth_digest_compute_response_md5 (const gchar * method, const gchar * a1,
+    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 = NULL;
+
+  if (strlen (a1) != 32)
+    goto done;
+
+  memcpy (hex_a1, a1, 32);
   g_checksum_reset (md5_context);
 
   /* compute A2 */
@@ -576,6 +589,8 @@ auth_digest_compute_response_md5 (const gchar * method, const gchar * realm,
 
   g_checksum_update (md5_context, (const guchar *) hex_a2, 32);
   response = g_strdup (g_checksum_get_string (md5_context));
+
+done:
   g_checksum_free (md5_context);
 
   return response;
@@ -605,6 +620,7 @@ 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)
 {
+  gchar *ret = NULL;
   g_return_val_if_fail (method != NULL, NULL);
   g_return_val_if_fail (realm != NULL, NULL);
   g_return_val_if_fail (username != NULL, NULL);
@@ -612,9 +628,42 @@ gst_rtsp_generate_digest_auth_response (const gchar * algorithm,
   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) {
+    gchar *a1 = auth_digest_compute_a1_md5 (realm, username, password);
+    ret = auth_digest_compute_response_md5 (method, a1, uri, nonce);
+    g_free (a1);
+  }
+
+  return ret;
+}
+
+/**
+ * gst_rtsp_generate_digest_auth_response_from_md5:
+ * @algorithm: (allow-none): Hash algorithm to use, or %NULL for MD5
+ * @method: Request method, e.g. PLAY
+ * @md5: The md5 sum of username:realm:password
+ * @uri: Original request URI
+ * @nonce: Nonce
+ *
+ * Calculates the digest auth response from the values given by the server and
+ * the md5sum. See RFC2069 for details.
+ *
+ * This function is useful when the passwords are not stored in clear text,
+ * but instead in the same format as the .htdigest file.
+ *
+ * Currently only supported algorithm "md5".
+ *
+ * Returns: Authentication response or %NULL if unsupported
+ *
+ * Since: 1.16
+ */
+gchar *
+gst_rtsp_generate_digest_auth_response_from_md5 (const gchar * algorithm,
+    const gchar * method, const gchar * md5, const gchar * uri,
+    const gchar * nonce)
+{
   if (algorithm == NULL || g_ascii_strcasecmp (algorithm, "md5") == 0)
-    return auth_digest_compute_response_md5 (method, realm, username, password,
-        uri, nonce);
+    return auth_digest_compute_response_md5 (method, md5, uri, nonce);
 
   return NULL;
 }
index 0f9fe81..345da9e 100644 (file)
@@ -437,6 +437,13 @@ gchar *            gst_rtsp_generate_digest_auth_response (const gchar *algorith
                                                            const gchar *uri,
                                                            const gchar *nonce);
 
+GST_RTSP_API
+gchar *            gst_rtsp_generate_digest_auth_response_from_md5 (const gchar *algorithm,
+                                                                    const gchar * method,
+                                                                    const gchar * md5,
+                                                                    const gchar * uri,
+                                                                    const gchar * nonce);
+
 G_END_DECLS
 
 #endif /* __GST_RTSP_DEFS_H__ */