When a ticket is needed to during a connection to a SPICE channel, if there is no ticket set in the current SPICE session, we can now use the SpiceAuthFile class to lookup credentials for the connection stored in a config file, as described on http://libvirt.org/auth.html --- gtk/spice-channel.c | 67 ++++++++++++++++++++++++++++++++++++++++++------ gtk/spice-session-priv.h | 2 ++ gtk/spice-session.c | 18 +++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c index 74a02fb..335f8e5 100644 --- a/gtk/spice-channel.c +++ b/gtk/spice-channel.c @@ -19,6 +19,7 @@ #include "spice-common.h" #include "glib-compat.h" +#include "spice-auth-file.h" #include "spice-channel-priv.h" #include "spice-session-priv.h" #include "spice-marshal.h" @@ -1018,6 +1019,40 @@ static int spice_channel_read(SpiceChannel *channel, void *data, size_t length) return length; } +static char *spice_channel_get_session_password(SpiceChannel *channel) +{ + const char *password; + const char *hostname; + const char *port; + char *host; + const char *auth_file; + SpiceChannelPrivate *priv = channel->priv; + + password = spice_session_get_password(priv->session); + if (password != NULL) + return g_strdup(password); + + hostname = spice_session_get_host(priv->session); + if (hostname == NULL) + return NULL; + + if (priv->tls) { + port = spice_session_get_tls_port(priv->session); + } else { + port = spice_session_get_port(priv->session); + } + if (port == NULL) + return NULL; + + auth_file = spice_session_get_auth_file(priv->session); + host = g_strdup_printf("%s:%s", hostname, port); + password = spice_auth_file_lookup_credential(auth_file, host, + "password", NULL); + g_free(host); + + return (char *)password; +} + /* coroutine context */ static void spice_channel_send_spice_ticket(SpiceChannel *channel) { @@ -1045,7 +1080,7 @@ static void spice_channel_send_spice_ticket(SpiceChannel *channel) The use of RSA encryption limit the potential maximum password length. for RSA_PKCS1_OAEP_PADDING it is RSA_size(rsa) - 41. */ - g_object_get(c->session, "password", &password, NULL); + password = spice_channel_get_session_password(channel); if (password == NULL) password = g_strdup(""); rc = RSA_public_encrypt(strlen(password) + 1, (uint8_t*)password, @@ -1242,18 +1277,29 @@ static gchar *addr_to_string(GSocketAddress *addr) return ret; } +static void +spice_channel_free_sasl_credentials(sasl_interact_t *interact) +{ + unsigned int ninteract; + + if (interact == NULL) + return; + + for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) { + if (interact[ninteract].id == SASL_CB_PASS) + g_free((char *)interact[ninteract].result); + } +} + static gboolean spice_channel_gather_sasl_credentials(SpiceChannel *channel, - sasl_interact_t *interact) + sasl_interact_t *interact) { - SpiceChannelPrivate *c; int ninteract; g_return_val_if_fail(channel != NULL, FALSE); g_return_val_if_fail(channel->priv != NULL, FALSE); - c = channel->priv; - /* FIXME: we could keep connection open and ask connection details if missing */ for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) { @@ -1263,14 +1309,17 @@ spice_channel_gather_sasl_credentials(SpiceChannel *channel, g_warn_if_reached(); break; - case SASL_CB_PASS: - if (spice_session_get_password(c->session) == NULL) + case SASL_CB_PASS: { + char *password; + password = spice_channel_get_session_password(channel); + if (password == NULL) return FALSE; - interact[ninteract].result = spice_session_get_password(c->session); + interact[ninteract].result = password; interact[ninteract].len = strlen(interact[ninteract].result); break; } + } } CHANNEL_DEBUG(channel, "Filled SASL interact"); @@ -1631,6 +1680,7 @@ restart: } complete: + spice_channel_free_sasl_credentials(interact); CHANNEL_DEBUG(channel, "%s", "SASL authentication complete"); spice_channel_read(channel, &len, sizeof(len)); if (len != SPICE_LINK_ERR_OK) @@ -1643,6 +1693,7 @@ complete: return ret; error: + spice_channel_free_sasl_credentials(interact); g_clear_object(&addr); if (saslconn) sasl_dispose(&saslconn); diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h index 218f5c3..8423d0f 100644 --- a/gtk/spice-session-priv.h +++ b/gtk/spice-session-priv.h @@ -139,6 +139,8 @@ guint spice_session_get_verify(SpiceSession *session); const gchar* spice_session_get_password(SpiceSession *session); const gchar* spice_session_get_auth_file(SpiceSession *session); const gchar* spice_session_get_host(SpiceSession *session); +const gchar* spice_session_get_port(SpiceSession *session); +const gchar* spice_session_get_tls_port(SpiceSession *session); const gchar* spice_session_get_cert_subject(SpiceSession *session); const gchar* spice_session_get_ciphers(SpiceSession *session); const gchar* spice_session_get_ca_file(SpiceSession *session); diff --git a/gtk/spice-session.c b/gtk/spice-session.c index 9746051..289d7e7 100644 --- a/gtk/spice-session.c +++ b/gtk/spice-session.c @@ -2118,6 +2118,24 @@ const gchar* spice_session_get_host(SpiceSession *session) } G_GNUC_INTERNAL +const gchar* spice_session_get_port(SpiceSession *session) +{ + SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); + + g_return_val_if_fail(s != NULL, NULL); + return s->port; +} + +G_GNUC_INTERNAL +const gchar* spice_session_get_tls_port(SpiceSession *session) +{ + SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); + + g_return_val_if_fail(s != NULL, NULL); + return s->tls_port; +} + +G_GNUC_INTERNAL const gchar* spice_session_get_cert_subject(SpiceSession *session) { SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session); -- 1.8.2.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel