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); }
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); }
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 }