Added cookie-file location guessing

* User may now specify a browser to use
* Or he may choose to guess the best, based on mtime of cookie files
* Command line application accepts flags for this functionality
master
Ben Eills 2013-06-27 20:51:41 +01:00
parent 6423b9bcb5
commit 3217c96dd6
3 changed files with 92 additions and 20 deletions

View File

@ -5,17 +5,22 @@ Extract cookies from Firefox, Chrome or Chromium sqlite cookie stores into a wge
### Install ### ### Install ###
gem install cookie_extractor gem install cookie_extractor
### Usage ### ### Usage ###
cookie_extractor /path/to/firefox/cookies.sqlite > cookies.txt cookie_extractor /path/to/firefox/cookies.sqlite > cookies.txt
cookie_extractor --guess # Guess which browser to use and open corresponding file
cookie_extractor --browser chrome|chromium|firefox # Open corresponding DB
Typical locations for the cookies file on Linux are: Typical locations for the cookies file on Linux are:
* Firefox: ~/.mozilla/firefox/(profile directory)/cookies.sqlite * Firefox: *~/.mozilla/firefox/(profile directory)/cookies.sqlite*
* Chrome: ~/.config/google-chrome/Default/Cookies * Chrome: *~/.config/google-chrome/Default/Cookies*
* Chromium: ~/.config/chromium/Default/Cookies * Chromium: *~/.config/chromium/Default/Cookies*
### License ### ### License ###

View File

@ -2,22 +2,46 @@
require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "cookie_extractor")) require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "cookie_extractor"))
# TODO: Locate cookie dbs automatically
filename = ARGV.first def usage msg=nil
unless filename puts msg if msg
puts "Usage: (Firefox) cookie_extractor /path/to/cookies.sqlite" puts "Usage: cookie_extractor /path/to/cookies.sqlite Open a DB file"
puts " (Chrome) cookie_extractor /path/to/Cookies" puts " cookie_extractor --guess Guess which browser to use and open corresponding file"
puts " cookie_extractor --browser chrome|chromium|firefox Open DB corresponding to a particular browser"
exit exit
end end
if File.exists?(filename)
begin begin
extractor = CookieExtractor::BrowserDetector.new_extractor(filename) extractor =
puts extractor.extract.join("\n") case ARGV.first
rescue SQLite3::NotADatabaseException, when '--guess', '-g'
CookieExtractor::BrowserNotDetectedException begin
puts "Error: File '#{filename}' is not a Firefox or Chrome cookie database" CookieExtractor::BrowserDetector.guess()
end rescue CookieExtractor::NoCookieFileFoundException
else abort "Error: we couldn't find any supported broswer's cookies"
puts "Error: File '#{filename}' does not exist" end
when '--browser', '-b'
browser = ARGV[1]
usage "Error: Please supply a browser name" unless browser
begin
CookieExtractor::BrowserDetector.browser_extractor(browser)
rescue CookieExtractor::InvalidBrowserNameException
abort "Error: '#{browser}' is not a valid browser name"
rescue CookieExtractor::NoCookieFileFoundException
abort "Error: Could not locate cookie file for browser #{browser}"
end
when nil
usage
else
filename = ARGV.first
abort "Error: #{filename} does not exist" unless File.exists?(filename)
CookieExtractor::BrowserDetector.new_extractor(filename)
end
puts extractor.extract.join("\n")
rescue SQLite3::NotADatabaseException,
CookieExtractor::BrowserNotDetectedException
abort "Error: File '#{filename}' is not a Firefox or Chrome cookie database"
end end

View File

@ -1,7 +1,46 @@
module CookieExtractor module CookieExtractor
class BrowserNotDetectedException < Exception; end class BrowserNotDetectedException < Exception; end
class InvalidBrowserNameException < Exception; end
class NoCookieFileFoundException < Exception; end
class BrowserDetector class BrowserDetector
@cookie_locations = {
"chrome" => "~/.config/google-chrome/Default/Cookies",
"chromium" => "~/.config/chromium/Default/Cookies",
"firefox" => "~/.mozilla/firefox/*.default/cookies.sqlite"
}
# Returns the extractor of the most recently used browser's cookies
# or raise NoCookieFileFoundException if there are no cookies
def self.guess
full_cookie_locations = @cookie_locations.select { |browser, path|
!Dir.glob(File.expand_path(path)).empty?
}.sort_by { |browser, path|
File.mtime(Dir.glob(File.expand_path(path)).first)
}.reverse.each { |tuple|
browser = tuple.first
begin
extractor = self.browser_extractor(browser)
rescue BrowserNotDetectedException, NoCookieFileFoundException
# better try the next one...
else
return extractor
end
}
# If we make it here, we've failed...
raise NoCookieFileFoundException, "Couldn't find any browser's cookies"
end
# Open a browser's cookie file using intelligent guesswork
def self.browser_extractor(browser)
raise InvalidBrowserNameException, "Browser must be one of: #{self.supported_browsers.join(', ')}" unless self.supported_browsers.include?(browser)
paths = Dir.glob(File.expand_path(@cookie_locations[browser]))
if paths.length < 1 or not File.exists?(paths.first)
raise NoCookieFileFoundException, "File #{paths.first} does not exist!"
end
self.new_extractor(paths.first)
end
def self.new_extractor(db_filename) def self.new_extractor(db_filename)
browser = detect_browser(db_filename) browser = detect_browser(db_filename)
@ -12,6 +51,10 @@ module CookieExtractor
end end
end end
def self.supported_browsers
@cookie_locations.keys
end
def self.detect_browser(db_filename) def self.detect_browser(db_filename)
db = SQLite3::Database.new(db_filename) db = SQLite3::Database.new(db_filename)
browser = browser =