lockbox

password manager
Log | Files | Refs | README | LICENSE

commit 0cfb65eb2b65c12eb6804452f47d52bb4f8aeaaf
parent 54688528fb1af59bc792417730eb848c8399ea04
Author: Sean Enck <sean@ttypty.com>
Date:   Mon, 23 Aug 2021 18:55:59 -0400

using stock utils

Diffstat:
Mcmd/lb-diff/main.go | 5+++--
Mcmd/lb-pwgen/main.go | 23++++++++++++-----------
Mcmd/lb-rekey/main.go | 11++++++-----
Mcmd/lb-rw/main.go | 9+++++----
Mcmd/lb-stats/main.go | 11++++++-----
Mcmd/lb-totp/main.go | 11++++++-----
Mcmd/lb/main.go | 49+++++++++++++++++++++++++------------------------
Mgo.mod | 2++
Mgo.sum | 2++
Minternal/clip.go | 6++++--
Minternal/utils.go | 22+++-------------------
11 files changed, 74 insertions(+), 77 deletions(-)

diff --git a/cmd/lb-diff/main.go b/cmd/lb-diff/main.go @@ -5,17 +5,18 @@ import ( "os" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) func main() { args := os.Args l, err := internal.NewLockbox("", "", args[len(args)-1]) if err != nil { - internal.Die("unable to make lockbox model instance", err) + stock.Die("unable to make lockbox model instance", err) } result, err := l.Decrypt() if err != nil { - internal.Die("unable to read file", err) + stock.Die("unable to read file", err) } if result != nil { fmt.Println(string(result)) diff --git a/cmd/lb-pwgen/main.go b/cmd/lb-pwgen/main.go @@ -12,6 +12,7 @@ import ( "time" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) const ( @@ -41,15 +42,15 @@ func main() { var paths []string parts := strings.Split(src, ":") for _, p := range parts { - if internal.PathExists(p) { + if stock.PathExists(p) { info, err := os.Stat(p) if err != nil { - internal.Die("unable to stat", err) + stock.Die("unable to stat", err) } if info.IsDir() { files, err := os.ReadDir(p) if err != nil { - internal.Die("failed to read directory", err) + stock.Die("failed to read directory", err) } var results []string for _, f := range files { @@ -62,7 +63,7 @@ func main() { } } if len(paths) == 0 { - internal.Die("no paths found for generation", internal.NewLockboxError("unable to read paths")) + stock.Die("no paths found for generation", internal.NewLockboxError("unable to read paths")) } result := "" l := *length @@ -92,37 +93,37 @@ func main() { name = newValue case transformModeSed: if len(sedPattern) == 0 { - internal.Die("unable to use sed transform without pattern", internal.NewLockboxError("set PWGEN_SED")) + stock.Die("unable to use sed transform without pattern", internal.NewLockboxError("set PWGEN_SED")) } cmd := exec.Command("sed", "-e", sedPattern) stdin, err := cmd.StdinPipe() if err != nil { - internal.Die("unable to attach stdin to sed", err) + stock.Die("unable to attach stdin to sed", err) } var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Start(); err != nil { - internal.Die("failed to run sed", err) + stock.Die("failed to run sed", err) } if _, err := io.WriteString(stdin, name); err != nil { stdin.Close() - internal.Die("write to stdin failed for sed", err) + stock.Die("write to stdin failed for sed", err) } stdin.Close() if err := cmd.Wait(); err != nil { - internal.Die("sed failed", err) + stock.Die("sed failed", err) } errors := strings.TrimSpace(stderr.String()) if len(errors) > 0 { - internal.Die("sed stderr failure", internal.NewLockboxError(errors)) + stock.Die("sed stderr failure", internal.NewLockboxError(errors)) } name = strings.TrimSpace(stdout.String()) case transformModeNone: break default: - internal.Die("unknown transform mode", internal.NewLockboxError(transform)) + stock.Die("unknown transform mode", internal.NewLockboxError(transform)) } result += name } diff --git a/cmd/lb-rekey/main.go b/cmd/lb-rekey/main.go @@ -6,6 +6,7 @@ import ( "strings" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) func main() { @@ -16,24 +17,24 @@ func main() { flag.Parse() found, err := internal.Find(internal.GetStore(), false) if err != nil { - internal.Die("failed finding entries", err) + stock.Die("failed finding entries", err) } for _, file := range found { fmt.Printf("rekeying: %s\n", file) in, err := internal.NewLockbox(*inKey, *inMode, file) if err != nil { - internal.Die("unable to make input lockbox", err) + stock.Die("unable to make input lockbox", err) } decrypt, err := in.Decrypt() if err != nil { - internal.Die("failed to process file decryption", err) + stock.Die("failed to process file decryption", err) } out, err := internal.NewLockbox(*outKey, *outMode, file) if err != nil { - internal.Die("unable to make output lockbox", err) + stock.Die("unable to make output lockbox", err) } if err := out.Encrypt([]byte(strings.TrimSpace(string(decrypt)))); err != nil { - internal.Die("failed to encrypt file", err) + stock.Die("failed to encrypt file", err) } } } diff --git a/cmd/lb-rw/main.go b/cmd/lb-rw/main.go @@ -5,6 +5,7 @@ import ( "fmt" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) func main() { @@ -15,20 +16,20 @@ func main() { flag.Parse() l, err := internal.NewLockbox(*key, *keyMode, *file) if err != nil { - internal.Die("unable to make lockbox model instance", err) + stock.Die("unable to make lockbox model instance", err) } switch *mode { case "encrypt": if err := l.Encrypt(nil); err != nil { - internal.Die("failed to encrypt", err) + stock.Die("failed to encrypt", err) } case "decrypt": results, err := l.Decrypt() if err != nil { - internal.Die("failed to decrypt", err) + stock.Die("failed to decrypt", err) } fmt.Println(string(results)) default: - internal.Die("invalid mode", internal.NewLockboxError("bad mode")) + stock.Die("invalid mode", internal.NewLockboxError("bad mode")) } } diff --git a/cmd/lb-stats/main.go b/cmd/lb-stats/main.go @@ -9,6 +9,7 @@ import ( "strings" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) type ( @@ -32,7 +33,7 @@ func main() { store := internal.GetStore() items, err := internal.Find(store, true) if err != nil { - internal.Die("unable to find entries", err) + stock.Die("unable to find entries", err) } results := []Stats{} for _, item := range items { @@ -48,7 +49,7 @@ func main() { cmd := exec.Command("git", "-C", store, "log", "--format=%h %aI", fmt.Sprintf("%s%s", item, internal.Extension)) b, err := cmd.Output() if err != nil { - internal.Die("failed to get git history", err) + stock.Die("failed to get git history", err) } history := []History{} for _, value := range strings.Split(string(b), "\n") { @@ -58,7 +59,7 @@ func main() { } parts := strings.Split(cleaned, " ") if len(parts) != 2 { - internal.Die("invalid format entry", internal.NewLockboxError("mismatch between format string and struct?")) + stock.Die("invalid format entry", internal.NewLockboxError("mismatch between format string and struct?")) } history = append(history, History{Hash: parts[0], Date: parts[1]}) } @@ -66,11 +67,11 @@ func main() { results = append(results, stat) } if len(results) == 0 { - internal.Die("found no entries", internal.NewLockboxError("no entries")) + stock.Die("found no entries", internal.NewLockboxError("no entries")) } j, err := json.MarshalIndent(results, "", " ") if err != nil { - internal.Die("unable to prep json", err) + stock.Die("unable to prep json", err) } fmt.Println(string(j)) } diff --git a/cmd/lb-totp/main.go b/cmd/lb-totp/main.go @@ -11,6 +11,7 @@ import ( otp "github.com/pquerna/otp/totp" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) const ( @@ -52,7 +53,7 @@ func clear() { func display(token string, clip bool) error { tok := strings.TrimSpace(token) store := filepath.Join(getEnv(), tok+internal.Extension) - if !internal.PathExists(store) { + if !stock.PathExists(store) { return internal.NewLockboxError("object does not exist") } l, err := internal.NewLockbox("", "", store) @@ -119,13 +120,13 @@ func colorize(start, text, end string) { func main() { args := os.Args if len(args) > 3 || len(args) < 2 { - internal.Die("subkey required", internal.NewLockboxError("invalid arguments")) + stock.Die("subkey required", internal.NewLockboxError("invalid arguments")) } cmd := args[1] if cmd == "list" || cmd == "ls" { result, err := list() if err != nil { - internal.Die("invalid list response", err) + stock.Die("invalid list response", err) } sort.Strings(result) for _, entry := range result { @@ -136,12 +137,12 @@ func main() { clip := false if len(args) == 3 { if cmd != "-c" && cmd != "clip" { - internal.Die("subcommand not supported", internal.NewLockboxError("invalid sub command")) + stock.Die("subcommand not supported", internal.NewLockboxError("invalid sub command")) } clip = true cmd = args[2] } if err := display(cmd, clip); err != nil { - internal.Die("failed to show totp token", err) + stock.Die("failed to show totp token", err) } } diff --git a/cmd/lb/main.go b/cmd/lb/main.go @@ -10,6 +10,7 @@ import ( "time" "voidedtech.com/lockbox/internal" + "voidedtech.com/stock" ) var ( @@ -18,7 +19,7 @@ var ( func getEntry(store string, args []string, idx int) string { if len(args) != idx+1 { - internal.Die("invalid entry given", internal.NewLockboxError("specific entry required")) + stock.Die("invalid entry given", internal.NewLockboxError("specific entry required")) } return filepath.Join(store, args[idx]) + internal.Extension } @@ -76,7 +77,7 @@ func readInput() (string, error) { func main() { args := os.Args if len(args) < 2 { - internal.Die("missing arguments", internal.NewLockboxError("requires subcommand")) + stock.Die("missing arguments", internal.NewLockboxError("requires subcommand")) } command := args[1] store := internal.GetStore() @@ -86,13 +87,13 @@ func main() { searchTerm := "" if isFind { if len(args) < 3 { - internal.Die("find requires an argument to search for", internal.NewLockboxError("search term required")) + stock.Die("find requires an argument to search for", internal.NewLockboxError("search term required")) } searchTerm = args[2] } files, err := internal.Find(store, true) if err != nil { - internal.Die("unable to list files", err) + stock.Die("unable to list files", err) } for _, f := range files { if isFind { @@ -109,20 +110,20 @@ func main() { idx := 2 switch len(args) { case 2: - internal.Die("insert missing required arguments", internal.NewLockboxError("entry required")) + stock.Die("insert missing required arguments", internal.NewLockboxError("entry required")) case 3: case 4: multi = args[2] == "-m" if !multi { - internal.Die("multi-line insert must be after 'insert'", internal.NewLockboxError("invalid command")) + stock.Die("multi-line insert must be after 'insert'", internal.NewLockboxError("invalid command")) } idx = 3 default: - internal.Die("too many arguments", internal.NewLockboxError("insert can only perform one operation")) + stock.Die("too many arguments", internal.NewLockboxError("insert can only perform one operation")) } isPipe := isInputFromPipe() entry := getEntry(store, args, idx) - if internal.PathExists(entry) { + if stock.PathExists(entry) { if !isPipe { if !confirm("overwrite existing") { return @@ -130,9 +131,9 @@ func main() { } } else { dir := filepath.Dir(entry) - if !internal.PathExists(dir) { + if !stock.PathExists(dir) { if err := os.MkdirAll(dir, 0755); err != nil { - internal.Die("failed to create directory structure", err) + stock.Die("failed to create directory structure", err) } } } @@ -140,47 +141,47 @@ func main() { if !multi && !isPipe { input, err := readInput() if err != nil { - internal.Die("password input failed", err) + stock.Die("password input failed", err) } password = input } else { input, err := stdin(false) if err != nil { - internal.Die("failed to read stdin", err) + stock.Die("failed to read stdin", err) } password = input } if password == "" { - internal.Die("empty password provided", internal.NewLockboxError("password can NOT be empty")) + stock.Die("empty password provided", internal.NewLockboxError("password can NOT be empty")) } l, err := internal.NewLockbox("", "", entry) if err != nil { - internal.Die("unable to make lockbox model instance", err) + stock.Die("unable to make lockbox model instance", err) } if err := l.Encrypt([]byte(password)); err != nil { - internal.Die("failed to save password", err) + stock.Die("failed to save password", err) } fmt.Println("") case "rm": entry := getEntry(store, args, 2) - if !internal.PathExists(entry) { - internal.Die("does not exists", internal.NewLockboxError("can not delete unknown entry")) + if !stock.PathExists(entry) { + stock.Die("does not exists", internal.NewLockboxError("can not delete unknown entry")) } if confirm("remove entry") { os.Remove(entry) } case "show", "-c", "clip": entry := getEntry(store, args, 2) - if !internal.PathExists(entry) { - internal.Die("invalid entry", internal.NewLockboxError("entry not found")) + if !stock.PathExists(entry) { + stock.Die("invalid entry", internal.NewLockboxError("entry not found")) } l, err := internal.NewLockbox("", "", entry) if err != nil { - internal.Die("unable to make lockbox model instance", err) + stock.Die("unable to make lockbox model instance", err) } decrypt, err := l.Decrypt() if err != nil { - internal.Die("unable to decrypt", err) + stock.Die("unable to decrypt", err) } value := strings.TrimSpace(string(decrypt)) if command == "show" { @@ -192,7 +193,7 @@ func main() { idx := 0 val, err := stdin(false) if err != nil { - internal.Die("unable to read value to clear", err) + stock.Die("unable to read value to clear", err) } val = strings.TrimSpace(val) for idx < internal.MaxClipTime { @@ -215,7 +216,7 @@ func main() { c.Stdout = os.Stdout c.Stderr = os.Stderr if err := c.Run(); err != nil { - internal.Die("bad command", err) + stock.Die("bad command", err) } } } @@ -232,7 +233,7 @@ func confirm(prompt string) bool { fmt.Printf("%s? (y/N) ", prompt) resp, err := stdin(true) if err != nil { - internal.Die("failed to get response", err) + stock.Die("failed to get response", err) } return resp == "Y" || resp == "y" } diff --git a/go.mod b/go.mod @@ -8,3 +8,5 @@ require ( golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect ) + +require voidedtech.com/stock v0.0.0-20210823174715-003d4cd6133c // indirect diff --git a/go.sum b/go.sum @@ -20,3 +20,5 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +voidedtech.com/stock v0.0.0-20210823174715-003d4cd6133c h1:Fm4M/LmSmWI3DoSaIcR/ZuGTy4xTr8yeccoZRzbt5z4= +voidedtech.com/stock v0.0.0-20210823174715-003d4cd6133c/go.mod h1:fDeTx9Bymp++UZEUI+pxljhMDzibXQvRKTcg1h+5tw4= diff --git a/internal/clip.go b/internal/clip.go @@ -3,6 +3,8 @@ package internal import ( "fmt" "os/exec" + + "voidedtech.com/stock" ) const ( @@ -23,7 +25,7 @@ func pipeTo(command, value string, wait bool, args ...string) { cmd := exec.Command(command, args...) stdin, err := cmd.StdinPipe() if err != nil { - Die("unable to get stdin pipe", err) + stock.Die("unable to get stdin pipe", err) } go func() { @@ -39,6 +41,6 @@ func pipeTo(command, value string, wait bool, args ...string) { ran = cmd.Start() } if ran != nil { - Die("failed to run command", ran) + stock.Die("failed to run command", ran) } } diff --git a/internal/utils.go b/internal/utils.go @@ -3,12 +3,13 @@ package internal import ( "bufio" "bytes" - "fmt" "io/fs" "os" "path/filepath" "sort" "strings" + + "voidedtech.com/stock" ) const ( @@ -24,7 +25,7 @@ func GetStore() string { // Find will find all lockbox files in a directory store. func Find(store string, display bool) ([]string, error) { var results []string - if !PathExists(store) { + if !stock.PathExists(store) { return nil, NewLockboxError("store does not exists") } err := filepath.Walk(store, func(path string, info fs.FileInfo, err error) error { @@ -52,13 +53,6 @@ func Find(store string, display bool) ([]string, error) { return results, nil } -// Die will print messages and exit. -func Die(message string, err error) { - msg := fmt.Sprintf("%s (%v)", message, err) - fmt.Fprintln(os.Stderr, msg) - os.Exit(1) -} - // Stdin reads one (or more) lines from stdin. func Stdin(one bool) ([]byte, error) { scanner := bufio.NewScanner(os.Stdin) @@ -75,13 +69,3 @@ func Stdin(one bool) ([]byte, error) { } return b.Bytes(), nil } - -// PathExists indicates if a path exists. -func PathExists(path string) bool { - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - return false - } - } - return true -}