Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handle #12

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
488 changes: 394 additions & 94 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ tracing-subscriber = { version = "^0.3", default-features = true, features = ["e

anyhow = "^1"
miette = { version = "^7", default-features = true }
thiserror = { version = "^1" }
thiserror = { version = "^2" }

serde = { version = "^1", default-features = false, features = ["derive"] }
serde_json = { version = "^1", default-features = false }
Expand Down
12 changes: 5 additions & 7 deletions crates/decrypt-cookies/src/browser/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,26 @@ use std::path::PathBuf;
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum BuilderError {
#[error("No such file")]
Io(#[from] std::io::Error),
#[error("No such file: {0:?}")]
NoFile(PathBuf),
#[error("Create dir failed: {0:?}")]
CreateDir(PathBuf),
#[error("Ini load error")]
#[error(transparent)]
Ini(#[from] ini::Error),
#[error("Profile {0} missing `Name` properties")]
ProfilePath(String),
#[error("Install {0} missing `Default` properties")]
InstallPath(String),
#[cfg(target_os = "linux")]
#[error("Decrypter error")]
#[error(transparent)]
Decrypter(#[from] crate::chromium::crypto::linux::CryptoError),
#[cfg(target_os = "windows")]
#[error("Decrypter error")]
#[error(transparent)]
Decrypter(#[from] crate::chromium::crypto::win::CryptoError),
#[cfg(target_os = "macos")]
#[error("Decrypt error")]
#[error(transparent)]
Decrypt(#[from] crate::chromium::crypto::macos::CryptoError),
#[error("Db err")]
#[error(transparent)]
Db(#[from] sea_orm::DbErr),
}

Expand Down
4 changes: 2 additions & 2 deletions crates/decrypt-cookies/src/chromium/crypto/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use crate::browser::need_safe_storage;
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum CryptoError {
#[error("Get secret failed")]
#[error(transparent)]
GetPass(#[from] secret_service::Error),
#[error("Unpad error: {0}")]
Unpadding(block_padding::UnpadError),
#[error("Not utf-8: {0}")]
#[error(transparent)]
StringUtf8(#[from] std::string::FromUtf8Error),
}

Expand Down
2 changes: 1 addition & 1 deletion crates/decrypt-cookies/src/chromium/crypto/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use pbkdf2::pbkdf2_hmac;
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum CryptoError {
#[error("Get keyring failed")]
#[error(transparent)]
Keyring(#[from] keyring::Error),
#[error("Unpad error: {0}")]
Unpadding(block_padding::UnpadError),
Expand Down
43 changes: 27 additions & 16 deletions crates/decrypt-cookies/src/chromium/crypto/win.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{ffi::c_void, path::Path, ptr, slice};
use std::{
ffi::c_void,
path::{Path, PathBuf},
ptr, slice,
};

use aes_gcm::{
aead::{generic_array::GenericArray, Aead},
Expand All @@ -13,20 +17,24 @@ use crate::chromium::local_state::LocalState;
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum CryptoError {
#[error("Io error")]
Io(#[from] std::io::Error),
#[error("Serialize error")]
#[error("{source}, path: {path}")]
IO {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(transparent)]
Serde(#[from] serde_json::Error),
#[error("Decode error")]
#[error(transparent)]
Base64(#[from] base64::DecodeError),
#[error("Task failed")]
#[error(transparent)]
Task(#[from] tokio::task::JoinError),
#[error("Task failed")]
#[error("{0}")]
Aead(String),
#[error("Windows CryptUnprotectData")]
#[error(transparent)]
CryptUnprotectData(#[from] windows::core::Error),
#[error("Windows CryptUnprotectData")]
CryptUnprotectDataNull(&'static str),
#[error("CryptUnprotectData returned a null pointer")]
CryptUnprotectDataNull,
}

type Result<T> = std::result::Result<T, CryptoError>;
Expand Down Expand Up @@ -60,13 +68,18 @@ impl Decrypter {
impl Decrypter {
/// the method will use default `LocalState` path,
/// custom that path use `DecrypterBuilder`
pub async fn build<A: AsRef<Path> + Send>(key_path: A) -> Result<Self> {
pub async fn build<A: AsRef<Path> + Send + Sync>(key_path: A) -> Result<Self> {
let pass = Self::get_pass(key_path).await?;
Ok(Self { pass })
}
// https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/sync/os_crypt_win.cc;l=108
async fn get_pass<A: AsRef<Path> + Send>(key_path: A) -> Result<Vec<u8>> {
let string_str = fs::read_to_string(key_path).await?;
async fn get_pass<A: AsRef<Path> + Send + Sync>(key_path: A) -> Result<Vec<u8>> {
let string_str = fs::read_to_string(&key_path)
.await
.map_err(|e| CryptoError::IO {
path: key_path.as_ref().to_owned(),
source: e,
})?;
let local_state: LocalState = serde_json::from_str(&string_str)?;
let encrypted_key = general_purpose::STANDARD.decode(local_state.os_crypt.encrypted_key)?;
let mut key = encrypted_key[Self::K_DPAPIKEY_PREFIX.len()..].to_vec();
Expand Down Expand Up @@ -119,9 +132,7 @@ pub fn decrypt_with_dpapi(ciphertext: &mut [u8]) -> Result<Vec<u8>> {
)?;
};
if output.pbData.is_null() {
return Err(CryptoError::CryptUnprotectDataNull(
"CryptUnprotectData returned a null pointer",
));
return Err(CryptoError::CryptUnprotectDataNull);
}

let decrypted_data =
Expand Down
10 changes: 5 additions & 5 deletions crates/decrypt-cookies/src/chromium/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ use crate::{
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum ChromiumError {
#[error("Tokio task failed")]
#[error(transparent)]
Task(#[from] JoinError),
#[error("Database error")]
#[error(transparent)]
Db(#[from] DbErr),
#[cfg(target_os = "linux")]
#[error("Decrypt error")]
#[error(transparent)]
Decrypt(#[from] crate::chromium::crypto::linux::CryptoError),
#[cfg(target_os = "windows")]
#[error("Decrypt error")]
#[error(transparent)]
Decrypt(#[from] crate::chromium::crypto::win::CryptoError),
#[cfg(target_os = "macos")]
#[error("Decrypt error")]
#[error(transparent)]
Decrypt(#[from] crate::chromium::crypto::macos::CryptoError),
}

Expand Down
17 changes: 12 additions & 5 deletions crates/decrypt-cookies/src/safari/items/cookie/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ use crate::{
#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum CookiesGetterError {
#[error("Parse cookies failed")]
#[error(transparent)]
Parse(#[from] crate::utils::binary_cookies::ParseError),
#[error("Io error")]
Io(#[from] std::io::Error),
#[error("Tokio task failed")]
#[error("{source}, path: {path}")]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(transparent)]
Task(#[from] tokio::task::JoinError),
}

Expand Down Expand Up @@ -59,11 +63,14 @@ impl CookiesGetter {
cookie_path.push(Self::COOKIES_OLD);
}
}
let content = fs::read(cookie_path).await?;
let content = fs::read(&cookie_path)
.await
.map_err(|e| CookiesGetterError::Io { path: cookie_path, source: e })?;
let binary_cookies = spawn_blocking(move || BinaryCookies::parse(&content)).await??;

Ok(Self { binary_cookies })
}

pub fn get_session_csrf(&self, host: &str) -> LeetCodeCookies {
let mut lc_cookies = LeetCodeCookies::default();
for ck in self
Expand Down
4 changes: 2 additions & 2 deletions crates/decrypt-cookies/src/utils/binary_cookies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ pub enum ParseError {
EndHeader,
#[error("Cookies end broken")]
End,
#[error("Parser f64 failed")]
#[error(transparent)]
ParseF64(#[from] std::num::ParseFloatError),
#[error("Parser f64 failed")]
#[error(transparent)]
Array(#[from] TryFromSliceError),
}

Expand Down