diff --git a/README.md b/README.md index c3b440f..09f1893 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # otpish OTPish is a bash script that wraps oathtool and age to provide a workflow to manage totp codes. - + This is just thrown together and should probably not be used in production. - -YMMV. \ No newline at end of file + +YMMV. + +`otpish help` should be useful diff --git a/otpish b/otpish new file mode 100755 index 0000000..09f0105 --- /dev/null +++ b/otpish @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +COMMAND=$1 +NAME=$2 +DEPENDS=("age" "oathtool") +OTPISH_HOME=${HOME}/.otpish +OTP=${OTPISH_HOME}/otp +PRIVKEY=${OTPISH_HOME}/privkey +PUBKEY=${OTPISH_HOME}/pubkey + +print_help() { + echo otpish is a little wrapper around oathtool + echo this was just thrown together an is probably not prod ready + echo it stores your password encrypted key at ~/.otpish/key + echo it stores your encrypted otp secret keys in ~/.otpish/otp + echo depends on: $(for i in ${DEPENDS[@]}; do echo -n "${i} "; done) + echo commands: + echo help print this help + echo dump dump out all raw otpauth uris + echo get get otp code with passed name +} + +if [ "${COMMAND}" = "help" ]; then + print_help +fi + +# check if dependent packages exist +for pkg in ${DEPENDS[@]}; do + if ! command -v ${pkg} &> /dev/null; then + echo "please install ${pkg}" + echo "install using apt? y/N" + read install_pkg + if [ "${install_pkg}" = "y" ] || [ "${install_pkg}" = "Y"]; then + sudo apt install ${pkg} + fi + fi +done + +# check if key exists +if ! [ -d "${OTPISH_HOME}" ]; then + mkdir ${OTPISH_HOME} +fi + +if ! [ -f "${PRIVKEY}" ]; then + echo creating keypair + age-keygen 2> ${PUBKEY} | age --passphrase --output ${PRIVKEY} + sed -i 's/Public key: //' ${PUBKEY} +fi + +if [ "${COMMAND}" = "dump" ]; then + if ! [ -f ${OTP} ]; then echo no otps configured add one first; exit; fi + age -i ${PRIVKEY} -d ${OTP} + exit +fi + +if [ "${COMMAND}" = "get" ]; then + if [ -z ${NAME} ]; then echo get requires a name; exit; fi + if ! [ -f ${OTP} ]; then echo no otps configured add one first; exit; fi + uri=$(age -i ${PRIVKEY} -d ${OTP} | grep "${NAME}?") + otp_info=$(echo -n ${uri} | cut -d '?' -f 2) + oIFS=${IFS} + IFS="&" + declare -a fields=(${otp_info}) + IFS=${oIFS} + for i in ${fields[@]}; do + if [ "$(echo ${i} | cut -d'=' -f1)" = "secret" ]; then secret=$(echo ${i} | cut -d'=' -f2); fi + if [ "$(echo ${i} | cut -d'=' -f1)" = "digits" ]; then digits=$(echo ${i} | cut -d'=' -f2); fi + if [ "$(echo ${i} | cut -d'=' -f1)" = "period" ]; then period=$(echo ${i} | cut -d'=' -f2); fi + done + oathtool --totp -b -s "${period}s" -d ${digits} ${secret} + exit +fi + +if [ "${COMMAND}" = "add" ]; then + echo input otpauth uri + read otp_uri + uri=${otp_uri} + if [ -f ${OTP} ]; then echo unlocking otp file; uris=$(age -i ${PRIVKEY} -d ${OTP}); else uris=""; fi + uris=(${uris} ${uri}) + echo ${uris[@]} | sed 's/ /\n/g' | age -r $(cat ${PUBKEY}) -o ${OTP} + exit +fi