Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions docs/commands/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ The `audit` command will decrypt all secrets and scan for weak passwords or othe
$ gopass audit
```

## Excludes

You can exclude certain secrets from the audit by adding a `.gopass-audit-exclude` file to the secret. The file should contain a list of RE2 patters to exclude, one per line. For example:

```
# Lines starting with # are ignored. Trailing comments are not supported.
# Exclude all secrets in the pin folder.
# Note: These are RE2, not Glob patterns!
pin/.*
# Literal matches are also valid RE2 patterns
test_folder/ignore_this
# Gopass internally uses forward slashes as path separators, even on Windows. So no need to escape backslashes.
```

## Password strength backends

| Backend | Description |
|-------------------------------------------------|------------------------------------------------------------------------|
| [`zxcvbn`](https://github.com/nbutton23/zxcvbn) | [zxcvbn](https://github.com/dropbox/zxcvbn) password strength checker. |
| [`crunchy`](https://github.com/muesli/crunchy) | Crunchy password strength checker |
| `name` | Checks if password equals the name of the secret |


12 changes: 11 additions & 1 deletion internal/action/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,18 @@ func (s *Action) Audit(c *cli.Context) error {
return nil
}

var excludes string
st := s.Store.Storage(ctx, c.Args().First())
if buf, err := st.Get(ctx, ".gopass-audit-ignore"); err == nil && buf != nil {
excludes = string(buf)
}
nList := audit.FilterExcludes(excludes, list)
if len(nList) < len(list) {
out.Warningf(ctx, "Excluding %d secrets based on .gopass-audit-ignore", len(list)-len(nList))
}

a := audit.New(c.Context, s.Store)
r, err := a.Batch(ctx, list)
r, err := a.Batch(ctx, nList)
if err != nil {
return exit.Error(exit.Unknown, err, "failed to audit password store: %s", err)
}
Expand Down
62 changes: 62 additions & 0 deletions internal/audit/excludes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package audit

import (
"regexp"
"strings"

"github.com/gopasspw/gopass/pkg/debug"
)

type res []*regexp.Regexp

func (r res) Matches(s string) bool {
for _, re := range r {
if re.MatchString(s) {
debug.Log("Matched %s against %s", s, re.String())

return true
}
}

return false
}

// FilterExcludes filters the given list of secrets against the given exclude patterns (RE2 syntax).
func FilterExcludes(excludes string, in []string) []string {
debug.Log("Filtering %d secrets against %d exclude patterns", len(in), strings.Count(excludes, "\n"))

res := make(res, 0, 10)
for _, line := range strings.Split(excludes, "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
if strings.HasPrefix(line, "#") {
continue
}
re, err := regexp.Compile(line)
if err != nil {
debug.Log("failed to compile exclude pattern %q: %s", line, err)

continue
}
debug.Log("Adding exclude pattern %q", re.String())
res = append(res, re)
}

// shortcut if we have no excludes
if len(res) < 1 {
return in
}

// check all secrets against all excludes
out := make([]string, 0, len(in))
for _, s := range in {
if res.Matches(s) {
continue
}
out = append(out, s)
}

return out
}