[Spice-devel] [PATCH] Provide support for using the passthru smartcard mode in libcacard.

Marc-André Lureau marcandre.lureau at gmail.com
Mon Jan 19 07:26:44 PST 2015


On Mon, Jan 19, 2015 at 4:01 PM, Jeremy White <jwhite at codeweavers.com> wrote:
>
> Signed-off-by: Jeremy White <jwhite at codeweavers.com>
> ---
>  gtk/smartcard-manager.c |   14 ++++++++++++++
>  gtk/spice-option.c      |   23 +++++++++++++++++++++--
>  gtk/spice-session.c     |   26 ++++++++++++++++++++++++++
>  man/spice-client.pod    |    7 +++++--
>  4 files changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c
> index 9e228e9..d605c99 100644
> --- a/gtk/smartcard-manager.c
> +++ b/gtk/smartcard-manager.c
> @@ -416,14 +416,28 @@ static gboolean smartcard_manager_init(SmartcardManagerInitArgs *args)
>      gchar *dbname = NULL;
>      GStrv certificates = NULL;
>      gboolean retval = FALSE;
> +    gchar *smartcard_type = NULL;
>
>      SPICE_DEBUG("smartcard_manager_init");
>      g_return_val_if_fail(SPICE_IS_SESSION(args->session), FALSE);
>      g_object_get(G_OBJECT(args->session),
>                   "smartcard-db", &dbname,
>                   "smartcard-certificates", &certificates,
> +                 "smartcard-type", &smartcard_type,
>                   NULL);
>
> +    if (g_strcmp0(smartcard_type, "passthru") == 0) {
> +        emul_args = g_strdup_printf("use_hw=yes hw_type=passthru");
> +        options = vcard_emul_options(emul_args);
> +        if (options == NULL) {
> +            args->err = g_error_new(SPICE_CLIENT_ERROR,
> +                                    SPICE_CLIENT_ERROR_FAILED,
> +                                    "vcard_emul_options() for passthru failed!");
> +            goto end;
> +        }
> +        goto init;
> +    }
> +
>      if ((certificates == NULL) || (g_strv_length(certificates) != 3))
>          goto init;
>
> diff --git a/gtk/spice-option.c b/gtk/spice-option.c
> index 958e03c..5b53cb3 100644
> --- a/gtk/spice-option.c
> +++ b/gtk/spice-option.c
> @@ -35,6 +35,7 @@ static char *smartcard_certificates = NULL;
>  static char *usbredir_auto_redirect_filter = NULL;
>  static char *usbredir_redirect_on_connect = NULL;
>  static gboolean smartcard = FALSE;
> +static char * smartcard_type = NULL;
>  static gboolean disable_audio = FALSE;
>  static gboolean disable_usbredir = FALSE;
>  static gint cache_size = 0;
> @@ -149,6 +150,22 @@ static gboolean parse_usbredir_filter(const gchar *option_name,
>      return TRUE;
>  }
>
> +static gboolean parse_smartcard(const gchar *option_name, const gchar *value,
> +                                      gpointer data, GError **error)
> +{
> +    if (! value || strlen(value) == 0 || g_strcmp0(value, "nssemul") == 0)
> +        smartcard_type = "nssemul";
> +    else if (g_strcmp0(value, "passthru") == 0)
> +        smartcard_type = "passthru";
> +    else {
> +            g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
> +                        _("invalid smartcard type (%s), valid types: nssemul, passthru"), value);
> +            return FALSE;
> +    }
> +
> +    smartcard = TRUE;
> +    return TRUE;
> +}
>
>  /**
>   * spice_get_option_group: (skip)
> @@ -173,8 +190,8 @@ GOptionGroup* spice_get_option_group(void)
>            N_("Subject of the host certificate (field=value pairs separated by commas)"), N_("<host-subject>") },
>          { "spice-disable-audio", '\0', 0, G_OPTION_ARG_NONE, &disable_audio,
>            N_("Disable audio support"), NULL },
> -        { "spice-smartcard", '\0', 0, G_OPTION_ARG_NONE, &smartcard,
> -          N_("Enable smartcard support"), NULL },
> +        { "spice-smartcard", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, parse_smartcard,
> +          N_("Enable smartcard support (you can specify nssemul, the default, or passthru)"), NULL },
>          { "spice-smartcard-certificates", '\0', 0, G_OPTION_ARG_STRING, &smartcard_certificates,
>            N_("Certificates to use for software smartcards (field=values separated by commas)"), N_("<certificates>") },
>          { "spice-smartcard-db", '\0', 0, G_OPTION_ARG_STRING, &smartcard_db,
> @@ -258,6 +275,8 @@ void spice_set_session_option(SpiceSession *session)
>          }
>          if (smartcard_db)
>              g_object_set(session, "smartcard-db", smartcard_db, NULL);
> +        if (smartcard_type)
> +            g_object_set(session, "smartcard-type", smartcard_type, NULL);
>      }
>      if (usbredir_auto_redirect_filter) {
>          SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL);
> diff --git a/gtk/spice-session.c b/gtk/spice-session.c
> index 7971f3c..6f97fd0 100644
> --- a/gtk/spice-session.c
> +++ b/gtk/spice-session.c
> @@ -64,6 +64,7 @@ struct _SpiceSessionPrivate {
>
>      /* whether to enable smartcard event forwarding to the server */
>      gboolean          smartcard;
> +    gchar             *smartcard_type;
>
>      /* list of certificates to use for the software smartcard reader if
>       * enabled. For now, it has to contain exactly 3 certificates for
> @@ -182,6 +183,7 @@ enum {
>      PROP_MIGRATION_STATE,
>      PROP_AUDIO,
>      PROP_SMARTCARD,
> +    PROP_SMARTCARD_TYPE,
>      PROP_SMARTCARD_CERTIFICATES,
>      PROP_SMARTCARD_DB,
>      PROP_USBREDIR,

Missing g_free(s->smartcard_type); in finalize

> @@ -570,6 +572,9 @@ static void spice_session_get_property(GObject    *gobject,
>      case PROP_SMARTCARD:
>          g_value_set_boolean(value, s->smartcard);
>          break;
> +    case PROP_SMARTCARD_TYPE:
> +        g_value_set_string(value, s->smartcard_type);
> +        break;
>      case PROP_SMARTCARD_CERTIFICATES:
>          g_value_set_boxed(value, s->smartcard_certificates);
>          break;
> @@ -696,6 +701,10 @@ static void spice_session_set_property(GObject      *gobject,
>      case PROP_SMARTCARD:
>          s->smartcard = g_value_get_boolean(value);
>          break;
> +    case PROP_SMARTCARD_TYPE:
> +        g_free(s->smartcard_type);
> +        s->smartcard_type = g_value_dup_string(value);
> +        break;
>      case PROP_SMARTCARD_CERTIFICATES:
>          g_strfreev(s->smartcard_certificates);
>          s->smartcard_certificates = g_value_dup_boxed(value);
> @@ -1025,6 +1034,23 @@ static void spice_session_class_init(SpiceSessionClass *klass)
>                            G_PARAM_STATIC_STRINGS));
>
>      /**
> +     * SpiceSession:smartcard-type:
> +     *
> +     * Can be set to nssemul to emulate a CAC card via libnss, or
> +     *  passthru to use pcsclite to pass smartcard access through
> +     *
> +     * Since: 0.28
> +     **/
> +    g_object_class_install_property
> +        (gobject_class, PROP_SMARTCARD_TYPE,
> +         g_param_spec_string("smartcard-type",
> +                          "Type of smartcard access to use.",
> +                          "The default is nssemul, which uses libnss to emulate a CAC card.  Specifying passthru will use pcsclite to directly interact with the card.",
> +                          FALSE,

Default value should not be FALSE, I would use "nssemul".

However, I wonder since the possible values are defined and fixed, and
not passed directly to vcard_emul_options(), if it shouldn't be an
enum instead.

Actually, a more future-proof property would be to have a smartcard
emul-options string, don't you think?

> +                          G_PARAM_READWRITE |
> +                          G_PARAM_STATIC_STRINGS));
> +
> +    /**
>       * SpiceSession:enable-audio:
>       *
>       * If set to TRUE, the audio channels will be enabled for
> diff --git a/man/spice-client.pod b/man/spice-client.pod
> index 69ea84c..acf457f 100644
> --- a/man/spice-client.pod
> +++ b/man/spice-client.pod
> @@ -140,9 +140,12 @@ when a SPICE connection to a remote display has been established.
>
>  Display Spice-GTK version information
>
> -=item --spice-smartcard
> +=item --spice-smartcard[=type]
>
> -Enable smartcard support
> +Enable smartcard support.  By default (type nssemul) the client will use
> +libnss to access the card, and simulate a CAC card.  If a type of passthru
> +is given, the client will instead use pcsclite and attempt to pass thru
> +the raw card commands.
>
>  =item --spice-smartcard-db=<certificate-db>
>

Other than this discussion around the option & property, patch is good to me.

> --
> 1.7.10.4
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel



-- 
Marc-André Lureau


More information about the Spice-devel mailing list