lockbox

password manager
Log | Files | Refs | README | LICENSE

commit bf3c7236c2700bb1f429582c5fb6c3fac615565d
parent cfca4f9a9b4bce37e0c51ecb3f1ad1809353f5b5
Author: Sean Enck <sean@ttypty.com>
Date:   Sun,  3 Sep 2023 08:05:30 -0400

restructure files

Diffstat:
Minternal/config/core.go | 14--------------
Ainternal/config/key.go | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainternal/config/key_test.go | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minternal/config/vars.go | 50--------------------------------------------------
Minternal/config/vars_test.go | 52----------------------------------------------------
5 files changed, 134 insertions(+), 116 deletions(-)

diff --git a/internal/config/core.go b/internal/config/core.go @@ -91,22 +91,8 @@ type ( Start int End int } - // Key is a wrapper to help manage the returned key - Key struct { - key []byte - } ) -// Interactive indicates if the key requires interactive input -func (e *Key) Interactive() bool { - return e.key == nil -} - -// Key returns the key data -func (e *Key) Key() []byte { - return e.key -} - func shlex(in string) ([]string, error) { return shell.Fields(in, os.Getenv) } diff --git a/internal/config/key.go b/internal/config/key.go @@ -0,0 +1,74 @@ +// Package config handles user inputs/UI elements. +package config + +import ( + "errors" + "fmt" + "os/exec" + "strings" +) + +type ( + // Key is a wrapper to help manage the returned key + Key struct { + key []byte + } +) + +// Interactive indicates if the key requires interactive input +func (e *Key) Interactive() bool { + return e.key == nil +} + +// Key returns the key data +func (e *Key) Key() []byte { + return e.key +} + +// GetKey will get the encryption key setup for lb +func GetKey(dryrun bool) (*Key, error) { + useKey := envKey.Get() + keyMode := envKeyMode.Get() + if keyMode == askKeyMode { + isInteractive, err := EnvInteractive.Get() + if err != nil { + return nil, err + } + if !isInteractive { + return nil, errors.New("ask key mode requested in non-interactive mode") + } + if useKey != "" { + return nil, errors.New("key can NOT be set in ask key mode") + } + return &Key{}, nil + } + if useKey == "" { + return nil, nil + } + if dryrun { + return &Key{key: []byte{0}}, nil + } + var data []byte + switch keyMode { + case commandKeyMode: + parts, err := shlex(useKey) + if err != nil { + return nil, err + } + cmd := exec.Command(parts[0], parts[1:]...) + b, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("key command failed: %w", err) + } + data = b + case plainKeyMode: + data = []byte(useKey) + default: + return nil, errors.New("unknown keymode") + } + b := []byte(strings.TrimSpace(string(data))) + if len(b) == 0 { + return nil, errors.New("key is empty") + } + return &Key{key: b}, nil +} diff --git a/internal/config/key_test.go b/internal/config/key_test.go @@ -0,0 +1,60 @@ +package config_test + +import ( + "os" + "testing" + + "github.com/enckse/lockbox/internal/config" +) + +func TestGetKey(t *testing.T) { + os.Setenv("LOCKBOX_KEY", "aaa") + os.Setenv("LOCKBOX_KEYMODE", "lak;jfea") + if k, err := config.GetKey(false); err.Error() != "unknown keymode" || k != nil { + t.Errorf("invalid error: %v", err) + } + os.Setenv("LOCKBOX_KEYMODE", "plaintext") + os.Setenv("LOCKBOX_KEY", "") + if k, err := config.GetKey(false); err != nil || k != nil { + t.Errorf("invalid error: %v", err) + } + os.Setenv("LOCKBOX_KEY", "key") + k, err := config.GetKey(false) + if err != nil || k == nil || string(k.Key()) != "key" || k.Interactive() { + t.Error("invalid key retrieval") + } + os.Setenv("LOCKBOX_KEY", "key") + k, err = config.GetKey(true) + if err != nil || k == nil || len(k.Key()) != 1 || k.Key()[0] != 0 || k.Interactive() { + t.Error("invalid key retrieval") + } + os.Setenv("LOCKBOX_KEYMODE", "command") + os.Setenv("LOCKBOX_KEY", "invalid command text is long and invalid via shlex") + if k, err := config.GetKey(false); err == nil || k != nil { + t.Error("should have failed") + } + os.Setenv("LOCKBOX_INTERACTIVE", "yes") + os.Setenv("LOCKBOX_KEYMODE", "ask") + os.Setenv("LOCKBOX_KEY", "") + if k, err := config.GetKey(false); err != nil || k == nil || !k.Interactive() { + t.Errorf("invalid error: %v", err) + } + os.Setenv("LOCKBOX_INTERACTIVE", "yes") + os.Setenv("LOCKBOX_KEYMODE", "ask") + os.Setenv("LOCKBOX_KEY", "") + if k, err := config.GetKey(true); err != nil || k == nil || !k.Interactive() { + t.Errorf("invalid error: %v", err) + } + os.Setenv("LOCKBOX_INTERACTIVE", "no") + os.Setenv("LOCKBOX_KEYMODE", "ask") + os.Setenv("LOCKBOX_KEY", "") + if k, err := config.GetKey(false); err == nil || err.Error() != "ask key mode requested in non-interactive mode" || k != nil { + t.Errorf("invalid error: %v", err) + } + os.Setenv("LOCKBOX_INTERACTIVE", "yes") + os.Setenv("LOCKBOX_KEYMODE", "ask") + os.Setenv("LOCKBOX_KEY", "aaa") + if k, err := config.GetKey(false); err == nil || err.Error() != "key can NOT be set in ask key mode" || k != nil { + t.Errorf("invalid error: %v", err) + } +} diff --git a/internal/config/vars.go b/internal/config/vars.go @@ -2,11 +2,9 @@ package config import ( - "errors" "flag" "fmt" "net/url" - "os/exec" "sort" "strings" "time" @@ -121,54 +119,6 @@ func GetReKey(args []string) ([]string, error) { return out, nil } -// GetKey will get the encryption key setup for lb -func GetKey(dryrun bool) (*Key, error) { - useKey := envKey.Get() - keyMode := envKeyMode.Get() - if keyMode == askKeyMode { - isInteractive, err := EnvInteractive.Get() - if err != nil { - return nil, err - } - if !isInteractive { - return nil, errors.New("ask key mode requested in non-interactive mode") - } - if useKey != "" { - return nil, errors.New("key can NOT be set in ask key mode") - } - return &Key{}, nil - } - if useKey == "" { - return nil, nil - } - if dryrun { - return &Key{key: []byte{0}}, nil - } - var data []byte - switch keyMode { - case commandKeyMode: - parts, err := shlex(useKey) - if err != nil { - return nil, err - } - cmd := exec.Command(parts[0], parts[1:]...) - b, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("key command failed: %w", err) - } - data = b - case plainKeyMode: - data = []byte(useKey) - default: - return nil, errors.New("unknown keymode") - } - b := []byte(strings.TrimSpace(string(data))) - if len(b) == 0 { - return nil, errors.New("key is empty") - } - return &Key{key: b}, nil -} - // ListEnvironmentVariables will print information about env variables func ListEnvironmentVariables() []string { var results []string diff --git a/internal/config/vars_test.go b/internal/config/vars_test.go @@ -76,58 +76,6 @@ func TestTOTP(t *testing.T) { } } -func TestGetKey(t *testing.T) { - os.Setenv("LOCKBOX_KEY", "aaa") - os.Setenv("LOCKBOX_KEYMODE", "lak;jfea") - if k, err := config.GetKey(false); err.Error() != "unknown keymode" || k != nil { - t.Errorf("invalid error: %v", err) - } - os.Setenv("LOCKBOX_KEYMODE", "plaintext") - os.Setenv("LOCKBOX_KEY", "") - if k, err := config.GetKey(false); err != nil || k != nil { - t.Errorf("invalid error: %v", err) - } - os.Setenv("LOCKBOX_KEY", "key") - k, err := config.GetKey(false) - if err != nil || k == nil || string(k.Key()) != "key" || k.Interactive() { - t.Error("invalid key retrieval") - } - os.Setenv("LOCKBOX_KEY", "key") - k, err = config.GetKey(true) - if err != nil || k == nil || len(k.Key()) != 1 || k.Key()[0] != 0 || k.Interactive() { - t.Error("invalid key retrieval") - } - os.Setenv("LOCKBOX_KEYMODE", "command") - os.Setenv("LOCKBOX_KEY", "invalid command text is long and invalid via shlex") - if k, err := config.GetKey(false); err == nil || k != nil { - t.Error("should have failed") - } - os.Setenv("LOCKBOX_INTERACTIVE", "yes") - os.Setenv("LOCKBOX_KEYMODE", "ask") - os.Setenv("LOCKBOX_KEY", "") - if k, err := config.GetKey(false); err != nil || k == nil || !k.Interactive() { - t.Errorf("invalid error: %v", err) - } - os.Setenv("LOCKBOX_INTERACTIVE", "yes") - os.Setenv("LOCKBOX_KEYMODE", "ask") - os.Setenv("LOCKBOX_KEY", "") - if k, err := config.GetKey(true); err != nil || k == nil || !k.Interactive() { - t.Errorf("invalid error: %v", err) - } - os.Setenv("LOCKBOX_INTERACTIVE", "no") - os.Setenv("LOCKBOX_KEYMODE", "ask") - os.Setenv("LOCKBOX_KEY", "") - if k, err := config.GetKey(false); err == nil || err.Error() != "ask key mode requested in non-interactive mode" || k != nil { - t.Errorf("invalid error: %v", err) - } - os.Setenv("LOCKBOX_INTERACTIVE", "yes") - os.Setenv("LOCKBOX_KEYMODE", "ask") - os.Setenv("LOCKBOX_KEY", "aaa") - if k, err := config.GetKey(false); err == nil || err.Error() != "key can NOT be set in ask key mode" || k != nil { - t.Errorf("invalid error: %v", err) - } -} - func TestListVariables(t *testing.T) { known := make(map[string]struct{}) for _, v := range config.ListEnvironmentVariables() {