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

Jeremy White jwhite at codeweavers.com
Thu Jan 22 09:02:31 PST 2015


*blush*.  This is badly broken..

Teach me to test man pages / help stuff, without revisiting basic
functionality.

v3 to follow, sorry for the noise.

Cheers,

Jeremy

On 01/21/2015 03:05 PM, Jeremy White wrote:
> Add an optional args parameter to the --spice-smartcard which
> will be passed to vcard_emul_options.
> 
> This allows us to deprecate the --smartcard-db and
> --smartcard-certificates options as well.
> 
> Signed-off-by: Jeremy White <jwhite at codeweavers.com>
> ---
>  gtk/smartcard-manager.c |   14 ++++++++++++++
>  gtk/spice-option.c      |   21 +++++++++++++++++++--
>  gtk/spice-session.c     |   36 ++++++++++++++++++++++++++++++++++--
>  man/spice-client.pod    |   37 ++++++++++++++++++++++++++++---------
>  4 files changed, 95 insertions(+), 13 deletions(-)
> 
> diff --git a/gtk/smartcard-manager.c b/gtk/smartcard-manager.c
> index 9e228e9..9e4b313 100644
> --- a/gtk/smartcard-manager.c
> +++ b/gtk/smartcard-manager.c
> @@ -416,14 +416,27 @@ static gboolean smartcard_manager_init(SmartcardManagerInitArgs *args)
>      gchar *dbname = NULL;
>      GStrv certificates = NULL;
>      gboolean retval = FALSE;
> +    gchar *smartcard_args = 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-args", &smartcard_args,
>                   NULL);
>  
> +    if (smartcard_args) {
> +        options = vcard_emul_options(smartcard_args);
> +        if (options == NULL) {
> +            args->err = g_error_new(SPICE_CLIENT_ERROR,
> +                                    SPICE_CLIENT_ERROR_FAILED,
> +                                    "vcard_emul_options() failed!");
> +            goto end;
> +        }
> +        goto init;
> +    }
> +
>      if ((certificates == NULL) || (g_strv_length(certificates) != 3))
>          goto init;
>  
> @@ -466,6 +479,7 @@ init:
>  
>  end:
>      SPICE_DEBUG("smartcard_manager_init end: %d", retval);
> +    g_free(smartcard_args);
>      g_free(emul_args);
>      g_free(dbname);
>      g_strfreev(certificates);
> diff --git a/gtk/spice-option.c b/gtk/spice-option.c
> index 958e03c..f444656 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_args = NULL;
>  static gboolean disable_audio = FALSE;
>  static gboolean disable_usbredir = FALSE;
>  static gint cache_size = 0;
> @@ -150,6 +151,19 @@ static gboolean parse_usbredir_filter(const gchar *option_name,
>  }
>  
>  
> +static gboolean parse_smartcard(const gchar *option_name, const gchar *value,
> +                                      gpointer data, GError **error)
> +{
> +    if (! value || strlen(value) == 0)
> +        smartcard_args = NULL;
> +    else
> +        smartcard_args = g_strdup(value);
> +
> +    smartcard = TRUE;
> +    return TRUE;
> +}
> +
> +
>  /**
>   * spice_get_option_group: (skip)
>   *
> @@ -173,8 +187,9 @@ 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[=emul_args]", '\0', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, parse_smartcard,
> +          N_("Enable smartcard support.  By default, the client will emulate a CAC card using libnss. "
> +             "Specify an argument of 'passthru' to use pcsclite to pass card data directly"), 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 +273,8 @@ void spice_set_session_option(SpiceSession *session)
>          }
>          if (smartcard_db)
>              g_object_set(session, "smartcard-db", smartcard_db, NULL);
> +        if (smartcard_args)
> +            g_object_set(session, "smartcard-args", smartcard_args, 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 d7f014c..85b1036 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_args;
>  
>      /* 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_ARGS,
>      PROP_SMARTCARD_CERTIFICATES,
>      PROP_SMARTCARD_DB,
>      PROP_USBREDIR,
> @@ -326,6 +328,7 @@ spice_session_finalize(GObject *gobject)
>      g_free(s->ca_file);
>      g_free(s->ciphers);
>      g_free(s->cert_subject);
> +    g_free(s->smartcard_args);
>      g_strfreev(s->smartcard_certificates);
>      g_free(s->smartcard_db);
>      g_strfreev(s->disable_effects);
> @@ -570,6 +573,9 @@ static void spice_session_get_property(GObject    *gobject,
>      case PROP_SMARTCARD:
>          g_value_set_boolean(value, s->smartcard);
>          break;
> +    case PROP_SMARTCARD_ARGS:
> +        g_value_set_string(value, s->smartcard_args);
> +        break;
>      case PROP_SMARTCARD_CERTIFICATES:
>          g_value_set_boxed(value, s->smartcard_certificates);
>          break;
> @@ -696,6 +702,10 @@ static void spice_session_set_property(GObject      *gobject,
>      case PROP_SMARTCARD:
>          s->smartcard = g_value_get_boolean(value);
>          break;
> +    case PROP_SMARTCARD_ARGS:
> +        g_free(s->smartcard_args);
> +        s->smartcard_args = 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 +1035,26 @@ static void spice_session_class_init(SpiceSessionClass *klass)
>                            G_PARAM_STATIC_STRINGS));
>  
>      /**
> +     * SpiceSession:smartcard-args:
> +     *
> +     * Can be specified in order to set vcard_emul_options.
> +     *  The most useful alternate value is
> +     *    "hw=yes hw_type=passthru"
> +     *  which will use pcsclite to pass smartcard access through
> +     *
> +     * Since: 0.28
> +     **/
> +    g_object_class_install_property
> +        (gobject_class, PROP_SMARTCARD_ARGS,
> +         g_param_spec_string("smartcard-args",
> +                          "Arguments to pass when connecting the smartcard.",
> +                          "Options to pass to vcard_emul_options to create a smartcard.  The default is 'emulnss' which will use libnss to emulate a CAC card."
> +                          " A value of 'passthru' will use pcsclite to directly interact with the card.",
> +                          FALSE,
> +                          G_PARAM_READWRITE |
> +                          G_PARAM_STATIC_STRINGS));
> +
> +    /**
>       * SpiceSession:enable-audio:
>       *
>       * If set to TRUE, the audio channels will be enabled for
> @@ -1051,12 +1081,13 @@ static void spice_session_class_init(SpiceSessionClass *klass)
>       * See also spice_smartcard_manager_insert_card()
>       *
>       * Since: 0.7
> +     * Deprecated since: 0.28
>       **/
>      g_object_class_install_property
>          (gobject_class, PROP_SMARTCARD_CERTIFICATES,
>           g_param_spec_boxed("smartcard-certificates",
>                              "Smartcard certificates",
> -                            "Smartcard certificates for software-based smartcards",
> +                            "Smartcard certificates for software-based smartcards. Deprecated; use soft=(,Spice Software Smartcard,cac,,cert1,cert2,cert3) in smartcard-args instead.",
>                              G_TYPE_STRV,
>                              G_PARAM_READABLE |
>                              G_PARAM_WRITABLE |
> @@ -1069,12 +1100,13 @@ static void spice_session_class_init(SpiceSessionClass *klass)
>       * use to simulate a software smartcard
>       *
>       * Since: 0.7
> +     * Deprecated since: 0.28
>       **/
>      g_object_class_install_property
>          (gobject_class, PROP_SMARTCARD_DB,
>           g_param_spec_string("smartcard-db",
>                                "Smartcard certificate database",
> -                              "Path to the database for smartcard certificates",
> +                              "Path to the database for smartcard certificates. Deprecated; add db=\"name\" to smartcard-args instead.",
>                                NULL,
>                                G_PARAM_READABLE |
>                                G_PARAM_WRITABLE |
> diff --git a/man/spice-client.pod b/man/spice-client.pod
> index 69ea84c..0085345 100644
> --- a/man/spice-client.pod
> +++ b/man/spice-client.pod
> @@ -140,27 +140,46 @@ when a SPICE connection to a remote display has been established.
>  
>  Display Spice-GTK version information
>  
> -=item --spice-smartcard
> +=item --spice-smartcard=[smartcard-args]
>  
>  Enable smartcard support
>  
> +The optional argument can be:
> +  emulnss   (default)
> +  passthru
> +  [db="<certificate-db>"] soft=(,Spice Software Smartcard,CAC,,cert1,cert2,cert3)
> +
> +The emulnss option is the default, and will cause the client to use libnss to access
> +the card, and then to simulate a CAC card.
> +
> +The passthru option will cause the client to use pcsclite to access the card,
> +and attempt to pass through the raw card data.
> +
> +The final option is used for testing to simulate a smartcard using certificates.
> +
> +The certificate-db is an optional path to the location of the certificates;
> +the default is /etc/pki/nssdb.  cert1, cert2, and cert3 are certificate names that
> +you have previously generated.
> +
> +See C<http://www.spice-space.org/page/SmartcardUsage#Using_a_software_smartcard>
> +for more details about how to generate these certificates.
> +
> +You can also learn more about these arguments by examining the usage statement
> +of the vscclient utility.
> +
>  =item --spice-smartcard-db=<certificate-db>
>  
>  Path to the local certificate database to use for software smartcard certificates
>  
> -This option is only useful for testing purpose. Instead of having a hardware
> -smartcard reader, and a physical smartcard, you can specify a file containing 3
> -certificates which will be used to emulate a smartcard in software. See
> -C<http://www.spice-space.org/page/SmartcardUsage#Using_a_software_smartcard>
> -for more details about how to generate these certificates.
> +This option is deprecated; the database path should be given in the arguments to the
> +--spice-smartcard option.
>  
>  =item --spice-smartcard-certificates=<certificates>
>  
>  Certificates to use for software smartcards (field=values separated by commas)
>  
> -This option is only useful for testing purpose. This allows to specify which
> -certificates from the certificate database specified with --spice-smartcard-db
> -should be used for smartcard emulation.
> +This option is deprecated; the certificates should be passed as an argument to
> +the --spice-smartcard option.
>  
>  =item --spice-cache-size=<bytes>
>  
> 



More information about the Spice-devel mailing list