mirror of
https://github.com/bitwarden/clients.git
synced 2026-07-01 21:10:49 +08:00
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:
parent
f0dbf65dd6
commit
23da514cce
@ -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())),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {}
|
||||
}
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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::{
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -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};
|
||||
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)]
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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!(
|
||||
|
||||
@ -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.");
|
||||
|
||||
@ -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.");
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user