Commit Graph

5 Commits

Author SHA1 Message Date
Roger 5f42d4fe5f refactor: redesign logging system for CLI-friendly output (#561)
* refactor: redesign logging system for CLI-friendly output
* refactor: remove ANSI color support from logger
* fix: address PR review feedback
2026-04-07 16:50:01 +08:00
Roger 410bffe643 refactor: naming cleanup and crypto package improvements (#551)
* refactor: naming cleanup across all packages
2026-04-05 16:51:56 +08:00
Roger 068b82178f fix: improve extract parsing with proper decoding and error handling (#543)
* fix: implement proper Chromium localStorage LevelDB parsing
* feat: add IsMeta field to StorageEntry and keep META entries
* fix: add error logging for decryption and missing data fields
* fix: address PR review for localStorage parsing
* fix: use naïve instead of café in Latin-1 test to avoid typos false positive
* fix: extension enabled detection and sessionStorage decoding
* fix: session storage origin resolution and extension enabled detection
* fix: address PR review comments for storage parsing
2026-04-04 18:52:54 +08:00
Roger 1a3aea553e feat: add Firefox Browser with new v2 architecture (#536)
* feat: add Firefox Browser implementation with new v2 architecture

Add Firefox NewBrowsers + Extract pipeline following the Chromium v2
pattern. Firefox-specific differences handled:
- Profile discovery: random directory names (e.g. abc123.default-release)
- Master key: NSS/ASN1PBE from key4.db (platform-agnostic, no DPAPI/Keychain)
- Key validation: reuse logins.json from acquireFiles tempPaths
- Extract: only Password needs masterKey; Cookie is plaintext
- No CreditCard or SessionStorage support

Files:
- firefox_new.go: Browser struct, NewBrowsers, Extract, getMasterKey,
  extractCategory, deriveKeys, validateKeyWithLogins, profile discovery
- masterkey.go: extracted shared NSS logic (processMasterKey, queryMetaData,
  queryNssPrivateCandidates, parseLoginCipherPairs, canDecryptAnyLoginCipherPair)
- firefox_new_test.go: table-driven tests with shared fixtures
- source.go: remove dataSource wrapper, use []sourcePath directly
- firefox.go: remove functions moved to masterkey.go

* fix: address Copilot review feedback on Firefox v2

- Fix stale comment referencing removed readLoginCipherPairs
- Rename finallyKey to derivedKey for clarity in processMasterKey
- Add sqlite driver import to masterkey.go for self-containedness

* refactor: rewrite Firefox masterkey and improve naming

Masterkey rewrite:
- Replace raw SQL functions with structured key4DB type (globalSalt,
  passwordCheck, privateKeys) for clear data modeling
- Split processMasterKey into verifyPasswordCheck + decryptPrivateKey
- Add nssKeyTypeTag constant for the magic bytes
- Rename finallyKey to derivedKey
- Add sqlite driver import for self-containedness
- Return error (not fallback) when logins validation explicitly fails

Naming cleanup:
- loginPair → encryptedLogin (clarify these are encrypted blobs)
- parseLoginPairs → sampleEncryptedLogins (clarify sampling purpose)
- canDecryptLogin → tryDecryptLogins (accurate verb, plural alignment)
- Expand abbreviated variables: p→login, uPBE→userPBE, pPBE→pwdPBE

Password extraction:
- Keep entries when decryptPBE fails (URL preserved, user/pwd empty)
- Align with Chromium behavior where decrypt failure doesn't skip records

Old code cleanup:
- firefox.go GetMasterKey now delegates to retrieveMasterKey
- Remove functions moved to masterkey.go

* docs: add RFC-003 for crypto package naming cleanup

Track accumulated naming and structural issues in crypto/asn1pbe.go
and cross-browser shared code for a future dedicated refactoring pass.

* refactor: move masterkey tests to masterkey_test.go

- Rename firefox_test.go to masterkey_test.go since all tests in
  this file test masterkey.go functions (readKey4DB, sampleEncryptedLogins)
- Fix TestReadKey4DB to check nssPrivate rows as a set instead of
  assuming SQLite insertion order
- Future deletion of firefox.go won't accidentally remove masterkey tests
2026-04-04 01:41:02 +08:00
Roger 1ec2781131 feat: add Firefox extract methods and complete data model fields (#527)
* feat: add Firefox extract methods and complete data model fields

Firefox extract methods:
- extractPasswords: JSON + ASN1PBE decryption via decryptPBE helper
- extractCookies: SQLite, plaintext (no encryption), journalOff
- extractHistories: SQLite, visit count ASC sort (matches old behavior)
- extractDownloads: SQLite, moz_annos JOIN with JSON content parsing
- extractBookmarks: SQLite, moz_bookmarks JOIN moz_places
- extractExtensions: JSON, filter by location=app-profile
- extractLocalStorage: SQLite webappsstore2, reversed originKey parsing

Complete data model fields (union of Chromium and Firefox):
- CookieEntry: add HasExpire, IsPersistent
- DownloadEntry: add MimeType
- CreditCardEntry: add NickName, Address
- ExtensionEntry: add HomepageURL, Enabled

Update Chromium extractors to populate new fields:
- extract_cookie.go: fill HasExpire, IsPersistent
- extract_download.go: SELECT and fill mime_type
- extract_creditcard.go: SELECT nickname, billing_address_id
- extract_extension.go: fill HomepageURL, Enabled (state==1)

Tests:
- Full test coverage for all 7 Firefox extract functions
- Password test uses known ASN1PBE test vectors from crypto package
- Table-driven tests for parseOriginKey
- Updated Chromium tests for new fields

* fix: add COALESCE for nullable bookmark title in Firefox query

Firefox moz_bookmarks.title can be NULL (PR #500 fixed this in old code).
Add COALESCE to handle NULL gracefully in SQL instead of relying on
driver-specific NULL→string conversion behavior.

* fix: enable journalOff for all Firefox SQLite extractors and populate cookie flags

- Set journalOff=true for extract_history, extract_download, extract_bookmark
  (Firefox databases require PRAGMA journal_mode=off to avoid lock errors)
- Populate HasExpire and IsPersistent for Firefox cookies (derived from expiry>0)
- Add test assertions for HasExpire/IsPersistent in both Chromium and Firefox
2026-04-04 01:41:02 +08:00