lockbox

password manager
Log | Files | Refs | README | LICENSE

commit cccf70e9fd5389c24cbe63375e2a34fabeacc0c4
parent 8bdbcaeb5c0b7788b9f2d5603ce91c0bfcd915e0
Author: Sean Enck <sean@ttypty.com>
Date:   Wed, 26 Jul 2023 21:44:13 -0400

requirements are really more than boolean and a key+keyfile is the reason why

Diffstat:
Minternal/inputs/env.go | 6+++---
Minternal/inputs/vars.go | 32+++++++++++++++++++-------------
Minternal/inputs/vars_test.go | 2+-
Mtests/Makefile | 2+-
Mtests/run.sh | 35++++++++++++++++++-----------------
5 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/internal/inputs/env.go b/internal/inputs/env.go @@ -32,9 +32,9 @@ type ( // SystemPlatform represents the platform lockbox is running on. SystemPlatform string environmentBase struct { - key string - required bool - desc string + key string + desc string + requirement string } // EnvironmentInt are environment settings that are integers EnvironmentInt struct { diff --git a/internal/inputs/vars.go b/internal/inputs/vars.go @@ -14,12 +14,13 @@ import ( ) const ( - prefixKey = "LOCKBOX_" - clipBaseEnv = prefixKey + "CLIP_" - plainKeyMode = "plaintext" - commandKeyMode = "command" - commandArgsExample = "[cmd args...]" - detectedValue = "(detected)" + prefixKey = "LOCKBOX_" + clipBaseEnv = prefixKey + "CLIP_" + plainKeyMode = "plaintext" + commandKeyMode = "command" + commandArgsExample = "[cmd args...]" + detectedValue = "(detected)" + requiredKeyOrKeyFile = "a key, a key file, or both must be set" // ModTimeFormat is the expected modtime format ModTimeFormat = time.RFC3339 // JSONDataOutputHash means output data is hashed @@ -54,7 +55,7 @@ var ( // EnvPlatform is the platform that the application is running on EnvPlatform = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "PLATFORM", desc: "override the detected platform"}, defaultValue: detectedValue, allowed: PlatformSet(), canDefault: false} // EnvStore is the location of the keepass file/store - EnvStore = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "STORE", required: true, desc: "directory to the database file"}, canDefault: false, allowed: []string{"file"}} + EnvStore = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "STORE", desc: "directory to the database file", requirement: "must be set"}, canDefault: false, allowed: []string{"file"}} // EnvHookDir is the directory of hooks to execute EnvHookDir = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "HOOKDIR", desc: "the path to hooks to execute on actions against the database"}, allowed: []string{"directory"}, canDefault: true, defaultValue: ""} // EnvClipCopy allows overriding the clipboard copy command @@ -63,16 +64,16 @@ var ( EnvClipPaste = EnvironmentCommand{environmentBase: environmentBase{key: clipBaseEnv + "PASTE", desc: "override the detected platform paste command"}} // EnvTOTPColorBetween handles terminal coloring for TOTP windows (seconds) EnvTOTPColorBetween = EnvironmentString{environmentBase: environmentBase{key: EnvTOTPToken.key + "_BETWEEN", desc: "override when to set totp generated outputs to different colors, must be a\nlist of one (or more) rules where a semicolon delimits the start and end\nsecond (0-60 for each)"}, canDefault: true, defaultValue: TOTPDefaultBetween, allowed: []string{"start:end,start:end,start:end..."}} - // EnvKeyFile is an OPTIONAL keyfile for the database - EnvKeyFile = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYFILE", desc: "additional keyfile to access/protect the database"}, allowed: []string{"keyfile"}, canDefault: true, defaultValue: ""} + // EnvKeyFile is an keyfile for the database + EnvKeyFile = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYFILE", requirement: requiredKeyOrKeyFile, desc: "keyfile to access/protect the database"}, allowed: []string{"keyfile"}, canDefault: true, defaultValue: ""} // EnvModTime is modtime override ability for entries EnvModTime = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "SET_MODTIME", desc: fmt.Sprintf("input modification time to set for the entry\n(expected format: %s)", ModTimeFormat)}, canDefault: true, defaultValue: "", allowed: []string{"modtime"}} // EnvJSONDataOutput controls how JSON is output in the 'data' field EnvJSONDataOutput = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "JSON_DATA_OUTPUT", desc: fmt.Sprintf("changes what the data field in JSON outputs will contain\nuse '%s' with CAUTION", JSONDataOutputRaw)}, canDefault: true, defaultValue: string(JSONDataOutputHash), allowed: []string{string(JSONDataOutputRaw), string(JSONDataOutputHash), string(JSONDataOutputBlank)}} // EnvFormatTOTP supports formatting the TOTP tokens for generation of tokens EnvFormatTOTP = EnvironmentFormatter{environmentBase: environmentBase{key: EnvTOTPToken.key + "_FORMAT", desc: "override the otpauth url used to store totp tokens. It must have ONE format\nstring ('%s') to insert the totp base code"}, fxn: formatterTOTP, allowed: "otpauth//url/%s/args..."} - envKeyMode = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYMODE", required: true, desc: "how to retrieve the database store password"}, allowed: []string{commandKeyMode, plainKeyMode}, canDefault: true, defaultValue: commandKeyMode} - envKey = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEY", required: true, desc: fmt.Sprintf("the database key ('%s' mode) or command to run ('%s' mode)\nto retrieve the database password", plainKeyMode, commandKeyMode)}, allowed: []string{commandArgsExample, "password"}, canDefault: false} + envKeyMode = EnvironmentString{environmentBase: environmentBase{key: prefixKey + "KEYMODE", requirement: "must be set to a valid mode", desc: "how to retrieve the database store password"}, allowed: []string{commandKeyMode, plainKeyMode}, canDefault: true, defaultValue: commandKeyMode} + envKey = EnvironmentString{environmentBase: environmentBase{requirement: requiredKeyOrKeyFile, key: prefixKey + "KEY", desc: fmt.Sprintf("the database key ('%s' mode) or command to run ('%s' mode)\nto retrieve the database password", plainKeyMode, commandKeyMode)}, allowed: []string{commandArgsExample, "password"}, canDefault: false} ) // GetReKey will get the rekey environment settings @@ -114,7 +115,7 @@ func GetKey() ([]byte, error) { useKeyMode := envKeyMode.Get() useKey := envKey.Get() if useKey == "" { - return nil, errors.New("no key given") + return nil, nil } var data []byte switch useKeyMode { @@ -155,7 +156,12 @@ func ListEnvironmentVariables(showValues bool) []string { value = "(unset)" } description := strings.ReplaceAll(env.desc, "\n", "\n ") - text := fmt.Sprintf("\n%s\n %s\n\n required: %t\n value: %s\n options: %s\n", env.key, description, env.required, value, strings.Join(allow, "|")) + requirement := "optional/default" + r := strings.TrimSpace(env.requirement) + if r != "" { + requirement = r + } + text := fmt.Sprintf("\n%s\n %s\n\n requirement: %s\n value: %s\n options: %s\n", env.key, description, requirement, value, strings.Join(allow, "|")) results = append(results, text) } return results diff --git a/internal/inputs/vars_test.go b/internal/inputs/vars_test.go @@ -84,7 +84,7 @@ func TestGetKey(t *testing.T) { } os.Setenv("LOCKBOX_KEYMODE", "plaintext") os.Setenv("LOCKBOX_KEY", "") - if _, err := inputs.GetKey(); err.Error() != "no key given" { + if _, err := inputs.GetKey(); err != nil { t.Errorf("invalid error: %v", err) } os.Setenv("LOCKBOX_KEY", "key") diff --git a/tests/Makefile b/tests/Makefile @@ -1,4 +1,4 @@ -TESTS := password keyfile +TESTS := password keyfile both all: $(TESTS) diff --git a/tests/run.sh b/tests/run.sh @@ -9,7 +9,6 @@ CLIP_PASTE="$DATA/clip.paste" _execute() { export LOCKBOX_HOOKDIR="" export LOCKBOX_STORE="${DATA}/passwords.kdbx" - export LOCKBOX_KEY="testingkey" export LOCKBOX_TOTP=totp export LOCKBOX_INTERACTIVE=no export LOCKBOX_READONLY=no @@ -165,19 +164,21 @@ echo "============" mkdir -p "$DATA" find "$DATA" -type f -delete -case "$1" in - "password") - export LOCKBOX_KEYFILE="" - _evaluate - ;; - "keyfile") - KEYFILE="$DATA/test.key" - echo "thisisatest" > "$KEYFILE" - export LOCKBOX_KEYFILE="$KEYFILE" - _evaluate - ;; - *) - echo "unknown test: $1" - exit 1 - ;; -esac +export LOCKBOX_KEYFILE="" +export LOCKBOX_KEY="" +VALID=0 +if [ "$1" == "password" ] || [ "$1" == "both" ]; then + VALID=1 + export LOCKBOX_KEY="testingkey" +fi +if [ "$1" == "keyfile" ] || [ "$1" == "both" ]; then + VALID=1 + KEYFILE="$DATA/test.key" + echo "thisisatest" > "$KEYFILE" + export LOCKBOX_KEYFILE="$KEYFILE" +fi +if [ "$VALID" -eq 0 ]; then + echo "invalid test" + exit 1 +fi +_evaluate