Implement x-kde-passwordManagerHint

This commit is contained in:
nora 2025-09-19 20:50:32 +02:00
parent 660afa0bc8
commit a2bfdf331b
5 changed files with 77 additions and 13 deletions

43
Cargo.lock generated
View file

@ -614,6 +614,7 @@ name = "clippyboard"
version = "0.1.0"
dependencies = [
"ciborium",
"ctrlc",
"dirs",
"eframe",
"egui_extras",
@ -727,6 +728,17 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "ctrlc"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3"
dependencies = [
"dispatch",
"nix",
"windows-sys 0.61.0",
]
[[package]]
name = "cursor-icon"
version = "1.2.0"
@ -3609,7 +3621,7 @@ dependencies = [
"windows-collections",
"windows-core 0.61.2",
"windows-future",
"windows-link",
"windows-link 0.1.3",
"windows-numerics",
]
@ -3643,7 +3655,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement 0.60.0",
"windows-interface 0.59.1",
"windows-link",
"windows-link 0.1.3",
"windows-result 0.3.4",
"windows-strings 0.4.2",
]
@ -3655,7 +3667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
"windows-core 0.61.2",
"windows-link",
"windows-link 0.1.3",
"windows-threading",
]
@ -3709,6 +3721,12 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-numerics"
version = "0.2.0"
@ -3716,7 +3734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core 0.61.2",
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@ -3734,7 +3752,7 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@ -3753,7 +3771,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]
@ -3792,6 +3810,15 @@ dependencies = [
"windows-targets 0.53.3",
]
[[package]]
name = "windows-sys"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-link 0.2.0",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
@ -3829,7 +3856,7 @@ version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
"windows-link",
"windows-link 0.1.3",
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
@ -3846,7 +3873,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [
"windows-link",
"windows-link 0.1.3",
]
[[package]]

View file

@ -11,6 +11,7 @@ name = "clippyboard-select"
[dependencies]
ciborium = "0.2.2"
ctrlc = "3.5.0"
dirs = "6.0.0"
eframe = "0.32.2"
egui_extras = { version = "0.32.2", features = ["image"] }

View file

@ -12,6 +12,8 @@ pkgs.mkShell rec {
libxkbcommon
];
CLIPPYBOARD_SOCKET = "./clippyboard.socket";
LD_LIBRARY_PATH =
builtins.foldl' (a: b: "${a}:${b}/lib") "${pkgs.vulkan-loader}/lib" buildInputs;
}

View file

@ -175,23 +175,47 @@ impl Dispatch<ExtDataControlDeviceV1, ()> for WlState {
.expect("missing InProgressOffer data for ExtDataControlOfferV1");
let mime_types = offer_data.mime_types.lock().unwrap();
let has_password_manager_hint =
mime_types.contains("x-kde-passwordManagerHint");
let Some(mime) = MIME_TYPES.iter().find(|mime| mime_types.contains(**mime))
else {
warn!(
"No supported mime type found. Found mime types: {:?}",
offer_data.mime_types
mime_types
);
return;
};
drop(mime_types);
let history_state = state.shared_state.clone();
let time = offer_data.time;
let (reader, writer) = std::io::pipe().unwrap();
offer.receive(mime.to_string(), writer.as_fd());
let history_state = state.shared_state.clone();
let mime = mime.to_string();
let time = offer_data.time;
let password_manager_hint_reader = if has_password_manager_hint {
let (reader, writer) = std::io::pipe().unwrap();
offer.receive(mime.to_string(), writer.as_fd());
Some(reader)
} else {
None
};
std::thread::spawn(move || {
if let Some(mut password_manager_hint_reader) = password_manager_hint_reader
{
let mut buf = Vec::new();
if password_manager_hint_reader.read_to_end(&mut buf).is_ok()
&& buf == b"secret"
{
info!("Clipboard entry is marked as secret, not storing it");
return;
}
}
let mime = mime.to_string();
let result = read_fd_into_history(&history_state, time, mime, reader);
if let Err(err) = result {
warn!("Failed to read clipboard: {:?}", err)
@ -394,6 +418,7 @@ fn read_fd_into_history(
data_reader
.read_to_end(&mut data)
.wrap_err("reading content data")?;
let new_entry = HistoryItem {
id: history_state
.next_item_id
@ -435,6 +460,12 @@ fn read_fd_into_history(
}
pub fn main(socket_path: &PathBuf) -> eyre::Result<()> {
let socket_path2 = socket_path.clone();
let _ = ctrlc::set_handler(move || {
cleanup(&socket_path2);
std::process::exit(130); // sigint
});
let Err(err) = main_inner(socket_path);
if let Some(ioerr) = err.downcast_ref::<io::Error>()
@ -495,7 +526,6 @@ pub fn main_inner(socket_path: &PathBuf) -> eyre::Result<Infallible> {
ExtDataControlManagerV1::interface().name
);
}
rustix::fs::fcntl_setfl(notify_write_recv.as_fd(), OFlags::NONBLOCK).expect("todo");
rustix::fs::fcntl_setfl(conn.as_fd(), OFlags::NONBLOCK).expect("TODO");

View file

@ -34,6 +34,10 @@ const MESSAGE_READ: u8 = 1;
const MESSAGE_COPY: u8 = 2;
pub fn socket_path() -> eyre::Result<PathBuf> {
if let Some(path) = std::env::var_os("CLIPPYBOARD_SOCKET") {
return Ok(path.into());
}
Ok(dirs::runtime_dir()
.ok_or_eyre("missing XDG_RUNTIME_DIR")?
.join("clippyboard.sock"))