Skip to content

Commit 150d3b2

Browse files
authored
Merge branch 'gopasspw:master' into mindFlagCompleter
2 parents 33e6e6e + 98deb46 commit 150d3b2

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed

docs/commands/otp.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The command tries to parse the password and the totp fields as an OTP URL.
55

66
Note: HTOP is currently not supported.
77

8+
Note: If `show.safecontent` is enabled, OTP URLs are hidden from the `show` command.
9+
810
## Modes of operation
911

1012
* Generate the current TOTP token from a valid OTP URL
@@ -17,4 +19,4 @@ Note: HTOP is currently not supported.
1719
| `--clip` | `-c` | Copy the time-based token into the clipboard. |
1820
| `--qr` | `-q` | Write QR code to file. |
1921
| `--password` | `-o` | Only display the token. For use in scripts. |
20-
| `--snip` | `-s` | Try and find a QR code in the screen content to add as OTP to the entry. |
22+
| `--snip` | `-s` | Try and find a QR code in the screen content to add as OTP to the entry. |

docs/commands/show.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ The secrets are split into 3 categories:
108108
username, it should be enclosed in string delimiters: `username: "0123"` will always be parsed as the string `0123`
109109
and not as octal.
110110
111+
By default, `safecontent` will remove the first line (the password), every line starting with `otpauth://` in the body, and every YAML values where the key is one of the following: `hotp`, `otpauth`, `password`, `totp`.
112+
111113
Both the key-value and the YAML format support so-called "unsafe-keys", which is a key-value that allows you to specify keys that should be hidden when using `gopass show` with `gopass config safecontent` set to true.
112114
E.g:
113115
```

internal/action/show.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"slices"
78
"strconv"
89
"strings"
910

@@ -273,7 +274,7 @@ func (s *Action) showGetContent(ctx context.Context, sec gopass.Secret) (string,
273274
// everything but the first line.
274275
if config.Bool(ctx, "show.safecontent") && !ctxutil.IsForce(ctx) && ctxutil.IsShowParsing(ctx) {
275276
body := showSafeContent(sec)
276-
if IsAlsoClip(ctx) {
277+
if IsAlsoClip(ctx) || config.Bool(ctx, "show.autoclip") {
277278
return pw, body, nil
278279
}
279280

@@ -306,13 +307,21 @@ func showSafeContent(sec gopass.Secret) string {
306307
}
307308
}
308309

309-
sb.WriteString(sec.Body())
310+
for _, l := range strings.Split(sec.Body(), "\n") {
311+
if strings.HasPrefix(l, "otpauth://") {
312+
sb.WriteString(fmt.Sprintf("\notpauth://%s", randAsterisk()))
313+
314+
continue
315+
}
316+
sb.WriteString(l)
317+
}
310318

311319
return sb.String()
312320
}
313321

314322
func isUnsafeKey(key string, sec gopass.Secret) bool {
315-
if strings.ToLower(key) == "password" {
323+
duks := []string{"hotp", "otpauth", "password", "totp"}
324+
if slices.Contains(duks, key) {
316325
return true
317326
}
318327

internal/action/show_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,33 @@ func TestShowMulti(t *testing.T) {
119119
buf.Reset()
120120
})
121121

122+
t.Run("show entry with otpauth field with safecontent enabled", func(t *testing.T) {
123+
require.NoError(t, act.insertStdin(ctx, "otpauth", []byte("123\n---\notpauth://totp/WEBSITE:@USER?secret=SECRET&issuer=GoPass"), false))
124+
buf.Reset()
125+
126+
c := gptest.CliCtx(ctx, t, "otpauth")
127+
require.NoError(t, act.Show(c))
128+
assert.Contains(t, buf.String(), "otpauth://*****")
129+
buf.Reset()
130+
})
131+
132+
t.Run("show entry with otp as keys field with safecontent enabled", func(t *testing.T) {
133+
sec := secrets.NewAKV()
134+
sec.SetPassword("123")
135+
require.NoError(t, sec.Set("otpauth", "otpauth://totp/WEBSITE:@USER?secret=SECRET&issuer=GoPass"))
136+
require.NoError(t, sec.Set("totp", "otpauth://totp/WEBSITE:@USER?secret=SECRET&issuer=GoPass"))
137+
require.NoError(t, sec.Set("hotp", "otpauth://totp/WEBSITE:@USER?secret=SECRET&issuer=GoPass"))
138+
require.NoError(t, act.Store.Set(ctx, "otpauthKeys", sec))
139+
buf.Reset()
140+
141+
c := gptest.CliCtx(ctx, t, "otpauthKeys")
142+
require.NoError(t, act.Show(c))
143+
assert.Contains(t, buf.String(), "otpauth: *****")
144+
assert.Contains(t, buf.String(), "hotp: *****")
145+
assert.Contains(t, buf.String(), "totp: *****")
146+
buf.Reset()
147+
})
148+
122149
t.Run("show twoliner with safecontent enabled", func(t *testing.T) {
123150
c := gptest.CliCtx(ctx, t, "bar/baz")
124151

@@ -315,6 +342,18 @@ func TestShowAutoClip(t *testing.T) {
315342
stdoutBuf.Reset()
316343
stderrBuf.Reset()
317344
})
345+
346+
// gopass show foo with show.autoclip and show.safecontent true
347+
// -> ONLY Copy to clipboard
348+
t.Run("show foo with safecontent and autoclip enabled", func(t *testing.T) {
349+
require.NoError(t, act.cfg.Set("", "show.autoclip", "true"))
350+
require.NoError(t, act.cfg.Set("", "show.safecontent", "true"))
351+
c := gptest.CliCtx(ctx, t, "foo")
352+
require.NoError(t, act.Show(c))
353+
assert.Contains(t, stderrBuf.String(), "WARNING")
354+
assert.NotContains(t, stdoutBuf.String(), "secret")
355+
stdoutBuf.Reset()
356+
})
318357
}
319358

320359
func TestShowHandleRevision(t *testing.T) {

internal/create/wizard.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func mkActFunc(tpl Template, s *root.Store, cb ActionCallback) func(context.Cont
225225
if v.Min > 0 && len(sv) < v.Min {
226226
return fmt.Errorf("%s is too short (needs %d)", v.Name, v.Min)
227227
}
228-
if v.Max > 0 && len(sv) > v.Min {
228+
if v.Max > 0 && len(sv) > v.Max {
229229
return fmt.Errorf("%s is too long (at most %d)", v.Name, v.Max)
230230
}
231231
if wantForName[k] {

0 commit comments

Comments
 (0)