commit 85c9c3bea37db984b6cccb75331ecba8ebfc6541
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2022-08-13T15:40:12Z |
| subject | Added 16_keystore |
commit 85c9c3bea37db984b6cccb75331ecba8ebfc6541
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2022-08-13T15:40:12Z
Added 16_keystore
---
bash/bashrc/sources/16_keystore | 230 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 230 insertions(+)
diff --git a/bash/bashrc/sources/16_keystore b/bash/bashrc/sources/16_keystore
new file mode 100644
index 0000000..f455aaf
--- /dev/null
+++ b/bash/bashrc/sources/16_keystore
@@ -0,0 +1,230 @@
+#!/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
+
+if [ -z `which xxd` ]; then
+ echo "xxd is required" >&2
+ return 1
+fi
+
+_AUTH_DB=$RBASH_HOME/keystore.db
+_AUTH_SECRET=
+_KSTORE_DEF_PROP=${_KSTORE_DEF_PROP:-val}
+
+if [ -f "$RBASH_HOME/keystore.secret" ]; then
+ _AUTH_SECRET=$( cat "$RBASH_HOME/keystore.secret" )
+fi
+
+function kstore {
+ case $1 in
+ add) shift; kstore-add "$@" ;;
+ del) shift; kstore-del "$@" ;;
+ get) shift; kstore-get "$@" ;;
+ list) shift; kstore-list "$@" ;;
+ query) shift; kstore-query "$@" ;;
+ update) shift; kstore-update "$@" ;;
+ search) shift; kstore-search $@ ;;
+ secret) shift; kstore-secret $@ ;;
+ *)
+ __func_head "add key value [prop, default: $_KSTORE_DEF_PROP]"
+ __func_help "update key value [prop, default: $_KSTORE_DEF_PROP]"
+ __func_help "get key [prop, default: $_KSTORE_DEF_PROP]"
+ __func_help "list"
+ __func_help "del key"
+ __func_help "search key"
+ __func_help "query SQL"
+ return 1
+ ;;
+ esac
+ return $?
+}
+
+function kstore-secret {
+ case "$1" in
+ clear) shift; kstore-secret-clear "$@" ;;
+ config) shift; kstore-secret-config "$@" ;;
+ *)
+ __func_head "clear"
+ __func_help "config"
+ ;;
+ esac
+}
+
+function kstore-init {
+ cat <<___SQL___ | $_SQLITE "$_AUTH_DB"
+CREATE TABLE IF NOT EXISTS store (
+ key TEXT UNIQUE NOT NULL
+ , prop TEXT NOT NULL
+ , data BLOB
+ , PRIMARY KEY( key ASC, prop ASC )
+);
+___SQL___
+ kstore secret config
+}
+
+function kstore-quote {
+ echo -n "$1" | sed -e "s/'/''/g"
+}
+
+function kstore-enc {
+ if [ -z "$_AUTH_SECRET" ]; then
+ echo "Secret key is not set yet" >&2
+ return 1
+ fi
+
+ openssl enc -e -aes-256-cbc -pbkdf2 -k "$_AUTH_SECRET" | xxd -p | tr -d "\n"
+}
+
+function kstore-dec {
+ 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"
+}
+
+function kstore-secret-macos {
+ 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"
+ ;;
+ *)
+ echo "Unknown action: $1" >&2
+ return 1
+ ;;
+ esac
+}
+
+function kstore-secret-windows {
+ # Not impelemented yet
+ if [ "$1" == "get" ]; then
+ return 1
+ fi
+ return 1
+}
+
+function kstore-secret-config {
+ local _CONFIRM
+ if [ -z "$_AUTH_SECRET" ]; then
+
+ kstore-secret-windows get || kstore-secret-macos get
+ 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
+
+ read -p "Save this password to OS's keystore? (y/n): " _CONFIRM
+ if [ "$_CONFIRM" != "y" ]; then
+ return 0
+ fi
+
+ case $OSTYPE in
+ darwin*) kstore-secret-macos "set" ;;
+ esac
+ fi
+}
+
+function kstore-secret-clear {
+ _AUTH_SECRET=
+ case $OSTYPE in
+ darwin*)
+ security delete-generic-password -a default -s rbash-kstore 2>&1 > /dev/null
+ ;;
+ esac
+}
+
+function kstore-update {
+ kstore-init || return 1
+ local _key _val _prop
+ _key=`kstore-quote "$1"`
+ _val=`echo -n "$2" | kstore-enc`
+ _val=`kstore-quote "$_val"`
+ _prop=`kstore-quote "${3:-$_KSTORE_DEF_PROP}"`
+ _cond="key = '$_key' AND prop = '$_prop'"
+ $_SQLITE "$_AUTH_DB" "UPDATE store SET data = '$_val' WHERE $_cond;"
+}
+
+function kstore-add {
+ kstore-init || return 1
+ local _key _val _prop
+ _key=`kstore-quote "$1"`
+ _val=`echo -n "$2" | kstore-enc`
+ _val=`kstore-quote "$_val"`
+ _prop=`kstore-quote "${3:-$_KSTORE_DEF_PROP}"`
+ sqlite3 "$_AUTH_DB" \
+ "INSERT INTO store ( key, prop, data )
+ VALUES( '$_key', '$_prop', X'$_val' );"
+}
+
+function kstore-get {
+ kstore-init || return 1
+ local _key _prop _cond
+ _key=`kstore-quote "$1"`
+ _prop=`kstore-quote "${2:-$_KSTORE_DEF_PROP}"`
+ _cond="key = '$_key' AND prop = '$_prop'"
+
+ echo -n "`$_SQLITE -list "$_AUTH_DB" "SELECT ( data ) FROM store WHERE $_cond;"`" | kstore-dec
+}
+
+function kstore-del {
+ kstore-init || return 1
+
+ local _CONFIRM _key _prop _cond
+ _key=`kstore-quote "$1"`
+ _prop=`kstore-quote "${2:-$_KSTORE_DEF_PROP}"`
+ _cond="key = '$_key' AND prop = '$_prop'"
+
+ sqlite3 "$_AUTH_DB" "SELECT 1111 FROM store WHERE $_cond;" | grep -q 1111
+ if [ $? -eq 0 ]; then
+ sqlite3 "$_AUTH_DB" "SELECT * FROM store WHERE $_cond;"
+ echo
+ read -p "Delete this entry (yes/no)? " _CONFIRM
+ if [ "$_CONFIRM" == "yes" ]; then
+ sqlite3 "$_AUTH_DB" "DELETE FROM store WHERE $_cond;"
+ if [ $? -eq 0 ]; then
+ echo "deleted"
+ fi
+ else
+ echo "action canceled"
+ fi
+ else
+ echo "$1 not found"
+ fi
+}
+
+function kstore-search {
+ echo "Not implemented yet"
+}
+
+function kstore-list {
+ $_SQLITE -header -column "$_AUTH_DB" "SELECT key, prop, length( data ) FROM store;"
+}
+
+function kstore-query {
+ sqlite3 "$_AUTH_DB" "$@"
+}