LiteVault_vault/LiteVault.sh
2023-08-10 12:42:10 +02:00

492 lines
16 KiB
Bash
Executable file

#!/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"
echo -e "$cBOLD --delete --token <TOKEN> -mk <MasterKey> $cDEFAULT"
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
# ----------------------------------------------------------------------------