2023-08-10 12:35:47 +02:00
|
|
|
#!/bin/bash
|
|
|
|
<<LITEVAULT
|
|
|
|
Author: Luis G.L.
|
|
|
|
Program: LiteVault
|
|
|
|
Description:
|
|
|
|
Program that performs Vault tasks for username/password storage
|
|
|
|
Symmetric key file encryption is used:
|
|
|
|
GPG symmetrically encrypted data (AES256 cipher)
|
|
|
|
ChangeLog:
|
|
|
|
v1.0: Encryption + Decryption and listing accounts
|
|
|
|
v1.5: Token management and user creation
|
|
|
|
v2.0: Account creation and deletion
|
|
|
|
v2.5: Full CRUD
|
|
|
|
v2.7: Variable setting and error code output
|
|
|
|
v2.9: Inclusion of masterkey to open LiteVault
|
|
|
|
v3.0: Check empty MasteKey and different CyPass per user
|
|
|
|
v3.1: Show TOKEN chunk to facilitate search
|
|
|
|
v3.2: Now you only need the TOKEN and the MasterKey to manage accounts
|
|
|
|
-------------------------------------------------------------------------------------------------------
|
|
|
|
.LiteVault file format (always in the home of the user who launches it)
|
|
|
|
_______________________________________
|
|
|
|
account account.name #Token (unique value)
|
|
|
|
login User
|
|
|
|
password UserPassword
|
|
|
|
account account.name #Token (unique value)
|
|
|
|
login User
|
|
|
|
password UserPassword
|
|
|
|
(...)
|
|
|
|
_______________________________________
|
|
|
|
-------------------------------------------------------------------------------------------------------
|
|
|
|
NOTES AND STEPS:
|
|
|
|
1) To generate CyPass (internal encryption key) use
|
|
|
|
gpg --gen-random --armor 1 50| tr -dc 'A-za-z0-9';echo
|
|
|
|
1.a) Replace 'INTERNALCIPHERKEY' with the value obtained in CyPass
|
|
|
|
2.b) Store the CyPass value in a safe place (for emergencies only)
|
|
|
|
2) Compile and obfuscate this script using the shc program:
|
|
|
|
shc -r -f LiteVault.sh -o LiteVault
|
|
|
|
3) Use only the binary program created and delete the script
|
|
|
|
-------------------------------------------------------------------------------------------------------
|
|
|
|
LITEVAULT
|
|
|
|
|
|
|
|
# VARIABLES TO BE USED BY LiteVault ----------------------------
|
|
|
|
EE="PUB"
|
|
|
|
CyPass=$EE"INTERNALCIPHERKEY"$(whoami |cut -c1-3)
|
|
|
|
FLiteVaultD=~/.LiteVault
|
|
|
|
FLiteVault=~/.LiteVault.gpg
|
|
|
|
ErrCode=0
|
|
|
|
VERSION="3.2"
|
|
|
|
NEWTOKEN=""
|
|
|
|
cBOLD='\e[1m'
|
|
|
|
cDEFAULT='\e[0m'
|
|
|
|
FMasterKEY=""
|
|
|
|
MASTERKEY=""
|
|
|
|
# ----------------------------------------------------------
|
|
|
|
|
|
|
|
function GenerateToken() {
|
|
|
|
NEWTOKEN=$(gpg --gen-random --armor 1 15| tr -dc 'A-za-z0-9'|tr [:lower:] [:upper:])
|
|
|
|
}
|
|
|
|
function Header() {
|
|
|
|
echo
|
|
|
|
echo "┌────────────────────────────────────────────────────────────────────┐"
|
|
|
|
echo -e "│$cBOLD LiteVault $cDEFAULT- User/Password management in encrypted Vault - Ver.$VERSION │"
|
|
|
|
echo "└────────────────────────────────────────────────────────────────────┘"
|
|
|
|
}
|
|
|
|
|
|
|
|
function ShowHelp() {
|
|
|
|
Header
|
|
|
|
echo " SINTAX: $0 --ACTION parameter ..."
|
|
|
|
echo -e "$cBOLD --help $cDEFAULT"
|
|
|
|
echo " Show help"
|
|
|
|
echo -e "$cBOLD --list $cDEFAULT"
|
|
|
|
echo " List of all account names"
|
|
|
|
echo -e "$cBOLD --new$cDEFAULT"
|
|
|
|
echo " Create new vault file: $FLiteVault"
|
|
|
|
echo " CAUTION: ¡The old one will be removed!"
|
|
|
|
echo -e "$cBOLD --create --account <ACCOUNT> -mk <MasterKey> $cDEFAULT"
|
|
|
|
echo " CREATE new account in LiteVault"
|
|
|
|
echo -e "$cBOLD --show [-t|--token] <TOKEN> -mk <MasterKey> $cDEFAULT"
|
|
|
|
echo " SHOW Login and assword of the account with that token"
|
|
|
|
echo " --show -t <TOKEN> [-l|--login] [-p|--password] -mk <MasterKey>"
|
|
|
|
echo " SHOW only Login or Password of the account with that token"
|
|
|
|
echo -e "$cBOLD --update [-t|--token] <TOKEN> -mk <MasterKey> $cDEFAULT"
|
|
|
|
echo " UPDATE account (Login and Password) of the indicated token"
|
2023-08-10 12:42:10 +02:00
|
|
|
echo -e "$cBOLD --delete --token <TOKEN> -mk <MasterKey> $cDEFAULT"
|
2023-08-10 12:35:47 +02:00
|
|
|
echo " DELETE account with the indicated token"
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
echo " NOTE: Use -mk <MasterKey> to use the decryption key "
|
|
|
|
echo " Otherwise it will be requested by console "
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
|
|
|
function ShowErrorCodes() {
|
|
|
|
Header
|
|
|
|
echo " [Error Codes]"
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
echo " 0: OK. Correct "
|
|
|
|
echo " 1: Generic Error "
|
|
|
|
echo " 2: Account/Token not found "
|
|
|
|
echo " 5: Missing Account or Token "
|
|
|
|
echo " 8: Passwords do not match "
|
|
|
|
echo " 9: Incorrect Parameters "
|
|
|
|
echo " 404: File $FLiteVault not found "
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
echo
|
|
|
|
ErrCode=0
|
|
|
|
}
|
|
|
|
|
|
|
|
function Author() {
|
|
|
|
Header
|
|
|
|
echo -e "│ Author/Autor: $cBOLD Luis Gutierrez Lopez$cDEFAULT (luisgulo@gmail.com) │ "
|
|
|
|
echo "└────────────────────────────────────────────────────────────────────┘ "
|
|
|
|
echo
|
|
|
|
ErrCode=0
|
|
|
|
}
|
|
|
|
|
|
|
|
function CheckMK() {
|
|
|
|
FMasterKEY=$(echo -e $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null | grep 'MasterKEY'|awk '{print $2}')
|
|
|
|
if [ "$FMasterKEY" == "" ]
|
|
|
|
then
|
|
|
|
# Without MasterKEY (empty)
|
|
|
|
ErrCode=0
|
|
|
|
else
|
|
|
|
# MasterKey with value
|
|
|
|
if [ "$XMK" == "YES" ]
|
|
|
|
then
|
|
|
|
ErrCode=0
|
|
|
|
else
|
|
|
|
# Enter the MasterKey
|
|
|
|
read -s -p " Enter the 'MasterKey' to open the LiteVault: " MASTERKEY
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
# If MasterKey is OK
|
|
|
|
if [ "$FMasterKEY" == "$MASTERKEY" ]
|
|
|
|
then
|
|
|
|
# All OK. Continue...
|
|
|
|
ErrCode=0
|
|
|
|
else
|
|
|
|
ErrCode=8
|
|
|
|
echo " Error: Incorrect MasterKey"
|
|
|
|
echo
|
|
|
|
exit $ErrCode
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function ListAll() {
|
|
|
|
# Show Account Data in file .LiteVault and Token chunk
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null |grep 'account' | awk '{print $1 " " $2 " [" substr($3,0,4) "***" substr($3,length($3)-4,4) "]"}'
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
}
|
|
|
|
|
|
|
|
function EncryptLiteVault(){
|
|
|
|
echo -e $CyPass"\n"$CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -c $FLiteVaultD 2>/dev/null
|
|
|
|
ErrCode=$?
|
|
|
|
rm $FLiteVaultD
|
|
|
|
}
|
|
|
|
|
|
|
|
function ShowAccountData() {
|
|
|
|
NUMEROFLINES=$(echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null |grep $TOKEN | wc -l)
|
|
|
|
if [ $NUMEROFLINES -eq 0 ]
|
|
|
|
then
|
|
|
|
Header
|
|
|
|
echo " Error: Account not found in LiteVault"
|
|
|
|
ErrCode=2
|
|
|
|
else
|
|
|
|
# Search account
|
|
|
|
AUTH=( $(echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null | grep $TOKEN -A2 |tail -2|awk '{print $2}') )
|
|
|
|
AUTHLOGIN=${AUTH[0]}
|
|
|
|
AUTHPASSW=${AUTH[1]}
|
|
|
|
if [ "$XLOGIN" == "YES" ] && [ "$XPASSWORD" == "YES" ]
|
|
|
|
then
|
|
|
|
echo $AUTHLOGIN" "$AUTHPASSW
|
|
|
|
ErrCode=0
|
|
|
|
fi
|
|
|
|
if [ "$XLOGIN" == "" ] && [ "$XPASSWORD" == "" ]
|
|
|
|
then
|
|
|
|
echo $AUTHLOGIN" "$AUTHPASSW
|
|
|
|
ErrCode=0
|
|
|
|
fi
|
|
|
|
if [ "$XLOGIN" == "YES" ] && [ "$XPASSWORD" == "" ]
|
|
|
|
then
|
|
|
|
echo $AUTHLOGIN
|
|
|
|
ErrCode=0
|
|
|
|
fi
|
|
|
|
if [ "$XLOGIN" == "" ] && [ "$XPASSWORD" == "YES" ]
|
|
|
|
then
|
|
|
|
echo $AUTHPASSW
|
|
|
|
ErrCode=0
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function UpdateAccount() {
|
|
|
|
# if not found, abort
|
|
|
|
LOCATED=$(echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null|grep $TOKEN | wc -l)
|
|
|
|
if [ $LOCATED -eq 0 ]
|
|
|
|
then
|
|
|
|
echo " Error: Account not found"
|
|
|
|
echo
|
|
|
|
ErrCode=2
|
|
|
|
exit $ErrCode
|
|
|
|
fi
|
|
|
|
# Save previous data: Account and Token
|
|
|
|
NEWACCOUNT=$(echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null|grep $TOKEN|awk '{print $2}' )
|
|
|
|
echo " Updating the LOGIN and PASSWORD for the $NEWACCOUNT"
|
|
|
|
echo
|
|
|
|
RequestLoginPass
|
|
|
|
NEWLOGIN=$NEWUSER
|
|
|
|
NEWPASSWORD=$NEWPASSWORDA
|
|
|
|
# Delete previous account
|
|
|
|
DeleteAccount
|
|
|
|
# Prepare LiteVault
|
|
|
|
ExtractLiteVault
|
|
|
|
# Save update Account
|
|
|
|
echo "account $NEWACCOUNT $TOKEN" >> $FLiteVaultD
|
|
|
|
echo " login $NEWLOGIN" >> $FLiteVaultD
|
|
|
|
echo " password $NEWPASSWORD" >> $FLiteVaultD
|
|
|
|
EncryptLiteVault
|
|
|
|
ErrCode=0
|
|
|
|
}
|
|
|
|
|
|
|
|
function RequestLoginPass() {
|
|
|
|
# Pedimos LOGIN
|
|
|
|
read -p " Write the LOGIN to save: " NEWUSER
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
# Pedimos PASSWORD (2 veces)
|
|
|
|
echo " You must write the password 2 times (it is not shown on the screen)"
|
|
|
|
read -s -p " Write the PASSWORD (1/2): " NEWPASSWORDA
|
|
|
|
echo
|
|
|
|
read -s -p " Repeat the PASSWORD (2/2): " NEWPASSWORDB
|
|
|
|
echo
|
|
|
|
echo "──────────────────────────────────────────────────────────────────────"
|
|
|
|
if [ "$NEWPASSWORDA" != "$NEWPASSWORDB" ]
|
|
|
|
then
|
|
|
|
echo " Error: Password do not match -Abort-"
|
|
|
|
echo
|
|
|
|
ErrCode=8
|
|
|
|
exit $ErrCode
|
|
|
|
fi
|
|
|
|
ErrCode=0
|
|
|
|
}
|
|
|
|
|
|
|
|
function CreateAccount() {
|
|
|
|
# Prepare TOKEN for new account
|
|
|
|
# TOKEN is unique
|
|
|
|
while true
|
|
|
|
do
|
|
|
|
GenerateToken
|
|
|
|
# Token found. Generating unique Token
|
|
|
|
TOKENLOCATED=$(echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null | grep $NEWTOKEN |head -1| awk '{print $3}')
|
|
|
|
if [ "$NEWTOKEN" != "$TOKENLOCATED" ]
|
|
|
|
then
|
|
|
|
# Token is unique. Exit (break) with unique Token
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
# Request LOGIN and PASSWORD
|
|
|
|
RequestLoginPass
|
|
|
|
# All data values OK
|
|
|
|
ExtractLiteVault
|
|
|
|
# Saving data
|
|
|
|
echo "account $ACCOUNT $NEWTOKEN" >> $FLiteVaultD
|
|
|
|
echo " login $NEWUSER" >> $FLiteVaultD
|
|
|
|
echo " password $NEWPASSWORDA" >> $FLiteVaultD
|
|
|
|
EncryptLiteVault
|
|
|
|
echo
|
|
|
|
echo -e " New account $ACCOUNT included. $cBOLD Take note of the TOKEN !!$cDEFAULT"
|
|
|
|
echo "$NEWTOKEN"
|
|
|
|
ErrCode=0
|
|
|
|
}
|
|
|
|
|
|
|
|
function DeleteAccount() {
|
|
|
|
# Delete account
|
|
|
|
# Locate account line number
|
|
|
|
# Detele that line an the next 2
|
|
|
|
ExtractLiteVault
|
|
|
|
LINEFORDELETE=$(grep -n "$TOKEN" $FLiteVaultD|awk -F ':' '{print $1}')
|
|
|
|
if [ "$LINEFORDELETE" == "" ]
|
|
|
|
then
|
|
|
|
# Not Found
|
|
|
|
rm $FLiteVaultD 2>/dev/null
|
|
|
|
echo " Error: Account not found with that Token"
|
|
|
|
ErrCode=2
|
|
|
|
else
|
|
|
|
# Account located. Delete account (1/3)
|
|
|
|
sed -i $LINEFORDELETE"d" $FLiteVaultD
|
|
|
|
# Delete line LOGIN (2/3)
|
|
|
|
sed -i $LINEFORDELETE"d" $FLiteVaultD
|
|
|
|
# Delete line PASSWORD (3/3)
|
|
|
|
sed -i $LINEFORDELETE"d" $FLiteVaultD
|
|
|
|
EncryptLiteVault
|
|
|
|
ErrCode=0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function ExtractLiteVault() {
|
|
|
|
# Extract file LiteVault.gpg to modify it
|
|
|
|
echo $CyPass | gpg --batch --yes --passphrase-fd --no-use-agent -d $FLiteVault 2>/dev/null > $FLiteVaultD
|
|
|
|
}
|
|
|
|
|
|
|
|
function CreateNewLiteVault() {
|
|
|
|
Header
|
|
|
|
echo
|
|
|
|
read -p " A new LiteVault will be generated [Y/n]: " YESNO
|
|
|
|
YESNO=$(echo $YESNO|tr [:lower:] [:upper:])
|
|
|
|
if [ "$YESNO" == "Y" ] || [ "$YESNO" == "" ]
|
|
|
|
then
|
|
|
|
# Create empty LiteVault an encrypt it
|
|
|
|
#> $FLiteVaultD
|
|
|
|
# Request MasterKEY
|
|
|
|
echo
|
|
|
|
read -s -p " Enter a *masterkey* (to decipher) [1/2]: " MKeyA
|
|
|
|
echo
|
|
|
|
read -s -p " Repeat *masterkey* (to decipher) [2/2]: " MKeyB
|
|
|
|
if [ "$MKeyA" == "$MKeyB" ]
|
|
|
|
then
|
|
|
|
# MK A and B OK. Saving MK in the LiteVault itselff
|
|
|
|
echo "MasterKEY $MKeyA" > $FLiteVaultD
|
|
|
|
EncryptLiteVault
|
|
|
|
ErrCode=0
|
|
|
|
else
|
|
|
|
# Error
|
|
|
|
ErrCode=1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo
|
|
|
|
exit $ErrCode
|
|
|
|
}
|
|
|
|
|
|
|
|
function CheckVault() {
|
|
|
|
if [ -f $FLiteVault ]
|
|
|
|
then
|
|
|
|
ErrCode=0
|
|
|
|
else
|
|
|
|
echo
|
|
|
|
echo " Error: File $FLiteVault not found"
|
|
|
|
echo
|
|
|
|
CreateNewLiteVault
|
|
|
|
echo
|
|
|
|
exit $ErrCode
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------
|
|
|
|
# MAIN
|
|
|
|
CheckVault
|
|
|
|
# Check parameters
|
|
|
|
while [[ $# > 0 ]] # Obtain all parameters
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
--author | --autor )
|
|
|
|
Author
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
-h | --help )
|
|
|
|
ShowHelp
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
--list )
|
|
|
|
ACTION="LIST"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--errcode )
|
|
|
|
ShowErrorCodes
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
--new )
|
|
|
|
CreateNewLiteVault
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
-c | --create )
|
|
|
|
ACTION="CREATE"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-s | --show )
|
|
|
|
ACTION="SHOW"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-u | --update )
|
|
|
|
ACTION="UPDATE"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-d | --delete )
|
|
|
|
ACTION="DELETE"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-a | --account )
|
|
|
|
shift
|
|
|
|
ACCOUNT="$1"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-t | --token )
|
|
|
|
shift
|
|
|
|
TOKEN="$1"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-l | --login )
|
|
|
|
XLOGIN="YES"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-p | --password )
|
|
|
|
XPASSWORD="YES"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-mk | --mk )
|
|
|
|
XMK="YES"
|
|
|
|
shift
|
|
|
|
MASTERKEY="$1"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
* )
|
|
|
|
# Wrong parameter... it is ignored
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
# Processs actions
|
|
|
|
# CRUD for LiteVault
|
|
|
|
case "$ACTION" in
|
|
|
|
LIST )
|
|
|
|
Header
|
|
|
|
CheckMK
|
|
|
|
ListAll
|
|
|
|
;;
|
|
|
|
CREATE )
|
|
|
|
Header
|
|
|
|
if [ "$ACCOUNT" == "" ]
|
|
|
|
then
|
|
|
|
echo " Error: Provide the name of account to create"
|
|
|
|
ErrCode=5
|
|
|
|
else
|
|
|
|
CheckMK
|
|
|
|
echo " The account $ACCOUNT will be created"
|
|
|
|
CreateAccount
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
SHOW )
|
|
|
|
# Not Header need !
|
|
|
|
if [ "$TOKEN" == "" ]
|
|
|
|
then
|
|
|
|
# Token is empty
|
|
|
|
Header
|
|
|
|
echo " Error: Must indicate the Token"
|
|
|
|
ErrCode=5
|
|
|
|
else
|
|
|
|
CheckMK
|
|
|
|
ShowAccountData
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
UPDATE )
|
|
|
|
Header
|
|
|
|
if [ "$TOKEN" == "" ]
|
|
|
|
then
|
|
|
|
echo " Error: Must indicate the Token"
|
|
|
|
ErrCode=5
|
|
|
|
else
|
|
|
|
CheckMK
|
|
|
|
UpdateAccount
|
|
|
|
exit $ErrCode
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
DELETE )
|
|
|
|
Header
|
|
|
|
if [ "$TOKEN" == "" ]
|
|
|
|
then
|
|
|
|
echo " Error: Must indicate the Token"
|
|
|
|
ErrCode=5
|
|
|
|
else
|
|
|
|
CheckMK
|
|
|
|
DeleteAccount
|
|
|
|
if [ $ErrCode -eq 0 ]
|
|
|
|
then
|
|
|
|
echo " Successfully deleted $ACCOUNT"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
* )
|
|
|
|
Header
|
|
|
|
echo " ERROR: Invalid Parameter"
|
|
|
|
echo -e " Try:$cBOLD $0 --help $cDEFAULT"
|
|
|
|
echo
|
|
|
|
ErrCode=9
|
|
|
|
exit $ErrCode
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
# Exit with the Error Code
|
|
|
|
exit $ErrCode
|
|
|
|
# ----------------------------------------------------------------------------
|