lockbox

password manager
Log | Files | Refs | README | LICENSE

commit 988578c2cb6eaa14cc10bbd8a0b5ce7dd69e1e24
parent 8749b4bb88e99f3c18c893ae31ee8969756a27f8
Author: Sean Enck <sean@ttypty.com>
Date:   Wed, 13 Jul 2022 18:47:37 -0400

allow for dump

Diffstat:
Mcmd/lb-bash/completions.bash | 5++++-
Mcmd/lb-totp/main.go | 2+-
Mcmd/lb/main.go | 60+++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mtests/expected.log | 18++++++++++++++++++
Mtests/run.sh | 3+++
5 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/cmd/lb-bash/completions.bash b/cmd/lb-bash/completions.bash @@ -18,12 +18,15 @@ _lb() { fi cur=${COMP_WORDS[COMP_CWORD]} if [ "$COMP_CWORD" -eq 1 ]; then - opts="version ls show insert rm rekey totp list pwgen find$clip_enabled" + opts="version ls show insert rm rekey totp list pwgen dump find$clip_enabled" # shellcheck disable=SC2207 COMPREPLY=( $(compgen -W "$opts" -- "$cur") ) else if [ "$COMP_CWORD" -eq 2 ]; then case ${COMP_WORDS[1]} in + "dump") + opts="-yes $(lb ls)" + ;; "insert") opts="-m $(lb ls)" ;; diff --git a/cmd/lb-totp/main.go b/cmd/lb-totp/main.go @@ -9,8 +9,8 @@ import ( "strings" "time" - otp "github.com/pquerna/otp/totp" "github.com/enckse/lockbox/internal" + otp "github.com/pquerna/otp/totp" ) func getEnv() string { diff --git a/cmd/lb/main.go b/cmd/lb/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "os" "os/exec" @@ -17,6 +18,14 @@ var ( libExec = "" ) +type ( + // Dump represents the output structure from a JSON dump. + Dump struct { + Path string `json:"path,omitempty"` + Value string `json:"name"` + } +) + func getEntry(store string, args []string, idx int) string { if len(args) != idx+1 { internal.Die("invalid entry given", internal.NewLockboxError("specific entry required")) @@ -146,9 +155,20 @@ func main() { os.Remove(entry) hooks() } - case "show", "-c", "clip": - inEntry := getEntry(store, args, 2) - isShow := command == "show" + case "show", "-c", "clip", "dump": + isDump := command == "dump" + startEntry := 2 + confirmDump := true + if isDump { + if len(args) > 2 { + if args[2] == "-yes" { + startEntry = 3 + confirmDump = false + } + } + } + inEntry := getEntry(store, args, startEntry) + isShow := command == "show" || isDump entries := []string{inEntry} if strings.Contains(inEntry, "*") { matches, err := filepath.Glob(inEntry) @@ -168,6 +188,7 @@ func main() { if err != nil { internal.Die("unable to get color for terminal", err) } + dumpData := []Dump{} for _, entry := range entries { if !internal.PathExists(entry) { internal.Die("invalid entry", internal.NewLockboxError("entry not found")) @@ -181,6 +202,7 @@ func main() { internal.Die("unable to decrypt", err) } value := strings.TrimSpace(string(decrypt)) + dump := Dump{} if isShow { if isGlob { fileName := strings.ReplaceAll(entry, store, "") @@ -188,13 +210,41 @@ func main() { fileName = fileName[1:] } fileName = strings.ReplaceAll(fileName, internal.Extension, "") - fmt.Printf("%s%s:%s\n", startColor, fileName, endColor) + if isDump { + dump.Path = fileName + } else { + fmt.Printf("%s%s:%s\n", startColor, fileName, endColor) + } + } + if isDump { + dump.Value = value + dumpData = append(dumpData, dump) + } else { + fmt.Println(value) } - fmt.Println(value) continue } internal.CopyToClipboard(value) } + if isDump { + if confirmDump { + if !confirm("dump data to stdout as plaintext") { + return + } + } + fmt.Println("[") + for idx, d := range dumpData { + if idx > 0 { + fmt.Println(",") + } + b, err := json.MarshalIndent(d, "", " ") + if err != nil { + internal.Die("failed to marshal dump item", err) + } + fmt.Println(string(b)) + } + fmt.Println("]") + } case "clear": idx := 0 val, err := internal.Stdin(false) diff --git a/tests/expected.log b/tests/expected.log @@ -6,6 +6,17 @@ keys/one: test keys/one2: test2 +[ +{ + "path": "keys/one", + "name": "test" +} +, +{ + "path": "keys/one2", + "name": "test2" +} +] HOOK RAN keys/one @@ -24,6 +35,11 @@ keys2/three test2 test3 test4 +dump data to stdout as plaintext? (y/N) [ +{ + "name": "test3\ntest4" +} +] HOOK RAN test @@ -36,3 +52,5 @@ remove entry? (y/N) HOOK RAN unable to decrypt (decrypt not ok) rekeying: /keys/one2.lb test2 +[ +] diff --git a/tests/run.sh b/tests/run.sh @@ -37,6 +37,7 @@ _run() { echo "test" | "$BIN/lb" insert keys/one echo "test2" | "$BIN/lb" insert keys/one2 "$BIN/lb" show keys/* + "$BIN/lb" dump -yes 'keys/*' echo -e "test3\ntest4" | "$BIN/lb" insert keys2/three "$BIN/lb" ls "$BIN/lb-pwgen" -special -length 10 @@ -47,6 +48,7 @@ _run() { "$BIN/lb" find e "$BIN/lb" show keys/one2 "$BIN/lb" show keys2/three + echo "y" | "$BIN/lb" dump keys2/three echo "5ae472abqdekjqykoyxk7hvc2leklq5n" | "$BIN/lb" insert totp/test "$BIN/lb-totp" -ls "$BIN/lb-totp" test | tr '[:digit:]' 'X' @@ -58,6 +60,7 @@ _run() { LOCKBOX_KEY="invalid" "$BIN/lb" show keys/one2 "$BIN/lb-rekey" -outkey "test" -outmode "plaintext" "$BIN/lb-rw" -file bin/lb/keys/one2.lb -key "test" -keymode "plaintext" -mode "decrypt" + echo "y" | "$BIN/lb" dump -yes "*" } LOG=$TESTS/lb.log