[Spice-devel] [spice-gtk 5/5] Use credentials from config file
Christophe Fergeau
cfergeau at redhat.com
Tue Jun 4 07:19:14 PDT 2013
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
More information about the Spice-devel
mailing list