1- use crate :: { Error , Result , cache} ;
2- use anyhow:: anyhow;
3- use diesel:: prelude:: * ;
4- use keyring:: Entry ;
5- use openssl:: { hash, pkcs5, symm} ;
1+ use crate :: { Error , Result } ;
62use std:: { collections:: HashMap , fmt:: Display } ;
73
8- /// LeetCode Cookies Schema
9- mod schema {
10- table ! {
11- cookies ( host_key) {
12- encrypted_value -> Binary ,
13- host_key -> Text ,
14- name -> Text ,
15- }
16- }
17- }
18-
19- /// Please make sure the order
20- ///
21- /// The order between table and struct must be same.
22- #[ derive( Queryable , Debug , Clone ) ]
23- struct Cookies {
24- pub encrypted_value : Vec < u8 > ,
25- #[ allow( dead_code) ]
26- pub host_key : String ,
27- pub name : String ,
28- }
29-
304/// Spawn cookies to cookie format
315#[ derive( Debug ) ]
326pub struct Ident {
@@ -54,38 +28,13 @@ pub fn cookies() -> Result<Ident> {
5428 } ) ;
5529 }
5630
57- // If doesn't config SESSION and csrftoken
58- use self :: schema:: cookies:: dsl:: * ;
59- trace ! ( "Derive cookies from google chrome..." ) ;
60-
61- let home = dirs:: home_dir ( ) . ok_or ( Error :: NoneError ) ?;
62- let p = match std:: env:: consts:: OS {
63- "macos" => home. join ( "Library/Application Support/Google/Chrome/Default/Cookies" ) ,
64- "linux" => home. join ( ".config/google-chrome/Default/Cookies" ) ,
65- _ => panic ! ( "Opps...only works on OSX or Linux now..." ) ,
66- } ;
67-
68- debug ! ( "Chrome Cookies path is {:?}" , & p) ;
69- let mut conn = cache:: conn ( p. to_string_lossy ( ) . to_string ( ) ) ;
70- let res = cookies
71- . filter ( host_key. like ( format ! ( "#{}" , ccfg. site) ) )
72- . load :: < Cookies > ( & mut conn)
73- . expect ( "Loading cookies from google chrome failed." ) ;
74-
75- debug ! ( "res {:?}" , & res) ;
76- if res. is_empty ( ) {
77- return Err ( Error :: CookieError ) ;
78- }
79-
80- // Get system password
81- let ring = Entry :: new ( "Chrome Safe Storage" , "Chrome" ) ?;
82- let pass = ring. get_password ( ) . expect ( "Get Password failed" ) ;
83-
84- // Decode cookies
8531 let mut m: HashMap < String , String > = HashMap :: new ( ) ;
86- for c in res {
32+
33+ let domains = vec ! [ format!( "{}" , ccfg. site) ] ;
34+ let cookies = rookie:: chrome ( Some ( domains) ) . unwrap ( ) ;
35+ for c in cookies {
8736 if ( c. name == "csrftoken" ) || ( c. name == "LEETCODE_SESSION" ) {
88- m. insert ( c. name , decode_cookies ( & pass , c . encrypted_value ) ? ) ;
37+ m. insert ( c. name , c . value ) ;
8938 }
9039 }
9140
@@ -98,56 +47,3 @@ pub fn cookies() -> Result<Ident> {
9847 } )
9948}
10049
101- /// Decode cookies from chrome
102- fn decode_cookies ( pass : & str , v : Vec < u8 > ) -> Result < String > {
103- let mut key = [ 0_u8 ; 16 ] ;
104- match std:: env:: consts:: OS {
105- "macos" => {
106- pkcs5:: pbkdf2_hmac (
107- pass. as_bytes ( ) ,
108- b"saltysalt" ,
109- 1003 ,
110- hash:: MessageDigest :: sha1 ( ) ,
111- & mut key,
112- )
113- . expect ( "pbkdf2 hmac went error." ) ;
114- }
115- "linux" => {
116- pkcs5:: pbkdf2_hmac (
117- b"peanuts" ,
118- b"saltysalt" ,
119- 1 ,
120- hash:: MessageDigest :: sha1 ( ) ,
121- & mut key,
122- )
123- . expect ( "pbkdf2 hmac went error." ) ;
124- }
125- _ => return Err ( anyhow ! ( "only supports OSX or Linux for now" ) . into ( ) ) ,
126- }
127-
128- chrome_decrypt ( v, key)
129- }
130-
131- /// Decrypt chrome cookie value with aes-128-cbc
132- fn chrome_decrypt ( v : Vec < u8 > , key : [ u8 ; 16 ] ) -> Result < String > {
133- // <space>: \u16
134- let iv = vec ! [ 32_u8 ; 16 ] ;
135- let mut decrypter = symm:: Crypter :: new (
136- symm:: Cipher :: aes_128_cbc ( ) ,
137- symm:: Mode :: Decrypt ,
138- & key,
139- Some ( & iv) ,
140- ) ?;
141-
142- let data_len = v. len ( ) - 3 ;
143- let block_size = symm:: Cipher :: aes_128_cbc ( ) . block_size ( ) ;
144- let mut plaintext = vec ! [ 0 ; data_len + block_size] ;
145-
146- decrypter. pad ( false ) ;
147-
148- let count = decrypter. update ( & v[ 3 ..] , & mut plaintext) ?;
149- decrypter. finalize ( & mut plaintext[ count..] ) ?;
150- plaintext. retain ( |x| x >= & 20_u8 ) ;
151-
152- Ok ( String :: from_utf8_lossy ( & plaintext. to_vec ( ) ) . to_string ( ) )
153- }
0 commit comments