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.
calculate-access/scripts/cl-access-add

301 lines
6.6 KiB

#!/bin/bash
PATH=/lib/rc/bin:$PATH
TEXTDOMAIN=cl_access_add
CL_ACCESS_VERSION=0.1.0_alpha1
DESCRIPTION=$"Access preparing tools"
DEBUG_LOG=/var/log/calculate/cl-access-add.log
USERNAME=access
ACCESSDIR=/var/lib/calculate/calculate-access/
STORAGE=$ACCESSDIR/storage
# прервать скрипт в случае ошибки любой из команд
# break the script execution in case of a command error
set -e
: >$DEBUG_LOG
# вывод короткой справки
# show the short help message
usage() {
echo "Usage: $0 --id ID [--ssh-key PKEY] [--header HEADER] --key KEYFILE --device DEVICE --mount DIR
Version: $CL_ACCESS_VERSION
${DESCRIPTION}
-h, --help display all options and exit"
}
# вывод полной справки
# show the long help message
long_usage() {
echo "Usage: $0 --id ID [--ssh-key PKEY] [--header HEADER] --key KEYFILE --device DEVICE --mount DIR
Version: $CL_ACCESS_VERSION
${DESCRIPTION}
--id ID set access id
-s PKEY, --ssh-key PKEY public authorized key
-H HEADER, --header HEADER separated LUKS header
-k KEYFILE, --key KEYFILE LUKS key file
-d DEVICE, --device DEVICE LUKS device (/dev or PARTUUID)
-m DIR, --mount DIR mount point
"
}
# подготовить параметры командной строки
# prepare the commmand line parameters
rearrange_params() {
set +e
TEMP=$(unset POSIXLY_CORRECT; getopt \
-o "hs:H:k:d:m:" \
--long help \
--long id: \
--long ssh-key: \
--long header: \
--long key: \
--long device: \
--long mount: \
-- "$@" 2>&1)
if (( $? != 0 )); then
echo "$TEMP" | sed 's/getopt: /cl-access-add: /;$d'
exit 1
fi
set -e
}
# выполнить параметры командной строки
# apply the command line parameters
do_args() {
while :; do
case $1 in
-h|--help)
long_usage
exit 0
;;
--id)
ID="$2"
shift
;;
-s|--ssh-key)
SSHKEY="$2"
shift
;;
-H|--header)
HEADER="$2"
shift
;;
-k|--key)
KEY="$2"
shift
;;
-d|--device)
DEVICE="$2"
shift
;;
-m|--mount)
MP="$2"
shift
;;
--) shift; break;;
*) usage;
eerror $"Unknown option: $1"
;;
esac
shift
done
if [[ -n $1 ]]
then
usage;
eerror $"Unknown argument: $1"
fi
}
######################
# Обработать параметры
# Process the options
######################
rearrange_params "$@"
eval set -- "$TEMP"
do_args "$@"
check_setup() {
[[ -d $ACCESSDIR ]]
}
id_not_exists() {
local id=$1
[[ ! -d $STORAGE/$id ]]
}
create_id() {
local id=$1
local dn=$STORAGE/$id
mkdir -p $dn
chown $USERNAME. -R $dn
}
update_sshkey() {
local id=$1
local sshkey=$2
local publickey=$STORAGE/$id/id_rsa.pub
local sshdir=$ACCESSDIR/.ssh
local authkeys=$sshdir/authorized_keys
cp $sshkey $publickey
chown $USERNAME. $publickey
if [[ -f $authkeys ]]
then
sed -i "/access-shell $id/d" $authkeys
else
if [[ ! -d $sshdir ]]
then
mkdir -p $sshdir
chown $USERNAME. $sshdir
fi
touch $authkeys
fi
cat >>$authkeys <<EOF
command="~/bin/access-shell $id",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty $(cat $publickey)
EOF
chown $USERNAME. $authkeys
}
ask_rewrite_sshkey() {
while true
do
read -p $"Do you want replace authorzied key? " yn
case $yn in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) ewarn $"Please answer yes or no." ;;
esac
done
}
check_sshkey() {
local sshkey=$1
if ! [[ -f $sshkey ]]
then
eerror $"Public authorized key not found"
return 1
fi
if grep -q "PRIVATE KEY" $sshkey
then
eerror $"You should use public key instead private"
return 1
fi
if ! ssh-keygen -l -f $sshkey &>/dev/null
then
eerror $"$sshkey is not public key"
return 1
fi
return 0
}
check_luks_header() {
local header=$1
if ! [[ -f $header ]]
then
eerror $"LUKS header not found"
return 1
fi
if ! cryptsetup isLuks $header &>/dev/null
then
eerror $"LUKS header is wrong"
return 1
fi
return 0
}
check_luks_key() {
local key=$1
local header=$2
if ! [[ -f $key ]]
then
eerror $"LUKS key not found"
return 1
fi
if [[ -z $header ]]
then
ewarn $"Could not check key without header"
return 0
else
cryptsetup -d $key -q luksDump --dump-master-key $header &>/dev/null || eerror "Wrong LUKS key/header pair"
fi
}
check_device_name() {
local device=$1
is_uuid $device || is_dev $device || eerror $"Device must be PARTUUID or /dev"
}
is_uuid() {
[[ "$1" =~ ^(PARTUUID=)?\"?(([0-9a-f]+-)+[0-9a-f]+)\"?$ ]]
}
is_dev() {
[[ "$1" =~ ^/dev/ ]]
}
create_record() {
local id=$1
local key=$2
local device=$3
local mp=$4
local header=$5
for rec in {0..99}
do
recdn=$STORAGE/$id/$rec
if [[ ! -d $recdn ]]
then
mkdir -p $recdn
[[ -n $header ]] && cp $header $recdn/header
cp $key $recdn/key
if is_uuid $device
then
echo ${BASH_REMATCH[2]} >$recdn/partuuid
else
echo $device >$recdn/dev
fi
echo $mp >$recdn/mountpoint
break
fi
done
}
check_setup || eerror $"Calculate access is not setup"
[[ -z $ID ]] && usage && eerror $"Please specify ID"
[[ -z $SSHKEY ]] && id_not_exists $ID && eerror $"You should specify ssh key for register new ID"
[[ -z $KEY ]] && usage && eerror $"Please specify LUKS key"
[[ -z $DEVICE ]] && usage && eerror $"Please specify LUKS device"
[[ -z $MP ]] && usage && eerror $"Please specify mount point"
[[ -n $HEADER ]] && check_luks_header $HEADER
[[ -n $KEY ]] && check_luks_key $KEY $HEADER
[[ -n $SSHKEY ]] && check_sshkey $SSHKEY
#check_mount_point_name $MOUNTPOINT
check_device_name $DEVICE
if [[ -n $SSHKEY ]]
then
id_not_exists $ID || ask_rewrite_sshkey
fi
id_not_exists $ID && create_id $ID
create_record "$ID" "$KEY" "$DEVICE" "$MP" "$HEADER"
[[ -n $SSHKEY ]] && update_sshkey $ID $SSHKEY
einfo "All OK!"