|
@@ -68,3 +68,55 @@
|
|
|
|
|
|
|
|
(defmethod yason:encode ((object cl-mongo::bson-time) &optional (stream *standard-output*))
|
|
(defmethod yason:encode ((object cl-mongo::bson-time) &optional (stream *standard-output*))
|
|
|
(yason:encode (cl-mongo::raw object) stream))
|
|
(yason:encode (cl-mongo::raw object) stream))
|
|
|
|
|
+
|
|
|
|
|
+;; Google Chrome Cookies loading
|
|
|
|
|
+(defvar *chrome-cookie-password*
|
|
|
|
|
+ (crypto:ascii-string-to-byte-array "peanuts")
|
|
|
|
|
+ "Password for PBKDF2")
|
|
|
|
|
+(defvar *chrome-cookie-salt*
|
|
|
|
|
+ (crypto:ascii-string-to-byte-array "saltysalt")
|
|
|
|
|
+ "Salt for PBKDF2")
|
|
|
|
|
+(defvar *chrome-cookie-iterations* 1 "PBKDF2 iteration count")
|
|
|
|
|
+(defvar *chrome-cookie-key-length* 16 "PBKDF2 key length")
|
|
|
|
|
+
|
|
|
|
|
+(defun chrome-make-cookie-cipher ()
|
|
|
|
|
+ (crypto:make-cipher 'crypto:aes :mode 'crypto:cbc
|
|
|
|
|
+ :key (crypto:derive-key
|
|
|
|
|
+ (crypto:make-kdf 'crypto:pbkdf2 :digest 'crypto:sha1)
|
|
|
|
|
+ *chrome-cookie-password*
|
|
|
|
|
+ *chrome-cookie-salt*
|
|
|
|
|
+ *chrome-cookie-iterations*
|
|
|
|
|
+ *chrome-cookie-key-length*)
|
|
|
|
|
+ :initialization-vector (crypto:ascii-string-to-byte-array
|
|
|
|
|
+ " ")))
|
|
|
|
|
+
|
|
|
|
|
+(defvar *chrome-cookie-file*
|
|
|
|
|
+ (merge-pathnames #P".config/google-chrome/Default/Cookies"
|
|
|
|
|
+ (user-homedir-pathname)))
|
|
|
|
|
+
|
|
|
|
|
+(defun chrome-cookie-decode (value)
|
|
|
|
|
+ (when (mismatch (subseq value 0 3)
|
|
|
|
|
+ (mapcar #'char-code (coerce "v10" 'list)))
|
|
|
|
|
+ (error 'bad-encoding-verion))
|
|
|
|
|
+ (crypto:decrypt-in-place (chrome-make-cookie-cipher) value :start 3)
|
|
|
|
|
+ (coerce (mapcar #'code-char (subseq (coerce value 'list)
|
|
|
|
|
+ 3 (- (length value)
|
|
|
|
|
+ (elt value (1- (length value)))))) 'string))
|
|
|
|
|
+
|
|
|
|
|
+(defun load-chrome-cookie-jar (domain)
|
|
|
|
|
+ (sqlite:with-open-database (db *chrome-cookie-file*)
|
|
|
|
|
+ (make-instance 'drakma:cookie-jar
|
|
|
|
|
+ :cookies (loop
|
|
|
|
|
+ for (name host-key value path expires secure-p http-only-p encrypted)
|
|
|
|
|
+ in (sqlite::execute-to-list
|
|
|
|
|
+ db (format nil "select name, host_key, value, path, expires_utc, secure, httponly, encrypted_value from cookies where host_key like '%~A%'" domain))
|
|
|
|
|
+ collect (make-instance 'drakma:cookie
|
|
|
|
|
+ :name name
|
|
|
|
|
+ :domain host-key
|
|
|
|
|
+ :value (if (string= value "")
|
|
|
|
|
+ (chrome-cookie-decode encrypted)
|
|
|
|
|
+ value)
|
|
|
|
|
+ :path path
|
|
|
|
|
+ :expires (if (equal expires 0) nil (floor expires 1000))
|
|
|
|
|
+ :securep (equal secure-p 1)
|
|
|
|
|
+ :http-only-p (equal http-only-p 1))))))
|