diff --git a/browingdata/bookmark/bookmark.go b/browingdata/bookmark/bookmark.go index fd3327b..89d8283 100644 --- a/browingdata/bookmark/bookmark.go +++ b/browingdata/bookmark/bookmark.go @@ -40,7 +40,7 @@ func (c *ChromiumBookmark) Parse(masterKey []byte) error { return true }) } - // TODO: refactor with go generics + sort.Slice(*c, func(i, j int) bool { return (*c)[i].DateAdded.After((*c)[j].DateAdded) }) diff --git a/browingdata/browsingdata.go b/browingdata/browsingdata.go index 4f700c5..3bec04d 100644 --- a/browingdata/browsingdata.go +++ b/browingdata/browsingdata.go @@ -28,11 +28,11 @@ type Source interface { Length() int } -func New(sources []item.Item) *Data { +func New(items []item.Item) *Data { bd := &Data{ sources: make(map[item.Item]Source), } - bd.addSource(sources) + bd.addSources(items) return bd } @@ -46,7 +46,7 @@ func (d *Data) Recovery(masterKey []byte) error { } func (d *Data) Output(dir, browserName, flag string) { - output := NewOutPutter(flag) + output := newOutPutter(flag) for _, source := range d.sources { if source.Length() == 0 { @@ -72,8 +72,8 @@ func (d *Data) Output(dir, browserName, flag string) { } } -func (d *Data) addSource(Sources []item.Item) { - for _, source := range Sources { +func (d *Data) addSources(items []item.Item) { + for _, source := range items { switch source { case item.ChromiumPassword: d.sources[source] = &password.ChromiumPassword{} diff --git a/browingdata/outputter.go b/browingdata/outputter.go index bda9806..a72d379 100644 --- a/browingdata/outputter.go +++ b/browingdata/outputter.go @@ -13,13 +13,13 @@ import ( "golang.org/x/text/transform" ) -type OutPutter struct { +type outPutter struct { json bool csv bool } -func NewOutPutter(flag string) *OutPutter { - o := &OutPutter{} +func newOutPutter(flag string) *outPutter { + o := &outPutter{} if flag == "json" { o.json = true } else { @@ -28,7 +28,7 @@ func NewOutPutter(flag string) *OutPutter { return o } -func (o *OutPutter) Write(data Source, writer io.Writer) error { +func (o *outPutter) Write(data Source, writer io.Writer) error { switch o.json { case true: encoder := json.NewEncoder(writer) @@ -45,7 +45,7 @@ func (o *OutPutter) Write(data Source, writer io.Writer) error { } } -func (o *OutPutter) CreateFile(dir, filename string) (*os.File, error) { +func (o *outPutter) CreateFile(dir, filename string) (*os.File, error) { if filename == "" { return nil, errors.New("empty filename") } @@ -69,7 +69,7 @@ func (o *OutPutter) CreateFile(dir, filename string) (*os.File, error) { return file, nil } -func (o *OutPutter) Ext() string { +func (o *outPutter) Ext() string { if o.json { return "json" } diff --git a/browingdata/outputter_test.go b/browingdata/outputter_test.go index ca3c6ab..0cab67e 100644 --- a/browingdata/outputter_test.go +++ b/browingdata/outputter_test.go @@ -7,7 +7,7 @@ import ( func TestNewOutPutter(t *testing.T) { t.Parallel() - out := NewOutPutter("json") + out := newOutPutter("json") if out == nil { t.Error("New() returned nil") } diff --git a/browser/browser.go b/browser/browser.go index 3e23cfa..61c3b23 100644 --- a/browser/browser.go +++ b/browser/browser.go @@ -17,9 +17,10 @@ type Browser interface { // Name is browser's name Name() string // BrowsingData returns all browsing data in the browser. - BrowsingData() (*browingdata.Data, error) + BrowsingData(isFullExport bool) (*browingdata.Data, error) } +// PickBrowsers returns a list of browsers that match the name and profile. func PickBrowsers(name, profile string) ([]Browser, error) { var browsers []Browser clist := pickChromium(name, profile) @@ -42,18 +43,18 @@ func pickChromium(name, profile string) []Browser { name = strings.ToLower(name) if name == "all" { for _, v := range chromiumList { - if !fileutil.FolderExists(filepath.Clean(v.profilePath)) { + if !fileutil.IsDirExists(filepath.Clean(v.profilePath)) { log.Noticef("find browser %s failed, profile folder does not exist", v.name) continue } - if multiChromium, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { - log.Noticef("find browser %s success", v.name) - for _, b := range multiChromium { - log.Noticef("find browser %s success", b.Name()) - browsers = append(browsers, b) - } - } else { - log.Errorf("new chromium error: %s", err.Error()) + multiChromium, err := chromium.New(v.name, v.storage, v.profilePath, v.items) + if err != nil { + log.Errorf("new chromium error: %v", err) + continue + } + for _, b := range multiChromium { + log.Noticef("find browser %s success", b.Name()) + browsers = append(browsers, b) } } } @@ -61,7 +62,7 @@ func pickChromium(name, profile string) []Browser { if profile == "" { profile = c.profilePath } - if !fileutil.FolderExists(filepath.Clean(profile)) { + if !fileutil.IsDirExists(filepath.Clean(profile)) { log.Fatalf("find browser %s failed, profile folder does not exist", c.name) } chromiumList, err := chromium.New(c.name, c.storage, profile, c.items) @@ -86,7 +87,7 @@ func pickFirefox(name, profile string) []Browser { } else { profile = fileutil.ParentDir(profile) } - if !fileutil.FolderExists(filepath.Clean(profile)) { + if !fileutil.IsDirExists(filepath.Clean(profile)) { log.Noticef("find browser firefox %s failed, profile folder does not exist", v.name) continue } diff --git a/browser/chromium/chromium.go b/browser/chromium/chromium.go index c6bce82..ea024e0 100644 --- a/browser/chromium/chromium.go +++ b/browser/chromium/chromium.go @@ -28,7 +28,7 @@ func New(name, storage, profilePath string, items []item.Item) ([]*Chromium, err profilePath: profilePath, items: items, } - multiItemPaths, err := c.getMultiItemPath(c.profilePath, c.items) + multiItemPaths, err := c.userItemPaths(c.profilePath, c.items) if err != nil { return nil, err } @@ -48,8 +48,13 @@ func (c *Chromium) Name() string { return c.name } -func (c *Chromium) BrowsingData() (*browingdata.Data, error) { - b := browingdata.New(c.items) +func (c *Chromium) BrowsingData(isFullExport bool) (*browingdata.Data, error) { + items := c.items + if !isFullExport { + items = item.FilterSensitiveItems(c.items) + } + + data := browingdata.New(items) if err := c.copyItemToLocal(); err != nil { return nil, err @@ -61,10 +66,10 @@ func (c *Chromium) BrowsingData() (*browingdata.Data, error) { } c.masterKey = masterKey - if err := b.Recovery(c.masterKey); err != nil { + if err := data.Recovery(c.masterKey); err != nil { return nil, err } - return b, nil + return data, nil } func (c *Chromium) copyItemToLocal() error { @@ -72,7 +77,7 @@ func (c *Chromium) copyItemToLocal() error { filename := i.String() var err error switch { - case fileutil.FolderExists(path): + case fileutil.IsDirExists(path): if i == item.ChromiumLocalStorage { err = fileutil.CopyDir(path, filename, "lock") } @@ -89,8 +94,8 @@ func (c *Chromium) copyItemToLocal() error { return nil } -func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) { - // multiItemPaths is a map of user to item path, map[profile 1][item's name & path key pair] +// userItemPaths return a map of user to item path, map[profile 1][item's name & path key pair] +func (c *Chromium) userItemPaths(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) { multiItemPaths := make(map[string]map[item.Item]string) parentDir := fileutil.ParentDir(profilePath) err := filepath.Walk(parentDir, chromiumWalkFunc(items, multiItemPaths)) @@ -120,6 +125,7 @@ func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[ return t, nil } +// chromiumWalkFunc return a filepath.WalkFunc to find item's path func chromiumWalkFunc(items []item.Item, multiItemPaths map[string]map[item.Item]string) filepath.WalkFunc { return func(path string, info fs.FileInfo, err error) error { for _, v := range items { @@ -145,7 +151,7 @@ func chromiumWalkFunc(items []item.Item, multiItemPaths map[string]map[item.Item func fillLocalStoragePath(itemPaths map[item.Item]string, storage item.Item) { if p, ok := itemPaths[item.ChromiumHistory]; ok { lsp := filepath.Join(filepath.Dir(p), storage.FileName()) - if fileutil.FolderExists(lsp) { + if fileutil.IsDirExists(lsp) { itemPaths[item.ChromiumLocalStorage] = lsp } } diff --git a/browser/chromium/chromium_darwin.go b/browser/chromium/chromium_darwin.go index 08bf85d..d6323c4 100644 --- a/browser/chromium/chromium_darwin.go +++ b/browser/chromium/chromium_darwin.go @@ -6,6 +6,7 @@ import ( "bytes" "crypto/sha1" "errors" + "fmt" "os" "os/exec" "strings" @@ -22,34 +23,34 @@ var ( ) func (c *Chromium) GetMasterKey() ([]byte, error) { - var ( - cmd *exec.Cmd - stdout, stderr bytes.Buffer - ) // don't need chromium key file for macOS defer os.Remove(item.TempChromiumKey) // Get the master key from the keychain // $ security find-generic-password -wa 'Chrome' - cmd = exec.Command("security", "find-generic-password", "-wa", strings.TrimSpace(c.storage)) //nolint:gosec + var ( + stdout, stderr bytes.Buffer + ) + cmd := exec.Command("security", "find-generic-password", "-wa", strings.TrimSpace(c.storage)) //nolint:gosec cmd.Stdout = &stdout cmd.Stderr = &stderr - err := cmd.Run() - if err != nil { - return nil, err + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("run security command failed: %w, message %s", err, stderr.String()) } + if stderr.Len() > 0 { if strings.Contains(stderr.String(), "could not be found") { return nil, errCouldNotFindInKeychain } return nil, errors.New(stderr.String()) } - chromeSecret := bytes.TrimSpace(stdout.Bytes()) - if chromeSecret == nil { + + secret := bytes.TrimSpace(stdout.Bytes()) + if len(secret) == 0 { return nil, errWrongSecurityCommand } - chromeSalt := []byte("saltysalt") + salt := []byte("saltysalt") // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_mac.mm;l=157 - key := pbkdf2.Key(chromeSecret, chromeSalt, 1003, 16, sha1.New) + key := pbkdf2.Key(secret, salt, 1003, 16, sha1.New) if key == nil { return nil, errWrongSecurityCommand } diff --git a/browser/chromium/chromium_linux.go b/browser/chromium/chromium_linux.go index c3475a1..6ad2229 100644 --- a/browser/chromium/chromium_linux.go +++ b/browser/chromium/chromium_linux.go @@ -4,7 +4,7 @@ package chromium import ( "crypto/sha1" - "errors" + "fmt" "os" "github.com/godbus/dbus/v5" @@ -17,12 +17,13 @@ import ( func (c *Chromium) GetMasterKey() ([]byte, error) { // what is d-bus @https://dbus.freedesktop.org/ - var chromiumSecret []byte + // don't need chromium key file for Linux + defer os.Remove(item.TempChromiumKey) + conn, err := dbus.SessionBus() if err != nil { return nil, err } - defer os.Remove(item.TempChromiumKey) svc, err := keyring.GetSecretService(conn) if err != nil { return nil, err @@ -40,6 +41,7 @@ func (c *Chromium) GetMasterKey() ([]byte, error) { if err != nil { return nil, err } + var secret []byte for _, col := range collections { items, err := col.GetAllItems() if err != nil { @@ -54,19 +56,20 @@ func (c *Chromium) GetMasterKey() ([]byte, error) { if label == c.storage { se, err := i.GetSecret(session.Path()) if err != nil { - return nil, errors.New("get storage from dbus error:" + err.Error()) + return nil, fmt.Errorf("get storage from dbus error: %v" + err.Error()) } - chromiumSecret = se.Value + secret = se.Value } } } - if chromiumSecret == nil { - // @https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100 - chromiumSecret = []byte("peanuts") + + if len(secret) == 0 { + // set default secret @https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100 + secret = []byte("peanuts") } - chromiumSalt := []byte("saltysalt") + salt := []byte("saltysalt") // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_linux.cc - key := pbkdf2.Key(chromiumSecret, chromiumSalt, 1, 16, sha1.New) + key := pbkdf2.Key(secret, salt, 1, 16, sha1.New) c.masterKey = key log.Infof("%s initialized master key success", c.name) return key, nil diff --git a/browser/chromium/chromium_windows.go b/browser/chromium/chromium_windows.go index 17c172b..1063e69 100644 --- a/browser/chromium/chromium_windows.go +++ b/browser/chromium/chromium_windows.go @@ -9,6 +9,7 @@ import ( "github.com/tidwall/gjson" + "github.com/moond4rk/HackBrowserData/crypto" "github.com/moond4rk/HackBrowserData/item" "github.com/moond4rk/HackBrowserData/log" "github.com/moond4rk/HackBrowserData/utils/fileutil" @@ -17,20 +18,22 @@ import ( var errDecodeMasterKeyFailed = errors.New("decode master key failed") func (c *Chromium) GetMasterKey() ([]byte, error) { - keyFile, err := fileutil.ReadFile(item.TempChromiumKey) + b, err := fileutil.ReadFile(item.TempChromiumKey) if err != nil { return nil, err } - defer os.Remove(keyFile) - encryptedKey := gjson.Get(keyFile, "os_crypt.encrypted_key") + defer os.Remove(item.TempChromiumKey) + + encryptedKey := gjson.Get(b, "os_crypt.encrypted_key") if !encryptedKey.Exists() { return nil, nil } - pureKey, err := base64.StdEncoding.DecodeString(encryptedKey.String()) + + key, err := base64.StdEncoding.DecodeString(encryptedKey.String()) if err != nil { return nil, errDecodeMasterKeyFailed } - c.masterKey, err = crypto.DPAPI(pureKey[5:]) + c.masterKey, err = crypto.DPAPI(key[5:]) log.Infof("%s initialized master key success", c.name) return c.masterKey, err } diff --git a/browser/firefox/firefox.go b/browser/firefox/firefox.go index 3f75346..2c329f6 100644 --- a/browser/firefox/firefox.go +++ b/browser/firefox/firefox.go @@ -39,7 +39,7 @@ func New(name, storage, profilePath string, items []item.Item) ([]*Firefox, erro firefoxList := make([]*Firefox, 0, len(multiItemPaths)) for name, itemPaths := range multiItemPaths { firefoxList = append(firefoxList, &Firefox{ - name: fmt.Sprintf("Firefox-%s", name), + name: fmt.Sprintf("firefox-%s", name), items: typeutil.Keys(itemPaths), itemPaths: itemPaths, }) @@ -87,8 +87,13 @@ func (f *Firefox) Name() string { return f.name } -func (f *Firefox) BrowsingData() (*browingdata.Data, error) { - b := browingdata.New(f.items) +func (f *Firefox) BrowsingData(isFullExport bool) (*browingdata.Data, error) { + items := f.items + if !isFullExport { + items = item.FilterSensitiveItems(f.items) + } + + b := browingdata.New(items) if err := f.copyItemToLocal(); err != nil { return nil, err diff --git a/cmd/hack-browser-data/main.go b/cmd/hack-browser-data/main.go index ff26680..5fa6450 100644 --- a/cmd/hack-browser-data/main.go +++ b/cmd/hack-browser-data/main.go @@ -17,6 +17,7 @@ var ( verbose bool compress bool profilePath string + isFullExport bool ) func main() { @@ -36,27 +37,26 @@ func Execute() { &cli.StringFlag{Name: "results-dir", Aliases: []string{"dir"}, Destination: &outputDir, Value: "results", Usage: "export dir"}, &cli.StringFlag{Name: "format", Aliases: []string{"f"}, Destination: &outputFormat, Value: "csv", Usage: "file name csv|json"}, &cli.StringFlag{Name: "profile-path", Aliases: []string{"p"}, Destination: &profilePath, Value: "", Usage: "custom profile dir path, get with chrome://version"}, + &cli.BoolFlag{Name: "full-export", Aliases: []string{"full"}, Destination: &isFullExport, Value: true, Usage: "is export full browsing data"}, }, HideHelpCommand: true, Action: func(c *cli.Context) error { if verbose { - log.Init("debug") - } else { - log.Init("notice") + log.SetVerbose() } - browsers, err := browser.PickBrowsers(browserName, profilePath) if err != nil { log.Error(err) } for _, b := range browsers { - data, err := b.BrowsingData() + data, err := b.BrowsingData(isFullExport) if err != nil { log.Error(err) } data.Output(outputDir, b.Name(), outputFormat) } + if compress { if err = fileutil.CompressDir(outputDir); err != nil { log.Error(err) diff --git a/crypto/crypto.go b/crypto/crypto.go index 7ada066..53deef5 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -63,15 +63,15 @@ type nssPBE struct { func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { glmp := append(globalSalt, masterPwd...) hp := sha1.Sum(glmp) - s := append(hp[:], n.entrySalt()...) + s := append(hp[:], n.salt()...) chp := sha1.Sum(s) - pes := paddingZero(n.entrySalt(), 20) + pes := paddingZero(n.salt(), 20) tk := hmac.New(sha1.New, chp[:]) tk.Write(pes) - pes = append(pes, n.entrySalt()...) + pes = append(pes, n.salt()...) k1 := hmac.New(sha1.New, chp[:]) k1.Write(pes) - tkPlus := append(tk.Sum(nil), n.entrySalt()...) + tkPlus := append(tk.Sum(nil), n.salt()...) k2 := hmac.New(sha1.New, chp[:]) k2.Write(tkPlus) k := append(k1.Sum(nil), k2.Sum(nil)...) @@ -79,7 +79,7 @@ func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { return des3Decrypt(k[:24], iv, n.encrypted()) } -func (n nssPBE) entrySalt() []byte { +func (n nssPBE) salt() []byte { return n.AlgoAttr.SaltAttr.EntrySalt } @@ -136,12 +136,12 @@ type slatAttr struct { func (m metaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) { k := sha1.Sum(globalSalt) - key := pbkdf2.Key(k[:], m.entrySalt(), m.iterationCount(), m.keySize(), sha256.New) + key := pbkdf2.Key(k[:], m.salt(), m.iterationCount(), m.keySize(), sha256.New) iv := append([]byte{4, 14}, m.iv()...) return aes128CBCDecrypt(key, iv, m.encrypted()) } -func (m metaPBE) entrySalt() []byte { +func (m metaPBE) salt() []byte { return m.AlgoAttr.Data.Data.SlatAttr.EntrySalt } diff --git a/crypto/crypto_darwin.go b/crypto/crypto_darwin.go index 44ed959..0a84f1d 100644 --- a/crypto/crypto_darwin.go +++ b/crypto/crypto_darwin.go @@ -2,12 +2,12 @@ package crypto +var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} + func Chromium(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) <= 3 { return nil, errPasswordIsEmpty } - - iv := []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} return aes128CBCDecrypt(key, iv, encryptPass[3:]) } diff --git a/crypto/crypto_linux.go b/crypto/crypto_linux.go index 05bd49b..e9c6108 100644 --- a/crypto/crypto_linux.go +++ b/crypto/crypto_linux.go @@ -2,13 +2,13 @@ package crypto +var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} + func Chromium(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) < 3 { return nil, errPasswordIsEmpty } - - chromeIV := []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} - return aes128CBCDecrypt(key, chromeIV, encryptPass[3:]) + return aes128CBCDecrypt(key, iv, encryptPass[3:]) } func DPAPI(data []byte) ([]byte, error) { diff --git a/crypto/crypto_windows.go b/crypto/crypto_windows.go index 943f8c7..ba4e1a8 100644 --- a/crypto/crypto_windows.go +++ b/crypto/crypto_windows.go @@ -10,7 +10,7 @@ import ( ) func Chromium(key, encryptPass []byte) ([]byte, error) { - if len(encryptPass) < 3 { + if len(encryptPass) < 15 { return nil, errPasswordIsEmpty } @@ -51,7 +51,7 @@ type dataBlob struct { pbData *byte } -func NewBlob(d []byte) *dataBlob { +func newBlob(d []byte) *dataBlob { if len(d) == 0 { return &dataBlob{} } @@ -78,7 +78,7 @@ func DPAPI(data []byte) ([]byte, error) { procDecryptData := dllCrypt.NewProc("CryptUnprotectData") procLocalFree := dllKernel.NewProc("LocalFree") var outBlob dataBlob - r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob))) + r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob))) if r == 0 { return nil, err } diff --git a/go.mod b/go.mod index e135dab..a2c50ab 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/ppacher/go-dbus-keyring v1.0.1 github.com/syndtr/goleveldb v1.0.0 github.com/tidwall/gjson v1.14.4 - github.com/urfave/cli/v2 v2.23.0 + github.com/urfave/cli/v2 v2.25.0 golang.org/x/crypto v0.7.0 - golang.org/x/exp v0.0.0-20230307190834-24139beb5833 + golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 golang.org/x/text v0.8.0 ) diff --git a/go.sum b/go.sum index 260f6eb..3e8fb1f 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/urfave/cli/v2 v2.23.0 h1:pkly7gKIeYv3olPAeNajNpLjeJrmTPYCoZWaV+2VfvE= -github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= +github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8= +github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= @@ -65,8 +65,8 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRT github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/exp v0.0.0-20230307190834-24139beb5833 h1:SChBja7BCQewoTAU7IgvucQKMIXrEpFxNMs0spT3/5s= -golang.org/x/exp v0.0.0-20230307190834-24139beb5833/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 h1:LGJsf5LRplCck6jUCH3dBL2dmycNruWNF5xugkSlfXw= +golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/item/item.go b/item/item.go index 671cb0e..06bea3f 100644 --- a/item/item.go +++ b/item/item.go @@ -121,6 +121,31 @@ func (i Item) String() string { } } +// IsSensitive returns whether the item is sensitive data +// password, cookie, credit card, master key is unlimited +func (i Item) IsSensitive() bool { + switch i { + case ChromiumKey, ChromiumCookie, ChromiumPassword, ChromiumCreditCard, + FirefoxKey4, FirefoxPassword, FirefoxCookie, FirefoxCreditCard, + YandexPassword, YandexCreditCard: + return true + default: + return false + } +} + +// FilterSensitiveItems returns the sensitive items +func FilterSensitiveItems(items []Item) []Item { + var filtered []Item + for _, item := range items { + if item.IsSensitive() { + filtered = append(filtered, item) + } + } + return filtered +} + +// DefaultFirefox returns the default items for the firefox browser var DefaultFirefox = []Item{ FirefoxKey4, FirefoxPassword, @@ -133,6 +158,7 @@ var DefaultFirefox = []Item{ FirefoxExtension, } +// DefaultYandex returns the default items for the yandex browser var DefaultYandex = []Item{ ChromiumKey, ChromiumCookie, @@ -145,6 +171,7 @@ var DefaultYandex = []Item{ YandexCreditCard, } +// DefaultChromium returns the default items for the chromium browser var DefaultChromium = []Item{ ChromiumKey, ChromiumPassword, diff --git a/log/log.go b/log/log.go index cbcf023..4bd48fe 100644 --- a/log/log.go +++ b/log/log.go @@ -8,19 +8,20 @@ import ( var std = &slog.SugaredLogger{} -func Init(l string) { - if l == "debug" { - std = newStdLogger(slog.DebugLevel) - } else { - std = newStdLogger(slog.NoticeLevel) - } +func init() { + std = newStdLogger(slog.NoticeLevel) +} + +// SetVerbose set log level to debug +func SetVerbose() { + std = newStdLogger(slog.DebugLevel) } const template = "[{{level}}] [{{caller}}] {{message}} {{data}} {{extra}}\n" -// NewStdLogger instance +// newStdLogger is a new std logger func newStdLogger(level slog.Level) *slog.SugaredLogger { - return slog.NewSugaredLogger(os.Stdout, level).Configure(func(sl *slog.SugaredLogger) { + return slog.NewSugaredLogger(os.Stdout, level).Config(func(sl *slog.SugaredLogger) { sl.SetName("stdLogger") sl.ReportCaller = true sl.CallerSkip = 7 diff --git a/utils/fileutil/filetutil.go b/utils/fileutil/filetutil.go index 59b7bd6..f126b66 100644 --- a/utils/fileutil/filetutil.go +++ b/utils/fileutil/filetutil.go @@ -13,8 +13,8 @@ import ( cp "github.com/otiai10/copy" ) -// FileExists checks if the file exists in the provided path -func FileExists(filename string) bool { +// IsFileExists checks if the file exists in the provided path +func IsFileExists(filename string) bool { info, err := os.Stat(filename) if os.IsNotExist(err) { return false @@ -25,9 +25,9 @@ func FileExists(filename string) bool { return !info.IsDir() } -// FolderExists checks if the folder exists -func FolderExists(foldername string) bool { - info, err := os.Stat(foldername) +// IsDirExists checks if the folder exists +func IsDirExists(folder string) bool { + info, err := os.Stat(folder) if os.IsNotExist(err) { return false } @@ -39,8 +39,8 @@ func FolderExists(foldername string) bool { // FilesInFolder returns the filepath contains in the provided folder func FilesInFolder(dir, filename string) ([]string, error) { - if !FolderExists(dir) { - return nil, errors.New(dir + " folder does not exist") + if !IsDirExists(dir) { + return nil, errors.New(dir + "folder does not exist") } var files []string err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { @@ -114,7 +114,7 @@ func ItemName(browser, item, ext string) string { } func BrowserName(browser, user string) string { - replace := strings.NewReplacer(" ", "_", ".", "_", "-", "_", "Profile", "User") + replace := strings.NewReplacer(" ", "_", ".", "_", "-", "_", "Profile", "user") return strings.ToLower(fmt.Sprintf("%s_%s", replace.Replace(browser), replace.Replace(user))) }