From 8ef8f37b370fac27948d10061ef2edfee126c2b3 Mon Sep 17 00:00:00 2001 From: Shubham Singh Date: Wed, 4 Sep 2024 14:46:38 +0530 Subject: [PATCH] feat(firefox): incomplete firefox implementation --- core/src/commands/generate.rs | 8 ++-- core/src/trust_stores/errors.rs | 26 +++++++++- core/src/trust_stores/firefox.rs | 71 ++++++++++++++++++++++++++++ core/src/trust_stores/mod.rs | 1 + core/src/trust_stores/nss.rs | 18 +++---- core/src/trust_stores/nss_profile.rs | 17 +------ 6 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 core/src/trust_stores/firefox.rs diff --git a/core/src/commands/generate.rs b/core/src/commands/generate.rs index 578b599..8cfc5d0 100644 --- a/core/src/commands/generate.rs +++ b/core/src/commands/generate.rs @@ -313,10 +313,10 @@ pub fn generate( }; ca_value_object.install_certificate()?; let nss_profile_object: NSSProfile = NSSProfile::new(); - let ca_unique_name = "vanish-root-test-123456-ujjwal".to_string(); - let caroot = "/home/jerry/.local/share/vanish/ca_cert.pem".to_string(); - let mkcert = NSSValue::new(nss_profile_object, ca_unique_name, caroot); - let success = mkcert.install_nss(); + let ca_unique_name: String = "vanish-root-test-123456-ujjwalpppp".to_string(); + let caroot: String = "/home/jerry/.local/share/vanish/ca_cert.pem".to_string(); + let mkcert: NSSValue = NSSValue::new(nss_profile_object, ca_unique_name, caroot); + let success: bool = mkcert.install_nss(); if success { println!("Certificate installed successfully."); diff --git a/core/src/trust_stores/errors.rs b/core/src/trust_stores/errors.rs index f00097b..9270c32 100644 --- a/core/src/trust_stores/errors.rs +++ b/core/src/trust_stores/errors.rs @@ -1,5 +1,5 @@ use openssl::error::ErrorStack; -use std::{error::Error, fmt, io}; +use std::{env::VarError, error::Error, fmt, io}; #[derive(Debug)] pub enum TrustStoreError { @@ -24,4 +24,26 @@ impl fmt::Display for TrustStoreError { } } -impl Error for TrustStoreError {} \ No newline at end of file +impl Error for TrustStoreError {} + +pub enum FirefoxTrustStoreError { + ENVVariableNotFound(VarError, String), + IOError(io::Error), +} + +impl fmt::Display for FirefoxTrustStoreError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::ENVVariableNotFound(err, variable) => { + write!( + f, + "Error getting Environment varibale {} : {}", + variable, err + ) + } + Self::IOError(err) => { + write!(f, "Error reading the default firefox directoryL {}", err) + } + } + } +} diff --git a/core/src/trust_stores/firefox.rs b/core/src/trust_stores/firefox.rs new file mode 100644 index 0000000..edb9513 --- /dev/null +++ b/core/src/trust_stores/firefox.rs @@ -0,0 +1,71 @@ +use super::errors::FirefoxTrustStoreError; +use std::{ + env, ffi, fs, io, + path::{Path, PathBuf}, +}; + +pub struct FirefoxTrustStore { + firefox_profile: Vec, +} + +impl FirefoxTrustStore { + pub fn new() -> Result { + let mut firefox_profile: Vec = Vec::::new(); + #[cfg(target_os = "linux")] + { + let home: String = env::var("HOME").map_err(|err: env::VarError| { + FirefoxTrustStoreError::ENVVariableNotFound(err, "HOME".to_string()) + })?; + firefox_profile.push(home.clone() + "/.morzilla/firefox/"); + firefox_profile.push(home + "/snap/firefox/common/.mozilla/firefox/"); + } + #[cfg(target_os = "windows")] + { + let userprofile: String = env::var("USERPROFILE").map_err(|err: env::VarError| { + FirefoxTrustStoreError::ENVVariableNotFound(err, "USERPROFILE".to_string()) + })?; + firefox_profile.push(userprofile + "\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles"); + } + #[cfg(target_os = "macos")] + { + let home: String = env::var("HOME").map_err(|err: env::VarError| { + FirefoxTrustStoreError::ENVVariableNotFound(err, "HOME".to_string()) + })?; + firefox_profile.push(home + "/Library/Application Support/Firefox/Profiles/"); + } + Ok(FirefoxTrustStore { firefox_profile }) + } + + pub fn find_cert_directories(&self) -> Result, FirefoxTrustStoreError> { + let mut cert_dirs: Vec = Vec::new(); + + for profile_dir in &self.firefox_profile { + let path: &Path = Path::new(profile_dir); + if path.exists() && path.is_dir() { + for entry in fs::read_dir(path) + .map_err(|err: io::Error| FirefoxTrustStoreError::IOError(err))? + { + let entry: fs::DirEntry = + entry.map_err(|err: io::Error| FirefoxTrustStoreError::IOError(err))?; + let entry_path: PathBuf = entry.path(); + if entry_path.is_dir() { + let cert9_path: PathBuf = entry_path.join("cert9.db"); + let cert8_path: PathBuf = entry_path.join("cert8.db"); + if cert9_path.exists() || cert8_path.exists() { + cert_dirs.push(entry_path); + } + } + } + } + } + + if cert_dirs.is_empty() { + eprintln!("No directories containing certificate databases were found for any of your Firefox Profiles."); + std::process::exit(1); + } else { + Ok(cert_dirs) + } + } + + pub fn install_firefox_certificates(&self) {} +} diff --git a/core/src/trust_stores/mod.rs b/core/src/trust_stores/mod.rs index 57701a9..51e2ce4 100644 --- a/core/src/trust_stores/mod.rs +++ b/core/src/trust_stores/mod.rs @@ -1,4 +1,5 @@ mod errors; +pub mod firefox; pub mod nss; pub mod nss_profile; diff --git a/core/src/trust_stores/nss.rs b/core/src/trust_stores/nss.rs index 01d94ba..1bd3335 100644 --- a/core/src/trust_stores/nss.rs +++ b/core/src/trust_stores/nss.rs @@ -1,6 +1,6 @@ -use super::nss_profile::NSSProfile; +use crate::trust_stores::nss_profile::NSSProfile; use std::{ - io, + fs, io, path::Path, process::{Command, ExitStatus}, }; @@ -107,18 +107,12 @@ impl NSSValue { F: FnMut(&str), { let mut found: usize = 0; - let mut profiles: Vec = Vec::new(); + let profiles = &self.profile.nss_dbs; - profiles.extend_from_slice(&self.profile.nss_dbs); - for ff in &self.profile.firefox_paths { - let path: &Path = Path::new(ff); - if path.exists() { - profiles.push(ff.clone()); - } - } + println!("{:?}", profiles); - for profile in &profiles { - let stat: Result = Path::new(profile).metadata(); + for profile in profiles { + let stat: Result = Path::new(profile).metadata(); if stat.is_ok() && stat.unwrap().is_dir() { if NSSProfile::path_exists(&format!("{}/cert9.db", profile)) { f(&format!("sql:{}", profile)); diff --git a/core/src/trust_stores/nss_profile.rs b/core/src/trust_stores/nss_profile.rs index 28faba1..0933c9a 100644 --- a/core/src/trust_stores/nss_profile.rs +++ b/core/src/trust_stores/nss_profile.rs @@ -6,7 +6,6 @@ pub struct NSSProfile { pub has_certutil: bool, pub certutil_path: Option, pub nss_dbs: Vec, - pub firefox_paths: Vec, } impl NSSProfile { @@ -27,21 +26,8 @@ impl NSSProfile { "/etc/pki/nssdb".to_string(), ]; - let firefox_paths: Vec = vec![ - "/usr/bin/firefox".to_string(), - "/usr/bin/firefox-nightly".to_string(), - "/usr/bin/firefox-developer-edition".to_string(), - "/snap/firefox".to_string(), - "/Applications/Firefox.app".to_string(), - "/Applications/FirefoxDeveloperEdition.app".to_string(), - "/Applications/Firefox Developer Edition.app".to_string(), - "/Applications/Firefox Nightly.app".to_string(), - "C:\\Program Files\\Mozilla Firefox".to_string(), - ]; - let mut has_nss: bool = false; - let all_paths: Vec = [&nss_dbs[..], &firefox_paths[..]].concat(); - for path in &all_paths { + for path in &nss_dbs { if Path::new(path).exists() { has_nss = true; break; @@ -78,7 +64,6 @@ impl NSSProfile { has_certutil, certutil_path, nss_dbs, - firefox_paths, } }