utils/bash/sources/16_keystore

497 lines
12 KiB
Plaintext
Raw Permalink Normal View History

2022-08-13 15:40:12 +00:00
#!/bin/bash
_SQLITE=$( which sqlite3 2>&1 )
if [ $? -ne 0 ]; then
echo "sqlite3 is missing" >&2
return 1
fi
echo "test" | openssl enc -e -aes-256-cbc -pbkdf2 -k test 2>/dev/null > /dev/null
if [ $? -ne 0 ]; then
echo "openssl does not exists nor support pbkdf2" >&2
return 1
fi
_AUTH_DB=$RBASH_HOME/keystore.db
_AUTH_SECRET=
_KSTORE_DEF_PROP=${_KSTORE_DEF_PROP:-val}
2024-07-10 23:22:43 +00:00
_KSTORE_DEC_FAILED="$RBASH_HOME/.decypt-failed"
2024-11-10 22:28:53 +00:00
_KSTORE_TABLE=store
2022-08-13 15:40:12 +00:00
if [ -f "$RBASH_HOME/keystore.secret" ]; then
_AUTH_SECRET=$( cat "$RBASH_HOME/keystore.secret" )
fi
2024-07-10 23:22:43 +00:00
2022-08-13 15:40:12 +00:00
function kstore {
case $1 in
2023-10-13 12:15:41 +00:00
add) shift; _kstoreadd "$@" ;;
del) shift; _kstoredel "$@" ;;
get) shift; _kstoreget "$@" ;;
list) shift; _kstorelist "$@" ;;
query) shift; _kstorequery "$@" ;;
update) shift; _kstoreupdate "$@" ;;
search) shift; _kstoresearch $@ ;;
secret) shift; _kstoresecret $@ ;;
2022-08-13 15:40:12 +00:00
*)
2022-08-13 17:47:12 +00:00
__func_head "add [key] [value|file|-] [prop, default: $_KSTORE_DEF_PROP]"
__func_help "update [key] [value|file|-] [prop, default: $_KSTORE_DEF_PROP]"
2022-08-13 18:01:33 +00:00
__func_help "get [key] [prop, default: $_KSTORE_DEF_PROP]"
2023-10-08 18:37:42 +00:00
__func_help "del [key] [prop, default: $_KSTORE_DEF_PROP]"
2022-08-13 15:40:12 +00:00
__func_help "list"
2022-08-13 18:01:33 +00:00
__func_help "search [key] [prop]"
2022-08-13 17:47:12 +00:00
__func_help "secret ..."
2022-08-15 13:21:53 +00:00
__func_help "upload s3-compatible-provider-name"
2022-08-13 15:40:12 +00:00
__func_help "query SQL"
return 1
;;
esac
return $?
}
2023-10-13 12:43:09 +00:00
function _kstore {
local CUR=${COMP_WORDS[COMP_CWORD]}
local SCOPE=${COMP_WORDS[COMP_CWORD-1]}
local t
COMPREPLY=()
case "$SCOPE" in
kstore)
COMPREPLY=( $(compgen -W "add del get list query update search secret" -- $CUR) )
return
;;
get|update)
2024-11-10 22:28:53 +00:00
COMPREPLY=( $(compgen -W "$( _kstorequery "SELECT DISTINCT key FROM $_KSTORE_TABLE" )" -- $CUR) )
2023-10-13 12:43:09 +00:00
;;
esac
t=${COMP_WORDS[COMP_CWORD-2]}
case "$t" in
get|update)
t=`_kstorequote "$SCOPE"`
2024-11-10 22:28:53 +00:00
COMPREPLY=( $(compgen -W "$( _kstorequery "SELECT DISTINCT prop FROM $_KSTORE_TABLE WHERE key = '$t'" )" -- $CUR) )
2023-10-13 12:43:09 +00:00
;;
esac
}
complete -F _kstore kstore
2023-10-13 12:15:41 +00:00
function _kstoresecret {
2022-08-13 15:40:12 +00:00
case "$1" in
2023-10-13 12:15:41 +00:00
clear) shift; _kstoresecret-clear "$@" ;;
config) shift; _kstoresecret-config "$@" ;;
change) shift; _kstoresecret-change "$@" ;;
2022-08-13 15:40:12 +00:00
*)
__func_head "clear"
__func_help "config"
2022-08-13 17:47:12 +00:00
__func_help "change"
2022-08-13 15:40:12 +00:00
;;
esac
}
2023-10-13 12:15:41 +00:00
function _kstoreinit {
if [ ! -f "$_AUTH_DB" ]; then
cat <<___SQL___ | $_SQLITE "$_AUTH_DB"
2024-11-10 22:28:53 +00:00
CREATE TABLE IF NOT EXISTS $_KSTORE_TABLE (
2022-08-13 16:52:26 +00:00
key TEXT NOT NULL
2022-08-13 15:40:12 +00:00
, prop TEXT NOT NULL
, data TEXT
2022-08-13 15:40:12 +00:00
, PRIMARY KEY( key ASC, prop ASC )
);
___SQL___
chmod 600 "$_AUTH_DB"
fi
2022-08-13 15:40:12 +00:00
kstore secret config
}
2023-10-13 12:15:41 +00:00
function _kstorequote {
2022-08-13 15:40:12 +00:00
echo -n "$1" | sed -e "s/'/''/g"
}
2023-10-13 12:15:41 +00:00
function _kstoreenc {
2022-08-13 15:40:12 +00:00
if [ -z "$_AUTH_SECRET" ]; then
echo "Secret key is not set yet" >&2
return 1
fi
if [ "$1" == "-" ]; then
openssl enc -e -aes-256-cbc -pbkdf2 -k "$_AUTH_SECRET" -a -A
elif [ -f "$1" ]; then
openssl enc -e -aes-256-cbc -pbkdf2 -k "$_AUTH_SECRET" -a -A -in "$1"
else
echo -n "$1" | openssl enc -e -aes-256-cbc -pbkdf2 -k "$_AUTH_SECRET" -a -A
fi
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoredec {
2022-08-13 15:40:12 +00:00
if [ -z "$_AUTH_SECRET" ]; then
echo "Secret key is not set yet" >&2
return 1
fi
openssl enc -d -aes-256-cbc -pbkdf2 -k "$_AUTH_SECRET" -a -A
2024-07-10 22:54:47 +00:00
_code=$?
if [ $_code -ne 0 ]; then
2024-07-10 23:22:43 +00:00
touch $_KSTORE_DEC_FAILED
2024-07-10 22:54:47 +00:00
return $_code
fi
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-auto {
2022-08-13 17:47:12 +00:00
case $OSTYPE in
2023-10-13 12:15:41 +00:00
darwin*) _kstoresecret-macos "$@" ;;
cygwin) _kstoresecret-cygwin "$@" ;;
2022-08-13 17:47:12 +00:00
*)
echo "$OSTYPE is Not supported yet" >&2
;;
esac
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-cygwin {
2023-10-08 20:00:21 +00:00
local _A
which kstorecred 2>/dev/null > /dev/null
if [ $? -ne 0 ]; then
2023-10-13 12:15:41 +00:00
_kstoredl-kstorecred
2023-10-08 20:00:21 +00:00
fi
case $1 in
get)
_A=$( kstorecred get )
if [ $? -ne 0 ]; then
return 1
fi
_AUTH_SECRET="$_A"
;;
set)
kstorecred set "$_AUTH_SECRET"
;;
del)
kstorecred del
;;
*)
echo "Unknown action: $1" >&2
return 1
;;
esac
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-macos {
2022-08-13 15:40:12 +00:00
local _A
case $1 in
get)
_A=`security find-generic-password -a default -gs rbash-kstore 2>&1 | grep ^password | cut -c 11-`
if [ $? -ne 0 ]; then
return 1
fi
_AUTH_SECRET="${_A:1:-1}"
;;
set)
security add-generic-password -a default -s rbash-kstore -w "$_AUTH_SECRET"
;;
2022-08-13 17:47:12 +00:00
del)
security delete-generic-password -a default -s rbash-kstore
;;
2022-08-13 15:40:12 +00:00
*)
echo "Unknown action: $1" >&2
return 1
;;
esac
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-config {
2022-08-13 15:40:12 +00:00
local _CONFIRM
2024-07-10 23:22:43 +00:00
if [ -f "$_KSTORE_DEC_FAILED" ]; then
rm $_KSTORE_DEC_FAILED
_AUTH_SECRET=
fi
2022-08-13 15:40:12 +00:00
if [ -z "$_AUTH_SECRET" ]; then
2023-10-13 12:15:41 +00:00
_kstoresecret-auto get
2022-08-13 15:40:12 +00:00
if [ -n "$_AUTH_SECRET" ]; then
return 0
fi
read -sp "Enter passphrase: " _AUTH_SECRET
echo
if [ -z "$_AUTH_SECRET" ]; then
echo "Passphrase cannot be empty" >&2
return 1
fi
case $OSTYPE in
cygwin|darwin*)
read -p "Save this password to OS's keystore? (y/n): " _CONFIRM
if [ "$_CONFIRM" != "y" ]; then
return 0
fi
_kstoresecret-auto set
;;
esac
2022-08-13 17:47:12 +00:00
fi
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-change {
_kstoresecret-config
2022-08-13 17:47:12 +00:00
local _NEW_SECRET i _key _prop _O_SECRET _BAK
read -sp "Enter the new passphrase: " _NEW_SECRET
echo
read -sp "Enter the passphrase again: " i
echo
if [ "$i" != "$_NEW_SECRET" ]; then
echo "Passphrase mismatched" >&2
return 1
2022-08-13 15:40:12 +00:00
fi
2022-08-13 17:47:12 +00:00
_BAK=$( mktemp )
cp "$_AUTH_DB" "$_BAK"
echo "Backed up at $_BAK"
_O_SECRET="$_AUTH_SECRET"
2024-11-10 22:28:53 +00:00
for i in `$_SQLITE -list "$_AUTH_DB" "SELECT _ROWID_ FROM $_KSTORE_TABLE;"`; do
2022-08-13 17:47:12 +00:00
_AUTH_SECRET=$_O_SECRET
2024-11-10 22:28:53 +00:00
_key=`$_SQLITE -list "$_AUTH_DB" "SELECT key FROM $_KSTORE_TABLE WHERE _ROWID_ = $i;"`
2023-10-13 12:15:41 +00:00
_key=`_kstorequote "$_key"`
2024-11-10 22:28:53 +00:00
_prop=`$_SQLITE -list "$_AUTH_DB" "SELECT prop FROM $_KSTORE_TABLE WHERE _ROWID_ = $i;"`
2023-10-13 12:15:41 +00:00
_prop=`_kstorequote "$_prop"`
2022-08-13 17:47:12 +00:00
_val=`kstore get "$_key" "$_prop"`
if [ $? -ne 0 ]; then
echo "Current passphrase is incorrect?" >&2
return 1
fi
_AUTH_SECRET=$_NEW_SECRET
echo Updating: [$_key] [$_prop]
kstore update "$_key" "$_val" "$_prop"
done
2023-10-13 12:15:41 +00:00
_kstoresecret-auto get
2022-08-13 17:47:12 +00:00
if [ -n "$_AUTH_SECRET" ]; then
2023-10-13 12:15:41 +00:00
_kstoresecret-auto del 2>&1 > /dev/null
2022-08-13 17:47:12 +00:00
_AUTH_SECRET=$_NEW_SECRET
2023-10-13 12:15:41 +00:00
_kstoresecret-auto set
2022-08-13 17:47:12 +00:00
if [ $? -eq 0 ]; then
echo "New passphrase saved in OS's keystore."
fi
fi
_AUTH_SECRET=$_NEW_SECRET
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoresecret-clear {
2023-10-08 20:00:21 +00:00
unset _AUTH_SECRET
2023-10-13 12:15:41 +00:00
_kstoresecret-auto del
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoreupdate {
2023-10-08 18:37:42 +00:00
if [ -z "$1" ]; then
__func_head "[key] [value|file|-] [prop, default: $_KSTORE_DEF_PROP]"
return 1
fi
2023-10-13 12:15:41 +00:00
_kstoreinit || return 1
2022-08-13 15:40:12 +00:00
local _key _val _prop
2023-10-13 12:15:41 +00:00
_key=`_kstorequote "$1"`
_val=`_kstoreenc "$2"`
_val=`_kstorequote "$_val"`
_prop=`_kstorequote "${3:-$_KSTORE_DEF_PROP}"`
2022-08-13 15:40:12 +00:00
_cond="key = '$_key' AND prop = '$_prop'"
2024-11-10 22:28:53 +00:00
$_SQLITE "$_AUTH_DB" "UPDATE $_KSTORE_TABLE SET data = '$_val' WHERE $_cond;"
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoreadd {
2023-10-08 18:37:42 +00:00
if [ -z "$1" ]; then
__func_head "[key] [value|file|-] [prop, default: $_KSTORE_DEF_PROP]"
return 1
fi
2023-10-13 12:15:41 +00:00
_kstoreinit || return 1
2022-08-13 15:40:12 +00:00
local _key _val _prop
2023-10-13 12:15:41 +00:00
_key=`_kstorequote "$1"`
_val=`_kstoreenc "$2"`
_val=`_kstorequote "$_val"`
_prop=`_kstorequote "${3:-$_KSTORE_DEF_PROP}"`
2023-10-08 18:37:42 +00:00
$_SQLITE "$_AUTH_DB" \
2024-11-10 22:28:53 +00:00
"INSERT INTO $_KSTORE_TABLE ( key, prop, data )
VALUES( '$_key', '$_prop', '$_val' );"
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoreget {
2023-10-08 18:37:42 +00:00
if [ -z "$1" ]; then
__func_head "[key] [prop, default: $_KSTORE_DEF_PROP]"
return 1
fi
2023-10-13 12:15:41 +00:00
_kstoreinit || return 1
2022-08-13 15:40:12 +00:00
local _key _prop _cond
2023-10-13 12:15:41 +00:00
_key=`_kstorequote "$1"`
_prop=`_kstorequote "${2:-$_KSTORE_DEF_PROP}"`
2022-08-13 15:40:12 +00:00
_cond="key = '$_key' AND prop = '$_prop'"
2024-11-10 22:28:53 +00:00
$_SQLITE "$_AUTH_DB" "SELECT 1111 FROM $_KSTORE_TABLE WHERE $_cond;" | grep -q 1111
if [ $? -eq 0 ]; then
2024-11-10 22:28:53 +00:00
$_SQLITE -list "$_AUTH_DB" "SELECT ( data ) FROM $_KSTORE_TABLE WHERE $_cond;" | _kstoredec
else
2023-10-08 18:37:42 +00:00
echo "\"$1\" not found (prop: $_prop)" >&2
2023-09-23 15:11:09 +00:00
return 1
fi
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoredel {
2023-10-08 18:37:42 +00:00
if [ -z "$1" ]; then
__func_head "[key] [prop, default: $_KSTORE_DEF_PROP]"
return 1
fi
2023-10-13 12:15:41 +00:00
_kstoreinit || return 1
2022-08-13 15:40:12 +00:00
local _CONFIRM _key _prop _cond
2023-10-13 12:15:41 +00:00
_key=`_kstorequote "$1"`
_prop=`_kstorequote "${2:-$_KSTORE_DEF_PROP}"`
2022-08-13 15:40:12 +00:00
_cond="key = '$_key' AND prop = '$_prop'"
2024-11-10 22:28:53 +00:00
$_SQLITE "$_AUTH_DB" "SELECT 1111 FROM $_KSTORE_TABLE WHERE $_cond;" | grep -q 1111
2022-08-13 15:40:12 +00:00
if [ $? -eq 0 ]; then
2024-11-10 22:28:53 +00:00
$_SQLITE "$_AUTH_DB" "SELECT * FROM $_KSTORE_TABLE WHERE $_cond;"
2022-08-13 15:40:12 +00:00
echo
read -p "Delete this entry (yes/no)? " _CONFIRM
if [ "$_CONFIRM" == "yes" ]; then
2024-11-10 22:28:53 +00:00
$_SQLITE "$_AUTH_DB" "DELETE FROM $_KSTORE_TABLE WHERE $_cond;"
2022-08-13 15:40:12 +00:00
if [ $? -eq 0 ]; then
echo "deleted"
fi
else
echo "action canceled"
fi
else
2023-10-08 18:37:42 +00:00
echo "\"$1\" not found (prop: $_prop)" >&2
2022-08-13 15:40:12 +00:00
fi
}
2023-10-13 12:15:41 +00:00
function _kstoredl-s3au {
2023-09-17 14:34:40 +00:00
local p tmp _NAME
2022-08-15 14:32:16 +00:00
p="https://git.k8s.astropenguin.net/penguin/s3-arch-utils/raw/branch/master"
2023-10-07 17:42:47 +00:00
_CSUM=$1
_NAME=$2
2022-08-15 14:32:16 +00:00
2023-10-07 17:51:13 +00:00
tmp=$( mktemp )
__download "$p/$_NAME" > $tmp
sha256sum $tmp | grep -q "$_CSUM"
if [ $? -eq 0 ]; then
_NAME=$( basename "${_NAME//_/-}" .sh )
mv $tmp "$RBASH_BIN/$_NAME"
chmod +x "$RBASH_BIN/$_NAME"
echo "> $RBASH_BIN/$_NAME"
else
echo "$_NAME: Signature mismatch"
return 1
2022-08-15 14:32:16 +00:00
fi
}
2023-10-13 12:15:41 +00:00
function _kstoredl-kstorecred {
2023-10-08 20:00:21 +00:00
local p tmp _NAME
_NAME="kstorecred"
p="https://penguins-workspace.s3.ap-southeast-1.astropenguin.net/keystore/kstorecred.exe"
_CSUM="031b4474b8eb8deafbb96df73b79f8b654fd3c2209f041fd34cb6f494791bcd4"
tmp=$( mktemp )
__download "$p" > $tmp
sha256sum $tmp | grep -q "$_CSUM"
if [ $? -eq 0 ]; then
mv $tmp "$RBASH_BIN/$_NAME"
chmod +x "$RBASH_BIN/$_NAME"
echo "> $RBASH_BIN/$_NAME"
else
echo "$_NAME: Signature mismatch"
return 1
fi
}
2023-10-13 12:15:41 +00:00
function _kstoreinit-s3au {
_kstoredl-s3au "574d106cdced150fa6e04a9437d356d8688035cb2c63a045fa0d4ead8b3ec941" "arch_delete_aws4.sh" || return 1
_kstoredl-s3au "ce04b3f90b7d9a2578587c8ff841186810d977545943fb4a8234a6d6e9f7b568" "arch_delete_many_aws4.sh" || return 1
_kstoredl-s3au "31709a639fab27b5ba071dd4c843fd3e90d4cea07bbb055c08c9720d31a8d11d" "arch_download_aws4.sh" || return 1
_kstoredl-s3au "0bee6f925a41f496f66654062b49ea2a1cc55d877f4617d56bf91244aaf0be51" "arch_getacl_aws4.sh" || return 1
_kstoredl-s3au "dcb89894e78351af702fabb521cf1cf6ca512db9cd4cf3c70631bb1e51ab9340" "arch_list_aws4.sh" || return 1
_kstoredl-s3au "759ef3841525ce240d00e03578c39533c30bf246d61c12c2f3ba2ab37c5f814e" "arch_upload_aws4.sh" || return 1
2023-10-08 18:28:27 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoreupload-db {
2023-10-08 18:28:27 +00:00
local _T _W
2023-10-13 12:15:41 +00:00
_kstoreinit || return 1
2023-10-08 18:28:27 +00:00
_T=$( date +%Y%m%d%H%M%S )
echo $_T > "$RBASH_HOME/keystore.latest"
2023-10-08 18:39:12 +00:00
which arch-upload-aws4 2>&1 > /dev/null
2023-10-08 18:28:27 +00:00
if [ $? -ne 0 ]; then
2023-10-13 12:15:41 +00:00
_kstoreinit-s3au
2023-10-08 18:28:27 +00:00
fi
2023-10-13 12:15:41 +00:00
_kstoreenc $_AUTH_DB > "$RBASH_HOME/$_T.enc"
2023-10-08 18:28:27 +00:00
arch-upload-aws4 "keystore/$_T.enc" "$RBASH_HOME/$_T.enc"
arch-upload-aws4 "keystore/latest" "$RBASH_HOME/keystore.latest"
rm "$RBASH_HOME/$_T.enc"
rm "$RBASH_HOME/keystore.latest"
}
2023-10-13 12:15:41 +00:00
function _kstoredownload-db {
2023-10-08 18:28:27 +00:00
local _T _DOMAIN _URL _TMP _CONFIRM
kstore secret config || return 1
_DOMAIN="penguins-workspace.s3.ap-southeast-1.astropenguin.net"
2023-10-08 20:00:21 +00:00
_T=$( __download "https://$_DOMAIN/keystore/latest" )
2023-10-08 18:28:27 +00:00
if [ $? -ne 0 ]; then
return 1
fi
_TMP=$( mktemp )
2023-10-13 12:15:41 +00:00
__download "https://$_DOMAIN/keystore/$_T.enc" | _kstoredec > $_TMP
2023-10-08 18:28:27 +00:00
if [ $? -ne 0 ]; then
return 1
fi
2024-11-10 22:28:53 +00:00
_T=$( $_SQLITE "$_TMP" "SELECT COUNT( * ) FROM $_KSTORE_TABLE" )
2023-10-08 18:28:27 +00:00
if [ $? -ne 0 ]; then
return 1
fi
if [ -f "$_AUTH_DB" ]; then
read -p "Replace existing db? (yes/no): " _CONFIRM
if [ "$_CONFIRM" == "yes" ]; then
_T="$_AUTH_DB.old.$( date +%Y%m%d%H%M%S )"
mv "$_AUTH_DB" "$_T"
mv $_TMP $_AUTH_DB
echo "Original copy: $_T"
else
echo "action canceled"
rm $_TMP
fi
else
mv $_TMP $_AUTH_DB
fi
2022-08-15 14:32:16 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstoresearch {
2022-08-13 18:01:33 +00:00
local _termk _termp _cond
2023-10-13 12:15:41 +00:00
_termk=`_kstorequote "$1"`
_termp=`_kstorequote "$2"`
2022-08-13 18:01:33 +00:00
_cond="key LIKE '%$_termk%' AND prop LIKE '%$_termp%'"
2024-11-10 22:28:53 +00:00
$_SQLITE -header -column "$_AUTH_DB" "SELECT key, prop, length( data ) FROM $_KSTORE_TABLE WHERE $_cond;"
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstorelist {
2024-11-10 22:28:53 +00:00
$_SQLITE -header -column "$_AUTH_DB" "SELECT key, prop, length( data ) FROM $_KSTORE_TABLE;"
2022-08-13 15:40:12 +00:00
}
2023-10-13 12:15:41 +00:00
function _kstorequery {
2023-09-23 15:11:09 +00:00
$_SQLITE "$_AUTH_DB" "$@"
2022-08-13 15:40:12 +00:00
}