98 lines
1.4 KiB
Bash
Executable File
98 lines
1.4 KiB
Bash
Executable File
#! /bin/sh
|
|
|
|
set -e
|
|
|
|
usage()
|
|
{
|
|
echo "$0 <dir>"
|
|
}
|
|
|
|
to_hex()
|
|
{
|
|
od -An -t x1 | tr -d ' ' | tr -d '\n'
|
|
}
|
|
|
|
to_bin()
|
|
{
|
|
sed -e 's,\([0-9a-f]\{2\}\),\\\\\\x\1,g' | xargs printf
|
|
}
|
|
|
|
mktemp_posix()
|
|
{
|
|
m4 <<EOF
|
|
mkstemp(${TMPDIR:-/tmp}/tmp.XXXXXX)
|
|
EOF
|
|
}
|
|
|
|
if [ $# != 1 ]; then
|
|
usage >&2
|
|
exit 1
|
|
fi
|
|
|
|
DIR=$1
|
|
|
|
echo Username: >&2
|
|
IFS= read -r USER
|
|
|
|
if printf '%s' "$USER" | grep -qe '[[:space:]]'
|
|
then
|
|
echo Username cannot contain whitespaces >&2
|
|
exit 1
|
|
fi
|
|
|
|
DB="$DIR/db.json"
|
|
|
|
if jq '.users[].name' "$DB" | grep -q $USER
|
|
then
|
|
echo User $USER already in $DB >&2
|
|
exit 1
|
|
fi
|
|
|
|
TTYCFG=$(stty -g)
|
|
trap "stty $TTYCFG" INT QUIT TERM EXIT
|
|
stty -echo
|
|
echo Password: >&2
|
|
IFS= read -r PWD
|
|
stty echo
|
|
# Force newline
|
|
echo
|
|
|
|
echo "Quota, in MiB (leave empty for unlimited quota):" >&2
|
|
read -r QUOTA
|
|
QUOTA="$(printf '%d' "$QUOTA")"
|
|
|
|
PWD=$(printf '%s' "$PWD" | to_hex)
|
|
SALT=$(openssl rand -hex 32)
|
|
KEY=$(openssl rand -hex 32)
|
|
PWD=$(printf '%s%s' "$SALT" "$PWD")
|
|
|
|
ROUNDS=1000
|
|
|
|
for i in $(seq $ROUNDS)
|
|
do
|
|
printf "\r%d/$ROUNDS" $i >&2
|
|
PWD=$(printf '%s' "$PWD" | to_bin | openssl sha256 -r | cut -d' ' -f1)
|
|
done
|
|
|
|
echo >&2
|
|
TMP=$(mktemp_posix)
|
|
|
|
cleanup()
|
|
{
|
|
rm -f $TMP
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
jq ".users += [
|
|
{
|
|
\"name\": \"$USER\",
|
|
\"password\": \""$PWD"\",
|
|
\"salt\": \"$SALT\",
|
|
\"key\": \"$KEY\",
|
|
\"quota\": \"$QUOTA\"
|
|
}]" "$DB" > $TMP
|
|
|
|
mkdir -p "$DIR/user/$USER"
|
|
mv $TMP "$DB"
|