mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-08-17 23:57:12 +02:00
fix: share key retriever across all browsers to avoid repeated prompts (#560)
* fix: share key retriever across all browsers to avoid repeated password prompts
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package chromium
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@@ -16,15 +17,15 @@ import (
|
||||
type Browser struct {
|
||||
cfg types.BrowserConfig
|
||||
profileDir string // absolute path to profile directory
|
||||
retriever keyretriever.KeyRetriever // shared across profiles of the same browser
|
||||
retriever keyretriever.KeyRetriever // set via SetRetriever after construction
|
||||
sources map[types.Category][]sourcePath // Category → candidate paths (priority order)
|
||||
extractors map[types.Category]categoryExtractor // Category → custom extract function override
|
||||
sourcePaths map[types.Category]resolvedPath // Category → discovered absolute path
|
||||
}
|
||||
|
||||
// NewBrowsers discovers Chromium profiles under cfg.UserDataDir and returns
|
||||
// one Browser per profile. Uses ReadDir to find profile directories,
|
||||
// then Stat to check which data sources exist in each profile.
|
||||
// one Browser per profile. Call SetRetriever on each returned browser before
|
||||
// Extract to enable decryption of sensitive data (passwords, cookies, etc.).
|
||||
func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
sources := sourcesForKind(cfg.Kind)
|
||||
extractors := extractorsForKind(cfg.Kind)
|
||||
@@ -34,11 +35,6 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Create the key retriever once and share it across all profiles.
|
||||
// This avoids repeated keychain password prompts on macOS, where each
|
||||
// profile would otherwise trigger a separate `security` command dialog.
|
||||
retriever := keyretriever.DefaultRetriever(cfg.KeychainPassword)
|
||||
|
||||
var browsers []*Browser
|
||||
for _, profileDir := range profileDirs {
|
||||
sourcePaths := resolveSourcePaths(sources, profileDir)
|
||||
@@ -48,7 +44,6 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
browsers = append(browsers, &Browser{
|
||||
cfg: cfg,
|
||||
profileDir: profileDir,
|
||||
retriever: retriever,
|
||||
sources: sources,
|
||||
extractors: extractors,
|
||||
sourcePaths: sourcePaths,
|
||||
@@ -57,6 +52,13 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
return browsers, nil
|
||||
}
|
||||
|
||||
// SetRetriever sets the key retriever used by Extract to obtain the
|
||||
// master encryption key. Must be called before Extract if encrypted
|
||||
// data (passwords, cookies, credit cards) needs to be decrypted.
|
||||
func (b *Browser) SetRetriever(r keyretriever.KeyRetriever) {
|
||||
b.retriever = r
|
||||
}
|
||||
|
||||
func (b *Browser) BrowserName() string { return b.cfg.Name }
|
||||
func (b *Browser) ProfileDir() string { return b.profileDir }
|
||||
func (b *Browser) ProfileName() string {
|
||||
@@ -120,6 +122,10 @@ func (b *Browser) acquireFiles(session *filemanager.Session, categories []types.
|
||||
// The retriever is always called regardless of whether Local State exists,
|
||||
// because macOS/Linux retrievers don't need it.
|
||||
func (b *Browser) getMasterKey(session *filemanager.Session) ([]byte, error) {
|
||||
if b.retriever == nil {
|
||||
return nil, fmt.Errorf("key retriever not set for %s", b.cfg.Name)
|
||||
}
|
||||
|
||||
// Try to locate and copy Local State (needed on Windows, ignored on macOS/Linux).
|
||||
// Multi-profile layout: Local State is in the parent of profileDir.
|
||||
// Flat layout (Opera): Local State is alongside data files in profileDir.
|
||||
|
||||
Reference in New Issue
Block a user