You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
6.1 KiB
267 lines
6.1 KiB
#!/bin/sh
|
|
|
|
AMNGRDB="${AMNGRDB:-${HOME}/.account.db}"
|
|
AMNGRID="${AMNGRID:-${USER}@${HOSTNAME}}"
|
|
AMNGRPWLEN="${AMNGRPWLEN:-10}"
|
|
|
|
alias random="cat /dev/urandom"
|
|
|
|
function rand_printable() {
|
|
if ! [[ "${1}" =~ "^[0-9]+$" ]]
|
|
then
|
|
printf "Usage: %s: [len]" "$0"
|
|
fi
|
|
echo -n "$(random | tr -dc ' !#-&(-~' | head -c${1:-512})"
|
|
}
|
|
|
|
function amngrdbinit() {
|
|
local DB="${1:-${AMNGRDB}}"
|
|
|
|
sqlite3 "${DB}" <<-EOD
|
|
PRAGMA foreign_keys = ON;
|
|
CREATE TABLE IF NOT EXISTS account (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name VARCHAR(128) UNIQUE NOT NULL,
|
|
desc TEXT DEFAULT NULL);
|
|
CREATE TABLE IF NOT EXISTS cred (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user VARCHAR(128) NOT NULL,
|
|
pass TEXT NOT NULL);
|
|
CREATE TABLE IF NOT EXISTS account_cred (
|
|
account_id INTEGER,
|
|
cred_id INTEGER,
|
|
state SMALLINT(1) NOT NULL,
|
|
FOREIGN KEY(account_id) REFERENCES account(id)
|
|
ON UPDATE CASCADE ON DELETE CASCADE,
|
|
FOREIGN KEY(cred_id) REFERENCES cred(id)
|
|
ON UPDATE CASCADE ON DELETE CASCADE);
|
|
EOD
|
|
}
|
|
|
|
function amngrdbdestroy() {
|
|
local DB="${1:-${AMNGRDB}}"
|
|
local CHECK
|
|
|
|
cat <<-EOT
|
|
WARNING: You are about to remove your account data. There is no way to
|
|
recover from this. Are you really shure you want to do this?
|
|
EOT
|
|
echo -n "[Yes|[No]]: " && read CHECK
|
|
CHECK="${CHECK:-No}"
|
|
|
|
test "${CHECK}" == "Yes" && rm -f "${AMNGRDB}"
|
|
}
|
|
|
|
function amngrid() {
|
|
local ACCOUNT_NAME="${1}"
|
|
echo "$(sqlite3 "${AMNGRDB}" <<-EOD
|
|
SELECT id FROM account WHERE name='${ACCOUNT_NAME}';
|
|
EOD
|
|
)"
|
|
}
|
|
|
|
function amngrcrypt() {
|
|
local PLAIN="${1}"
|
|
echo -n "${PLAIN}" | gpg -aeqr "${AMNGRID}"
|
|
}
|
|
|
|
function amngrgen() {
|
|
local LEN="${0:-${AMNGRPWLEN}}"
|
|
amngrcrypt "$(rand_printable "${LEN}")"
|
|
}
|
|
|
|
function amngradd() {
|
|
local ACCOUNT_NAME="${1}"
|
|
local USER="${2}"
|
|
local PASSWORD="$(amngrcrypt "${3}")"
|
|
local DESCRIPTION="${4:-NO DESCRIPTION}"
|
|
local ACCOUNT_ID="$(amngrid "${ACCOUNT_NAME}")"
|
|
local QUERY="$(cat <<-EOD
|
|
PRAGMA foreign_keys = ON;
|
|
BEGIN TRANSACTION;
|
|
INSERT INTO cred (user, pass)
|
|
VALUES ('${USER}', '${PASSWORD}');
|
|
EOD
|
|
)"
|
|
|
|
if [ -z "${ACCOUNT_ID}" ]
|
|
then
|
|
QUERY="$(cat <<-EOD
|
|
${QUERY}
|
|
INSERT INTO account (name, desc)
|
|
VALUES ('${ACCOUNT_NAME}', '${DESCRIPTION}');
|
|
EOD
|
|
)"
|
|
else
|
|
QUERY="$(cat <<-EOD
|
|
${QUERY}
|
|
UPDATE account_cred SET state=0
|
|
WHERE account_id=(SELECT id FROM account
|
|
WHERE name='${ACCOUNT_NAME}' AND state=2);
|
|
UPDATE account_cred SET state=2
|
|
WHERE account_id=(SELECT id FROM account
|
|
WHERE name='${ACCOUNT_NAME}' AND state=1);
|
|
EOD
|
|
)"
|
|
fi
|
|
|
|
QUERY="$(cat <<-EOD
|
|
${QUERY}
|
|
INSERT INTO account_cred (account_id, cred_id, state)
|
|
VALUES ((SELECT id FROM account WHERE name='${ACCOUNT_NAME}'),
|
|
(SELECT id FROM cred WHERE user='${USER}' AND pass='${PASSWORD}'),
|
|
1);
|
|
COMMIT TRANSACTION;
|
|
EOD
|
|
)"
|
|
|
|
sqlite3 "${AMNGRDB}" "${QUERY}"
|
|
}
|
|
|
|
function amngrcreate() {
|
|
local ACCOUNT_NAME="${1}"
|
|
local USER="${2}"
|
|
local DESCRIPTION="${3:-NO DESCRIPTION}"
|
|
local PASSWORD="$(rand_printable 10)"
|
|
|
|
amngradd "${ACCOUNT_NAME}" "${USER}" "${PASSWORD}" "${DESCRIPTION}"
|
|
amngrgetpass "${ACCOUNT_NAME}"
|
|
}
|
|
|
|
function amngrgetuser() {
|
|
local ACCOUNT_NAME="${1}"
|
|
local STATE="${2:-"1"}"
|
|
|
|
test "${STATE}" != "1" -a "${STATE}" != "2" && STATE="1"
|
|
|
|
sqlite3 "${AMNGRDB}" <<-EOD |\
|
|
awk 'NR>1{print p}{p=$0}END{ORS="";print}' | xclip -i
|
|
SELECT user FROM account
|
|
JOIN account_cred ON account.id=account_cred.account_id
|
|
JOIN cred ON cred.id=account_cred.cred_id
|
|
WHERE name='${ACCOUNT_NAME}' AND state=${STATE};
|
|
EOD
|
|
}
|
|
|
|
function amngrgetolduser() {
|
|
local ACCOUNT_NAME="${1}"
|
|
amngrgetuser "${ACCOUNT_NAME}" "2"
|
|
}
|
|
|
|
function amngrgetpass() {
|
|
local ACCOUNT_NAME="${1}"
|
|
local STATE="${2:-1}"
|
|
|
|
test "${STATE}" != "1" -a "${STATE}" != "2" && STATE="1"
|
|
|
|
sqlite3 "${AMNGRDB}" <<-EOD |\
|
|
awk 'NR>1{print p}{p=$0}END{ORS="";print}' | gpg -dq | xclip -i
|
|
SELECT pass FROM account
|
|
JOIN account_cred ON account.id=account_cred.account_id
|
|
JOIN cred ON cred.id=account_cred.cred_id
|
|
WHERE name='${ACCOUNT_NAME}' AND state=${STATE};
|
|
EOD
|
|
}
|
|
|
|
function amngrgetoldpass() {
|
|
local ACCOUNT_NAME="${1}"
|
|
amngrgetpass "${ACCOUNT_NAME}" "2"
|
|
}
|
|
|
|
function amngrrename() {
|
|
local OLD_NAME="${1}"
|
|
local NEW_NAME="${2}"
|
|
|
|
test -z "${OLD_NAME}" -o -z "${NEW_NAME}" && return 1
|
|
|
|
sqlite3 "${AMNGRDB}" <<-EOD
|
|
UPDATE account SET name='${NEW_NAME}'
|
|
WHERE name='${OLD_NAME}';
|
|
EOD
|
|
}
|
|
|
|
function amngrdelete() {
|
|
local ACCOUNT_NAME="${1}"
|
|
|
|
sqlite3 "${AMNGRDB}" <<-EOD
|
|
PRAGMA foreign_keys = ON;
|
|
BEGIN TRANSACTION;
|
|
DELETE FROM cred WHERE id IN (
|
|
SELECT cred_id FROM account
|
|
JOIN account_cred ON account.id=account_cred.account_id
|
|
WHERE name='${ACCOUNT_NAME}');
|
|
DELETE FROM account WHERE name='${ACCOUNT_NAME}';
|
|
COMMIT TRANSACTION;
|
|
EOD
|
|
}
|
|
|
|
function amngrlist() {
|
|
local SEPARATOR="${1:-" => "}"
|
|
sqlite3 -separator "${SEPARATOR}" "${AMNGRDB}" <<-EOD
|
|
SELECT name, user, desc FROM account
|
|
JOIN account_cred ON account.id=account_cred.account_id
|
|
JOIN cred ON cred.id=account_cred.cred_id
|
|
WHERE state=1;
|
|
EOD
|
|
}
|
|
|
|
function amngrsearch() {
|
|
local PATTERN
|
|
local DELIMITER=" => "
|
|
local USAGE="$(printf "Usage: %s: [-d delimiter] pattern" "$0")"
|
|
|
|
while getopts d: opt
|
|
do
|
|
case $opt in
|
|
d)
|
|
DELIMITER="${OPTARG}";;
|
|
?)
|
|
echo "${USAGE}"
|
|
exit 1;;
|
|
esac
|
|
done
|
|
shift $(($OPTIND-1))
|
|
|
|
if [ $# -lt 2 ]
|
|
then
|
|
echo "${USAGE}"
|
|
exit 1;;
|
|
fi
|
|
|
|
PATTERN="${1}"
|
|
|
|
sqlite3 -separator " => " "${AMNGRDB}" <<-EOD
|
|
SELECT name, user, desc FROM account
|
|
JOIN account_cred ON account.id=account_cred.account_id
|
|
JOIN cred ON cred.id=account_cred.cred_id
|
|
WHERE state=1 AND (
|
|
name LIKE '%${PATTERN}%' OR user LIKE '%${PATTERN}%' OR
|
|
desc LIKE '%${PATTERN}%');
|
|
EOD
|
|
}
|
|
|
|
case "$(basename -- "$0")" in
|
|
random) random;;
|
|
rand_printable) rand_printable;;
|
|
|
|
amngrdbinit) amngrdbinit;;
|
|
amngrdbdestroy) amngrdbdestroy;;
|
|
|
|
amngradd) amngradd "$@";;
|
|
amngrcreate) amngrcreate "$@";;
|
|
amngrcrypt) amngrcrypt "$@";;
|
|
amngrdelete) amngrdelete "$@";;
|
|
amngrgen) amngrgen "$@";;
|
|
amngrgetoldpass) amngrgetoldpass "$@";;
|
|
amngrgetolduser) amngrgetolduser "$@";;
|
|
amngrgetpass) amngrgetpass "$@";;
|
|
amngrgetuser) amngrgetuser "$@";;
|
|
amngrid) amngrid "$@";;
|
|
amngrlist) amngrlist;;
|
|
amngrrename) amngrrename "$@";;
|
|
amngrsearch) amngrsearch "$@";;
|
|
|
|
*) ;;
|
|
esac
|
|
|
|
# vim: set ft=sh ts=4 sw=4:
|