static gboolean
log_into_pkcs11_session (GckSession *session, GError **error)
{
	GckSessionInfo *sess;
	GckTokenInfo *info;
	GckSlot *slot;
	gboolean login;

	/* Perform the necessary 'user' login to secrets token. Doesn't unlock anything */
	slot = gck_session_get_slot (session);
	info = gck_slot_get_token_info (slot);
	login = info && (info->flags & CKF_LOGIN_REQUIRED);
	gck_token_info_free (info);
	g_object_unref (slot);

	if (login) {
		sess = gck_session_get_info (session);
		if (sess->state == CKS_RO_USER_FUNCTIONS ||
		    sess->state == CKS_RW_USER_FUNCTIONS)
			login = FALSE;
		gck_session_info_free (sess);
	}

	if (login && !gck_session_login (session, CKU_USER, NULL, 0, NULL, error))
		return FALSE;

	return TRUE;
}
Exemple #2
0
static GckSession*
open_and_login_session (GckSlot *slot, CK_USER_TYPE user_type, GError **error)
{
	GckSession *session;
	GError *err = NULL;

	g_return_val_if_fail (GCK_IS_SLOT (slot), NULL);

	if (!error)
		error = &err;

	session = gck_slot_open_session (slot, GCK_SESSION_READ_WRITE, NULL, error);
	if (session != NULL) {
		if (!gck_session_login (session, user_type, NULL, 0, NULL, error)) {
			if (g_error_matches (*error, GCK_ERROR, CKR_USER_ALREADY_LOGGED_IN)) {
				g_clear_error (error);
			} else {
				g_object_unref (session);
				session = NULL;
			}
		}
	}

	return session;
}
GckSession*
gkd_secret_service_get_pkcs11_session (GkdSecretService *self, const gchar *caller)
{
	ServiceClient *client;
	GError *error = NULL;
	GckTokenInfo *info;
	GckSlot *slot;
	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) {
		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;
		}

		/* Perform the necessary 'user' login to secrets token. Doesn't unlock anything */
		info = gck_slot_get_token_info (slot);
		login = info && (info->flags & CKF_LOGIN_REQUIRED);
		gck_token_info_free (info);
		if (login && !gck_session_login (client->pkcs11_session, CKU_USER, NULL, 0, NULL, &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;
}