[libsoup/wip/tpopela/negotiate: 35/64] Address more comments from [0]



commit 7a4fb0457ce5a0aa124ea580adcbc1f671a50200
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Oct 8 14:39:39 2015 +0200

    Address more comments from [0]
    
    Also add function to retrieve a name that is associated with the default
    credential for the default security mechanism. Not used yet.
    
    [0] - https://bugzilla.gnome.org/show_bug.cgi?id=587145#c47

 libsoup/libsoup-gssapi-2.4.sym |    4 ++-
 libsoup/soup-auth-manager.c    |    4 ++
 libsoup/soup-auth-negotiate.c  |   77 +++++++++++++++------------------------
 libsoup/soup-gssapi.c          |   79 +++++++++++++++++++++++++++++++++++++---
 4 files changed, 111 insertions(+), 53 deletions(-)
---
diff --git a/libsoup/libsoup-gssapi-2.4.sym b/libsoup/libsoup-gssapi-2.4.sym
index 2df49d6..58dbb6c 100644
--- a/libsoup/libsoup-gssapi-2.4.sym
+++ b/libsoup/libsoup-gssapi-2.4.sym
@@ -1,3 +1,5 @@
+soup_gss_client_cleanup
+soup_gss_client_get_name
 soup_gss_client_init
+soup_gss_client_inquire_cred
 soup_gss_client_step
-soup_gss_client_cleanup
diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index 0709c42..b38c6b5 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -13,6 +13,7 @@
 
 #include "soup-auth-manager.h"
 #include "soup.h"
+#include "soup-auth-negotiate.h"
 #include "soup-connection-auth.h"
 #include "soup-message-private.h"
 #include "soup-message-queue.h"
@@ -485,6 +486,9 @@ authenticate_auth (SoupAuthManager *manager, SoupAuth *auth,
        } else
                uri = soup_message_get_uri (msg);
 
+       if (SOUP_IS_AUTH_NEGOTIATE (auth))
+               return;
+
        /* If a password is specified explicitly in the URI, use it
         * even if the auth had previously already been authenticated.
         */
diff --git a/libsoup/soup-auth-negotiate.c b/libsoup/soup-auth-negotiate.c
index 978e8d9..7727b74 100644
--- a/libsoup/soup-auth-negotiate.c
+++ b/libsoup/soup-auth-negotiate.c
@@ -14,6 +14,7 @@
 #endif
 
 #include <string.h>
+#include <stdio.h>
 
 #include "soup-auth-negotiate.h"
 #include "soup-gssapi.h"
@@ -29,22 +30,21 @@ static void parse_trusted_uris (void);
 static gboolean check_auth_trusted_uri (SoupAuthNegotiate *negotiate,
                                        SoupMessage *msg);
 
-typedef struct {
-       char *username;
-} SoupAuthNegotiatePrivate;
-#define SOUP_AUTH_NEGOTIATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_AUTH_NEGOTIATE, 
SoupAuthNegotiatePrivate))
-
 G_DEFINE_TYPE (SoupAuthNegotiate, soup_auth_negotiate, SOUP_TYPE_CONNECTION_AUTH)
 
 /* Function pointers to dlopen'ed libsoup-gssapi */
 struct {
+       void (*client_cleanup)(SoupNegotiateConnectionState *conn);
+       char * (*client_get_name)(SoupAuth *auth,
+                                 GError **err);
        int (*client_init)(SoupNegotiateConnectionState *conn,
                           const char *host,
                           GError **err);
+       int (*client_inquire_cred)(SoupAuth *auth,
+                                  GError **err);
        int (*client_step)(SoupNegotiateConnectionState *conn,
                           const char *challenge,
                           GError **err);
-       void (*client_cleanup)(SoupNegotiateConnectionState *conn);
 } soup_gssapi_syms;
 gboolean have_gssapi;
 
@@ -55,16 +55,6 @@ soup_auth_negotiate_init (SoupAuthNegotiate *negotiate)
 {
 }
 
-static void
-soup_auth_negotiate_finalize (GObject *object)
-{
-       SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (object);
-
-       g_free (priv->username);
-
-       G_OBJECT_CLASS (soup_auth_negotiate_parent_class)->finalize (object);
-}
-
 static gpointer
 soup_auth_negotiate_create_connection_state (SoupConnectionAuth *auth)
 {
@@ -86,11 +76,15 @@ static gboolean
 soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *msg,
                                       const char *header, gpointer state)
 {
-       SoupAuthNegotiatePrivate *priv =
-               SOUP_AUTH_NEGOTIATE_GET_PRIVATE (auth);
        SoupNegotiateConnectionState *conn = state;
        GError *err = NULL;
 
+       if (!check_auth_trusted_uri (SOUP_AUTH_NEGOTIATE (auth), msg)) {
+               conn->state = SOUP_NEGOTIATE_FAILED;
+
+               return FALSE;
+       }
+
        if (conn->state > SOUP_NEGOTIATE_RECEIVED_CHALLENGE) {
                /* We already authenticated, but then got another 401.
                 * That means "permission denied", so don't try to
@@ -98,10 +92,6 @@ soup_auth_negotiate_update_connection (SoupConnectionAuth *auth, SoupMessage *ms
                 */
                conn->state = SOUP_NEGOTIATE_FAILED;
 
-               /* Make sure we don't claim to be authenticated */
-               g_free (priv->username);
-               priv->username = NULL;
-
                return FALSE;
        }
 
@@ -127,6 +117,7 @@ soup_auth_negotiate_get_protection_space (SoupAuth *auth, SoupURI *source_uri)
 
        space = g_strdup (source_uri->path);
 
+       /* FIXME does https://bugzilla.gnome.org/show_bug.cgi?id=755617 apply here as well? */
        /* Strip filename component */
        p = strrchr (space, '/');
        if (p && p != space && p[1])
@@ -139,28 +130,28 @@ static void
 soup_auth_negotiate_authenticate (SoupAuth *auth, const char *username,
                                  const char *password)
 {
-       SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (auth);
-
-       g_return_if_fail (username != NULL);
-       priv->username = g_strdup (username);
+       /* FIXME mark auth as not authenticated */
 }
 
 static gboolean
 soup_auth_negotiate_is_authenticated (SoupAuth *auth)
 {
-       return SOUP_AUTH_NEGOTIATE_GET_PRIVATE (auth)->username != NULL;
-}
+       gboolean has_credentials = FALSE;
+       GError *err = NULL;
 
-static gboolean
-soup_auth_negotiate_is_ready (SoupAuth *auth,
-                             SoupMessage *msg)
-{
-       SoupAuthNegotiate* negotiate = SOUP_AUTH_NEGOTIATE (auth);
-       return check_auth_trusted_uri (negotiate, msg);
+       if (have_gssapi)
+               has_credentials = soup_gssapi_syms.client_inquire_cred (auth, &err);
+
+       if (err)
+               g_warning ("%s", err->message);
+
+       g_clear_error (&err);
+
+       return has_credentials;
 }
 
 static void
-check_server_response(SoupMessage *msg, gpointer state)
+check_server_response (SoupMessage *msg, gpointer state)
 {
        gint ret;
        const char *auth_headers;
@@ -197,7 +188,6 @@ remove_server_response_handler(SoupMessage *msg, gpointer state)
                                              state);
 }
 
-
 static char *
 soup_auth_negotiate_get_connection_authorization (SoupConnectionAuth *auth,
                                                  SoupMessage *msg,
@@ -255,9 +245,11 @@ soup_gssapi_load (void)
 #define GSSAPI_BIND_SYMBOL(name) \
        g_return_val_if_fail (g_module_symbol (gssapi, "soup_gss_" #name, (gpointer)&soup_gssapi_syms.name), 
FALSE)
 
-       GSSAPI_BIND_SYMBOL(client_step);
-       GSSAPI_BIND_SYMBOL(client_init);
        GSSAPI_BIND_SYMBOL(client_cleanup);
+       GSSAPI_BIND_SYMBOL(client_get_name);
+       GSSAPI_BIND_SYMBOL(client_init);
+       GSSAPI_BIND_SYMBOL(client_inquire_cred);
+       GSSAPI_BIND_SYMBOL(client_step);
 #undef GSSPI_BIND_SYMBOL
        return TRUE;
 }
@@ -268,9 +260,6 @@ soup_auth_negotiate_class_init (SoupAuthNegotiateClass *auth_negotiate_class)
        SoupAuthClass *auth_class = SOUP_AUTH_CLASS (auth_negotiate_class);
        SoupConnectionAuthClass *conn_auth_class =
                        SOUP_CONNECTION_AUTH_CLASS (auth_negotiate_class);
-       GObjectClass *object_class = G_OBJECT_CLASS (auth_negotiate_class);
-
-       g_type_class_add_private (auth_negotiate_class, sizeof (SoupAuthNegotiatePrivate));
 
        auth_class->scheme_name = "Negotiate";
        auth_class->strength = 7;
@@ -278,7 +267,6 @@ soup_auth_negotiate_class_init (SoupAuthNegotiateClass *auth_negotiate_class)
        auth_class->get_protection_space = soup_auth_negotiate_get_protection_space;
        auth_class->authenticate = soup_auth_negotiate_authenticate;
        auth_class->is_authenticated = soup_auth_negotiate_is_authenticated;
-       auth_class->is_ready = soup_auth_negotiate_is_ready;
 
        conn_auth_class->create_connection_state = soup_auth_negotiate_create_connection_state;
        conn_auth_class->free_connection_state = soup_auth_negotiate_free_connection_state;
@@ -286,8 +274,6 @@ soup_auth_negotiate_class_init (SoupAuthNegotiateClass *auth_negotiate_class)
        conn_auth_class->get_connection_authorization = soup_auth_negotiate_get_connection_authorization;
        conn_auth_class->is_connection_ready = soup_auth_negotiate_is_connection_ready;
 
-       object_class->finalize = soup_auth_negotiate_finalize;
-
        parse_trusted_uris ();
        have_gssapi = soup_gssapi_load();
 }
@@ -387,13 +373,10 @@ match_base_uri (SoupURI *trusted_uri, SoupURI *msg_uri)
 static gboolean
 check_auth_trusted_uri (SoupAuthNegotiate *negotiate, SoupMessage *msg)
 {
-       SoupAuthNegotiatePrivate *priv =
-               SOUP_AUTH_NEGOTIATE_GET_PRIVATE (negotiate);
        SoupURI *msg_uri;
        GSList *matched = NULL;
 
        g_return_val_if_fail (negotiate != NULL, FALSE);
-       g_return_val_if_fail (priv != NULL, FALSE);
        g_return_val_if_fail (msg != NULL, FALSE);
 
        msg_uri = soup_message_get_uri (msg);
diff --git a/libsoup/soup-gssapi.c b/libsoup/soup-gssapi.c
index 3dc0284..10a26f2 100644
--- a/libsoup/soup-gssapi.c
+++ b/libsoup/soup-gssapi.c
@@ -17,17 +17,23 @@
 #include <gssapi/gssapi.h>
 #include <gssapi/gssapi_krb5.h>
 
+void
+soup_gss_client_cleanup (SoupNegotiateConnectionState *conn);
+
 int
 soup_gss_client_init (SoupNegotiateConnectionState *conn, const char *host, GError **err);
 
 int
-soup_gss_client_step (SoupNegotiateConnectionState *conn, const char *host, GError **err);
+soup_gss_client_inquire_cred (SoupAuth *auth, GError **err);
 
-void
-soup_gss_client_cleanup (SoupNegotiateConnectionState *conn);
+char *
+soup_gss_client_get_name (SoupAuth *auth, GError **err);
+
+int
+soup_gss_client_step (SoupNegotiateConnectionState *conn, const char *host, GError **err);
 
 static const char spnego_OID[] = "\x2b\x06\x01\x05\x05\x02";
-static const gss_OID_desc gss_mech_spnego = { 6, (void *)&spnego_OID };
+static const gss_OID_desc gss_mech_spnego = { 6, (void *) &spnego_OID };
 
 static void
 soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err)
@@ -75,6 +81,70 @@ soup_gss_error (OM_uint32 err_maj, OM_uint32 err_min, GError **err)
 }
 
 G_MODULE_EXPORT int
+soup_gss_client_inquire_cred (SoupAuth *auth, GError **err)
+{
+       gboolean ret = FALSE;
+       OM_uint32 maj_stat, min_stat;
+
+       maj_stat = gss_inquire_cred (&min_stat,
+                                    GSS_C_NO_CREDENTIAL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL);
+
+       if (GSS_ERROR (maj_stat))
+               soup_gss_error (maj_stat, min_stat, err);
+
+       ret = maj_stat == GSS_S_COMPLETE;
+
+       return ret;
+}
+
+G_MODULE_EXPORT char *
+soup_gss_client_get_name (SoupAuth *auth, GError **err)
+{
+       gchar *name = NULL;
+       OM_uint32 maj_stat, min_stat;
+       gss_name_t gss_name;
+       gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
+
+       maj_stat = gss_inquire_cred (&min_stat,
+                                    GSS_C_NO_CREDENTIAL,
+                                    &gss_name,
+                                    NULL,
+                                    NULL,
+                                    NULL);
+
+       if (GSS_ERROR (maj_stat)) {
+               soup_gss_error (maj_stat, min_stat, err);
+               goto out;
+       }
+
+       if (maj_stat != GSS_S_COMPLETE)
+               goto out;
+
+       maj_stat = gss_display_name (&min_stat,
+                                    gss_name,
+                                    &out,
+                                    NULL);
+
+       if (GSS_ERROR (maj_stat)) {
+               soup_gss_error (maj_stat, min_stat, err);
+               goto out;
+       }
+
+       if (maj_stat == GSS_S_COMPLETE)
+               name = g_strndup (out.value, out.length);
+
+       maj_stat = gss_release_buffer (&min_stat, &out);
+ out:
+       maj_stat = gss_release_name (&min_stat, &gss_name);
+
+       return name;
+}
+
+G_MODULE_EXPORT int
 soup_gss_client_init (SoupNegotiateConnectionState *conn, const char *host, GError **err)
 {
        OM_uint32 maj_stat, min_stat;
@@ -161,7 +231,6 @@ out:
        return ret;
 }
 
-
 G_MODULE_EXPORT void
 soup_gss_client_cleanup (SoupNegotiateConnectionState *conn)
 {


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