From f3089148e079d2ce4030da8e0bbc11f4c91e940f Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 14 Aug 2025 17:01:43 +0300 Subject: [PATCH] db: allow explicitly skipping sensitive entries Signed-off-by: NotAShelf Change-Id: I6a6a6964ed1deaac0215ae9c6f4c70cfdc50164d --- Cargo.lock | 1 + Cargo.toml | 5 ++++- src/db/mod.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95cd7eb..4810791 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1115,6 +1115,7 @@ dependencies = [ "imagesize", "inquire", "log", + "regex", "rmp-serde", "rusqlite", "serde", diff --git a/Cargo.toml b/Cargo.toml index b16b514..248e525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,9 @@ clap-verbosity-flag = "3.0.3" dirs = "6.0.0" rmp-serde = "1.3.0" imagesize = "0.14.0" -inquire = { default-features = false, version = "0.7.5", features = [ "crossterm" ] } +inquire = { default-features = false, version = "0.7.5", features = [ + "crossterm", +] } log = "0.4.27" env_logger = "0.11.8" thiserror = "2.0.14" @@ -24,6 +26,7 @@ smol = "2.0.2" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.142" base64 = "0.22.1" +regex = "1.11.1" [profile.release] diff --git a/src/db/mod.rs b/src/db/mod.rs index 0e7b943..6b64cf7 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,9 +1,12 @@ +use std::env; use std::fmt; +use std::fs; use std::io::{BufRead, BufReader, Read, Write}; use std::str; use imagesize::{ImageSize, ImageType}; -use log::{error, info}; +use log::{error, info, warn}; +use regex::Regex; use rusqlite::{Connection, OptionalExtension, params}; use serde::{Deserialize, Serialize}; @@ -176,6 +179,18 @@ impl ClipboardDb for SqliteClipboardDb { other => other, }; + // Try to load regex from systemd credential file, then env var + let regex = load_sensitive_regex(); + if let Some(re) = regex { + // Only check text data + if let Ok(s) = std::str::from_utf8(&buf) { + if re.is_match(s) { + warn!("Clipboard entry matches sensitive regex, skipping store."); + return Err(StashError::Store("Filtered by sensitive regex".to_string())); + } + } + } + self.deduplicate(&buf, max_dedupe_search)?; self.conn @@ -375,6 +390,31 @@ impl ClipboardDb for SqliteClipboardDb { } // Helper functions + +/// Try to load a sensitive regex from systemd credential or env. +/// +/// # Returns +/// `Some(Regex)` if present and valid, `None` otherwise. +fn load_sensitive_regex() -> Option { + if let Ok(regex_path) = env::var("CREDENTIALS_DIRECTORY") { + let file = format!("{}/clipboard_filter", regex_path); + if let Ok(contents) = fs::read_to_string(&file) { + if let Ok(re) = Regex::new(contents.trim()) { + return Some(re); + } + } + } + + // Fallback to an environment variable + if let Ok(pattern) = env::var("STASH_SENSITIVE_REGEX") { + if let Ok(re) = Regex::new(&pattern) { + return Some(re); + } + } + + None +} + pub fn extract_id(input: &str) -> Result { let id_str = input.split('\t').next().unwrap_or(""); id_str.parse().map_err(|_| "invalid id")