|
|
37ea90 |
From 3aa4de5e6f2b698abf063ddbea5008f5b732aa18 Mon Sep 17 00:00:00 2001
|
|
|
2f9b22 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
2f9b22 |
Date: Fri, 9 Feb 2018 16:40:53 -0500
|
|
|
2f9b22 |
Subject: [PATCH 2/2] smartcard: handle a smartcard getting removed very
|
|
|
2f9b22 |
shortly after login
|
|
|
2f9b22 |
|
|
|
2f9b22 |
Right now we depend on the smartcard used at login time to be inserted,
|
|
|
2f9b22 |
at least long enough to read some basic stats about it. This
|
|
|
2f9b22 |
assumption, of course doesn't necessarly need to hold true. A user
|
|
|
2f9b22 |
could remove the smartcard immediately after login and we would
|
|
|
2f9b22 |
misreport that the card wasn't used for login at all.
|
|
|
2f9b22 |
|
|
|
2f9b22 |
This commit addresses that edge case by creating a login_token
|
|
|
2f9b22 |
smartcard alias object that's around even if the login token isn't.
|
|
|
2f9b22 |
Once the login token does show up it gets synchronized with it, so
|
|
|
2f9b22 |
both object paths refer to the same underlying token.
|
|
|
2f9b22 |
---
|
|
|
37ea90 |
plugins/smartcard/gsd-smartcard-service.c | 82 +++++++++++++++++++++++
|
|
|
2f9b22 |
1 file changed, 82 insertions(+)
|
|
|
2f9b22 |
|
|
|
2f9b22 |
diff --git a/plugins/smartcard/gsd-smartcard-service.c b/plugins/smartcard/gsd-smartcard-service.c
|
|
|
2f9b22 |
index 0710334b..6969ff34 100644
|
|
|
2f9b22 |
--- a/plugins/smartcard/gsd-smartcard-service.c
|
|
|
2f9b22 |
+++ b/plugins/smartcard/gsd-smartcard-service.c
|
|
|
2f9b22 |
@@ -11,60 +11,61 @@
|
|
|
2f9b22 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
2f9b22 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
2f9b22 |
* General Public License for more details.
|
|
|
2f9b22 |
*
|
|
|
2f9b22 |
* You should have received a copy of the GNU General Public License
|
|
|
2f9b22 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
2f9b22 |
*
|
|
|
2f9b22 |
* Authors: Ray Strode
|
|
|
2f9b22 |
*/
|
|
|
2f9b22 |
|
|
|
2f9b22 |
#include "config.h"
|
|
|
2f9b22 |
|
|
|
2f9b22 |
#include "gsd-smartcard-service.h"
|
|
|
2f9b22 |
#include "org.gnome.SettingsDaemon.Smartcard.h"
|
|
|
2f9b22 |
#include "gsd-smartcard-manager.h"
|
|
|
2f9b22 |
#include "gsd-smartcard-enum-types.h"
|
|
|
2f9b22 |
#include "gsd-smartcard-utils.h"
|
|
|
2f9b22 |
|
|
|
2f9b22 |
#include <glib/gi18n.h>
|
|
|
2f9b22 |
#include <glib/gstdio.h>
|
|
|
2f9b22 |
#include <gio/gio.h>
|
|
|
2f9b22 |
|
|
|
2f9b22 |
struct _GsdSmartcardServicePrivate
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GDBusConnection *bus_connection;
|
|
|
2f9b22 |
GDBusObjectManagerServer *object_manager_server;
|
|
|
2f9b22 |
GsdSmartcardManager *smartcard_manager;
|
|
|
2f9b22 |
GCancellable *cancellable;
|
|
|
2f9b22 |
GHashTable *tokens;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
+ gboolean login_token_bound;
|
|
|
2f9b22 |
guint name_id;
|
|
|
2f9b22 |
};
|
|
|
2f9b22 |
|
|
|
2f9b22 |
#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
|
|
|
2f9b22 |
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
|
|
|
2f9b22 |
#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
|
|
|
2f9b22 |
|
|
|
2f9b22 |
#define GSD_SMARTCARD_DBUS_NAME GSD_DBUS_NAME ".Smartcard"
|
|
|
2f9b22 |
#define GSD_SMARTCARD_DBUS_PATH GSD_DBUS_PATH "/Smartcard"
|
|
|
2f9b22 |
#define GSD_SMARTCARD_MANAGER_DBUS_PATH GSD_SMARTCARD_DBUS_PATH "/Manager"
|
|
|
2f9b22 |
#define GSD_SMARTCARD_MANAGER_DRIVERS_DBUS_PATH GSD_SMARTCARD_MANAGER_DBUS_PATH "/Drivers"
|
|
|
2f9b22 |
#define GSD_SMARTCARD_MANAGER_TOKENS_DBUS_PATH GSD_SMARTCARD_MANAGER_DBUS_PATH "/Tokens"
|
|
|
2f9b22 |
|
|
|
2f9b22 |
enum {
|
|
|
2f9b22 |
PROP_0,
|
|
|
2f9b22 |
PROP_MANAGER,
|
|
|
2f9b22 |
PROP_BUS_CONNECTION
|
|
|
2f9b22 |
};
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static void gsd_smartcard_service_set_property (GObject *object,
|
|
|
2f9b22 |
guint property_id,
|
|
|
2f9b22 |
const GValue *value,
|
|
|
2f9b22 |
GParamSpec *param_spec);
|
|
|
2f9b22 |
static void gsd_smartcard_service_get_property (GObject *object,
|
|
|
2f9b22 |
guint property_id,
|
|
|
2f9b22 |
GValue *value,
|
|
|
2f9b22 |
GParamSpec *param_spec);
|
|
|
2f9b22 |
static void async_initable_interface_init (GAsyncInitableIface *interface);
|
|
|
2f9b22 |
static void smartcard_service_manager_interface_init (GsdSmartcardServiceManagerIface *interface);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
@@ -83,91 +84,139 @@ set_bus_connection (GsdSmartcardService *self,
|
|
|
2f9b22 |
GDBusConnection *connection)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardServicePrivate *priv = self->priv;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
if (priv->bus_connection != connection) {
|
|
|
2f9b22 |
g_clear_object (&priv->bus_connection);
|
|
|
2f9b22 |
priv->bus_connection = g_object_ref (connection);
|
|
|
2f9b22 |
g_object_notify (G_OBJECT (self), "bus-connection");
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static void
|
|
|
2f9b22 |
register_object_manager (GsdSmartcardService *self)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardServiceObjectSkeleton *object;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
self->priv->object_manager_server = g_dbus_object_manager_server_new (GSD_SMARTCARD_DBUS_PATH);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
object = gsd_smartcard_service_object_skeleton_new (GSD_SMARTCARD_MANAGER_DBUS_PATH);
|
|
|
2f9b22 |
gsd_smartcard_service_object_skeleton_set_manager (object,
|
|
|
2f9b22 |
GSD_SMARTCARD_SERVICE_MANAGER (self));
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_dbus_object_manager_server_export (self->priv->object_manager_server,
|
|
|
2f9b22 |
G_DBUS_OBJECT_SKELETON (object));
|
|
|
2f9b22 |
g_object_unref (object);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_dbus_object_manager_server_set_connection (self->priv->object_manager_server,
|
|
|
2f9b22 |
self->priv->bus_connection);
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
+static const char *
|
|
|
2f9b22 |
+get_login_token_object_path (GsdSmartcardService *self)
|
|
|
2f9b22 |
+{
|
|
|
2f9b22 |
+ return GSD_SMARTCARD_MANAGER_TOKENS_DBUS_PATH "/login_token";
|
|
|
2f9b22 |
+}
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+static void
|
|
|
2f9b22 |
+register_login_token_alias (GsdSmartcardService *self)
|
|
|
2f9b22 |
+{
|
|
|
2f9b22 |
+ GsdSmartcardServicePrivate *priv;
|
|
|
2f9b22 |
+ GDBusObjectSkeleton *object;
|
|
|
2f9b22 |
+ GDBusInterfaceSkeleton *interface;
|
|
|
2f9b22 |
+ const char *object_path;
|
|
|
2f9b22 |
+ const char *token_name;
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ token_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME");
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ if (token_name == NULL)
|
|
|
2f9b22 |
+ return;
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ priv = self->priv;
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ object_path = get_login_token_object_path (self);
|
|
|
2f9b22 |
+ object = G_DBUS_OBJECT_SKELETON (gsd_smartcard_service_object_skeleton_new (object_path));
|
|
|
2f9b22 |
+ interface = G_DBUS_INTERFACE_SKELETON (gsd_smartcard_service_token_skeleton_new ());
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ g_dbus_object_skeleton_add_interface (object, interface);
|
|
|
2f9b22 |
+ g_object_unref (interface);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ g_object_set (G_OBJECT (interface),
|
|
|
2f9b22 |
+ "name", token_name,
|
|
|
2f9b22 |
+ "used-to-login", TRUE,
|
|
|
2f9b22 |
+ "is-inserted", FALSE,
|
|
|
2f9b22 |
+ NULL);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ g_dbus_object_manager_server_export (self->priv->object_manager_server,
|
|
|
2f9b22 |
+ object);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ G_LOCK (gsd_smartcard_tokens);
|
|
|
2f9b22 |
+ g_hash_table_insert (priv->tokens, g_strdup (object_path), interface);
|
|
|
2f9b22 |
+ G_UNLOCK (gsd_smartcard_tokens);
|
|
|
2f9b22 |
+}
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
static void
|
|
|
2f9b22 |
on_bus_gotten (GObject *source_object,
|
|
|
2f9b22 |
GAsyncResult *result,
|
|
|
2f9b22 |
GTask *task)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardService *self;
|
|
|
2f9b22 |
GsdSmartcardServicePrivate *priv;
|
|
|
2f9b22 |
GDBusConnection *connection;
|
|
|
2f9b22 |
GError *error = NULL;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
connection = g_bus_get_finish (result, &error);
|
|
|
2f9b22 |
if (connection == NULL) {
|
|
|
2f9b22 |
g_task_return_error (task, error);
|
|
|
2f9b22 |
goto out;
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_debug ("taking name %s on session bus", GSD_SMARTCARD_DBUS_NAME);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
self = g_task_get_source_object (task);
|
|
|
2f9b22 |
priv = self->priv;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
set_bus_connection (self, connection);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
register_object_manager (self);
|
|
|
2f9b22 |
priv->name_id = g_bus_own_name_on_connection (connection,
|
|
|
2f9b22 |
GSD_SMARTCARD_DBUS_NAME,
|
|
|
2f9b22 |
G_BUS_NAME_OWNER_FLAGS_NONE,
|
|
|
2f9b22 |
NULL,
|
|
|
2f9b22 |
NULL,
|
|
|
2f9b22 |
NULL,
|
|
|
2f9b22 |
NULL);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ /* In case the login token is removed at start up, register an
|
|
|
2f9b22 |
+ * an alias interface that's always around
|
|
|
2f9b22 |
+ */
|
|
|
2f9b22 |
+ register_login_token_alias (self);
|
|
|
2f9b22 |
g_task_return_boolean (task, TRUE);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
out:
|
|
|
2f9b22 |
g_object_unref (task);
|
|
|
2f9b22 |
return;
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static gboolean
|
|
|
2f9b22 |
gsd_smartcard_service_initable_init_finish (GAsyncInitable *initable,
|
|
|
2f9b22 |
GAsyncResult *result,
|
|
|
2f9b22 |
GError **error)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GTask *task;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
task = G_TASK (result);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
return g_task_propagate_boolean (task, error);
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static void
|
|
|
2f9b22 |
gsd_smartcard_service_initable_init_async (GAsyncInitable *initable,
|
|
|
2f9b22 |
int io_priority,
|
|
|
2f9b22 |
GCancellable *cancellable,
|
|
|
2f9b22 |
GAsyncReadyCallback callback,
|
|
|
2f9b22 |
gpointer user_data)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (initable);
|
|
|
2f9b22 |
GTask *task;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
task = g_task_new (G_OBJECT (self), cancellable, callback, user_data);
|
|
|
2f9b22 |
@@ -191,60 +240,75 @@ get_object_path_for_token (GsdSmartcardService *self,
|
|
|
2f9b22 |
char *escaped_library_path;
|
|
|
2f9b22 |
SECMODModule *driver;
|
|
|
2f9b22 |
CK_SLOT_ID slot_id;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
driver = PK11_GetModule (card_slot);
|
|
|
2f9b22 |
slot_id = PK11_GetSlotID (card_slot);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
escaped_library_path = gsd_smartcard_utils_escape_object_path (driver->dllName);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
object_path = g_strdup_printf ("%s/token_from_%s_slot_%lu",
|
|
|
2f9b22 |
GSD_SMARTCARD_MANAGER_TOKENS_DBUS_PATH,
|
|
|
2f9b22 |
escaped_library_path,
|
|
|
2f9b22 |
(gulong) slot_id);
|
|
|
2f9b22 |
g_free (escaped_library_path);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
return object_path;
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static gboolean
|
|
|
2f9b22 |
gsd_smartcard_service_handle_get_login_token (GsdSmartcardServiceManager *manager,
|
|
|
2f9b22 |
GDBusMethodInvocation *invocation)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (manager);
|
|
|
2f9b22 |
GsdSmartcardServicePrivate *priv = self->priv;
|
|
|
2f9b22 |
PK11SlotInfo *card_slot;
|
|
|
2f9b22 |
char *object_path;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
card_slot = gsd_smartcard_manager_get_login_token (priv->smartcard_manager);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
if (card_slot == NULL) {
|
|
|
2f9b22 |
+ const char *login_token_object_path;
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ /* If we know there's a login token but it was removed before the
|
|
|
2f9b22 |
+ * smartcard manager could examine it, just return the generic login
|
|
|
2f9b22 |
+ * token object path
|
|
|
2f9b22 |
+ */
|
|
|
2f9b22 |
+ login_token_object_path = get_login_token_object_path (self);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ if (g_hash_table_contains (priv->tokens, login_token_object_path)) {
|
|
|
2f9b22 |
+ gsd_smartcard_service_manager_complete_get_login_token (manager,
|
|
|
2f9b22 |
+ invocation,
|
|
|
2f9b22 |
+ login_token_object_path);
|
|
|
2f9b22 |
+ return TRUE;
|
|
|
2f9b22 |
+ }
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
g_dbus_method_invocation_return_error (invocation,
|
|
|
2f9b22 |
GSD_SMARTCARD_MANAGER_ERROR,
|
|
|
2f9b22 |
GSD_SMARTCARD_MANAGER_ERROR_FINDING_SMARTCARD,
|
|
|
2f9b22 |
_("User was not logged in with smartcard."));
|
|
|
2f9b22 |
|
|
|
2f9b22 |
return TRUE;
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
object_path = get_object_path_for_token (self, card_slot);
|
|
|
2f9b22 |
gsd_smartcard_service_manager_complete_get_login_token (manager,
|
|
|
2f9b22 |
invocation,
|
|
|
2f9b22 |
object_path);
|
|
|
2f9b22 |
g_free (object_path);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
return TRUE;
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static gboolean
|
|
|
2f9b22 |
gsd_smartcard_service_handle_get_inserted_tokens (GsdSmartcardServiceManager *manager,
|
|
|
2f9b22 |
GDBusMethodInvocation *invocation)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardService *self = GSD_SMARTCARD_SERVICE (manager);
|
|
|
2f9b22 |
GsdSmartcardServicePrivate *priv = self->priv;
|
|
|
2f9b22 |
GList *inserted_tokens, *node;
|
|
|
2f9b22 |
GPtrArray *object_paths;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
inserted_tokens = gsd_smartcard_manager_get_inserted_tokens (priv->smartcard_manager,
|
|
|
2f9b22 |
NULL);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
object_paths = g_ptr_array_new ();
|
|
|
2f9b22 |
@@ -498,60 +562,78 @@ synchronize_token_now (GsdSmartcardService *self,
|
|
|
2f9b22 |
is_login_card = TRUE;
|
|
|
2f9b22 |
else
|
|
|
2f9b22 |
is_login_card = FALSE;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_debug ("===============================");
|
|
|
2f9b22 |
g_debug (" Token '%s'", token_name);
|
|
|
2f9b22 |
g_debug (" Inserted: %s", is_present? "yes" : "no");
|
|
|
2f9b22 |
g_debug (" Previously used to login: %s", is_login_card? "yes" : "no");
|
|
|
2f9b22 |
g_debug ("===============================\n");
|
|
|
2f9b22 |
|
|
|
2f9b22 |
if (!is_present && is_login_card) {
|
|
|
2f9b22 |
gboolean was_present;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_object_get (G_OBJECT (interface),
|
|
|
2f9b22 |
"is-inserted", &was_present,
|
|
|
2f9b22 |
NULL);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
if (was_present)
|
|
|
2f9b22 |
gsd_smartcard_manager_do_remove_action (priv->smartcard_manager);
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
g_object_set (G_OBJECT (interface),
|
|
|
2f9b22 |
"used-to-login", is_login_card,
|
|
|
2f9b22 |
"is-inserted", is_present,
|
|
|
2f9b22 |
NULL);
|
|
|
2f9b22 |
g_object_get (G_OBJECT (interface),
|
|
|
2f9b22 |
"used-to-login", &is_login_card,
|
|
|
2f9b22 |
"is-inserted", &is_present,
|
|
|
2f9b22 |
NULL);
|
|
|
2f9b22 |
|
|
|
2f9b22 |
+ if (is_login_card && !priv->login_token_bound) {
|
|
|
2f9b22 |
+ const char *login_token_path;
|
|
|
2f9b22 |
+ GDBusInterfaceSkeleton *login_token_interface;
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ login_token_path = get_login_token_object_path (self);
|
|
|
2f9b22 |
+ login_token_interface = g_hash_table_lookup (priv->tokens, login_token_path);
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
+ if (login_token_interface != NULL) {
|
|
|
2f9b22 |
+ g_object_bind_property (interface, "driver",
|
|
|
2f9b22 |
+ login_token_interface, "driver",
|
|
|
2f9b22 |
+ G_BINDING_SYNC_CREATE);
|
|
|
2f9b22 |
+ g_object_bind_property (interface, "is-inserted",
|
|
|
2f9b22 |
+ login_token_interface, "is-inserted",
|
|
|
2f9b22 |
+ G_BINDING_SYNC_CREATE);
|
|
|
2f9b22 |
+ priv->login_token_bound = TRUE;
|
|
|
2f9b22 |
+ }
|
|
|
2f9b22 |
+ }
|
|
|
2f9b22 |
+
|
|
|
2f9b22 |
out:
|
|
|
2f9b22 |
G_UNLOCK (gsd_smartcard_tokens);
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
typedef struct
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
PK11SlotInfo *card_slot;
|
|
|
2f9b22 |
char *object_path;
|
|
|
2f9b22 |
GSource *main_thread_source;
|
|
|
2f9b22 |
} RegisterNewTokenOperation;
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static void
|
|
|
2f9b22 |
destroy_register_new_token_operation (RegisterNewTokenOperation *operation)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
g_clear_pointer (&operation->main_thread_source,
|
|
|
2f9b22 |
(GDestroyNotify) g_source_destroy);
|
|
|
2f9b22 |
PK11_FreeSlot (operation->card_slot);
|
|
|
2f9b22 |
g_free (operation->object_path);
|
|
|
2f9b22 |
g_free (operation);
|
|
|
2f9b22 |
}
|
|
|
2f9b22 |
|
|
|
2f9b22 |
static gboolean
|
|
|
2f9b22 |
on_main_thread_to_register_new_token (GTask *task)
|
|
|
2f9b22 |
{
|
|
|
2f9b22 |
GsdSmartcardService *self;
|
|
|
2f9b22 |
GsdSmartcardServicePrivate *priv;
|
|
|
2f9b22 |
GDBusObjectSkeleton *object;
|
|
|
2f9b22 |
GDBusInterfaceSkeleton *interface;
|
|
|
2f9b22 |
RegisterNewTokenOperation *operation;
|
|
|
2f9b22 |
SECMODModule *driver;
|
|
|
2f9b22 |
--
|
|
|
37ea90 |
2.17.0
|
|
|
2f9b22 |
|