|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# __ __ |
| 4 | +# / /____ ___ ____ ___ ___ _/ / This script is provided to you by https://github.com/tegonal/scripts |
| 5 | +# / __/ -_) _ `/ _ \/ _ \/ _ `/ / It is licensed under Apache License 2.0 |
| 6 | +# \__/\__/\_, /\___/_//_/\_,_/_/ Please report bugs and contribute back your improvements |
| 7 | +# /___/ |
| 8 | +# Version: v4.5.0-SNAPSHOT |
| 9 | +# |
| 10 | +####### Description ############# |
| 11 | +# |
| 12 | +# Utility functions for secret-tool and secrets in general. |
| 13 | +# |
| 14 | +####### Usage ################### |
| 15 | +# |
| 16 | +# #!/usr/bin/env bash |
| 17 | +# set -euo pipefail |
| 18 | +# shopt -s inherit_errexit |
| 19 | +# # Assumes tegonal's scripts were fetched with gt - adjust location accordingly |
| 20 | +# dir_of_tegonal_scripts="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" >/dev/null && pwd 2>/dev/null)/../lib/tegonal-scripts/src" |
| 21 | +# source "$dir_of_tegonal_scripts/setup.sh" "$dir_of_tegonal_scripts" |
| 22 | +# |
| 23 | +# source "$dir_of_tegonal_scripts/utility/secret-utils.sh" |
| 24 | +# |
| 25 | +# # stores the entered password into the variable `secret` |
| 26 | +# promptForSecret "enter your password: " secret |
| 27 | +# |
| 28 | +# # retrieves a secret identified by `group` and `key` via secret-tool from the login keyring |
| 29 | +# # shellcheck disable=SC2034 # we know secret is not used, only a sample |
| 30 | +# secret="$(getSecretViaSecretTool "group" "key")" |
| 31 | +# |
| 32 | +# # stores the secret identified by `group` and `key` and value `mySecret` via secret-tool into the login keyring |
| 33 | +# storeSecretViaSecretTool "group" "key" "label as shown in e.g. seahorse" "mySecret" |
| 34 | +# |
| 35 | +# # stores the secret identified by `group` and `key` via secret-tool into the login keyring |
| 36 | +# # uses stdin as input (prompts for a password if there is no input) |
| 37 | +# storeSecretViaSecretTool "group" "key" "label as shown in e.g. seahorse" |
| 38 | +# |
| 39 | +# # retrieves a secret identified by `group` and `key` via secret-tool from the login keyring and |
| 40 | +# # stores it in the variable password. If the secret does not exist yet, then the given prompt is used and the secret is |
| 41 | +# # stores accordingly |
| 42 | +# getSecretViaSecretToolOrPromptAndStore "group" "key" "label as shown in e.g. seahorse" "enter your password: " password |
| 43 | +# |
| 44 | +################################### |
| 45 | +set -euo pipefail |
| 46 | +shopt -s inherit_errexit |
| 47 | +unset CDPATH |
| 48 | + |
| 49 | +if ! [[ -v dir_of_tegonal_scripts ]]; then |
| 50 | + dir_of_tegonal_scripts="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" >/dev/null && pwd 2>/dev/null)/.." |
| 51 | + source "$dir_of_tegonal_scripts/setup.sh" "$dir_of_tegonal_scripts" |
| 52 | +fi |
| 53 | +sourceOnce "$dir_of_tegonal_scripts/utility/checks.sh" |
| 54 | +sourceOnce "$dir_of_tegonal_scripts/utility/parse-utils.sh" |
| 55 | + |
| 56 | +function getSecretViaSecretToolOrPromptAndStore() { |
| 57 | + |
| 58 | + exitIfCommandDoesNotExist "secret-tool" "install it via 'sudo apt install libsecret-tools'" |
| 59 | + |
| 60 | + if (($# != 5)); then |
| 61 | + logError "getSecretViaSecretToolOrPromptAndStore requires exactly 5 arguments, given \033[0;36m%s\033[0m\nFollowing a description of the parameters:\n" "$#" |
| 62 | + echo >&2 "1: group the group in which the secret shall be stored -- referred to as attribute in secret-tool's documentation" |
| 63 | + echo >&2 "2: key the secret key -- referred to as value in the secret-tool's documentation" |
| 64 | + echo >&2 '3: label the description of this key (will be shown e.g. in seahorse)' |
| 65 | + echo >&2 '4: prompt the text used in case the secret does not yet exist' |
| 66 | + echo >&2 '5: outVar variable name where the secret shall be stored (next to the secret-tool itself)' |
| 67 | + exit 1 |
| 68 | + fi |
| 69 | + local -r getSecretViaSecretToolOrPromptAndStore_group=$1 |
| 70 | + local -r getSecretViaSecretToolOrPromptAndStore_key=$2 |
| 71 | + local -r getSecretViaSecretToolOrPromptAndStore_label=$3 |
| 72 | + local -r getSecretViaSecretToolOrPromptAndStore_prompt=$4 |
| 73 | + local -r getSecretViaSecretToolOrPromptAndStore_outVar=$5 |
| 74 | + |
| 75 | + exitIfVariablesNotDeclared "$getSecretViaSecretToolOrPromptAndStore_outVar" |
| 76 | + |
| 77 | + local getSecretViaSecretToolOrPromptAndStore_secret |
| 78 | + |
| 79 | + # shellcheck disable=SC2310 # we are aware of that set -e has no effect for getSecretViaSecretTool |
| 80 | + if ! getSecretViaSecretToolOrPromptAndStore_secret=$(getSecretViaSecretTool "$getSecretViaSecretToolOrPromptAndStore_group" "$getSecretViaSecretToolOrPromptAndStore_key"); then |
| 81 | + promptForSecret "$getSecretViaSecretToolOrPromptAndStore_prompt" getSecretViaSecretToolOrPromptAndStore_outVar |
| 82 | + storeSecretViaSecretTool "$getSecretViaSecretToolOrPromptAndStore_group" "$getSecretViaSecretToolOrPromptAndStore_key" "$getSecretViaSecretToolOrPromptAndStore_label" "$getSecretViaSecretToolOrPromptAndStore_secret" |
| 83 | + fi |
| 84 | + assignToVariableInOuterScope "$getSecretViaSecretToolOrPromptAndStore_outVar" "$getSecretViaSecretToolOrPromptAndStore_secret" |
| 85 | +} |
| 86 | + |
| 87 | +function getSecretViaSecretTool() { |
| 88 | + exitIfCommandDoesNotExist "secret-tool" "install it via 'sudo apt install libsecret-tools'" |
| 89 | + if (($# != 2)); then |
| 90 | + logError "getSecretViaSecretTool requires exactly 2 arguments, given \033[0;36m%s\033[0m\nFollowing a description of the parameters:\n" "$#" |
| 91 | + echo >&2 "1: group the group from which the secret shall be read -- referred to as attribute in secret-tool's documentation" |
| 92 | + echo >&2 "2: key the secret key -- referred to as value in the secret-tool's documentation" |
| 93 | + exit 1 |
| 94 | + fi |
| 95 | + secret-tool lookup "$1" "$2" |
| 96 | +} |
| 97 | + |
| 98 | +function storeSecretViaSecretTool() { |
| 99 | + exitIfCommandDoesNotExist "secret-tool" "install it via 'sudo apt install libsecret-tools'" |
| 100 | + if (($# != 3)) && (($# != 4)); then |
| 101 | + logError "storeSecretViaSecretTool requires either 3 or 4 arguments, given \033[0;36m%s\033[0m\nFollowing a description of the parameters:\n" "$#" |
| 102 | + echo >&2 "1: group the group from which the secret shall be read -- referred to as attribute in secret-tool's documentation" |
| 103 | + echo >&2 "2: key the secret key -- referred to as value in the secret-tool's documentation" |
| 104 | + echo >&2 '3: label the description of this key (will be shown e.g. in seahorse)' |
| 105 | + echo >&2 '4: secret the secret as such (or pass it via stdin)' |
| 106 | + exit 1 |
| 107 | + fi |
| 108 | + if (($# == 4)); then |
| 109 | + echo -n "$4" | secret-tool store --label="$3" "$1" "$2" |
| 110 | + else |
| 111 | + secret-tool store --label="$3" "$1" "$2" |
| 112 | + fi |
| 113 | +} |
| 114 | + |
| 115 | +function promptForSecret() { |
| 116 | + if (($# != 2)); then |
| 117 | + logError "promptForSecret requires exactly 2 arguments, given \033[0;36m%s\033[0m\nFollowing a description of the parameters:\n" "$#" |
| 118 | + echo >&2 '1: prompt the text used in the prompt' |
| 119 | + echo >&2 '2: outVar variable name to which the secret shall be assigned' |
| 120 | + echo "bla1" |
| 121 | + exit 1 |
| 122 | + fi |
| 123 | + |
| 124 | + exitIfVariablesNotDeclared "$2" |
| 125 | + |
| 126 | + # shellcheck disable=SC2059 # we want to be able to use newline in the $prompt, hence OK |
| 127 | + printf "$1" |
| 128 | + |
| 129 | + local promptForSecret_password='' |
| 130 | + |
| 131 | + while IFS= read -r -s -n 1 promptForSecret_char; do |
| 132 | + if [[ $promptForSecret_char == $'\0' || $promptForSecret_char == $'\n' ]]; then |
| 133 | + printf "break" |
| 134 | + break |
| 135 | + fi |
| 136 | + |
| 137 | + if [[ $promptForSecret_char == $'\177' ]]; then |
| 138 | + if [[ -n $promptForSecret_password ]]; then |
| 139 | + promptForSecret_password="${promptForSecret_password%?}" |
| 140 | + printf "\b \b" # move back, overwrite with space, move back again |
| 141 | + fi |
| 142 | + else |
| 143 | + promptForSecret_password+="$promptForSecret_char" |
| 144 | + printf "*" |
| 145 | + fi |
| 146 | + done |
| 147 | + |
| 148 | + printf "\n" |
| 149 | + |
| 150 | + if [[ -z $promptForSecret_password ]]; then |
| 151 | + die "looks like you pressed ENTER too early, secret was empty" |
| 152 | + fi |
| 153 | + assignToVariableInOuterScope "$2" "$promptForSecret_password" |
| 154 | +} |
0 commit comments