utils/diceware.sh
Irrlicht a0de6e56b2
[diceware] Script to automatically fetch words for a diceware password
The 5 digits IDs should be generated using a proper method like using
actual dice.
2026-08-26 21:17:06 +02:00

124 lines
3 KiB
Shell
Executable file

#!/bin/bash
shopt -s extglob
##########
# Config #
# Path to the Diceware ID list
# DICEWARE_PATH=
print_help() {
echo "diceware [-l | --list] [<args>]"
echo ""
echo "Given a number, asked for as many 5 digits numbers and print the resulting password using the diceware word list."
echo ""
echo "With no option, expect a non zero positive integer for the number of words the script should expect. With the <list> option, expect a list of 5 digits numbers to select the words in the diceware word list."
echo ""
echo "Expects the envrionment variable DICEWARE_PATH to be defined and pointing to a file that is a diceware word list. The structure should be in two columns, the first being the 5 digits ID and the second the corresponding word."
}
is_valid_id() {
if [ ! ${#1} == 5 ]; then
echo "${1} is not a valid id."
return 1
fi
for ((i=0; i < ${#1}; i++)); do
digit=${1:$i:1}
if [ $digit -lt 1 -o $digit -gt 6 ]; then
echo "${1} is not a valid id."
return 1
fi
done
return 0
}
error_not_enough_number() {
echo "Number ${1} too low: it is not safe to generate a password of less than 6 words!"
exit 1
}
read_word_id_list() {
local counter=0
local word_number=${word_id_list[0]}
# Remove first element which is the number or IDs expected
word_id_list=(${word_id_list[@]:1:${#word_id_list[@]}})
while [ $counter -lt $word_number ]; do
read -p "Enter next number: " number
is_valid_id $number
if [ $? -gt 0 ]; then
echo "$number is not a valid number!"
else
word_id_list+=($number)
((counter++))
fi
done
}
##################
# Begin commands #
if [ ! $DICEWARE_PATH ]; then
echo "No or invalid path to the word list!"
echo "DICEWARE_PATH=$DICEWARE_PATH"
exit 2
fi
word_id_list=()
word_number_limit=6
mode_list=0
# Parsing option
while [ $# -gt 0 ]
do
case ${1} in
+([[:digit:]]))
word_id_list+=($1)
shift
;;
-l|--list)
mode_list=1
shift
;;
-h|--help)
print_help
exit 0
;;
*)
echo "Invalid argument: $1."
exit 1
;;
esac
done
if [ ${#word_id_list} -eq 0 ]; then
echo "Need to specify a number of a list of IDs"
exit 1
fi
if [ ${mode_list} -eq 0 -a ${word_id_list[0]} -lt ${word_number_limit} ]; then
error_not_enough_number ${word_id_list[0]}
fi
if [ $mode_list -eq 0 ]; then
read_word_id_list
fi
if [ ${#word_id_list[@]} -lt 6 ]; then
error_not_enough_number ${#word_id_list[@]}
fi
# Check IDs are valid
for word_id in ${word_id_list[@]}; do
is_valid_id $word_id
if [ $? -gt 0 ]; then
exit $?
fi
done
# Get the actual word
password=()
for word_id in ${word_id_list[@]}; do
password+=($(grep ${word_id} ${DICEWARE_PATH} | awk '{ print $2 }'))
done
# Join everything in one string
echo "${password[@]} "
exit 0