diff options
Diffstat (limited to 'src/usb-snap.cpp')
-rw-r--r-- | src/usb-snap.cpp | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/src/usb-snap.cpp b/src/usb-snap.cpp deleted file mode 100644 index 2861166..0000000 --- a/src/usb-snap.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2016 Canonical Ltd. - * Copyright 2023 Robert Tari - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authors: - * Charles Kerr <charles.kerr@canonical.com> - * Robert Tari <robert@tari.in> - */ - -#include <src/dbus-names.h> -#include <src/usb-snap.h> - -#include <glib/gi18n.h> -#include <gio/gio.h> - -/*** -**** -***/ - -class UsbSnap::Impl -{ -public: - - explicit Impl(const std::string& fingerprint): - m_fingerprint{fingerprint}, - m_cancellable{g_cancellable_new()} - { - g_bus_get (G_BUS_TYPE_SESSION, m_cancellable, on_bus_ready_static, this); - } - - ~Impl() - { - g_cancellable_cancel(m_cancellable); - g_clear_object(&m_cancellable); - - if (m_subscription_id != 0) - g_dbus_connection_signal_unsubscribe (m_bus, m_subscription_id); - - if (m_notification_id != 0) { - GError* error {}; - g_dbus_connection_call_sync(m_bus, - DBusNames::Notify::NAME, - DBusNames::Notify::PATH, - DBusNames::Notify::INTERFACE, - "CloseNotification", - g_variant_new("(u)", m_notification_id), - nullptr, - G_DBUS_CALL_FLAGS_NONE, - -1, - nullptr, - &error); - if (error != nullptr) { - g_warning("Error closing notification: %s", error->message); - g_clear_error(&error); - } - } - - g_clear_object(&m_bus); - } - - core::Signal<AdbdClient::PKResponse,bool>& on_user_response() - { - return m_on_user_response; - } - -private: - - static void on_bus_ready_static(GObject* /*source*/, GAsyncResult* res, gpointer gself) - { - GError* error {}; - auto bus = g_bus_get_finish (res, &error); - if (error != nullptr) { - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning("UsbSnap: Error getting session bus: %s", error->message); - g_clear_error(&error); - } else { - static_cast<Impl*>(gself)->on_bus_ready(bus); - } - g_clear_object(&bus); - } - - void on_bus_ready(GDBusConnection* bus) - { - m_bus = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(bus))); - - m_subscription_id = g_dbus_connection_signal_subscribe(m_bus, - DBusNames::Notify::NAME, - DBusNames::Notify::INTERFACE, - nullptr, - DBusNames::Notify::PATH, - nullptr, - G_DBUS_SIGNAL_FLAGS_NONE, - on_notification_signal_static, - this, - nullptr); - - auto body = g_strdup_printf(_("The computer's RSA key fingerprint is: %s"), m_fingerprint.c_str()); - - GVariantBuilder actions_builder; - g_variant_builder_init(&actions_builder, G_VARIANT_TYPE_STRING_ARRAY); - g_variant_builder_add(&actions_builder, "s", ACTION_ALLOW); - g_variant_builder_add(&actions_builder, "s", _("Allow")); - g_variant_builder_add(&actions_builder, "s", ACTION_DENY); - g_variant_builder_add(&actions_builder, "s", _("Don't Allow")); - - GVariantBuilder hints_builder; - g_variant_builder_init(&hints_builder, G_VARIANT_TYPE_VARDICT); - - auto args = g_variant_new("(susssasa{sv}i)", - "", - uint32_t(0), - "computer-symbolic", - _("Allow USB Debugging?"), - body, - &actions_builder, - &hints_builder, - -1); - g_dbus_connection_call(m_bus, - DBusNames::Notify::NAME, - DBusNames::Notify::PATH, - DBusNames::Notify::INTERFACE, - "Notify", - args, - G_VARIANT_TYPE("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, // timeout - m_cancellable, - on_notify_reply_static, - this); - - g_clear_pointer(&body, g_free); - } - - static void on_notify_reply_static(GObject* obus, GAsyncResult* res, gpointer gself) - { - GError* error {}; - auto reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION(obus), res, &error); - if (error != nullptr) { - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning("UsbSnap: Error calling Notify: %s", error->message); - g_clear_error(&error); - } else { - uint32_t id {}; - g_variant_get(reply, "(u)", &id); - static_cast<Impl*>(gself)->on_notify_reply(id); - } - g_clear_pointer(&reply, g_variant_unref); - } - - void on_notify_reply(uint32_t id) - { - m_notification_id = id; - } - - static void on_notification_signal_static(GDBusConnection* /*connection*/, - const gchar* /*sender_name*/, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer gself) - { - g_return_if_fail(!g_strcmp0(object_path, DBusNames::Notify::PATH)); - g_return_if_fail(!g_strcmp0(interface_name, DBusNames::Notify::INTERFACE)); - - auto self = static_cast<Impl*>(gself); - - if (!g_strcmp0(signal_name, DBusNames::Notify::ActionInvoked::NAME)) - { - uint32_t id {}; - const char* action_name {}; - g_variant_get(parameters, "(u&s)", &id, &action_name); - if (id == self->m_notification_id) - self->on_action_invoked(action_name); - } - else if (!g_strcmp0(signal_name, DBusNames::Notify::NotificationClosed::NAME)) - { - uint32_t id {}; - uint32_t close_reason {}; - g_variant_get(parameters, "(uu)", &id, &close_reason); - if (id == self->m_notification_id) - self->on_notification_closed(close_reason); - } - } - - void on_action_invoked(const char* action_name) - { - const auto response = !g_strcmp0(action_name, ACTION_ALLOW) - ? AdbdClient::PKResponse::ALLOW - : AdbdClient::PKResponse::DENY; - - // FIXME: the current default is to cover the most common use case. - // We need to get the notification ui's checkbox working ASAP so - // that the user can provide this flag - const bool remember_this_choice = response == AdbdClient::PKResponse::ALLOW; - - m_on_user_response(response, remember_this_choice); - m_notification_id = 0; - } - - void on_notification_closed(uint32_t close_reason) - { - if (close_reason == DBusNames::Notify::NotificationClosed::Reason::EXPIRED) - m_on_user_response(AdbdClient::PKResponse::DENY, false); - - m_notification_id = 0; - } - - static constexpr char const * ACTION_ALLOW {"allow"}; - static constexpr char const * ACTION_DENY {"deny"}; - - const std::string m_fingerprint; - core::Signal<AdbdClient::PKResponse,bool> m_on_user_response; - GCancellable* m_cancellable {}; - GDBusConnection* m_bus {}; - uint32_t m_notification_id {}; - unsigned int m_subscription_id {}; -}; - -/*** -**** -***/ - -UsbSnap::UsbSnap(const std::string& public_key): - impl{new Impl{public_key}} -{ -} - -UsbSnap::~UsbSnap() -{ -} - -core::Signal<AdbdClient::PKResponse,bool>& -UsbSnap::on_user_response() -{ - return impl->on_user_response(); -} - |