[Spice-devel] [v4: PATCH 4/4] Add support to handle username when connecting with SASL
Marc-André Lureau
mlureau at redhat.com
Wed Oct 8 05:27:22 PDT 2014
----- Original Message -----
> Based on a patch from Dietmar Maurer <dietmar at proxmox.com>
> http://lists.freedesktop.org/archives/spice-devel/2013-October/015138.html
> ---
> Changes since v3:
> - Reset auth_needs_username_and_password in channel_reset(), so object could
> be
> recycled in clean state.
> ---
> gtk/spice-channel-priv.h | 1 +
> gtk/spice-channel.c | 47
> ++++++++++++++++++++++++++++++++++++++++++-----
> po/POTFILES.in | 1 +
> 3 files changed, 44 insertions(+), 5 deletions(-)
>
> diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
> index 03eed38..6067abc 100644
> --- a/gtk/spice-channel-priv.h
> +++ b/gtk/spice-channel-priv.h
> @@ -136,6 +136,7 @@ struct _SpiceChannelPrivate {
> GSList *flushing;
>
> gboolean disable_channel_msg;
> + gboolean auth_needs_username_and_password;
> GError *error;
> };
>
> diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
> index 5d1a86e..cd031e4 100644
> --- a/gtk/spice-channel.c
> +++ b/gtk/spice-channel.c
> @@ -26,6 +26,8 @@
> #include "spice-marshal.h"
> #include "bio-gio.h"
>
> +#include <glib/gi18n.h>
> +
> #include <openssl/rsa.h>
> #include <openssl/evp.h>
> #include <openssl/x509.h>
> @@ -107,6 +109,7 @@ static void spice_channel_init(SpiceChannel *channel)
> c->out_serial = 1;
> c->in_serial = 1;
> c->fd = -1;
> + c->auth_needs_username_and_password = FALSE;
superflous, we don't initialize to 0 or FALSE, since it's done by default.
ack anyway
> strcpy(c->name, "?");
> c->caps = g_array_new(FALSE, TRUE, sizeof(guint32));
> c->common_caps = g_array_new(FALSE, TRUE, sizeof(guint32));
> @@ -1242,6 +1245,7 @@ spice_channel_gather_sasl_credentials(SpiceChannel
> *channel,
> {
> SpiceChannelPrivate *c;
> int ninteract;
> + gboolean ret = TRUE;
>
> g_return_val_if_fail(channel != NULL, FALSE);
> g_return_val_if_fail(channel->priv != NULL, FALSE);
> @@ -1254,12 +1258,22 @@ spice_channel_gather_sasl_credentials(SpiceChannel
> *channel,
> switch (interact[ninteract].id) {
> case SASL_CB_AUTHNAME:
> case SASL_CB_USER:
> - g_warn_if_reached();
> + c->auth_needs_username_and_password = TRUE;
> + if (spice_session_get_username(c->session) == NULL)
> + return FALSE;
> +
> + interact[ninteract].result =
> spice_session_get_username(c->session);
> + interact[ninteract].len = strlen(interact[ninteract].result);
> break;
>
> case SASL_CB_PASS:
> - if (spice_session_get_password(c->session) == NULL)
> - return FALSE;
> + if (spice_session_get_password(c->session) == NULL) {
> + /* Even if we reach this point, we have to continue looking
> for
> + * SASL_CB_AUTHNAME|SASL_CB_USER, otherwise we would return
> a
> + * wrong error to the applications */
> + ret = FALSE;
> + continue;
> + }
>
> interact[ninteract].result =
> spice_session_get_password(c->session);
> interact[ninteract].len = strlen(interact[ninteract].result);
> @@ -1269,7 +1283,7 @@ spice_channel_gather_sasl_credentials(SpiceChannel
> *channel,
>
> CHANNEL_DEBUG(channel, "Filled SASL interact");
>
> - return TRUE;
> + return ret;
> }
>
> /*
> @@ -1308,6 +1322,22 @@ spice_channel_gather_sasl_credentials(SpiceChannel
> *channel,
> #define SASL_MAX_MECHNAME_LEN 100
> #define SASL_MAX_DATA_LEN (1024 * 1024)
>
> +static void spice_channel_set_detailed_authentication_error(SpiceChannel
> *channel)
> +{
> + SpiceChannelPrivate *c = channel->priv;
> +
> + if (c->auth_needs_username_and_password)
> + g_set_error_literal(&c->error,
> + SPICE_CLIENT_ERROR,
> +
> SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME,
> + _("Authentication failed: password and username
> are required"));
> + else
> + g_set_error_literal(&c->error,
> + SPICE_CLIENT_ERROR,
> + SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
> + _("Authentication failed: password is
> required"));
> +}
> +
> /* Perform the SASL authentication process
> */
> static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel)
> @@ -1323,6 +1353,8 @@ static gboolean
> spice_channel_perform_auth_sasl(SpiceChannel *channel)
> const void *val;
> sasl_ssf_t ssf;
> static const sasl_callback_t saslcb[] = {
> + { .id = SASL_CB_USER },
> + { .id = SASL_CB_AUTHNAME },
> { .id = SASL_CB_PASS },
> { .id = 0 },
> };
> @@ -1624,8 +1656,10 @@ restart:
> complete:
> CHANNEL_DEBUG(channel, "%s", "SASL authentication complete");
> spice_channel_read(channel, &len, sizeof(len));
> - if (len != SPICE_LINK_ERR_OK)
> + if (len != SPICE_LINK_ERR_OK) {
> + spice_channel_set_detailed_authentication_error(channel);
> g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0,
> SPICE_CHANNEL_ERROR_AUTH);
> + }
> ret = len == SPICE_LINK_ERR_OK;
> /* This must come *after* check-auth-result, because the former
> * is defined to be sent unencrypted, and setting saslconn turns
> @@ -1636,6 +1670,7 @@ complete:
> error:
> if (saslconn)
> sasl_dispose(&saslconn);
> + spice_channel_set_detailed_authentication_error(channel);
> g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0,
> SPICE_CHANNEL_ERROR_AUTH);
> c->has_error = TRUE; /* force disconnect */
> ret = FALSE;
> @@ -2552,6 +2587,8 @@ static void channel_reset(SpiceChannel *channel,
> gboolean migrating)
>
> c->fd = -1;
>
> + c->auth_needs_username_and_password = FALSE;
> +
> g_free(c->peer_msg);
> c->peer_msg = NULL;
> c->peer_pos = 0;
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 8809121..3375ab5 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -2,6 +2,7 @@ data/spice-mime.xml.in
> data/spicy.desktop.in.in
> gtk/channel-usbredir.c
> gtk/desktop-integration.c
> +gtk/spice-channel.c
> gtk/spice-cmdline.c
> gtk/spice-option.c
> gtk/spicy-screenshot.c
> --
> 2.1.0
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>
More information about the Spice-devel
mailing list