GckSession*
gkd_secret_service_internal_pkcs11_session (GkdSecretService *self)
{
	GError *error = NULL;
	GckSlot *slot;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);

	if (self->internal_session)
		return self->internal_session;

	slot = gkd_secret_service_get_pkcs11_slot (self);
	self->internal_session = gck_slot_open_session_full (slot, GCK_SESSION_READ_WRITE,
							     0, NULL, NULL, NULL, &error);
	if (!self->internal_session) {
		g_warning ("couldn't open pkcs11 session for secret service: %s",
			   egg_error_message (error));
		g_clear_error (&error);
		return NULL;
	}

	if (!log_into_pkcs11_session (self->internal_session, &error)) {
		g_warning ("couldn't log in to pkcs11 session for secret service: %s",
			   egg_error_message (error));
		g_clear_error (&error);
		g_object_unref (self->internal_session);
		self->internal_session = NULL;
		return NULL;
	}

	return self->internal_session;
}
GP11Session*
gkd_secret_service_get_pkcs11_session (GkdSecretService *self, const gchar *caller)
{
	ServiceClient *client;
	GError *error = NULL;
	GP11TokenInfo *info;
	GP11Slot *slot;
	gulong flags;
	gboolean login;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
	g_return_val_if_fail (caller, NULL);

	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);

	/* Open a new session if necessary */
	if (!client->pkcs11_session) {
		flags = CKF_RW_SESSION | CKF_G_APPLICATION_SESSION;
		slot = gkd_secret_service_get_pkcs11_slot (self);
		client->pkcs11_session = gp11_slot_open_session_full (slot, flags, &client->app,
		                                                      NULL, NULL, &error);
		if (!client->pkcs11_session) {
			g_warning ("couldn't open pkcs11 session for secret service: %s",
			           egg_error_message (error));
			g_clear_error (&error);
			return NULL;
		}

		/* Perform the necessary 'user' login to secrets token. Doesn't unlock anything */
		info = gp11_slot_get_token_info (slot);
		login = info && (info->flags & CKF_LOGIN_REQUIRED);
		gp11_token_info_free (info);
		if (login && !gp11_session_login (client->pkcs11_session, CKU_USER, NULL, 0, &error)) {
			g_warning ("couldn't log in to pkcs11 session for secret service: %s",
			           egg_error_message (error));
			g_clear_error (&error);
			g_object_unref (client->pkcs11_session);
			client->pkcs11_session = NULL;
			return NULL;
		}
	}

	return client->pkcs11_session;
}
static void
gkd_secret_service_get_property (GObject *obj, guint prop_id, GValue *value,
				 GParamSpec *pspec)
{
	GkdSecretService *self = GKD_SECRET_SERVICE (obj);

	switch (prop_id) {
	case PROP_CONNECTION:
		g_value_set_object (value, gkd_secret_service_get_connection (self));
		break;
	case PROP_PKCS11_SLOT:
		g_value_set_object (value, gkd_secret_service_get_pkcs11_slot (self));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
		break;
	}
}
GckSession*
gkd_secret_service_get_pkcs11_session (GkdSecretService *self, const gchar *caller)
{
	ServiceClient *client;
	GError *error = NULL;
	GckSlot *slot;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
	g_return_val_if_fail (caller, NULL);

	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);

	/* Open a new session if necessary */
	if (!client->pkcs11_session) {
		slot = gkd_secret_service_get_pkcs11_slot (self);
		client->pkcs11_session = gck_slot_open_session_full (slot, GCK_SESSION_READ_WRITE,
								     CKF_G_APPLICATION_SESSION, &client->app,
								     NULL, NULL, &error);
		if (!client->pkcs11_session) {
			g_warning ("couldn't open pkcs11 session for secret service: %s",
				   egg_error_message (error));
			g_clear_error (&error);
			return NULL;
		}

		if (!log_into_pkcs11_session (client->pkcs11_session, &error)) {
			g_warning ("couldn't log in to pkcs11 session for secret service: %s",
				   egg_error_message (error));
			g_clear_error (&error);
			g_object_unref (client->pkcs11_session);
			client->pkcs11_session = NULL;
			return NULL;
		}
	}

	return client->pkcs11_session;
}