diff --git a/Cargo.lock b/Cargo.lock index 12aae08b..3ac56848 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,7 +589,7 @@ checksum = "b01fe135c0bd16afe262b6dea349bd5ea30e6de50708cec639aae7c5c14cc7e4" dependencies = [ "bitflags 2.11.0", "cairo-sys-rs", - "glib", + "glib 0.21.5", "libc", ] @@ -599,7 +599,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06c28280c6b12055b5e39e4554271ae4e6630b27c0da9148c4cf6485fc6d245c" dependencies = [ - "glib-sys", + "glib-sys 0.21.5", "libc", "system-deps", ] @@ -798,7 +798,7 @@ dependencies = [ "credentialsd-common", "futures", "futures-lite", - "gio", + "gio 0.21.5", "libc", "libwebauthn", "nfc1", @@ -830,6 +830,7 @@ dependencies = [ "futures-lite", "gdk4-wayland", "gettext-rs", + "gio-unix", "gtk4", "libc", "qrcode", @@ -1392,8 +1393,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "debb0d39e3cdd84626edfd54d6e4a6ba2da9a0ef2e796e691c4e9f8646fda00c" dependencies = [ "gdk-pixbuf-sys", - "gio", - "glib", + "gio 0.21.5", + "glib 0.21.5", "libc", ] @@ -1403,9 +1404,9 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd95ad50b9a3d2551e25dd4f6892aff0b772fe5372d84514e9d0583af60a0ce7" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.21.5", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", "libc", "system-deps", ] @@ -1419,8 +1420,8 @@ dependencies = [ "cairo-rs", "gdk-pixbuf", "gdk4-sys", - "gio", - "glib", + "gio 0.21.5", + "glib 0.21.5", "libc", "pango", ] @@ -1433,9 +1434,9 @@ checksum = "a6d4e5b3ccf591826a4adcc83f5f57b4e59d1925cb4bf620b0d645f79498b034" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.21.5", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", "libc", "pango-sys", "pkg-config", @@ -1450,8 +1451,8 @@ checksum = "fcb81f3e1e7d9dac156e91a9dc81be33d8c99338975254ed93ca9f1de5cb3168" dependencies = [ "gdk4", "gdk4-wayland-sys", - "gio", - "glib", + "gio 0.21.5", + "glib 0.21.5", "libc", ] @@ -1461,7 +1462,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d739aa4ae9a1abb15f01ab2d8b8dd14a7792104ffb60bbc09bb94d76b905cfeb" dependencies = [ - "glib-sys", + "glib-sys 0.21.5", "libc", "system-deps", ] @@ -1557,8 +1558,25 @@ dependencies = [ "futures-core", "futures-io", "futures-util", - "gio-sys", - "glib", + "gio-sys 0.21.5", + "glib 0.21.5", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3848bcba3a35cc0a71df8ba8ecfd799d6bfb862342a53a4a915fb62213aa4e6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys 0.22.0", + "glib 0.22.7", "libc", "pin-project-lite", "smallvec", @@ -1570,13 +1588,51 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0071fe88dba8e40086c8ff9bbb62622999f49628344b1d1bf490a48a29d80f22" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", + "libc", + "system-deps", + "windows-sys 0.61.2", +] + +[[package]] +name = "gio-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64729ba2772c080448f9f966dba8f4456beeb100d8c28a865ef8a0f2ef4987e1" +dependencies = [ + "glib-sys 0.22.6", + "gobject-sys 0.22.6", "libc", "system-deps", "windows-sys 0.61.2", ] +[[package]] +name = "gio-unix" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9241b3df1288f8b59027e9499a999c54ec6993111e21644e72d4527fdafdb7c" +dependencies = [ + "gio 0.22.6", + "gio-unix-sys", + "glib 0.22.7", + "libc", +] + +[[package]] +name = "gio-unix-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bab97ce39112040216e268f074645f50b31caeb53af708ab5d7e4e67f0dbfd" +dependencies = [ + "gio-sys 0.22.0", + "glib-sys 0.22.6", + "gobject-sys 0.22.6", + "libc", + "system-deps", +] + [[package]] name = "glib" version = "0.21.5" @@ -1589,10 +1645,30 @@ dependencies = [ "futures-executor", "futures-task", "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", + "gio-sys 0.21.5", + "glib-macros 0.21.5", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c207e04e51605dcf7b2924c41591b3a10e1438eaac5bcf448fb91f325381104a" +dependencies = [ + "bitflags 2.11.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "glib-macros 0.22.6", + "glib-sys 0.22.6", + "gobject-sys 0.22.6", "libc", "memchr", "smallvec", @@ -1611,6 +1687,18 @@ dependencies = [ "syn 2.0.116", ] +[[package]] +name = "glib-macros" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "506d23499707c7142898429757e8d9a3871d965239a2cb66dfa05052be6d6f19" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.116", +] + [[package]] name = "glib-sys" version = "0.21.5" @@ -1621,6 +1709,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "glib-sys" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7fbac234ed5bc2a28359b7bde8e1b9cdf1441cc2d7f068e4824672d7db9445" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "glob" version = "0.3.3" @@ -1645,7 +1743,18 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dca35da0d19a18f4575f3cb99fe1c9e029a2941af5662f326f738a21edaf294" dependencies = [ - "glib-sys", + "glib-sys 0.21.5", + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a861859b887a79cf461359c192c97a57d8fb0229dd291232e57aa11f6fa72c" +dependencies = [ + "glib-sys 0.22.6", "libc", "system-deps", ] @@ -1656,7 +1765,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2730030ac9db663fd8bfe1e7093742c1cafb92db9c315c9417c29032341fe2f9" dependencies = [ - "glib", + "glib 0.21.5", "graphene-sys", "libc", ] @@ -1667,7 +1776,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915e32091ea9ad241e4b044af62b7351c2d68aeb24f489a0d7f37a0fc484fd93" dependencies = [ - "glib-sys", + "glib-sys 0.21.5", "libc", "pkg-config", "system-deps", @@ -1692,7 +1801,7 @@ checksum = "e755de9d8c5896c5beaa028b89e1969d067f1b9bf1511384ede971f5983aa153" dependencies = [ "cairo-rs", "gdk4", - "glib", + "glib 0.21.5", "graphene-rs", "gsk4-sys", "libc", @@ -1707,8 +1816,8 @@ checksum = "7ce91472391146f482065f1041876d8f869057b195b95399414caa163d72f4f7" dependencies = [ "cairo-sys-rs", "gdk4-sys", - "glib-sys", - "gobject-sys", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", "graphene-sys", "libc", "pango-sys", @@ -1726,8 +1835,8 @@ dependencies = [ "futures-channel", "gdk-pixbuf", "gdk4", - "gio", - "glib", + "gio 0.21.5", + "glib 0.21.5", "graphene-rs", "gsk4", "gtk4-macros", @@ -1757,9 +1866,9 @@ dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", "gdk4-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.21.5", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", "graphene-sys", "gsk4-sys", "libc", @@ -2744,8 +2853,8 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52d1d85e2078077a065bb7fc072783d5bcd4e51b379f22d67107d0a16937eb69" dependencies = [ - "gio", - "glib", + "gio 0.21.5", + "glib 0.21.5", "libc", "pango-sys", ] @@ -2756,8 +2865,8 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4f06627d36ed5ff303d2df65211fc2e52ba5b17bf18dd80ff3d9628d6e06cfd" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.21.5", + "gobject-sys 0.21.5", "libc", "system-deps", ] diff --git a/credentialsd-common/src/model.rs b/credentialsd-common/src/model.rs index a012bd5b..55b84d56 100644 --- a/credentialsd-common/src/model.rs +++ b/credentialsd-common/src/model.rs @@ -115,20 +115,6 @@ impl Transport { } } -/// Details about the calling application to be displayed in the UI. -#[derive(Debug, Default, Clone, Serialize, Deserialize, Type)] -pub struct RequestingApplication { - /// The App ID (if called on the portal interface) or path (if called on the - /// internal interface). - pub path_or_app_id: String, - - /// The name of the application. - pub name: Optional, - - /// The PID of the application - pub pid: u32, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Type)] pub struct RequestingParty { pub rp_id: String, diff --git a/credentialsd-common/src/server.rs b/credentialsd-common/src/server.rs index d2f023e9..0b06bb16 100644 --- a/credentialsd-common/src/server.rs +++ b/credentialsd-common/src/server.rs @@ -11,7 +11,7 @@ use zvariant::{ SerializeDict, Signature, Str, Structure, StructureBuilder, Type, Value, signature::Fields, }; -use crate::model::{Device, Operation, RequestId, RequestingApplication, UserInteractedEvent}; +use crate::model::{Device, Operation, RequestId, UserInteractedEvent}; const TAG_VALUE_SIGNATURE: &Signature = &Signature::Structure(Fields::Static { fields: &[&Signature::U32, &Signature::Variant], @@ -508,26 +508,6 @@ impl<'de> Deserialize<'de> for UserInteractedEvent { } } -#[derive(Clone, Debug, Serialize, Deserialize, Type)] -pub struct ViewRequest { - pub operation: Operation, - - /// ID of the request. - pub id: RequestId, - - /// The RP ID - pub rp_id: String, - - /// Details about the application requesting credentials. - pub requesting_app: RequestingApplication, - - /// Initial list of device interfaces that may provide credentials. - pub initial_devices: Vec, - - /// Client window handle. - pub window_handle: Optional, -} - #[derive(Clone, Debug, PartialEq, Type)] #[zvariant(signature = "s")] pub enum WindowHandle { diff --git a/credentialsd-ui/Cargo.toml b/credentialsd-ui/Cargo.toml index b8a691c3..b28c98c2 100644 --- a/credentialsd-ui/Cargo.toml +++ b/credentialsd-ui/Cargo.toml @@ -23,3 +23,4 @@ tracing.workspace = true tracing-subscriber = "0.3.19" zeroize = { version = "1.8.2" } zbus = { workspace = true, default-features = false, features = ["async-io"]} +gio-unix = "0.22.6" diff --git a/credentialsd-ui/src/dbus.rs b/credentialsd-ui/src/dbus.rs index f2151afb..aebe01fc 100644 --- a/credentialsd-ui/src/dbus.rs +++ b/credentialsd-ui/src/dbus.rs @@ -6,6 +6,8 @@ use async_std::{ task::JoinHandle, }; use futures_lite::{FutureExt, StreamExt}; +use gio_unix::DesktopAppInfo; +use gio_unix::prelude::AppInfoExt; use zbus::{ Connection, ObjectServer, fdo::{self, DBusProxy}, @@ -17,14 +19,11 @@ use zbus::{ }; use credentialsd_common::{ - model::{ - Device, Operation, PortalBackendOptions, RequestId, RequestingApplication, - UserInteractedEvent, - }, - server::{BackgroundEvent, ViewRequest, WindowHandle}, + model::{Device, Operation, PortalBackendOptions, RequestId, UserInteractedEvent}, + server::{BackgroundEvent, WindowHandle}, }; -use crate::client::FlowControlClient; +use crate::{RequestingApplication, ViewRequest, client::FlowControlClient}; pub struct CredentialPortalBackend { pub request_tx: Sender<( @@ -63,7 +62,6 @@ impl CredentialPortalBackend { request_id: RequestId, devices: Vec, app_id: String, - app_display_name: String, app_pid: u32, app_path: String, options: PortalBackendOptions, @@ -123,6 +121,15 @@ impl CredentialPortalBackend { ) }; + let app_display_name = DesktopAppInfo::new(&format!("{app_id}.desktop")) + .ok_or_else(|| { + fdo::Error::Failed(format!( + "Failed to retrieve app name for {app_id}: Could not find desktop file" + )) + })? + .display_name() + .to_string(); + let ui_context = UiContext { parent_window: parent_window.into(), origin, @@ -268,7 +275,7 @@ impl CeremonyObject { rp_id, requesting_app: RequestingApplication { path_or_app_id: self.ui_context.app_id.clone(), - name: Some(self.ui_context.app_display_name.clone()).into(), + name: self.ui_context.app_display_name.clone(), pid: self.ui_context.app_pid, }, initial_devices: self.ui_context.devices.clone(), diff --git a/credentialsd-ui/src/gui/mod.rs b/credentialsd-ui/src/gui/mod.rs index 9525d7b6..3c56663f 100644 --- a/credentialsd-ui/src/gui/mod.rs +++ b/credentialsd-ui/src/gui/mod.rs @@ -5,12 +5,9 @@ use std::{sync::Arc, thread::JoinHandle}; use async_std::{channel::Receiver, sync::Mutex as AsyncMutex}; -use credentialsd_common::{ - model::ViewUpdate, - server::{ViewRequest, WindowHandle}, -}; +use credentialsd_common::{model::ViewUpdate, server::WindowHandle}; -use crate::client::FlowControlClient; +use crate::{ViewRequest, client::FlowControlClient}; use view_model::ViewEvent; diff --git a/credentialsd-ui/src/gui/view_model/mod.rs b/credentialsd-ui/src/gui/view_model/mod.rs index 4b4454a5..3a5cb64b 100644 --- a/credentialsd-ui/src/gui/view_model/mod.rs +++ b/credentialsd-ui/src/gui/view_model/mod.rs @@ -7,15 +7,14 @@ use async_std::{ channel::{Receiver, Sender}, sync::Mutex as AsyncMutex, }; -use credentialsd_common::model::RequestingApplication; -use credentialsd_common::server::{BackgroundEvent, Credential, ViewRequest}; +use credentialsd_common::server::{BackgroundEvent, Credential}; use gettextrs::gettext; use serde::{Deserialize, Serialize}; use tracing::{error, info}; use credentialsd_common::model::{Device, HybridState, Operation, Transport, ViewUpdate}; -use crate::client::FlowControlClient; +use crate::{RequestingApplication, ViewRequest, client::FlowControlClient}; #[derive(Debug)] pub(crate) struct ViewModel { diff --git a/credentialsd-ui/src/main.rs b/credentialsd-ui/src/main.rs index a75ec19f..83472ad0 100644 --- a/credentialsd-ui/src/main.rs +++ b/credentialsd-ui/src/main.rs @@ -6,6 +6,9 @@ mod gui; use std::error::Error; +use credentialsd_common::model::{Device, Operation, RequestId}; +use credentialsd_common::server::WindowHandle; + use crate::dbus::CredentialPortalBackend; fn main() -> Result<(), Box> { @@ -40,3 +43,37 @@ async fn run() -> Result<(), Box> { Ok(()) } } + +/// Details about the calling application to be displayed in the UI. +#[derive(Debug, Default, Clone)] +pub struct RequestingApplication { + /// The App ID (if called on the portal interface) or path (if called on the + /// internal interface). + pub path_or_app_id: String, + + /// The display name of the application. + pub name: String, + + /// The PID of the application + pub pid: u32, +} + +#[derive(Clone, Debug)] +pub struct ViewRequest { + pub operation: Operation, + + /// ID of the request. + pub id: RequestId, + + /// The RP ID + pub rp_id: String, + + /// Details about the application requesting credentials. + pub requesting_app: RequestingApplication, + + /// Initial list of device interfaces that may provide credentials. + pub initial_devices: Vec, + + /// Client window handle. + pub window_handle: Option, +} diff --git a/credentialsd/src/credential_service/mod.rs b/credentialsd/src/credential_service/mod.rs index 2c6fe9a0..d95eeb30 100644 --- a/credentialsd/src/credential_service/mod.rs +++ b/credentialsd/src/credential_service/mod.rs @@ -412,112 +412,3 @@ impl From for AuthenticatorResponse { Self::CredentialsAsserted(value) } } - -#[cfg(test)] -mod test { - use std::{sync::Arc, time::Duration}; - - use base64::Engine as _; - use libwebauthn::{ - ops::webauthn::{ - MakeCredentialRequest, ResidentKeyRequirement, UserVerificationRequirement, - }, - proto::ctap2::{ - Ctap2COSEAlgorithmIdentifier, Ctap2CredentialType, Ctap2PublicKeyCredentialRpEntity, - Ctap2PublicKeyCredentialType, Ctap2PublicKeyCredentialUserEntity, - }, - }; - use tokio::sync::{oneshot, Mutex as AsyncMutex}; - - use crate::{ - credential_service::usb::InProcessUsbHandler, - dbus::test::{DummyFlowServer, DummyUiServer}, - model::CredentialRequest, - }; - - use super::{ - hybrid::{test::DummyHybridHandler, HybridStateInternal}, - nfc::InProcessNfcHandler, - AuthenticatorResponse, CredentialService, ManageDevice, - }; - - fn create_credential_request() -> CredentialRequest { - let challenge = "Ox0AXQz7WUER7BGQFzvVrQbReTkS3sepVGj26qfUhhrWSarkDbGF4T4NuCY1aAwHYzOzKMJJ2YRSatetl0D9bQ"; - let origin = "webauthn.io".to_string(); - let challenge_bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD - .decode(challenge) - .expect("valid base64url challenge"); - let make_request = MakeCredentialRequest { - challenge: challenge_bytes, - origin: origin.clone(), - top_origin: None, - relying_party: Ctap2PublicKeyCredentialRpEntity { - id: "webauthn.io".to_string(), - name: Some("webauthn.io".to_string()), - }, - user: Ctap2PublicKeyCredentialUserEntity { - id: "d2ViYXV0aG5pby0xMjM4OTF5".as_bytes().to_vec().into(), - name: Some("123891y".to_string()), - display_name: Some("123891y".to_string()), - }, - resident_key: Some(ResidentKeyRequirement::Preferred), - user_verification: UserVerificationRequirement::Preferred, - algorithms: vec![ - Ctap2CredentialType { - algorithm: Ctap2COSEAlgorithmIdentifier::ES256, - public_key_type: Ctap2PublicKeyCredentialType::PublicKey, - }, - Ctap2CredentialType { - algorithm: Ctap2COSEAlgorithmIdentifier::EDDSA, - public_key_type: Ctap2PublicKeyCredentialType::PublicKey, - }, - ], - exclude: None, - extensions: None, - timeout: Duration::from_secs(60), - }; - - CredentialRequest::CreatePublicKeyCredentialRequest(make_request) - } - - fn create_authenticator_response() -> AuthenticatorResponse { - use libwebauthn::{ - fido::{AuthenticatorData, AuthenticatorDataFlags}, - ops::webauthn::{Assertion, GetAssertionResponse}, - proto::ctap2::{Ctap2PublicKeyCredentialDescriptor, Ctap2Transport}, - }; - // SHA256("webauthn.io") - let rp_id_hash = [ - 0x74, 0xa6, 0xea, 0x92, 0x13, 0xc9, 0x9c, 0x2f, 0x74, 0xb2, 0x24, 0x92, 0xb3, 0x20, - 0xcf, 0x40, 0x26, 0x2a, 0x94, 0xc1, 0xa9, 0x50, 0xa0, 0x39, 0x7f, 0x29, 0x25, 0xb, - 0x60, 0x84, 0x1e, 0xf0, - ]; - - let auth_data = AuthenticatorData { - rp_id_hash, - flags: AuthenticatorDataFlags::USER_PRESENT | AuthenticatorDataFlags::USER_VERIFIED, - signature_count: 1, - attested_credential: None, - extensions: None, - raw: None, - }; - - let assertion = Assertion { - credential_id: Some(Ctap2PublicKeyCredentialDescriptor { - id: vec![0xca, 0xb1, 0xe].into(), - r#type: libwebauthn::proto::ctap2::Ctap2PublicKeyCredentialType::PublicKey, - transports: Some(vec![Ctap2Transport::Hybrid]), - }), - authenticator_data: auth_data, - signature: Vec::new(), - user: None, - credentials_count: Some(1), - user_selected: None, - unsigned_extensions_output: None, - }; - GetAssertionResponse { - assertions: vec![assertion], - } - .into() - } -} diff --git a/credentialsd/src/dbus/flow_control.rs b/credentialsd/src/dbus/flow_control.rs index acc063c6..ce883674 100644 --- a/credentialsd/src/dbus/flow_control.rs +++ b/credentialsd/src/dbus/flow_control.rs @@ -11,8 +11,8 @@ use std::{ use async_trait::async_trait; use credentialsd_common::model::{ - Error as CredentialServiceError, Operation, PortalBackendOptions, RequestingApplication, - UserInteractedEvent, WebAuthnError, + Error as CredentialServiceError, Operation, PortalBackendOptions, UserInteractedEvent, + WebAuthnError, }; use credentialsd_common::server::{BackgroundEvent, WindowHandle}; use futures_lite::{Stream, StreamExt}; @@ -24,7 +24,6 @@ use tokio::task::AbortHandle; use zbus::connection::Connection; use zbus::zvariant::OwnedObjectPath; -use crate::credential_service::{nfc::NfcState, DeviceStateUpdate, ManageDevice}; use crate::dbus::ui_control::Ceremony; use crate::dbus::UiControlServiceClient; use crate::{ @@ -32,9 +31,14 @@ use crate::{ dbus::ui_control::UiController, model::{CredentialRequest, CredentialResponse}, }; +use crate::{ + credential_service::{nfc::NfcState, DeviceStateUpdate, ManageDevice}, + model::ClientDetails, +}; + pub struct UiRequestContext { request: CredentialRequest, - app: RequestingApplication, + app: ClientDetails, /// Client window handle window_handle: Option, activation_token: Option, @@ -83,7 +87,7 @@ async fn handle>, ui_control_client: UC, msg: CredentialRequest, - requesting_app: RequestingApplication, + requesting_app: ClientDetails, window_handle: Option, activation_token: Option, ) -> Result { @@ -118,12 +122,11 @@ async fn handle() @@ -138,11 +141,9 @@ async fn handle, activation_token: Option, @@ -280,7 +281,7 @@ pub struct CredentialRequestControllerClient { impl CredentialRequestController for CredentialRequestControllerClient { async fn request_credential( &self, - app: RequestingApplication, + app: ClientDetails, request: CredentialRequest, window_handle: Option, activation_token: Option, diff --git a/credentialsd/src/dbus/mod.rs b/credentialsd/src/dbus/mod.rs index 9df11afc..2c713013 100644 --- a/credentialsd/src/dbus/mod.rs +++ b/credentialsd/src/dbus/mod.rs @@ -18,9 +18,3 @@ pub use self::{ }, ui_control::UiControlServiceClient, }; - -#[cfg(test)] -pub mod test { - pub use super::flow_control::test::DummyFlowServer; - pub use super::ui_control::test::DummyUiServer; -} diff --git a/credentialsd/src/dbus/ui_control.rs b/credentialsd/src/dbus/ui_control.rs index 702df901..c3e3d37b 100644 --- a/credentialsd/src/dbus/ui_control.rs +++ b/credentialsd/src/dbus/ui_control.rs @@ -29,7 +29,6 @@ pub trait UiController { request_id: RequestId, devices: Vec, app_id: String, - app_display_name: String, app_pid: u32, app_path: String, options: PortalBackendOptions, @@ -52,7 +51,6 @@ trait UiControlService2 { request_id: RequestId, devices: Vec, app_id: String, - app_display_name: String, app_pid: u32, app_path: String, options: PortalBackendOptions, @@ -122,7 +120,6 @@ impl UiController for UiControlServiceClient { request_id: RequestId, devices: Vec, app_id: String, - app_display_name: String, app_pid: u32, app_path: String, options: PortalBackendOptions, @@ -144,7 +141,6 @@ impl UiController for UiControlServiceClient { request_id, devices, app_id, - app_display_name, app_pid, app_path, options, @@ -174,160 +170,3 @@ async fn forward_ui_events( tracing::trace!("Stopping UI event forwarder"); Ok(()) } - -#[cfg(test)] -pub mod test { - use std::{ - error::Error, - fmt::Debug, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, - }; - - use credentialsd_common::{ - client::FlowController, - model::{Device, Operation, PortalBackendOptions, RequestId}, - server::{BackgroundEvent, ViewRequest, WindowHandle}, - }; - use futures_lite::StreamExt; - use tokio::sync::{ - mpsc::{self, Receiver, Sender}, - Mutex as AsyncMutex, Notify, - }; - use zbus::zvariant::OwnedObjectPath; - - use crate::dbus::ui_control::Ceremony; - - use super::UiController; - - #[derive(Debug)] - pub struct DummyUiClient { - tx: Sender, - } - - impl UiController for DummyUiClient { - async fn initialize( - &self, - _handle: OwnedObjectPath, - _parent_window: Option, - _origin: String, - _type: Operation, - _request_id: RequestId, - _devices: Vec, - _app_id: String, - _app_display_name: String, - _app_pid: u32, - _app_path: String, - _options: PortalBackendOptions, - ) -> Result> { - unimplemented!() - } - } - - pub struct DummyUiServer - where - F: FlowController + Debug, - { - rx: AsyncMutex>, - svc: Arc>>, - events: Arc>>, - stream_initialized: AtomicBool, - stream_initialized_notifier: Notify, - } - impl DummyUiServer { - pub fn new(events: Vec) -> (Self, DummyUiClient) { - let (tx, rx) = mpsc::channel(32); - let server = Self { - rx: AsyncMutex::new(rx), - svc: Arc::new(AsyncMutex::new(None)), - events: Arc::new(AsyncMutex::new(events)), - stream_initialized: AtomicBool::new(false), - stream_initialized_notifier: Notify::new(), - }; - let client = DummyUiClient { tx }; - (server, client) - } - - pub async fn init(&self, flow_controller: F) { - _ = self.svc.lock().await.insert(flow_controller); - } - - pub async fn run(&self) { - tracing::debug!( - target: "DummyUiServer", - "Starting launch_ui() request listener" - ); - let mut rx = self.rx.lock().await; - while let Some(request) = rx.recv().await { - self.launch_ui(request).await.unwrap(); - } - } - - pub async fn enter_client_pin(&self, pin: String) { - tracing::debug!( - target: "DummyUiServer", - "Received enter_client_pin() request" - ); - self.svc - .lock() - .await - .as_mut() - .unwrap() - .enter_client_pin(pin) - .await - .unwrap(); - } - - pub async fn select_credential(&self, _cred_id: String) { - tracing::debug!( - target: "DummyUiServer", - "Received select_credential() request" - ); - } - - async fn launch_ui(&self, request: ViewRequest) -> Result<(), Box> { - tracing::debug!( - target: "DummyUiServer", - "Received launch_ui() request" - ); - println!("Starting {:?} request UI", request.operation); - let events = self.events.clone(); - let mut stream = self - .svc - .lock() - .await - .as_mut() - .unwrap() - .subscribe() - .await - .unwrap(); - self.stream_initialized.store(true, Ordering::Release); - self.stream_initialized_notifier.notify_waiters(); - tokio::spawn(async move { - tracing::debug!(target: "DummyUiServer", "Starting background event stream"); - while let Some(event) = stream.next().await { - tracing::debug!( - target: "DummyUiServer", - "Received background event: {event:?}" - ); - events.lock().await.push(event); - } - }); - self.svc - .lock() - .await - .as_ref() - .unwrap() - .get_available_public_key_devices() - .await - .unwrap(); - tracing::debug!( - target: "DummyUiServer", - "Finished launch_ui() request" - ); - Ok(()) - } - } -} diff --git a/credentialsd/src/gateway/dbus.rs b/credentialsd/src/gateway/dbus.rs index 26e03016..ca5a7213 100644 --- a/credentialsd/src/gateway/dbus.rs +++ b/credentialsd/src/gateway/dbus.rs @@ -66,7 +66,6 @@ impl CredentialPortalGateway { cred_type: CredentialType, options: CreateCredentialPortalOptions, claimed_app_id: String, - claimed_app_display_name: Optional, ) -> PortalResult { let CreateCredentialPortalOptions { activation_token, @@ -86,7 +85,6 @@ impl CredentialPortalGateway { connection, &header, claimed_app_id, - claimed_app_display_name.into(), origin.clone(), top_origin.clone().into(), ) @@ -135,7 +133,6 @@ impl CredentialPortalGateway { origin: String, options: GetCredentialPortalOptions, claimed_app_id: String, - claimed_app_display_name: Optional, ) -> PortalResult { let GetCredentialPortalOptions { activation_token, @@ -146,7 +143,6 @@ impl CredentialPortalGateway { connection, &header, claimed_app_id, - claimed_app_display_name.into(), origin.clone(), top_origin.clone().into(), ) @@ -346,7 +342,6 @@ async fn validate_app_details( connection: &Connection, header: &Header<'_>, claimed_app_id: String, - claimed_app_display_name: Option, claimed_origin: String, claimed_top_origin: Option, ) -> Result { @@ -370,7 +365,6 @@ async fn validate_app_details( tracing::warn!("Invalid app ID passed: {claimed_app_id}"); return Err(Error::SecurityError); }; - let display_name = claimed_app_display_name.unwrap_or_default(); // Verify that the origin is valid for the given app ID. let claimed_origin = claimed_origin.parse().map_err(|err| { @@ -389,7 +383,6 @@ async fn validate_app_details( Ok(RequestContext { app_id, - app_name: display_name, pid, request_kind, }) diff --git a/credentialsd/src/gateway/mod.rs b/credentialsd/src/gateway/mod.rs index 7f7d05f6..41b02bec 100644 --- a/credentialsd/src/gateway/mod.rs +++ b/credentialsd/src/gateway/mod.rs @@ -10,7 +10,7 @@ use std::{ }; use credentialsd_common::{ - model::{RequestingApplication, WebAuthnError}, + model::WebAuthnError, server::{ CreateCredentialRequest, CreateCredentialResponse, GetCredentialRequest, GetCredentialResponse, WindowHandle, @@ -21,7 +21,7 @@ use zbus::Connection; use crate::{ dbus::CredentialRequestController, - model::{CredentialRequest, CredentialResponse}, + model::{ClientDetails, CredentialRequest, CredentialResponse}, webauthn::{AppId, NavigationContext, Origin}, }; use util::{ @@ -55,16 +55,16 @@ enum RequestKind { #[derive(Debug)] struct RequestContext { app_id: AppId, - app_name: String, pid: u32, request_kind: RequestKind, } -impl From for RequestingApplication { +impl From for ClientDetails { fn from(value: RequestContext) -> Self { - RequestingApplication { - path_or_app_id: value.app_id.as_ref().to_string(), - name: Some(value.app_name).into(), + ClientDetails { + app_id: value.app_id.as_ref().to_string(), + // TODO: put path in RequestContext + path: value.app_id.as_ref().to_string(), pid: value.pid, } } diff --git a/credentialsd/src/model.rs b/credentialsd/src/model.rs index cb59df99..95c40041 100644 --- a/credentialsd/src/model.rs +++ b/credentialsd/src/model.rs @@ -71,3 +71,9 @@ impl GetAssertionResponseInternal { } } } + +pub struct ClientDetails { + pub app_id: String, + pub path: String, + pub pid: u32, +} diff --git a/doc/api.md b/doc/api.md index 94aa8679..d445b615 100644 --- a/doc/api.md +++ b/doc/api.md @@ -207,7 +207,6 @@ CreateCredentialRequest( }, IN app_id s, - IN app_display_name s ) ``` @@ -261,7 +260,6 @@ type. public_key: s // WebAuthn credential attestation JSON }, IN app_id s, - IN app_display_name s ) ### Response @@ -328,7 +326,6 @@ GetCredentialRequest ( public_key: s }, IN app_id s, - IN app_display_name s ) ``` diff --git a/doc/xyz.iinuwa.credentialsd.Credentials.xml b/doc/xyz.iinuwa.credentialsd.Credentials.xml index 3d957358..bcf50702 100644 --- a/doc/xyz.iinuwa.credentialsd.Credentials.xml +++ b/doc/xyz.iinuwa.credentialsd.Credentials.xml @@ -27,7 +27,6 @@ - @@ -36,7 +35,6 @@ - @@ -140,4 +138,3 @@ - diff --git a/doc/xyz.iinuwa.credentialsd.UiControl.xml b/doc/xyz.iinuwa.credentialsd.UiControl.xml index e2357b0c..3fb0446f 100644 --- a/doc/xyz.iinuwa.credentialsd.UiControl.xml +++ b/doc/xyz.iinuwa.credentialsd.UiControl.xml @@ -43,7 +43,6 @@ - @@ -51,4 +50,3 @@ -