mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
ccc8643d86
* feat(darwin): add interactive terminal password prompt for keychain unlock (#556) * test: add unit tests for keyretriever and address review feedback - Add errStorageNotFound sentinel error for precise error matching - Non-TTY TerminalPasswordRetriever returns nil silently (review #558) - Add darwin tests: findStorageKey, empty password, non-TTY skip - Add linux tests: FallbackRetriever peanuts key, DefaultRetriever chain * fix: add nolint:unused for errStorageNotFound on Windows, clean up error message errStorageNotFound is only used on darwin/linux; Windows lint flagged it as unused. Also simplify error format to avoid "storage" duplication. * fix: add nolint:unused for errStorageNotFound, simplify error message errStorageNotFound is only referenced on darwin and linux; Windows lint flags it as unused. Also remove redundant "storage" prefix from the error format string.
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
//go:build linux
|
|
|
|
package keyretriever
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"fmt"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
keyring "github.com/ppacher/go-dbus-keyring"
|
|
)
|
|
|
|
// https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc
|
|
var linuxParams = pbkdf2Params{
|
|
salt: []byte("saltysalt"),
|
|
iterations: 1,
|
|
keySize: 16,
|
|
hashFunc: sha1.New,
|
|
}
|
|
|
|
// DBusRetriever queries GNOME Keyring / KDE Wallet via D-Bus Secret Service.
|
|
type DBusRetriever struct{}
|
|
|
|
func (r *DBusRetriever) RetrieveKey(storage, _ string) ([]byte, error) {
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("dbus session: %w", err)
|
|
}
|
|
|
|
svc, err := keyring.GetSecretService(conn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("secret service: %w", err)
|
|
}
|
|
|
|
session, err := svc.OpenSession()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open session: %w", err)
|
|
}
|
|
defer session.Close()
|
|
|
|
collections, err := svc.GetAllCollections()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get collections: %w", err)
|
|
}
|
|
|
|
for _, col := range collections {
|
|
items, err := col.GetAllItems()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, item := range items {
|
|
label, err := item.GetLabel()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if label == storage {
|
|
secret, err := item.GetSecret(session.Path())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get secret for %s: %w", storage, err)
|
|
}
|
|
if len(secret.Value) > 0 {
|
|
return linuxParams.deriveKey(secret.Value), nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("%q: %w", storage, errStorageNotFound)
|
|
}
|
|
|
|
// FallbackRetriever uses the hardcoded "peanuts" password when D-Bus is unavailable.
|
|
// https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100
|
|
type FallbackRetriever struct{}
|
|
|
|
func (r *FallbackRetriever) RetrieveKey(_, _ string) ([]byte, error) {
|
|
return linuxParams.deriveKey([]byte("peanuts")), nil
|
|
}
|
|
|
|
// DefaultRetriever returns the Linux retriever chain:
|
|
// D-Bus Secret Service first, then "peanuts" fallback.
|
|
// The keychainPassword parameter is unused on Linux.
|
|
func DefaultRetriever(_ string) KeyRetriever {
|
|
return NewChain(
|
|
&DBusRetriever{},
|
|
&FallbackRetriever{},
|
|
)
|
|
}
|