[Spice-devel] [PATCH v4 spice-gtk] Provide support for using the passthru smartcard mode in libcacard.
Jeremy White
jwhite at codeweavers.com
Mon Oct 12 10:59:52 PDT 2015
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>
---
Changes since v3:
* Retested with new libcacard
* Updated version numbers to current
---
man/spice-client.pod | 37 ++++++++++++++++++++++++++++---------
src/smartcard-manager.c | 14 ++++++++++++++
src/spice-option.c | 21 +++++++++++++++++++--
src/spice-session.c | 36 ++++++++++++++++++++++++++++++++++--
4 files changed, 95 insertions(+), 13 deletions(-)
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>
diff --git a/src/smartcard-manager.c b/src/smartcard-manager.c
index 8e0d239..7c6685d 100644
--- a/src/smartcard-manager.c
+++ b/src/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/src/spice-option.c b/src/spice-option.c
index 06b9b19..983dad9 100644
--- a/src/spice-option.c
+++ b/src/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;
@@ -178,6 +179,19 @@ static gboolean parse_preferred_compression(const gchar *option_name, const gcha
return TRUE;
}
+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)
*
@@ -203,8 +217,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", '\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,
@@ -295,6 +310,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/src/spice-session.c b/src/spice-session.c
index 85640a5..0e74f48 100644
--- a/src/spice-session.c
+++ b/src/spice-session.c
@@ -68,6 +68,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
@@ -186,6 +187,7 @@ enum {
PROP_MIGRATION_STATE,
PROP_AUDIO,
PROP_SMARTCARD,
+ PROP_SMARTCARD_ARGS,
PROP_SMARTCARD_CERTIFICATES,
PROP_SMARTCARD_DB,
PROP_USBREDIR,
@@ -366,6 +368,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);
@@ -644,6 +647,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;
@@ -780,6 +786,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);
@@ -1132,6 +1142,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.31
+ **/
+ 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
@@ -1158,12 +1188,13 @@ static void spice_session_class_init(SpiceSessionClass *klass)
* See also spice_smartcard_manager_insert_card()
*
* Since: 0.7
+ * Deprecated since: 0.30
**/
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 |
@@ -1176,12 +1207,13 @@ static void spice_session_class_init(SpiceSessionClass *klass)
* use to simulate a software smartcard
*
* Since: 0.7
+ * Deprecated since: 0.30
**/
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 |
--
2.1.4
More information about the Spice-devel
mailing list