diff --git a/apps/vault/locales/i18n.json b/apps/vault/locales/i18n.json index 205785e97..05fe35198 100644 --- a/apps/vault/locales/i18n.json +++ b/apps/vault/locales/i18n.json @@ -365,6 +365,18 @@ "zh": "选择字体", "en-tts": "Select a font style" }, + "vault.readout_switchover": { + "en": "Switching USB functions...", + "ja": "USB機能を切り替え中...", + "zh": "切换 USB 功能...", + "en-tts": "Switching USB functions..." + }, + "vault.readout_active": { + "en": "🔓Readout mode active.🔓\n\nHost is permitted to read and write unlocked records.\n\nPlease run your host scripts, then press any key to restore security.", + "ja": "🔓読み出しモードがアクティブです。🔓\n\nホストは、ロックされていないレコードの読み取りと書き込みを許可されています。\n\nホスト スクリプトを実行してから、任意のキーを押してセキュリティを復元してください。", + "zh": "🔓读出模式激活。🔓\n\n允许主机读取和写入未锁定的记录。\n\n请运行主机脚本,然后按任意键恢复安全。", + "en-tts": "Readout mode active.\n\nHost is permitted to read and write unlocked records.\n\nPlease run your host scripts, then press any key to restore security." + }, "vault.menu_autotype": { "en": "Autotype", "ja": "自動的に入力", @@ -407,6 +419,12 @@ "zh": "管理基础", "en-tts": "Manage Bases" }, + "vault.menu_readout_mode": { + "en": "Enable host readout", + "ja": "ホスト読み出しを有効にする", + "zh": "启用主机读出", + "en-tts": "Enable host readout" + }, "vault.menu_close": { "en": "Close submenu", "ja": "メニューを閉じる", diff --git a/apps/vault/src/main.rs b/apps/vault/src/main.rs index 36e4a15e7..ade97b345 100644 --- a/apps/vault/src/main.rs +++ b/apps/vault/src/main.rs @@ -128,6 +128,7 @@ pub(crate) enum VaultOp { MenuDeleteStage1, MenuEditStage1, MenuAutotype, + MenuReadoutMode, /// PDDB basis change BasisChange, @@ -452,6 +453,18 @@ fn main() -> ! { modals.show_notification(t!("vault.error.nothing_selected", xous::LANG), None).ok(); } } + Some(VaultOp::MenuReadoutMode) => { + modals.dynamic_notification(Some(t!("vault.readout_switchover", xous::LANG)), None).ok(); + vaultux.readout_mode(true); + modals.dynamic_notification_close().ok(); + + modals.show_notification(t!("vault.readout_active", xous::LANG), None).ok(); + // TODO: add some variable here to de-activate HID readout once this is done + + modals.dynamic_notification(Some(t!("vault.readout_switchover", xous::LANG)), None).ok(); + vaultux.readout_mode(false); + modals.dynamic_notification_close().ok(); + } Some(VaultOp::Quit) => { log::error!("got Quit"); break; diff --git a/apps/vault/src/submenu.rs b/apps/vault/src/submenu.rs index 03f805327..b9949858e 100644 --- a/apps/vault/src/submenu.rs +++ b/apps/vault/src/submenu.rs @@ -51,6 +51,13 @@ pub fn create_submenu(vault_conn: xous::CID, actions_conn: xous::CID, menu_mgr: action_payload: MenuPayload::Scalar([0, 0, 0, 0]), close_on_select: true, }); + menu_items.push(MenuItem { + name: xous_ipc::String::from_str(t!("vault.menu_readout_mode", xous::LANG)), + action_conn: Some(vault_conn), + action_opcode: VaultOp::MenuReadoutMode.to_u32().unwrap(), + action_payload: MenuPayload::Scalar([0, 0, 0, 0]), + close_on_select: true, + }); menu_items.push(MenuItem { name: xous_ipc::String::from_str(t!("vault.menu_close", xous::LANG)), action_conn: Some(actions_conn), diff --git a/apps/vault/src/ux/framework.rs b/apps/vault/src/ux/framework.rs index 010a1c046..a79628a04 100644 --- a/apps/vault/src/ux/framework.rs +++ b/apps/vault/src/ux/framework.rs @@ -779,4 +779,15 @@ impl VaultUx { self.usb_dev.ensure_core(self.usb_type).unwrap(); self.usb_dev.restrict_debug_access(true).unwrap(); } + /// In readout mode, the keyboard composite function has to be turned off, because + /// Windows will block any programs that try to talk to USB devices that contain a keyboard + /// (ostensibly to prevent keyboard loggers). + pub(crate) fn readout_mode(&mut self, enabled: bool) { + if enabled { + self.usb_type = UsbDeviceType::Fido; + } else { + self.usb_type = UsbDeviceType::FidoKbd; + } + self.usb_dev.ensure_core(self.usb_type).unwrap(); + } } \ No newline at end of file diff --git a/services/modals/src/lib.rs b/services/modals/src/lib.rs index 389900475..596bd41cb 100644 --- a/services/modals/src/lib.rs +++ b/services/modals/src/lib.rs @@ -11,6 +11,7 @@ use gam::*; use num_traits::*; #[cfg(feature = "ditherpunk")] use std::convert::TryInto; +#[cfg(feature = "ditherpunk")] use std::cmp::max; use xous::{send_message, Message, CID}; use xous_ipc::Buffer;