예제 #1
0
static void
on_service_open_session_plain (GObject *source,
                               GAsyncResult *result,
                               gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	OpenSessionClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SecretService *service = SECRET_SERVICE (source);
	GError *error = NULL;
	GVariant *response;

	response =  g_dbus_proxy_call_finish (G_DBUS_PROXY (service), result, &error);

	/* A successful response, decode it */
	if (response != NULL) {
		if (response_open_session_plain (closure->session, response)) {
			_secret_service_take_session (service, closure->session);
			closure->session = NULL;

		} else {
			g_simple_async_result_set_error (res, SECRET_ERROR, SECRET_ERROR_PROTOCOL,
			                                 _("Couldn’t communicate with the secret storage"));
		}

		g_simple_async_result_complete (res);
		g_variant_unref (response);

	} else {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete (res);
	}

	g_object_unref (res);
}
예제 #2
0
static void
on_service_open_session_aes (GObject *source,
                             GAsyncResult *result,
                             gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	OpenSessionClosure * closure = g_simple_async_result_get_op_res_gpointer (res);
	SecretService *service = SECRET_SERVICE (source);
	GError *error = NULL;
	GVariant *response;

	response =  g_dbus_proxy_call_finish (G_DBUS_PROXY (service), result, &error);

	/* A successful response, decode it */
	if (response != NULL) {
		if (response_open_session_aes (closure->session, response)) {
			_secret_service_take_session (service, closure->session);
			closure->session = NULL;

		} else {
			g_simple_async_result_set_error (res, SECRET_ERROR, SECRET_ERROR_PROTOCOL,
			                                 _("Couldn’t communicate with the secret storage"));
		}

		g_simple_async_result_complete (res);
		g_variant_unref (response);

	} else {
		/* AES session not supported, request a plain session */
		if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED)) {
			g_dbus_proxy_call (G_DBUS_PROXY (source), "OpenSession",
			                   request_open_session_plain (closure->session),
			                   G_DBUS_CALL_FLAGS_NONE, -1,
			                   closure->cancellable, on_service_open_session_plain,
			                   g_object_ref (res));
			g_error_free (error);

		/* Other errors result in a failure */
		} else {
			g_simple_async_result_take_error (res, error);
			g_simple_async_result_complete (res);
		}
	}

	g_object_unref (res);
}
예제 #3
0
void NetworkStorageSession::getCredentialFromPersistentStorage(const ProtectionSpace& protectionSpace, Function<void (Credential&&)> completionHandler)
{
#if USE(LIBSECRET)
    if (m_sessionID.isEphemeral()) {
        completionHandler({ });
        return;
    }

    const String& realm = protectionSpace.realm();
    if (realm.isEmpty()) {
        completionHandler({ });
        return;
    }

    GRefPtr<GHashTable> attributes = adoptGRef(secret_attributes_build(SECRET_SCHEMA_COMPAT_NETWORK,
        "domain", realm.utf8().data(),
        "server", protectionSpace.host().utf8().data(),
        "port", protectionSpace.port(),
        "protocol", schemeFromProtectionSpaceServerType(protectionSpace.serverType()),
        "authtype", authTypeFromProtectionSpaceAuthenticationScheme(protectionSpace.authenticationScheme()),
        nullptr));
    if (!attributes) {
        completionHandler({ });
        return;
    }

    m_persisentStorageCancellable = adoptGRef(g_cancellable_new());
    m_persisentStorageCompletionHandler = WTFMove(completionHandler);
    secret_service_search(nullptr, SECRET_SCHEMA_COMPAT_NETWORK, attributes.get(),
        static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS), m_persisentStorageCancellable.get(),
        [](GObject* source, GAsyncResult* result, gpointer userData) {
            GUniqueOutPtr<GError> error;
            GUniquePtr<GList> elements(secret_service_search_finish(SECRET_SERVICE(source), result, &error.outPtr()));
            if (g_error_matches (error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
                return;

            NetworkStorageSession* session = static_cast<NetworkStorageSession*>(userData);
            auto completionHandler = std::exchange(session->m_persisentStorageCompletionHandler, nullptr);
            if (error || !elements || !elements->data) {
                completionHandler({ });
                return;
            }

            GRefPtr<SecretItem> secretItem = adoptGRef(static_cast<SecretItem*>(elements->data));
            GRefPtr<GHashTable> attributes = adoptGRef(secret_item_get_attributes(secretItem.get()));
            String user = String::fromUTF8(static_cast<const char*>(g_hash_table_lookup(attributes.get(), "user")));
            if (user.isEmpty()) {
                completionHandler({ });
                return;
            }

            size_t length;
            GRefPtr<SecretValue> secretValue = adoptGRef(secret_item_get_secret(secretItem.get()));
            const char* passwordData = secret_value_get(secretValue.get(), &length);
            completionHandler(Credential(user, String::fromUTF8(passwordData, length), CredentialPersistencePermanent));
    }, this);
#else
    UNUSED_PARAM(protectionSpace);
    completionHandler({ });
#endif
}