decrypt_cookies/browser/
mod.rs

1pub mod cookies;
2
3use std::path::PathBuf;
4
5#[cfg(not(target_os = "windows"))]
6use const_format::concatcp;
7
8const CACHE_PATH: &str = "decrypt-cookies";
9
10macro_rules! push_exact {
11    ($base:ident, $val:path) => {
12        let mut additional = $val.len();
13        if crate::utils::need_sep(&$base) {
14            additional += 1;
15        }
16        $base.reserve_exact(additional);
17
18        $base.push($val);
19    };
20}
21
22macro_rules! push_temp {
23    ($cache:ident, $val:path) => {
24        let mut $cache = dirs::cache_dir().expect("Get cache dir failed");
25        $cache.reserve_exact(CACHE_PATH.len() + Self::NAME.len() + $val.len() + 3);
26        $cache.push(CACHE_PATH);
27        $cache.push(Self::NAME);
28        $cache.push($val);
29    };
30}
31
32pub trait ChromiumPath {
33    /// Suffix for browser data path
34    const BASE: &'static str;
35    /// Browser name for [`std::fmt::Display`]
36    const NAME: &'static str;
37    #[cfg(not(target_os = "windows"))]
38    /// Suffix for cookies data path (sqlite3 database)
39    const COOKIES: &str = "Default/Cookies";
40    #[cfg(target_os = "windows")]
41    /// Suffix for cookies data path (sqlite3 database)
42    const COOKIES: &str = r"Default\Network\Cookies";
43    /// Suffix for login data path (sqlite3 database)
44    const LOGIN_DATA: &str = "Default/Login Data";
45    /// Another login data (sqlite3)
46    const LOGIN_DATA_FOR_ACCOUNT: &str = "Default/Login Data For Account";
47    /// Suffix for decryption key path (json)
48    const KEY: &str = "Local State";
49    #[cfg(not(target_os = "windows"))]
50    /// Safe keyring Storage name
51    const SAFE_STORAGE: &str;
52    #[cfg(target_os = "macos")]
53    /// Safe keyring name
54    const SAFE_NAME: &str;
55
56    /// Decryption key path (json)
57    fn key(mut base: PathBuf) -> PathBuf {
58        push_exact!(base, Self::KEY);
59
60        base
61    }
62    /// Copy the decryption key file to a location to avoid conflicts with the browser over access to it.
63    fn key_temp() -> PathBuf {
64        push_temp!(cache, Self::KEY);
65
66        cache
67    }
68
69    /// Cookies path (sqlite3 database)
70    fn cookies(mut base: PathBuf) -> PathBuf {
71        push_exact!(base, Self::COOKIES);
72
73        base
74    }
75    /// Copy the cookies file to a location to avoid conflicts with the browser over access to it.
76    fn cookies_temp() -> PathBuf {
77        push_temp!(cache, Self::COOKIES);
78
79        cache
80    }
81
82    /// Login data file (sqlite3 database)
83    fn login_data(mut base: PathBuf) -> PathBuf {
84        push_exact!(base, Self::LOGIN_DATA);
85        base
86    }
87    /// Copy the Login data file to a location to avoid conflicts with the browser over access to it.
88    fn login_data_temp() -> PathBuf {
89        push_temp!(cache, Self::LOGIN_DATA);
90
91        cache
92    }
93
94    /// Login data file (sqlite3 database)
95    fn login_data_for_account(mut base: PathBuf) -> PathBuf {
96        push_exact!(base, Self::LOGIN_DATA_FOR_ACCOUNT);
97        base
98    }
99    /// Copy the Login data file to a location to avoid conflicts with the browser over access to it.
100    fn login_data_for_account_temp() -> PathBuf {
101        push_temp!(cache, Self::LOGIN_DATA_FOR_ACCOUNT);
102
103        cache
104    }
105}
106
107pub trait FirefoxPath {
108    /// Suffix for data path
109    const BASE: &'static str;
110    /// Name for [`std::fmt::Display`]
111    const NAME: &'static str;
112    /// Suffix for cookies data path (sqlite3 database)
113    const COOKIES: &str = "cookies.sqlite";
114    /// Suffix for login data path (json)
115    const LOGIN_DATA: &str = "logins.json";
116    /// Suffix for decryption key path (sqlite3 database)
117    const KEY: &str = "key4.db";
118
119    /// Decryption key path (sqlite3 database)
120    fn key(mut base: PathBuf) -> PathBuf {
121        push_exact!(base, Self::KEY);
122
123        base
124    }
125    /// Copy the decryption key file to a location to avoid conflicts with the browser over access to it.
126    fn key_temp() -> PathBuf {
127        push_temp!(cache, Self::KEY);
128
129        cache
130    }
131
132    /// Cookies path (sqlite3 database)
133    fn cookies(mut base: PathBuf) -> PathBuf {
134        push_exact!(base, Self::COOKIES);
135
136        base
137    }
138    /// Copy the cookies file to a location to avoid conflicts with the browser over access to it.
139    fn cookies_temp() -> PathBuf {
140        push_temp!(cache, Self::COOKIES);
141
142        cache
143    }
144
145    /// Login data path (json)
146    fn login_data(mut base: PathBuf) -> PathBuf {
147        push_exact!(base, Self::LOGIN_DATA);
148
149        base
150    }
151    /// Copy the login data file to a location to avoid conflicts with the browser over access to it.
152    fn login_data_temp() -> PathBuf {
153        push_temp!(cache, Self::LOGIN_DATA);
154
155        cache
156    }
157}
158
159macro_rules! chromium {
160    ($platform:literal, $browser:ident, base: $base:literal $(, cookies: $cookies:literal)? $(, login_data: $login_data:literal)? $(, login_data_fa: $login_data_fa:literal)? $(, key: $key:literal)? $(, safe_name: $safe_name:literal)? ) => {
161        #[cfg(target_os = $platform)]
162        #[derive(Clone, Copy)]
163        #[derive(Debug)]
164        #[derive(Default)]
165        #[derive(PartialEq, Eq, PartialOrd, Ord)]
166        #[expect(clippy::exhaustive_structs, reason = "unit struct")]
167        pub struct $browser;
168
169        #[cfg(target_os = $platform)]
170        impl ChromiumPath for $browser {
171            const BASE: &'static str = $base;
172            const NAME: &'static str = stringify!($browser);
173            $(const COOKIES: &str = $cookies;)?
174            $(const LOGIN_DATA: &str = $login_data;)?
175            $(const LOGIN_DATA_FOR_ACCOUNT: &str = $login_data_fa;)?
176            $(const KEY: &str = $key;)?
177            $(
178                const SAFE_STORAGE: &str = concatcp!($safe_name, " Safe Storage");
179                #[cfg(target_os = "macos")]
180                const SAFE_NAME: &str = $safe_name;
181            )?
182        }
183
184        #[cfg(target_os = $platform)]
185        impl std::fmt::Display for $browser {
186            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187                f.write_str(Self::NAME)
188            }
189        }
190    };
191}
192
193macro_rules! firefox {
194    (
195        $platform:literal,
196        $browser:ident,base:
197        $base:literal
198        $(,cookies: $cookies:literal)?
199        $(,login_data: $login_data:literal)?
200        $(,key = $key:literal)?
201    ) => {
202        #[cfg(target_os = $platform)]
203        #[derive(Clone, Copy)]
204        #[derive(Debug)]
205        #[derive(Default)]
206        #[derive(PartialEq, Eq, PartialOrd, Ord)]
207        #[expect(clippy::exhaustive_structs, reason = "unit struct")]
208        pub struct $browser;
209
210        #[cfg(target_os = $platform)]
211        impl FirefoxPath for $browser {
212            const BASE: &'static str = $base;
213            const NAME: &'static str = stringify!($browser);
214            $(const COOKIES: &str = $cookies;)?
215            $(const LOGIN_DATA: &str = $login_data;)?
216            $(const KEY: &str = $key;)?
217        }
218
219        #[cfg(target_os = $platform)]
220        impl std::fmt::Display for $browser {
221            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222                f.write_str(Self::NAME)
223            }
224        }
225    };
226}
227
228chromium!("linux", Chrome  , base: ".config/google-chrome"              , safe_name: "Chrome"         );
229chromium!("linux", Edge    , base: ".config/microsoft-edge"             , safe_name: "Microsoft Edge" );
230chromium!("linux", Chromium, base: ".config/chromium"                   , safe_name: "Chromium"       );
231chromium!("linux", Brave   , base: ".config/BraveSoftware/Brave-Browser", safe_name: "Brave"          );
232chromium!("linux", Vivaldi , base: ".config/vivaldi"                    , safe_name: "Vivaldi"        );
233chromium!("linux", Opera   , base: ".config/opera"                      , safe_name: "Opera"          );
234chromium!("linux", Yandex  , base: ".config/yandex-browser"             , login_data: "Default/Ya Passman Data", safe_name: "Yandex");
235
236macro_rules! cach_it {
237    ($($browser:ident,)*) => {
238        #[cfg(target_os = "linux")]
239        pub fn need_safe_storage(lab: &str) -> bool {
240            matches!(
241                lab,
242                $(| $browser::SAFE_STORAGE)*
243            )
244        }
245    };
246}
247cach_it!(Chrome, Edge, Chromium, Brave, Vivaldi, Opera, Yandex,);
248
249chromium!("macos", Chrome  , base: "Library/Application Support/Google/Chrome"              , safe_name: "Chrome"        );
250chromium!("macos", Edge    , base: "Library/Application Support/Microsoft Edge"             , safe_name: "Microsoft Edge");
251chromium!("macos", Chromium, base: "Library/Application Support/Chromium"                   , safe_name: "Chromium"      );
252chromium!("macos", Brave   , base: "Library/Application Support/BraveSoftware/Brave-Browser", safe_name: "Brave"         );
253chromium!("macos", Vivaldi , base: "Library/Application Support/Vivaldi"                    , safe_name: "Vivaldi"       );
254chromium!("macos", CocCoc  , base: "Library/Application Support/CocCoc/Browser"             , safe_name: "CocCoc"        );
255chromium!("macos", Arc     , base: "Library/Application Support/Arc/User Data"              , safe_name: "Arc"           );
256chromium!("macos", Opera   , base: "Library/Application Support/com.operasoftware.Opera"    , safe_name: "Opera"         );
257chromium!("macos", OperaGX , base: "Library/Application Support/com.operasoftware.OperaGX"  , cookies: "Cookies", login_data: "Login Data", safe_name: "Opera");
258chromium!("macos", Yandex  , base: "Library/Application Support/Yandex/YandexBrowser"       , login_data: "Default/Ya Passman Data", login_data_fa: "Default/Ya Passman Data", safe_name: "Yandex");
259
260chromium!("windows", Chrome  , base: r"AppData\Local\Google\Chrome\User Data"               );
261chromium!("windows", Edge    , base: r"AppData\Local\Microsoft\Edge\User Data"              );
262chromium!("windows", Chromium, base: r"AppData\Local\Chromium\User Data"                    );
263chromium!("windows", Brave   , base: r"AppData\Local\BraveSoftware\Brave-Browser\User Data" );
264chromium!("windows", Vivaldi , base: r"AppData\Local\Vivaldi\User Data"                     );
265chromium!("windows", Opera   , base: r"AppData\Roaming\Opera Software\Opera Stable"         );
266chromium!("windows", OperaGX , base: r"AppData\Roaming\Opera Software\Opera GX Stable"      , cookies: r"Network\Cookies", login_data: r"Login Data", login_data_fa: r"Login Data For Account" );
267chromium!("windows", CocCoc  , base: r"AppData\Local\CocCoc\Browser\User Data"              );
268chromium!("windows", Arc     , base: r"AppData\Local\Packages\TheBrowserCompany.Arc_ttt1ap7aakyb4\LocalCache\Local\Arc\User Data" );
269chromium!("windows", Yandex  , base: r"AppData\Local\Yandex\YandexBrowser\User Data"       , login_data: r"Default\Ya Passman Data" );
270
271firefox!("linux", Firefox, base: ".mozilla/firefox");
272firefox!("linux", Librewolf, base: ".librewolf");
273firefox!("linux", Floorp, base: ".floorp");
274
275firefox!("macos", Firefox, base: "Library/Application Support/Firefox");
276firefox!("macos", Librewolf, base: "Library/Application Support/librewolf");
277firefox!("macos", Floorp, base: "Library/Application Support/Floorp");
278
279firefox!("windows", Firefox, base: r"AppData\Roaming\Mozilla\Firefox");
280firefox!("windows", Librewolf, base: r"AppData\Roaming\librewolf");
281firefox!("windows", Floorp, base: r"AppData\Roaming\Floorp");