backup bash cli

This commit is contained in:
do butterflies cry? 2026-03-09 02:43:40 +10:00
parent ff0d13034b
commit 2f49295004
Signed by: cry
GPG key ID: F68745A836CA0412
7 changed files with 0 additions and 0 deletions

112
ceru.bak/subcmds/new/cache-key Executable file
View file

@ -0,0 +1,112 @@
#!/usr/bin/env bash
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
USAGE="${BOLD}${UNDERLINE}${RED}Usage${RESET}
${BOLD}${GREEN}$THIS new cache-key [option...]${RESET}
${BOLD}${UNDERLINE}${RED}Options${RESET}
${BOLD}${MAGENTA}-h, --help${RESET} Show this message (^_^)
${BOLD}${MAGENTA}-f, --force${RESET} Ignores all warnings!!
${BOLD}${MAGENTA}-j, --json${RESET} Output in JSON format
${BOLD}${MAGENTA}-n, --name${RESET} Identifier of the key (e.g. ${BOLD}${MAGENTA}cache.example.org-1${RESET})
${BOLD}${MAGENTA}-o, --out${RESET} Private key file name to write to (the public key is named identically but ends with ${BOLD}${MAGENTA}.pub${RESET})
${BOLD}${MAGENTA}-P, --private-only${RESET} Only generate the private key, not the entire keypair"
# ==== Argument Values ====
FORCE=false
PRIV_ONLY=false
JSON=false
NAME=""
SINK=""
# ==== Argument Values ====
# parse all args
while [[ $# -gt 0 ]]; do
ARG="$1"
case "$ARG" in
-h|--help)
throw-usage 0
;;
-n|--name)
shift
NAME="$1"; shift
;;
-P|--private-only)
shift
PRIV_ONLY=true
;;
-o|--out)
shift
SINK="$1"; shift
;;
-j|--json)
shift
JSON=true
;;
-f|--force)
shift
FORCE=true
;;
-*)
throw-badflag 1 "$ARG"
;;
*)
throw-badarg 1 "$ARG"
;;
esac
done; unset -v ARG
# fail if NAME not provided
required "$NAME" --name
# generate our keypair
PRIV_KEY=$(nix key generate-secret --key-name "$NAME")
PUB_KEY=$(nix key convert-secret-to-public <<<"$PRIV_KEY")
# result defaults to unset (only stays unset if we intend on writing to a file)
RESULT=""
# JSON formatting
if [[ "$JSON" = true ]]; then
RESULT="{
\"privateKey\": \"${PRIV_KEY}\"$(
[[ "$PRIV_ONLY" = true ]] \
|| echo ",\n \"publicKey\": \"${PUB_KEY}\"")
}"
if [[ -n "$SINK" ]]; then
# confirm the user understands files will be overwritten
[[ "$FORCE" = true ]] || confirm-file-overwrite "$SINK" || exit 0
echo -e "$RESULT" > "$SINK"
else
echo -e "$RESULT"
fi
# standard formatting (stdout)
elif [[ -z "$SINK" ]]; then
echo -e "${BOLD}${UNDERLINE}${RED}Private Key${RESET}
${BOLD}${GREEN}${PRIV_KEY}${RESET}$(
[[ "$PRIV_ONLY" = true ]] \
|| echo "\n${BOLD}${UNDERLINE}${RED}Public Key${RESET}\n ${BOLD}${GREEN}${PUB_KEY}${RESET}")"
# standard formatting (files)
else
PRIV_SINK="$SINK"
PUB_SINK="$SINK.pub"
# confirm the user understands files will be overwritten
[[ "$FORCE" = true ]] || confirm-file-overwrite "$PRIV_SINK" "$PUB_SINK" || exit 0
echo "$PRIV_KEY" > "$PRIV_SINK"
echo "$PUB_KEY" > "$PUB_SINK"
fi;
unset -v PRIV_SINK PUB_SINK PRIV_KEY PUB_KEY RESULT

52
ceru.bak/subcmds/new/default.sh Executable file
View file

@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
USAGE="${BOLD}${UNDERLINE}${RED}Usage${RESET}
${BOLD}${GREEN}$THIS new [option...] subcommand${RESET}
${BOLD}${UNDERLINE}${RED}Options${RESET}
${BOLD}${MAGENTA}-h, --help${RESET} Show this message (^_^)
${BOLD}${UNDERLINE}${RED}Subcommands${RESET}
${BOLD}${CYAN}cache-key${RESET} Generate a new binary-cache signing keypair
${BOLD}${CYAN}password${RESET} Generate a new hashed Unix user password
${BOLD}${CYAN}ssh-key${RESET} Generate a new SSH keypair
${BOLD}${CYAN}wg-key${RESET} Generate a new Wireguard keypair"
# parse all args
SUBCMD=false # where a subcommand was specified
while [[ $# -gt 0 ]]; do
ARG=$1
case $ARG in
-h|--help)
throw-usage 0 ;;
-*)
echo "[!] Unknown option \"$ARG\""
exit 1 ;;
*)
SUBCMD=true
break ;;
esac
done; unset -v ARG
# invalid usage occurs if no args or subcommand given
if [[ $# = 0 || "$SUBCMD" = false ]]; then
throw-usage 1
fi; unset -v SUBCMD
# run provided subcommand
run-subcmd "$@"

259
ceru.bak/subcmds/new/password Executable file
View file

@ -0,0 +1,259 @@
#!/usr/bin/env bash
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
USAGE="${BOLD}${UNDERLINE}${RED}Usage${RESET}
${BOLD}${GREEN}$THIS new password [option...]${RESET}
${BOLD}${UNDERLINE}${RED}Description${RESET}
Generates a new password hash in libxcrypt format with secure defaults.
For more advanced usage run the ${BOLD}${MAGENTA}\`mkpasswd\`${RESET} utility directly.
${BOLD}${UNDERLINE}${RED}Options${RESET}
${BOLD}${MAGENTA}-h, --help${RESET} Show this message (^_^)
${BOLD}${MAGENTA}-o, --out${RESET} Private key file name to write to (the public key is named identically but ends with ${BOLD}${CYAN}.pub${RESET})
${BOLD}${MAGENTA}-j, --json${RESET} Output in JSON format
${BOLD}${MAGENTA}-i, --stdin${RESET} Read the password to hash from stdin ${BOLD}$CYAN(single line only)${RESET}
${BOLD}${MAGENTA}-t, --type${RESET} The hash algorithm to use: ${BOLD}${MAGENTA}yescrypt, scrypt, bcrypt ${CYAN}(default: yescrypt)${RESET}
${BOLD}${MAGENTA}-r, --rounds${RESET} The number of KDF to apply ${BOLD}${MAGENTA}(format: ^[0-9]+\$) ${CYAN}(defaults: yescrypt=11, scrypt=10, bcrypt=14)${RESET}
${BOLD}${MAGENTA}-s, --salt${RESET} Specify the hash's salt directly ${BOLD}${RED}(not recommended)${RESET} ${BOLD}${CYAN}(default: libxcrypt secure default)${RESET}"
# ==== Argument Values ====
TYPE='yescrypt'
ROUNDS=''
SALTED=false
OUT=''
JSON=false
STDIN=false
EXTRA=''
# ==== Argument Values ====
# parse all args
while [[ $# -gt 0 ]]; do
ARG="$1"
case "$ARG" in
-h|--help)
throw-usage 0
;;
-o|--out)
shift
OUT="$1"; shift
;;
-j|--json)
shift
JSON=true
;;
-i|--stdin)
shift
STDIN=true
;;
-t|--type)
shift
# NOTE: ${1,,} is $1 in lowercase
TYPE="${1,,}"; shift
;;
-r|--rounds)
shift
ROUNDS="$1"; shift
;;
-s|--salt)
shift
if [[ "$SALTED" == false ]]; then
SALTED=true
EXTRA="$EXTRA --salt=\'$1\'"
fi
shift
;;
-*)
throw-badflag 1 "$ARG"
;;
*)
throw-badarg 1 "$ARG"
;;
esac
done; unset -v ARG
# NOTE: Available password hashing methods for /etc/passwd & /etc/shadow
# NOTE: Read the manual pages via `man 3 crypt` and `man 5 crypt` (if available)
# NOTE: Available online via https://man.archlinux.org/man/crypt.5
# WARNING: Due to modern developments in cryptography most of these methods
# WARNING: are no longer recommended however some distrobutions still use them.
# WARNING: Cerulean intentionally restricts access to only secure algorithms.
# $ mkpasswd -m help
## Available methods:
## yescrypt Yescrypt
## gost-yescrypt GOST Yescrypt
## scrypt scrypt
## bcrypt bcrypt
## bcrypt-a bcrypt (obsolete $2a$ version)
## sha512crypt SHA-512
## sha256crypt SHA-256
## sunmd5 SunMD5
## md5crypt MD5
## bsdicrypt BSDI extended DES-based crypt(3)
## descrypt standard 56 bit DES-based crypt(3)
## nt NT-Hash
function perr-unsupportedhash {
local ALGO="$1"
echo -e "${BOLD}${RED}The ${MAGENTA}$ALGO${RED} hash algorithm is unsupported!${RESET}" >&2
}
function perr-forbiddenhash {
local ALGO="$1"
echo -e "${BOLD}${CYAN}Cerulean${RED} intentionally forbids ${MAGENTA}$ALGO-based${RED} hashes.${RESET}" >&2
}
function perr-recommendhash {
local ALGO="$1"
echo -e "${BOLD}${CYAN}Cerulean${WHITE} recommends the ${MAGENTA}$ALGO${WHITE} algorithm ${GREEN}(embrace modernity loser)${RESET}" >&2
}
# ensure $TYPE is a valid hash algorithm
case "$TYPE" in
# ========= PERMITTED HASH ALGORITHMS =========
yescrypt)
if [[ -z "$ROUNDS" ]]; then
ROUNDS='11'
fi
;;
scrypt)
if [[ -z "$ROUNDS" ]]; then
ROUNDS='10'
fi
;;
bcrypt)
if [[ -z "$ROUNDS" ]]; then
ROUNDS='14'
fi
;;
# ========= FORBIDDEN HASH ALGORITHMS =========
gost-yescrypt)
perr-unsupportedhash "$TYPE"
perr-recommendhash 'yescrypt'
echo -e "${BOLD}${YELLOW}┏
┃ Dear Comrade,
┃ It is with a heavy heart I must inform you that \"GOST Algorithms
┃ Considered Harmful\" - Edsger Wybe Dijkstra (probably). Alas
┃ GOST is considered broken... It is no longer 1970, please grow up :(
┃ Слава Родине! - Glory to the Motherland!
┗${RESET}" >&2
exit 1
;;
bcrypt-a)
perr-unsupportedhash "$TYPE"
perr-recommendhash 'bcrypt'
echo -e "${BOLD}${YELLOW}┏
┃ The alternative prefix \"\$2y$\" is equivalent to \"\$2b$\".
┃ It exists for historical reasons only. The alternative prefixes
┃ \"\$2a$\" and \"\$2x$\" provide bug-compatibility with
┃ crypt_blowfish 1.0.4 and earlier, which incorrectly processed
┃ characters with the 8th bit set.
┗${RESET}" >&2
exit 1
;;
sha512crypt|sha256crypt)
perr-unsupportedhash "$TYPE"
perr-forbiddenhash 'SHA'
echo -e "${BOLD}${YELLOW}┏
┃ SHA-based hashes are considered outdated and generally insecure
┃ due to their vulnerabilit to brute-force and collision attacks.
┃ Modern algorithms such as yescrypt, scrypt, and bcrypt are recommended.
┗${RESET}" >&2
exit 1
;;
sunmd5|md5crypt)
perr-unsupportedhash "$TYPE"
perr-forbiddenhash 'MD5'
echo -e "${BOLD}${YELLOW}┏
┃ Not as weak as the DES-based hashes, but MD5 is so cheap
┃ on modern hardware that it should not be used for new hashes.
┗${RESET}" >&2
exit 1
;;
bsdicrypt|descrypt)
perr-unsupportedhash "$TYPE"
perr-forbiddenhash 'DES'
echo -e "${BOLD}${YELLOW}┏
┃ The DES block cipher is cheap on modern hardware. Because there are only
┃ 4096 possible salts and 2**56 distinct passphrases, which it
┃ truncates to 8 characters, it is feasible to discover any passphrase
┃ hashed with this method. It should only be used if you absolutely have to
┃ generate hashes that will work on an old operating system that supports nothing else.
┗${RESET}" >&2
exit 1
;;
nt)
perr-unsupportedhash "$TYPE"
echo -e "${BOLD}Please ${RED}repent${WHITE} for your filthy sins ${RED}you disgusting human...${RESET}" >&2
echo -e "${BOLD}${YELLOW}┏
┃ Available for cross-compatibility's sake on FreeBSD. Based on MD4.
┃ Has no salt or tunable cost parameter. It is so weak that
┃ almost any human-chosen passphrase hashed with this method is guessable.
┃ It should only be used if you absolutely have to generate hashes that
┃ will work on an old operating system that supports nothing else.
┗${RESET}" >&2
exit 1
;;
*)
echo -e "${BOLD}${RED}Unrecognised hash algorithm ${MAGENTA}\"$TYPE\"${RESET}" >&2
echo -e "${BOLD}${GREEN}Supported algorithms: ${MAGENTA}yescrypt, scrypt, bcrypt${RESET}" >&2
exit 1
;;
esac
unset -f perr-unsupportedhash perr-forbiddenhash perr-recommendhash
# ensure $ROUNDS is a valid numeric
if ! isnumeric "$ROUNDS"; then
throw-badval 1 "$ROUNDS" '-r|--rounds'
fi
# Acquire password from stdin
if [[ "$STDIN" == true ]]; then
read -s PASS
else
read -sp "$(echo -e "${BOLD}${GREEN}Password:${RESET} ")" PASS
echo # \n
read -sp "$(echo -e "${BOLD}${GREEN}Retype Password:${RESET} ")" PASS2
echo # \n
if [[ "$PASS" != "$PASS2" ]]; then
echo -e "${BOLD}${RED}Sorry, passwords do not match${RESET}" >&2
exit 1
fi
unset -v PASS2
fi
# Compute hash of password
RESULT=$(mkpasswd -sm "$TYPE" -R "$ROUNDS" $EXTRA <<<"$PASS")
unset -v PASS
# Format as JSON if necessary
if [[ "$JSON" == true ]]; then
RESULT="{
\"type\": \"${TYPE}\",
\"rounds\": ${ROUNDS},
\"hash\": \"${RESULT}\"
}"
fi
# Display hash result
if [[ -n "$OUT" ]]; then
echo "$RESULT" > "$OUT"
elif [[ "$JSON" == true ]]; then
echo "$RESULT"
else
echo -e "${BOLD}${GREEN}Hash:${WHITE} $RESULT${RESET}"
fi
unset -v RESULT
unset -v TYPE ROUNDS SALTED OUT JSON STDIN EXTRA

182
ceru.bak/subcmds/new/ssh-key Executable file
View file

@ -0,0 +1,182 @@
#!/usr/bin/env bash
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
# ===== CONFIGURATION =====
DEFAULT_TYPE='ecdsa'
DEFAULT_ROUNDS='100'
DEFAULT_BITS_ECDSA='521'
DEFAULT_BITS_RSA='4096'
DEFAULT_BITS_ED25519='NULL'
# ===== CONFIGURATION =====
USAGE="${BOLD}${UNDERLINE}${RED}Usage${RESET}
${BOLD}${GREEN}$THIS new ssh-key [option...]${RESET}
${BOLD}${UNDERLINE}${RED}Description${RESET}
Generates a new SSH keypair with secure defaults.
For more advanced usage run the ${BOLD}${MAGENTA}\`ssh-keygen\`${RESET} utility directly.
${BOLD}${UNDERLINE}${RED}Key Sizes${RESET}
Key sizes are specified in bits via the ${BOLD}${MAGENTA}-b|--bits${RESET} flag.
• ${BOLD}${CYAN}ECDSA keys${RESET} can only operate on elliptic curves of size: ${BOLD}${CYAN}256, 384, or 521 bits${RESET}
• ${BOLD}${CYAN}Ed25519 keys${RESET} have a ${BOLD}${MAGENTA}fixed length${RESET} so the key size is ignored
• ${BOLD}${CYAN}RSA keys${RESET} have been intentionally restricted to: ${BOLD}${CYAN}2048, 3072, 4096, or 8192 bits${RESET}
${BOLD}${UNDERLINE}${RED}Options${RESET}
${BOLD}${MAGENTA}-h, --help${RESET} Show this message (^_^)
${BOLD}${MAGENTA}-o, --out${RESET} Private key file name to write to (the public key is named identically but ends with ${BOLD}${MAGENTA}.pub${RESET})
${BOLD}${MAGENTA}-c, --comment${RESET} A comment or email address to write on the key
${BOLD}${MAGENTA}-t, --type${RESET} The cryptographic algorithm to use: ${BOLD}${MAGENTA}ecdsa, ed25519, rsa${RESET} ${BOLD}${CYAN}(default: $DEFAULT_TYPE)${RESET}
${BOLD}${MAGENTA}-r, --rounds${RESET} The number of KDF rounds to apply ${BOLD}${CYAN}(default: $DEFAULT_ROUNDS)${RESET}
${BOLD}${MAGENTA}-b, --bits${RESET} The key size in bits ${BOLD}${MAGENTA}(see \"Key Sizes\" above) ${CYAN}(defaults: ecdsa=$DEFAULT_BITS_ECDSA, rsa=$DEFAULT_BITS_RSA, ed25519=$DEFAULT_BITS_ED25519)${RESET}
${BOLD}${MAGENTA}-N, --nopasswd${RESET} Do not encrypt the private key with a password
${BOLD}${MAGENTA}-H, --hardware-key${RESET} Enable the use of a secure hardware key peripheral device (ie YubiKey)"
# ==== Argument Values ====
TYPE="$DEFAULT_TYPE"
ROUNDS="$DEFAULT_ROUNDS"
BITS=''
COMMENT=''
OUT=''
NOPASSWD=''
HWKEY=false
# ==== Argument Values ====
# parse all args
while [[ $# -gt 0 ]]; do
ARG="$1"
case "$ARG" in
-h|--help)
throw-usage 0
;;
-o|--out)
shift
OUT="$1"; shift
;;
-c|--comment)
shift
COMMENT="$1"; shift
;;
-t|--type)
shift
# NOTE: ${1,,} is $1 in lowercase
TYPE="${1,,}"; shift
;;
-r|--rounds)
shift
ROUNDS="$1"; shift
;;
-b|--bits)
shift
BITS="$1"; shift
;;
-N|--nopasswd)
shift
NOPASSWD="-N ''"
;;
-H|--hardware-key)
shift
HWKEY=true
;;
-*)
throw-badflag 1 "$ARG"
;;
*)
throw-badarg 1 "$ARG"
;;
esac
done; unset -v ARG
# ensure $ROUNDS is a valid numeric
if ! isnumeric "$ROUNDS"; then
throw-badval 1 "$ROUNDS" '-r|--rounds'
fi
case "$TYPE" in
ecdsa)
if [[ -z "$BITS" ]]; then
BITS='521'
else
# NOTE: ECDSA keys can only operate on elliptic curves
# NOTE: of sizes: 256, 384 or 521 bits
case "$BITS" in
256|384|512) true
;;
*)
throw-badval 1 "$BITS" '-b|--bits'
;;
esac
fi
;;
ed25519)
# NOTE: the value of BITS does not matter for Ed25519
# NOTE: as it operates on a fixed size elliptic curve
if [[ -z "$BITS" ]]; then
BITS='256'
fi
;;
rsa)
if [[ -z "$BITS" ]]; then
BITS='4096'
else
case "$BITS" in
2048)
echo -e "${BOLD}${UNDERLINE}${YELLOW}WARNING${RESET}${BOLD}: Although ${MAGENTA}2048-bit RSA keys${YELLOW} are considered secure,${RESET}" >&2
echo -e "${BOLD}${UNDERLINE}${YELLOW}WARNING${RESET}${BOLD}: it is the growing opinion that these will not be soon.${RESET}" >&2
echo -e "${BOLD}${UNDERLINE}${YELLOW}WARNING${RESET}${BOLD}: ${GREEN}Consider using a minimum of ${MAGENTA}3072-bit${YELLOW}, or ideally ${MAGENTA}4096-bit.${RESET}" >&2
;;
3072|4096|8192) true
;;
*)
throw-badval 1 "$BITS" '-b|--bits'
;;
esac
fi
;;
*)
throw-badval 1 "$TYPE" '-t|--type'
;;
esac
if ! isnumeric "$BITS"; then
throw-badval 1 "$BITS" '-b|--bits'
fi
if [[ "$HWKEY" == true ]]; then
if [[ "$TYPE" == "rsa" ]]; then
echo -e "${BOLD}${MAGENTA}-H|--hardware-key${RESET} flag is not valid for ${BOLD}${MAGENTA}RSA keys${RESET} ${BOLD}${CYAN}(use Ed25519 instead)${RESET}"
exit 1
fi
TYPE="$TYPE-sk"
fi
if [[ -z "$OUT" ]]; then
# fallback to ssh-keygen's default file (for chmod later)
OUT="$HOME/.ssh/id_$TYPE"
fi
# permit error during key generation
set +e
echo -e "${BOLD}${GREEN}[+] ssh-keygen -t $TYPE -a$ROUNDS -b$BITS -C '$COMMENT' -f '$OUT' $NOPASSWD${RESET}"
ssh-keygen -t $TYPE -a "$ROUNDS" -b "$BITS" -C "$COMMENT" -f "$OUT" $NOPASSWD
chmod 600 $OUT
chmod 644 $OUT.pub
# reset state
set -e
unset TYPE ROUNDS BITS COMMENT OUT NOPASSWD HWKEY \
DEFAULT_TYPE DEFAULT_ROUNDS DEFAULT_BITS_ECDSA DEFAULT_BITS_RSA DEFAULT_BITS_ED25519

96
ceru.bak/subcmds/new/wg-key Executable file
View file

@ -0,0 +1,96 @@
#!/usr/bin/env bash
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
USAGE="${BOLD}${UNDERLINE}${RED}Usage${RESET}
${BOLD}${GREEN}$THIS new cache-key [option...]${RESET}
${BOLD}${UNDERLINE}${RED}Options${RESET}
${BOLD}${MAGENTA}-h, --help${RESET} Show this message (^_^)
${BOLD}${MAGENTA}-o, --out${RESET} Private key file name to write to (the public key is named identically but ends with ${BOLD}${MAGENTA}.pub${RESET})
${BOLD}${MAGENTA}-j, --json${RESET} Output in JSON format
${BOLD}${MAGENTA}-f, --force${RESET} Ignores all warnings!!"
# ==== Argument Values ====
OUT=''
JSON=false
FORCE=false
# ==== Argument Values ====
# parse all args
while [[ $# -gt 0 ]]; do
ARG="$1"
case "$ARG" in
-h|--help)
throw-usage 0
;;
-o|--out)
shift
OUT="$1"; shift
;;
-j|--json)
shift
JSON=true
;;
-f|--force)
shift
FORCE=true
;;
-*)
throw-badflag 1 "$ARG"
;;
*)
throw-badarg 1 "$ARG"
;;
esac
done; unset -v ARG
# generate our keypair
PRIV_KEY=$(wg genkey)
PUB_KEY=$(wg pubkey <<<"$PRIV_KEY")
# NOTE: same logic as `subcmds/new/cache-key`
# result defaults to unset (only stays unset if we intend on writing to a file)
RESULT=""
# JSON formatting
if [[ "$JSON" = true ]]; then
RESULT="{
\"privateKey\": \"${PRIV_KEY}\"
\"publicKey\": \"${PUB_KEY}\"
}"
if [[ -n "$OUT" ]]; then
# confirm the user understands files will be overwritten
[[ "$FORCE" = true ]] || confirm-file-overwrite "$OUT" || exit 0
echo -e "$RESULT" > "$OUT"
else
echo -e "$RESULT"
fi
# standard formatting (stdout)
elif [[ -z "$OUT" ]]; then
echo -e "${BOLD}${UNDERLINE}${RED}Private Key${RESET}
${BOLD}${GREEN}${PRIV_KEY}${RESET}
${BOLD}${UNDERLINE}${RED}Public Key${RESET}
${BOLD}${GREEN}${PUB_KEY}${RESET}"
# standard formatting (files)
else
# confirm the user understands files will be overwritten
[[ "$FORCE" = true ]] || confirm-file-overwrite "$OUT" "$OUT.pub" || exit 0
echo "$PRIV_KEY" > "$OUT"
echo "$PUB_KEY" > "$OUT.pub"
fi;
unset -v OUT PRIV_KEY PUB_KEY RESULT