Desktop Native: Add missing docs lint for _some_ modules in core (#18983)

Adds the clippy lint for docs warning to core to align with our contributing docs guidelines.
This commit is contained in:
neuronull 2026-03-04 09:21:02 -07:00 committed by GitHub
parent f0dbf65dd6
commit 23da514cce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 91 additions and 3 deletions

View File

@ -21,6 +21,8 @@ use zbus_polkit::policykit1::{AuthorityProxy, CheckAuthorizationFlags, Subject};
use crate::secure_memory::{encrypted_memory_store::EncryptedMemoryStore, SecureMemoryStore as _};
/// Biometric lock system using Polkit for authentication and secure memory to hold the key on
/// Linux.
pub struct BiometricLockSystem {
// The userkeys that are held in memory MUST be protected from memory dumping attacks, to
// ensure locked vaults cannot be unlocked
@ -28,6 +30,7 @@ pub struct BiometricLockSystem {
}
impl BiometricLockSystem {
/// Creates a new biometric lock system with secure memory storage.
pub fn new() -> Self {
Self {
secure_memory: Arc::new(Mutex::new(EncryptedMemoryStore::default())),

View File

@ -1,3 +1,8 @@
//! Biometric unlock module
//!
//! This modules can protect a key, either in-memory or in persisted operating system APIs
//! and release it only after authenticating via biometrics.
use anyhow::Result;
#[allow(clippy::module_inception)]
@ -11,6 +16,7 @@ pub mod windows_focus;
pub use biometric_v2::BiometricLockSystem;
/// Platform-specific biometric-protected key storage
#[allow(async_fn_in_trait)]
pub trait BiometricTrait: Send + Sync {
/// Authenticate the user

View File

@ -1,6 +1,8 @@
/// Biometric lock system (unimplemented on this platform).
pub struct BiometricLockSystem {}
impl BiometricLockSystem {
/// Creates a new biometric lock system.
pub fn new() -> Self {
Self {}
}

View File

@ -82,6 +82,7 @@ pub struct BiometricLockSystem {
}
impl BiometricLockSystem {
/// Creates a new instance of the Windows biometric lock system.
pub fn new() -> Self {
Self {
secure_memory: Arc::new(Mutex::new(

View File

@ -1,3 +1,8 @@
//! Windows-specific window focus management for biometric prompts.
//!
//! A large part of this is hacks to get around limitations with the Windows-Hello API used,
//! since it does not bring the authentication prompt into focus automatically.
use windows::{
core::s,
Win32::{

View File

@ -1,8 +1,12 @@
//! Error types for desktop_core operations.
use std::fmt::Debug;
use thiserror::Error;
/// Errors that can occur in desktop_core operations.
#[derive(Error, Debug)]
#[allow(missing_docs)]
pub enum Error {
#[error("Error parsing CipherString: {0}")]
InvalidCipherString(#[from] CSParseError),
@ -11,7 +15,9 @@ pub enum Error {
Crypto(#[from] CryptoError),
}
/// Errors during cipher string parsing.
#[derive(Debug, Error)]
#[allow(missing_docs)]
pub enum CSParseError {
#[error("No type detected, missing '.' separator")]
NoType,
@ -23,16 +29,21 @@ pub enum CSParseError {
InvalidBase64Length { expected: usize, got: usize },
}
/// Errors during cryptographic operations.
#[derive(Debug, Error)]
#[allow(missing_docs)]
pub enum CryptoError {
#[error("Error while decrypting cipher string")]
KeyDecrypt,
}
/// Errors during KDF parameter validation.
#[derive(Debug, Error)]
#[allow(missing_docs)]
pub enum KdfParamError {
#[error("Invalid KDF parameters: {0}")]
InvalidParams(String),
}
/// Convenience Result type using [`Error`].
pub type Result<T, E = Error> = std::result::Result<T, E>;

View File

@ -1,3 +1,5 @@
//! IPC client for connecting to and communicating with the IPC server.
use std::path::PathBuf;
use futures::{SinkExt, StreamExt};
@ -7,6 +9,7 @@ use interprocess::local_socket::{
};
use tracing::{error, info};
/// Connects to an IPC server and handles bidirectional message passing.
pub async fn connect(
path: PathBuf,
send: tokio::sync::mpsc::Sender<String>,

View File

@ -1,3 +1,5 @@
//! Inter-process communication for native messaging and IPC server/client.
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_util::codec::{Framed, LengthDelimitedCodec};

View File

@ -1,3 +1,5 @@
//! IPC server for handling multiple client connections.
use std::{
error::Error,
path::{Path, PathBuf},
@ -15,22 +17,29 @@ use tracing::{error, info};
use super::MESSAGE_CHANNEL_BUFFER;
/// Message received from or sent to an IPC client.
#[derive(Debug)]
pub struct Message {
/// Unique identifier for the client connection.
pub client_id: u32,
/// Type of message.
pub kind: MessageType,
// This value should be Some for MessageType::Message and None for the rest
/// Message payload (Some for MessageType::Message, None otherwise).
pub message: Option<String>,
}
/// Type of IPC message.
#[derive(Debug)]
#[allow(missing_docs)]
pub enum MessageType {
Connected,
Disconnected,
Message,
}
/// IPC server that listens for client connections.
pub struct Server {
/// Path to the IPC socket.
pub path: PathBuf,
cancel_token: CancellationToken,
server_to_clients_send: broadcast::Sender<String>,

View File

@ -1,15 +1,30 @@
//! Desktop native core functionality for Bitwarden.
//!
//! Modules in this crate should fall into one of these categories:
//! * infrastructure to interface with the Electron client
//! * core functionality for the Desktop app that is not feature-specific
//! * library code that is used internally by other desktop_native crates.
#![warn(missing_docs)]
#[allow(missing_docs)]
pub mod autofill;
#[allow(missing_docs)]
pub mod autostart;
#[allow(missing_docs)] // staged to be removed
pub mod biometric;
pub mod biometric_v2;
#[allow(missing_docs)]
pub mod clipboard;
pub(crate) mod crypto;
pub mod error;
pub mod ipc;
pub mod password;
#[allow(missing_docs)]
pub mod powermonitor;
pub mod process_isolation;
pub mod secure_memory;
#[allow(missing_docs)] // staged to be removed
pub mod ssh_agent;
use zeroizing_alloc::ZeroAlloc;

View File

@ -1,3 +1,5 @@
//! macOS Keychain password operations.
use anyhow::Result;
use security_framework::passwords::{
delete_generic_password, get_generic_password, set_generic_password,
@ -5,6 +7,7 @@ use security_framework::passwords::{
use crate::password::PASSWORD_NOT_FOUND;
/// Retrieves a password from the macOS Keychain.
#[allow(clippy::unused_async)]
pub async fn get_password(service: &str, account: &str) -> Result<String> {
let password = get_generic_password(service, account).map_err(convert_error)?;
@ -12,18 +15,21 @@ pub async fn get_password(service: &str, account: &str) -> Result<String> {
Ok(result)
}
/// Stores a password in the macOS Keychain.
#[allow(clippy::unused_async)]
pub async fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
set_generic_password(service, account, password.as_bytes())?;
Ok(())
}
/// Deletes a password from the macOS Keychain.
#[allow(clippy::unused_async)]
pub async fn delete_password(service: &str, account: &str) -> Result<()> {
delete_generic_password(service, account).map_err(convert_error)?;
Ok(())
}
/// Checks if Keychain access is available.
#[allow(clippy::unused_async)]
pub async fn is_available() -> Result<bool> {
Ok(true)

View File

@ -1,3 +1,6 @@
//! Secure password storage and retrieval using platform keychains.
/// Error message returned when a password is not found in the system keychain.
pub const PASSWORD_NOT_FOUND: &str = "Password not found.";
#[allow(clippy::module_inception)]

View File

@ -6,6 +6,7 @@ use tracing::info;
use crate::password::PASSWORD_NOT_FOUND;
/// Retrieves a password from the Linux Secret Service keyring.
pub async fn get_password(service: &str, account: &str) -> Result<String> {
match get_password_new(service, account).await {
Ok(res) => Ok(res),
@ -51,6 +52,7 @@ async fn get_password_legacy(service: &str, account: &str) -> Result<String> {
}
}
/// Stores a password in the Linux Secret Service keyring.
pub async fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let keyring = oo7::Keyring::new().await?;
let _ = try_prompt(&keyring).await;

View File

@ -15,6 +15,7 @@ use crate::password::PASSWORD_NOT_FOUND;
const CRED_FLAGS_NONE: u32 = 0;
/// Retrieves a password from the Windows Credential Manager.
#[allow(clippy::unused_async)]
pub async fn get_password(service: &str, account: &str) -> Result<String> {
let target_name = U16CString::from_str(target_name(service, account))?;
@ -48,6 +49,7 @@ pub async fn get_password(service: &str, account: &str) -> Result<String> {
Ok(password)
}
/// Stores a password in the Windows Credential Manager.
#[allow(clippy::unused_async)]
pub async fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let mut target_name = U16CString::from_str(target_name(service, account))?;
@ -80,6 +82,7 @@ pub async fn set_password(service: &str, account: &str, password: &str) -> Resul
Ok(())
}
/// Deletes a password from the Windows Credential Manager.
#[allow(clippy::unused_async)]
pub async fn delete_password(service: &str, account: &str) -> Result<()> {
let target_name = U16CString::from_str(target_name(service, account))?;
@ -91,6 +94,7 @@ pub async fn delete_password(service: &str, account: &str) -> Result<()> {
Ok(())
}
/// Checks if the Windows Credential Manager is available. Always returns true on Windows.
#[allow(clippy::unused_async)]
pub async fn is_available() -> Result<bool> {
Ok(true)

View File

@ -1,9 +1,9 @@
#[allow(clippy::unused_async)]
#[allow(missing_docs, clippy::unused_async)]
pub async fn on_lock(_: tokio::sync::mpsc::Sender<()>) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!();
}
#[allow(clippy::unused_async)]
#[allow(missing_docs, clippy::unused_async)]
pub async fn is_lock_monitor_available() -> bool {
false
}

View File

@ -16,6 +16,8 @@ const RLIMIT_CORE: c_uint = 4;
// https://github.com/torvalds/linux/blob/a38297e3fb012ddfa7ce0321a7e5a8daeb1872b6/include/uapi/linux/prctl.h#L14
const PR_SET_DUMPABLE: c_int = 4;
/// Disables core dumps by setting RLIMIT_CORE to prevent memory from being
/// persisted to disk on crashes.
pub fn disable_coredumps() -> Result<()> {
let rlimit = libc::rlimit {
rlim_cur: 0,
@ -34,6 +36,7 @@ pub fn disable_coredumps() -> Result<()> {
Ok(())
}
/// Checks if core dumping is disabled by verifying that RLIMIT_CORE is set to 0.
pub fn is_core_dumping_disabled() -> Result<bool> {
let mut rlimit = libc::rlimit {
rlim_cur: 0,
@ -47,6 +50,8 @@ pub fn is_core_dumping_disabled() -> Result<bool> {
Ok(rlimit.rlim_cur == 0 && rlimit.rlim_max == 0)
}
/// Prevents other processes from dumping this process's memory or attaching a
/// debugger by setting PR_SET_DUMPABLE.
pub fn isolate_process() -> Result<()> {
let pid = std::process::id();
info!(

View File

@ -1,14 +1,17 @@
use anyhow::{bail, Result};
use tracing::info;
#[allow(missing_docs)]
pub fn disable_coredumps() -> Result<()> {
bail!("Not implemented on Mac")
}
#[allow(missing_docs)]
pub fn is_core_dumping_disabled() -> Result<bool> {
bail!("Not implemented on Mac")
}
#[allow(missing_docs)]
pub fn isolate_process() -> Result<()> {
let pid: u32 = std::process::id();
info!(pid, "Disabling ptrace on main process via PT_DENY_ATTACH.");

View File

@ -1,14 +1,18 @@
use anyhow::{bail, Result};
use tracing::info;
#[allow(missing_docs)]
pub fn disable_coredumps() -> Result<()> {
bail!("Not implemented on Windows")
}
#[allow(missing_docs)]
pub fn is_core_dumping_disabled() -> Result<bool> {
bail!("Not implemented on Windows")
}
/// Prevents other processes from accessing this process's memory by hardening the
/// process using DACL (Discretionary Access Control List).
pub fn isolate_process() -> Result<()> {
let pid: u32 = std::process::id();
info!(pid, "Isolating main process via DACL.");

View File

@ -29,6 +29,7 @@ impl<K> EncryptedMemoryStore<K>
where
K: std::cmp::Ord + std::fmt::Display + std::clone::Clone,
{
/// Creates a new encrypted memory store with a fresh encryption key.
#[must_use]
pub fn new() -> Self {
EncryptedMemoryStore {

View File

@ -1,3 +1,5 @@
//! Secure memory management with platform-specific protections.
#[cfg(target_os = "windows")]
pub(crate) mod dpapi;
@ -13,6 +15,7 @@ use crate::secure_memory::secure_key::DecryptionError;
/// platform-specific protections are applied to prevent memory dumps or debugger access from
/// reading the stored values.
pub trait SecureMemoryStore {
/// Key type used to identify stored values.
type KeyType;
/// Stores a copy of the provided value in secure memory.