|
| 1 | +From e25f0278e4063b8677bb27651f214f20f1a52296 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Patrick Griffis < [email protected]> |
| 3 | +Date: Sun, 8 Dec 2024 20:00:35 -0600 |
| 4 | +Subject: [PATCH 1/3] auth-digest: Handle missing realm in authenticate header |
| 5 | + |
| 6 | +Link: https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/417.patch |
| 7 | +--- |
| 8 | + libsoup/auth/soup-auth-digest.c | 3 ++ |
| 9 | + tests/auth-test.c | 50 +++++++++++++++++++++++++++++++++ |
| 10 | + 2 files changed, 53 insertions(+) |
| 11 | + |
| 12 | +diff --git a/libsoup/auth/soup-auth-digest.c b/libsoup/auth/soup-auth-digest.c |
| 13 | +index 13b6cc1..3289347 100644 |
| 14 | +--- a/libsoup/auth/soup-auth-digest.c |
| 15 | ++++ b/libsoup/auth/soup-auth-digest.c |
| 16 | +@@ -147,6 +147,9 @@ soup_auth_digest_update (SoupAuth *auth, SoupMessage *msg, |
| 17 | + guint qop_options; |
| 18 | + gboolean ok = TRUE; |
| 19 | + |
| 20 | ++ if (!soup_auth_get_realm (auth)) |
| 21 | ++ return FALSE; |
| 22 | ++ |
| 23 | + g_free (priv->domain); |
| 24 | + g_free (priv->nonce); |
| 25 | + g_free (priv->opaque); |
| 26 | +diff --git a/tests/auth-test.c b/tests/auth-test.c |
| 27 | +index 7f6fc4b..b3238dd 100644 |
| 28 | +--- a/tests/auth-test.c |
| 29 | ++++ b/tests/auth-test.c |
| 30 | +@@ -1831,6 +1831,55 @@ do_multiple_digest_algorithms (void) |
| 31 | + soup_test_server_quit_unref (server); |
| 32 | + } |
| 33 | + |
| 34 | ++static void |
| 35 | ++on_request_read_for_missing_realm (SoupServer *server, |
| 36 | ++ SoupServerMessage *msg, |
| 37 | ++ gpointer user_data) |
| 38 | ++{ |
| 39 | ++ SoupMessageHeaders *response_headers = soup_server_message_get_response_headers (msg); |
| 40 | ++ soup_message_headers_replace (response_headers, "WWW-Authenticate", "Digest qop=\"auth\""); |
| 41 | ++} |
| 42 | ++ |
| 43 | ++static void |
| 44 | ++do_missing_realm_test (void) |
| 45 | ++{ |
| 46 | ++ SoupSession *session; |
| 47 | ++ SoupMessage *msg; |
| 48 | ++ SoupServer *server; |
| 49 | ++ SoupAuthDomain *digest_auth_domain; |
| 50 | ++ gint status; |
| 51 | ++ GUri *uri; |
| 52 | ++ |
| 53 | ++ server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); |
| 54 | ++ soup_server_add_handler (server, NULL, |
| 55 | ++ server_callback, NULL, NULL); |
| 56 | ++ uri = soup_test_server_get_uri (server, "http", NULL); |
| 57 | ++ |
| 58 | ++ digest_auth_domain = soup_auth_domain_digest_new ( |
| 59 | ++ "realm", "auth-test", |
| 60 | ++ "auth-callback", server_digest_auth_callback, |
| 61 | ++ NULL); |
| 62 | ++ soup_auth_domain_add_path (digest_auth_domain, "/"); |
| 63 | ++ soup_server_add_auth_domain (server, digest_auth_domain); |
| 64 | ++ g_object_unref (digest_auth_domain); |
| 65 | ++ |
| 66 | ++ g_signal_connect (server, "request-read", |
| 67 | ++ G_CALLBACK (on_request_read_for_missing_realm), |
| 68 | ++ NULL); |
| 69 | ++ |
| 70 | ++ session = soup_test_session_new (NULL); |
| 71 | ++ msg = soup_message_new_from_uri ("GET", uri); |
| 72 | ++ g_signal_connect (msg, "authenticate", |
| 73 | ++ G_CALLBACK (on_digest_authenticate), |
| 74 | ++ NULL); |
| 75 | ++ |
| 76 | ++ status = soup_test_session_send_message (session, msg); |
| 77 | ++ |
| 78 | ++ g_assert_cmpint (status, ==, SOUP_STATUS_UNAUTHORIZED); |
| 79 | ++ g_uri_unref (uri); |
| 80 | ++ soup_test_server_quit_unref (server); |
| 81 | ++} |
| 82 | ++ |
| 83 | + static void |
| 84 | + redirect_server_callback (SoupServer *server, |
| 85 | + SoupServerMessage *msg, |
| 86 | +@@ -1938,6 +1987,7 @@ main (int argc, char **argv) |
| 87 | + g_test_add_func ("/auth/auth-uri", do_auth_uri_test); |
| 88 | + g_test_add_func ("/auth/cancel-request-on-authenticate", do_cancel_request_on_authenticate); |
| 89 | + g_test_add_func ("/auth/multiple-algorithms", do_multiple_digest_algorithms); |
| 90 | ++ g_test_add_func ("/auth/missing-realm", do_missing_realm_test); |
| 91 | + g_test_add_func ("/auth/strip-on-crossorigin-redirect", do_strip_on_crossorigin_redirect); |
| 92 | + |
| 93 | + ret = g_test_run (); |
| 94 | +-- |
| 95 | +2.34.1 |
| 96 | + |
| 97 | + |
| 98 | +From 093eef05add0f5087e4d9b72a9ea4a6a71f2d407 Mon Sep 17 00:00:00 2001 |
| 99 | +From: Patrick Griffis < [email protected]> |
| 100 | +Date: Thu, 26 Dec 2024 18:18:35 -0600 |
| 101 | +Subject: [PATCH 2/3] auth-digest: Handle missing nonce |
| 102 | + |
| 103 | +--- |
| 104 | + libsoup/auth/soup-auth-digest.c | 45 +++++++++++++++++++++++++-------- |
| 105 | + tests/auth-test.c | 19 ++++++++------ |
| 106 | + 2 files changed, 46 insertions(+), 18 deletions(-) |
| 107 | + |
| 108 | +diff --git a/libsoup/auth/soup-auth-digest.c b/libsoup/auth/soup-auth-digest.c |
| 109 | +index 3289347..cd83665 100644 |
| 110 | +--- a/libsoup/auth/soup-auth-digest.c |
| 111 | ++++ b/libsoup/auth/soup-auth-digest.c |
| 112 | +@@ -137,6 +137,19 @@ soup_auth_digest_get_qop (SoupAuthDigestQop qop) |
| 113 | + return g_string_free (out, FALSE); |
| 114 | + } |
| 115 | + |
| 116 | ++static gboolean |
| 117 | ++validate_params (SoupAuthDigest *auth_digest) |
| 118 | ++{ |
| 119 | ++ SoupAuthDigestPrivate *priv = soup_auth_digest_get_instance_private (auth_digest); |
| 120 | ++ |
| 121 | ++ if (priv->qop || priv->algorithm == SOUP_AUTH_DIGEST_ALGORITHM_MD5_SESS) { |
| 122 | ++ if (!priv->nonce) |
| 123 | ++ return FALSE; |
| 124 | ++ } |
| 125 | ++ |
| 126 | ++ return TRUE; |
| 127 | ++} |
| 128 | ++ |
| 129 | + static gboolean |
| 130 | + soup_auth_digest_update (SoupAuth *auth, SoupMessage *msg, |
| 131 | + GHashTable *auth_params) |
| 132 | +@@ -174,16 +187,21 @@ soup_auth_digest_update (SoupAuth *auth, SoupMessage *msg, |
| 133 | + if (priv->algorithm == -1) |
| 134 | + ok = FALSE; |
| 135 | + |
| 136 | +- stale = g_hash_table_lookup (auth_params, "stale"); |
| 137 | +- if (stale && !g_ascii_strcasecmp (stale, "TRUE") && *priv->hex_urp) |
| 138 | +- recompute_hex_a1 (priv); |
| 139 | +- else { |
| 140 | +- g_free (priv->user); |
| 141 | +- priv->user = NULL; |
| 142 | +- g_free (priv->cnonce); |
| 143 | +- priv->cnonce = NULL; |
| 144 | +- memset (priv->hex_urp, 0, sizeof (priv->hex_urp)); |
| 145 | +- memset (priv->hex_a1, 0, sizeof (priv->hex_a1)); |
| 146 | ++ if (!validate_params (auth_digest)) |
| 147 | ++ ok = FALSE; |
| 148 | ++ |
| 149 | ++ if (ok) { |
| 150 | ++ stale = g_hash_table_lookup (auth_params, "stale"); |
| 151 | ++ if (stale && !g_ascii_strcasecmp (stale, "TRUE") && *priv->hex_urp) |
| 152 | ++ recompute_hex_a1 (priv); |
| 153 | ++ else { |
| 154 | ++ g_free (priv->user); |
| 155 | ++ priv->user = NULL; |
| 156 | ++ g_free (priv->cnonce); |
| 157 | ++ priv->cnonce = NULL; |
| 158 | ++ memset (priv->hex_urp, 0, sizeof (priv->hex_urp)); |
| 159 | ++ memset (priv->hex_a1, 0, sizeof (priv->hex_a1)); |
| 160 | ++ } |
| 161 | + } |
| 162 | + |
| 163 | + return ok; |
| 164 | +@@ -275,6 +293,8 @@ soup_auth_digest_compute_hex_a1 (const char *hex_urp, |
| 165 | + |
| 166 | + /* In MD5-sess, A1 is hex_urp:nonce:cnonce */ |
| 167 | + |
| 168 | ++ g_assert (nonce && cnonce); |
| 169 | ++ |
| 170 | + checksum = g_checksum_new (G_CHECKSUM_MD5); |
| 171 | + g_checksum_update (checksum, (guchar *)hex_urp, strlen (hex_urp)); |
| 172 | + g_checksum_update (checksum, (guchar *)":", 1); |
| 173 | +@@ -365,6 +385,8 @@ soup_auth_digest_compute_response (const char *method, |
| 174 | + if (qop) { |
| 175 | + char tmp[9]; |
| 176 | + |
| 177 | ++ g_assert (cnonce); |
| 178 | ++ |
| 179 | + g_snprintf (tmp, 9, "%.8x", nc); |
| 180 | + g_checksum_update (checksum, (guchar *)tmp, strlen (tmp)); |
| 181 | + g_checksum_update (checksum, (guchar *)":", 1); |
| 182 | +@@ -428,6 +450,9 @@ soup_auth_digest_get_authorization (SoupAuth *auth, SoupMessage *msg) |
| 183 | + g_return_val_if_fail (uri != NULL, NULL); |
| 184 | + url = soup_uri_get_path_and_query (uri); |
| 185 | + |
| 186 | ++ g_assert (priv->nonce); |
| 187 | ++ g_assert (!priv->qop || priv->cnonce); |
| 188 | ++ |
| 189 | + soup_auth_digest_compute_response (soup_message_get_method (msg), url, priv->hex_a1, |
| 190 | + priv->qop, priv->nonce, |
| 191 | + priv->cnonce, priv->nc, |
| 192 | +diff --git a/tests/auth-test.c b/tests/auth-test.c |
| 193 | +index b3238dd..6422618 100644 |
| 194 | +--- a/tests/auth-test.c |
| 195 | ++++ b/tests/auth-test.c |
| 196 | +@@ -1832,16 +1832,17 @@ do_multiple_digest_algorithms (void) |
| 197 | + } |
| 198 | + |
| 199 | + static void |
| 200 | +-on_request_read_for_missing_realm (SoupServer *server, |
| 201 | +- SoupServerMessage *msg, |
| 202 | +- gpointer user_data) |
| 203 | ++on_request_read_for_missing_params (SoupServer *server, |
| 204 | ++ SoupServerMessage *msg, |
| 205 | ++ gpointer user_data) |
| 206 | + { |
| 207 | ++ const char *auth_header = user_data; |
| 208 | + SoupMessageHeaders *response_headers = soup_server_message_get_response_headers (msg); |
| 209 | +- soup_message_headers_replace (response_headers, "WWW-Authenticate", "Digest qop=\"auth\""); |
| 210 | ++ soup_message_headers_replace (response_headers, "WWW-Authenticate", auth_header); |
| 211 | + } |
| 212 | + |
| 213 | + static void |
| 214 | +-do_missing_realm_test (void) |
| 215 | ++do_missing_params_test (gconstpointer auth_header) |
| 216 | + { |
| 217 | + SoupSession *session; |
| 218 | + SoupMessage *msg; |
| 219 | +@@ -1864,8 +1865,8 @@ do_missing_realm_test (void) |
| 220 | + g_object_unref (digest_auth_domain); |
| 221 | + |
| 222 | + g_signal_connect (server, "request-read", |
| 223 | +- G_CALLBACK (on_request_read_for_missing_realm), |
| 224 | +- NULL); |
| 225 | ++ G_CALLBACK (on_request_read_for_missing_params), |
| 226 | ++ (gpointer)auth_header); |
| 227 | + |
| 228 | + session = soup_test_session_new (NULL); |
| 229 | + msg = soup_message_new_from_uri ("GET", uri); |
| 230 | +@@ -1987,7 +1988,9 @@ main (int argc, char **argv) |
| 231 | + g_test_add_func ("/auth/auth-uri", do_auth_uri_test); |
| 232 | + g_test_add_func ("/auth/cancel-request-on-authenticate", do_cancel_request_on_authenticate); |
| 233 | + g_test_add_func ("/auth/multiple-algorithms", do_multiple_digest_algorithms); |
| 234 | +- g_test_add_func ("/auth/missing-realm", do_missing_realm_test); |
| 235 | ++ g_test_add_data_func ("/auth/missing-params/realm", "Digest qop=\"auth\"", do_missing_params_test); |
| 236 | ++ g_test_add_data_func ("/auth/missing-params/nonce", "Digest realm=\"auth-test\", qop=\"auth,auth-int\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"", do_missing_params_test); |
| 237 | ++ g_test_add_data_func ("/auth/missing-params/nonce-md5-sess", "Digest realm=\"auth-test\", qop=\"auth,auth-int\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\" algorithm=\"MD5-sess\"", do_missing_params_test); |
| 238 | + g_test_add_func ("/auth/strip-on-crossorigin-redirect", do_strip_on_crossorigin_redirect); |
| 239 | + |
| 240 | + ret = g_test_run (); |
| 241 | +-- |
| 242 | +2.34.1 |
| 243 | + |
| 244 | + |
| 245 | +From f485dadb4e797d53ca62b9e6672abcf81a6ee108 Mon Sep 17 00:00:00 2001 |
| 246 | +From: Patrick Griffis < [email protected]> |
| 247 | +Date: Fri, 27 Dec 2024 13:52:52 -0600 |
| 248 | +Subject: [PATCH 3/3] auth-digest: Fix leak |
| 249 | + |
| 250 | +--- |
| 251 | + libsoup/auth/soup-auth-digest.c | 1 + |
| 252 | + 1 file changed, 1 insertion(+) |
| 253 | + |
| 254 | +diff --git a/libsoup/auth/soup-auth-digest.c b/libsoup/auth/soup-auth-digest.c |
| 255 | +index cd83665..ccd642d 100644 |
| 256 | +--- a/libsoup/auth/soup-auth-digest.c |
| 257 | ++++ b/libsoup/auth/soup-auth-digest.c |
| 258 | +@@ -71,6 +71,7 @@ soup_auth_digest_finalize (GObject *object) |
| 259 | + g_free (priv->nonce); |
| 260 | + g_free (priv->domain); |
| 261 | + g_free (priv->cnonce); |
| 262 | ++ g_free (priv->opaque); |
| 263 | + |
| 264 | + memset (priv->hex_urp, 0, sizeof (priv->hex_urp)); |
| 265 | + memset (priv->hex_a1, 0, sizeof (priv->hex_a1)); |
| 266 | +-- |
| 267 | +2.34.1 |
| 268 | + |
0 commit comments