[libsoup/carlosgc/authenticate: 7/9] auth: replace host property with authority




commit 7e36856eb20bae33904ac1730125d72481f44867
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Oct 27 12:38:13 2020 +0100

    auth: replace host property with authority
    
    The host name is not enough to identify the domain being authenticated,
    we need the port too.

 docs/reference/libsoup-3.0-sections.txt |  2 +-
 libsoup/auth/soup-auth-negotiate.c      | 16 ++++++------
 libsoup/auth/soup-auth-ntlm.c           |  8 +++++-
 libsoup/auth/soup-auth.c                | 43 ++++++++++++++++++---------------
 libsoup/auth/soup-auth.h                |  4 +--
 tests/proxy-test.c                      | 21 ++++++++++++++++
 6 files changed, 63 insertions(+), 31 deletions(-)
---
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index f89ac3b7..6e126e09 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -449,7 +449,7 @@ soup_auth_negotiate_supported
 <SUBSECTION>
 soup_auth_is_for_proxy
 soup_auth_get_scheme_name
-soup_auth_get_host
+soup_auth_get_authority
 soup_auth_get_realm
 soup_auth_get_info
 <SUBSECTION>
diff --git a/libsoup/auth/soup-auth-negotiate.c b/libsoup/auth/soup-auth-negotiate.c
index ddae3b98..8c29a759 100644
--- a/libsoup/auth/soup-auth-negotiate.c
+++ b/libsoup/auth/soup-auth-negotiate.c
@@ -98,7 +98,7 @@ static gboolean soup_gss_build_response (SoupNegotiateConnectionState *conn,
                                         SoupAuth *auth, GError **err);
 static void soup_gss_client_cleanup (SoupNegotiateConnectionState *conn);
 static gboolean soup_gss_client_init (SoupNegotiateConnectionState *conn,
-                                     const char *host, GError **err);
+                                     const char *authority, GError **err);
 static int soup_gss_client_step (SoupNegotiateConnectionState *conn,
                                 const char *host, GError **err);
 
@@ -472,7 +472,7 @@ static gboolean
 soup_gss_build_response (SoupNegotiateConnectionState *conn, SoupAuth *auth, GError **err)
 {
        if (!conn->initialized)
-               if (!soup_gss_client_init (conn, soup_auth_get_host (auth), err))
+               if (!soup_gss_client_init (conn, soup_auth_get_authority (auth), err))
                        return FALSE;
 
        if (soup_gss_client_step (conn, "", err) != AUTH_GSS_CONTINUE)
@@ -527,19 +527,21 @@ soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err)
 }
 
 static gboolean
-soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *host, GError **err)
+soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *authority, GError **err)
 {
        OM_uint32 maj_stat, min_stat;
        gchar *service = NULL;
        gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
        gboolean ret = FALSE;
-       gchar *h;
+       char *host;
+       const char *p;
 
        conn->server_name = GSS_C_NO_NAME;
        conn->context = GSS_C_NO_CONTEXT;
 
-       h = g_ascii_strdown (host, -1);
-       service = g_strconcat ("HTTP@", h, NULL);
+       p = g_strrstr (authority, ":");
+       host = g_ascii_strdown (authority, p ? strlen (authority) - strlen (p) : -1);
+       service = g_strconcat ("HTTP@", host, NULL);
        token.length = strlen (service);
        token.value = (gchar *) service;
 
@@ -557,7 +559,7 @@ soup_gss_client_init (SoupNegotiateConnectionState *conn, const gchar *host, GEr
        conn->initialized = TRUE;
        ret = TRUE;
 out:
-       g_free (h);
+       g_free (host);
        g_free (service);
        return ret;
 }
diff --git a/libsoup/auth/soup-auth-ntlm.c b/libsoup/auth/soup-auth-ntlm.c
index 6cc93b6e..d0b9440b 100644
--- a/libsoup/auth/soup-auth-ntlm.c
+++ b/libsoup/auth/soup-auth-ntlm.c
@@ -307,6 +307,8 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg,
        SoupAuthNTLMPrivate *priv = soup_auth_ntlm_get_instance_private (auth_ntlm);
        SoupNTLMConnectionState *conn = state;
        gboolean success = TRUE;
+       SoupURI *uri;
+       char *authority;
 
        /* Note that we only return FALSE if some sort of parsing error
         * occurs. Otherwise, the SoupAuth is still reusable (though it may
@@ -396,10 +398,14 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg,
        if (conn->state == SOUP_NTLM_SENT_REQUEST)
                conn->state = SOUP_NTLM_RECEIVED_CHALLENGE;
 
+       uri = soup_message_get_uri (msg);
+       authority = g_strdup_printf ("%s:%d", uri->host, uri->port);
        g_object_set (G_OBJECT (auth),
                      "realm", priv->domain,
-                     "host", soup_message_get_uri (msg)->host,
+                     "authority", authority,
                      NULL);
+       g_free (authority);
+
        return success;
 }
 
diff --git a/libsoup/auth/soup-auth.c b/libsoup/auth/soup-auth.c
index 9295400c..62690bb5 100644
--- a/libsoup/auth/soup-auth.c
+++ b/libsoup/auth/soup-auth.c
@@ -37,7 +37,7 @@
 
 typedef struct {
         char *realm;
-       char *host;
+       char *authority;
        gboolean proxy;
        gboolean cancelled;
 } SoupAuthPrivate;
@@ -49,7 +49,7 @@ enum {
 
        PROP_SCHEME_NAME,
        PROP_REALM,
-       PROP_HOST,
+       PROP_AUTHORITY,
        PROP_IS_FOR_PROXY,
        PROP_IS_AUTHENTICATED,
        PROP_IS_CANCELLED,
@@ -81,7 +81,7 @@ soup_auth_finalize (GObject *object)
        SoupAuthPrivate *priv = soup_auth_get_instance_private (auth);
 
        g_free (priv->realm);
-       g_free (priv->host);
+       g_free (priv->authority);
 
        G_OBJECT_CLASS (soup_auth_parent_class)->finalize (object);
 }
@@ -98,9 +98,9 @@ soup_auth_set_property (GObject *object, guint prop_id,
                g_free (priv->realm);
                priv->realm = g_value_dup_string (value);
                break;
-       case PROP_HOST:
-               g_free (priv->host);
-               priv->host = g_value_dup_string (value);
+       case PROP_AUTHORITY:
+               g_free (priv->authority);
+               priv->authority = g_value_dup_string (value);
                break;
        case PROP_IS_FOR_PROXY:
                priv->proxy = g_value_get_boolean (value);
@@ -125,8 +125,8 @@ soup_auth_get_property (GObject *object, guint prop_id,
        case PROP_REALM:
                g_value_set_string (value, soup_auth_get_realm (auth));
                break;
-       case PROP_HOST:
-               g_value_set_string (value, soup_auth_get_host (auth));
+       case PROP_AUTHORITY:
+               g_value_set_string (value, soup_auth_get_authority (auth));
                break;
        case PROP_IS_FOR_PROXY:
                g_value_set_boolean (value, priv->proxy);
@@ -188,15 +188,15 @@ soup_auth_class_init (SoupAuthClass *auth_class)
                                     G_PARAM_READWRITE |
                                     G_PARAM_STATIC_STRINGS));
        /**
-        * SoupAuth:host:
+        * SoupAuth:authority:
         *
-        * The host being authenticated to.
+        * The authority (host:port) being authenticated to.
         **/
        g_object_class_install_property (
-               object_class, PROP_HOST,
-               g_param_spec_string ("host",
-                                    "Host",
-                                    "Authentication host",
+               object_class, PROP_AUTHORITY,
+               g_param_spec_string ("authority",
+                                    "Authority",
+                                    "Authentication authority",
                                     NULL,
                                     G_PARAM_READWRITE |
                                     G_PARAM_STATIC_STRINGS));
@@ -264,6 +264,7 @@ soup_auth_new (GType type, SoupMessage *msg, const char *auth_header)
        GHashTable *params;
        const char *scheme;
        SoupURI *uri;
+       char *authority;
 
        g_return_val_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH), NULL);
        g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
@@ -273,10 +274,12 @@ soup_auth_new (GType type, SoupMessage *msg, const char *auth_header)
        if (!uri)
                return NULL;
 
+       authority = g_strdup_printf ("%s:%d", uri->host, uri->port);
        auth = g_object_new (type,
                             "is-for-proxy", (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED),
-                            "host", uri->host,
+                            "authority", authority,
                             NULL);
+       g_free (authority);
 
        SoupAuthPrivate *priv = soup_auth_get_instance_private (auth);
 
@@ -440,21 +443,21 @@ soup_auth_get_scheme_name (SoupAuth *auth)
 }
 
 /**
- * soup_auth_get_host:
+ * soup_auth_get_authority:
  * @auth: a #SoupAuth
  *
- * Returns the host that @auth is associated with.
+ * Returns the authority (host:port) that @auth is associated with.
  *
- * Return value: the hostname
+ * Returns: the authority
  **/
 const char *
-soup_auth_get_host (SoupAuth *auth)
+soup_auth_get_authority (SoupAuth *auth)
 {
        SoupAuthPrivate *priv = soup_auth_get_instance_private (auth);
 
        g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL);
 
-       return priv->host;
+       return priv->authority;
 }
 
 /**
diff --git a/libsoup/auth/soup-auth.h b/libsoup/auth/soup-auth.h
index 284aa3da..0773e25b 100644
--- a/libsoup/auth/soup-auth.h
+++ b/libsoup/auth/soup-auth.h
@@ -56,8 +56,8 @@ SOUP_AVAILABLE_IN_2_4
 gboolean    soup_auth_is_for_proxy          (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
 const char *soup_auth_get_scheme_name       (SoupAuth      *auth);
-SOUP_AVAILABLE_IN_2_4
-const char *soup_auth_get_host              (SoupAuth      *auth);
+SOUP_AVAILABLE_IN_ALL
+const char *soup_auth_get_authority         (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
 const char *soup_auth_get_realm             (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index f1824235..2992c000 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -46,6 +46,27 @@ authenticate (SoupMessage *msg,
              SoupAuth    *auth,
              gboolean     retrying)
 {
+       if (soup_auth_is_for_proxy (auth)) {
+               char *uri;
+               int i;
+               gboolean found = FALSE;
+
+               uri = g_strdup_printf ("http://%s";, soup_auth_get_authority (auth));
+               for (i = 1; i < G_N_ELEMENTS (proxies) && !found; i++) {
+                       if (strcmp (uri, proxies[i]) == 0)
+                               found = TRUE;
+               }
+               g_free (uri);
+               g_assert_true (found);
+       } else {
+               SoupURI *uri = soup_message_get_uri (msg);
+               char *authority;
+
+               authority = g_strdup_printf ("%s:%d", uri->host, uri->port);
+               g_assert_cmpstr (authority, ==, soup_auth_get_authority (auth));
+               g_free (authority);
+       }
+
        if (!retrying) {
                soup_auth_authenticate (auth, "user1", "realm1");
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]