|
|
|
@ -1,23 +1,5 @@
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
infile=$1
|
|
|
|
|
id=$2
|
|
|
|
|
|
|
|
|
|
error() {
|
|
|
|
|
echo $* 1>&2
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
die() {
|
|
|
|
|
error $*
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unpack_data() {
|
|
|
|
|
datafile=$1
|
|
|
|
|
tar xf $infile -C $STORAGE || die "Failed to unpack data"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_publickey() {
|
|
|
|
|
local publickey=$STORAGE/id_rsa.pub
|
|
|
|
|
if ! [[ -f $publickey ]]
|
|
|
|
@ -43,82 +25,304 @@ check_header() {
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_key() {
|
|
|
|
|
local datadir=$1
|
|
|
|
|
local key=$datadir/key
|
|
|
|
|
if ! [[ -f $key ]]
|
|
|
|
|
|
|
|
|
|
PATH=/lib/rc/bin:$PATH
|
|
|
|
|
|
|
|
|
|
TEXTDOMAIN=cl_access_add
|
|
|
|
|
CL_ACCESS_VERSION=0.1.0_beta1
|
|
|
|
|
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 [--sshkey PKEY] [--header HEADER] --key KEYFILE --device DEVICE --mountpoint MOUNTPOINT
|
|
|
|
|
|
|
|
|
|
Version: $CL_ACCESS_VERSION
|
|
|
|
|
|
|
|
|
|
${DESCRIPTION}
|
|
|
|
|
|
|
|
|
|
-h, --help display all options and exit"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# вывод полной справки
|
|
|
|
|
# show the long help message
|
|
|
|
|
long_usage() {
|
|
|
|
|
echo "Usage: $0 --id ID [--sshkey PKEY] [--header HEADER] --key KEYFILE --device DEVICE --mountpoint MOUNTPOINT
|
|
|
|
|
|
|
|
|
|
Version: $CL_ACCESS_VERSION
|
|
|
|
|
|
|
|
|
|
${DESCRIPTION}
|
|
|
|
|
|
|
|
|
|
--id ID set access id
|
|
|
|
|
--sshkey PKEY public authorized key
|
|
|
|
|
--header HEADER separated LUKS header
|
|
|
|
|
--key KEYFILE LUKS key file
|
|
|
|
|
--device DEVICE LUKS device (/dev or PARTUUID)
|
|
|
|
|
--mountpoint MOUNTPOINT mount point
|
|
|
|
|
"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# подготовить параметры командной строки
|
|
|
|
|
# prepare the commmand line parameters
|
|
|
|
|
rearrange_params() {
|
|
|
|
|
set +e
|
|
|
|
|
TEMP=$(unset POSIXLY_CORRECT; getopt \
|
|
|
|
|
-o "h" \
|
|
|
|
|
--long help \
|
|
|
|
|
--long id: \
|
|
|
|
|
--long sshkey: \
|
|
|
|
|
--long header: \
|
|
|
|
|
--long key: \
|
|
|
|
|
--long device: \
|
|
|
|
|
--long mountpoint: \
|
|
|
|
|
-- "$@" 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
|
|
|
|
|
;;
|
|
|
|
|
--sshkey)
|
|
|
|
|
SSHKEY="$2"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--header)
|
|
|
|
|
HEADER="$2"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--key)
|
|
|
|
|
KEY="$2"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--device)
|
|
|
|
|
DEVICE="$2"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--partuuid)
|
|
|
|
|
PARTUUID="$2"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
--mountpoint)
|
|
|
|
|
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 ssh-rsa $(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
|
|
|
|
|
error "Crypt key for $(basename $datadir) not found"
|
|
|
|
|
eerror $"$sshkey is not public key"
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_mountpoint() {
|
|
|
|
|
local datadir=$1
|
|
|
|
|
local mp=$datadir/mountpoint
|
|
|
|
|
if ! [[ -f $mp ]]
|
|
|
|
|
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
|
|
|
|
|
error "Mount point for $(basename $datadir) not found"
|
|
|
|
|
eerror $"LUKS header is wrong"
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_partuuid() {
|
|
|
|
|
local datadir=$1
|
|
|
|
|
local uuid=$datadir/partuuid
|
|
|
|
|
if ! [[ -f $uuid ]]
|
|
|
|
|
check_luks_key() {
|
|
|
|
|
local key=$1
|
|
|
|
|
local header=$2
|
|
|
|
|
|
|
|
|
|
if ! [[ -f $key ]]
|
|
|
|
|
then
|
|
|
|
|
error "UUID for $(basename $datadir) not found"
|
|
|
|
|
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 || 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]+)$ ]]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_mountdata() {
|
|
|
|
|
for dn in $STORAGE/*
|
|
|
|
|
is_dev() {
|
|
|
|
|
[[ "$1" =~ ^/dev/ ]]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
create_record() {
|
|
|
|
|
local id=$1
|
|
|
|
|
local header=$2
|
|
|
|
|
local key=$3
|
|
|
|
|
local device=$4
|
|
|
|
|
local mp=$5
|
|
|
|
|
for rec in {0..99}
|
|
|
|
|
do
|
|
|
|
|
if [[ -d $dn ]]
|
|
|
|
|
recdn=$STORAGE/$id/$rec
|
|
|
|
|
if [[ ! -d $recdn ]]
|
|
|
|
|
then
|
|
|
|
|
check_header $dn || return 1
|
|
|
|
|
check_key $dn || return 1
|
|
|
|
|
check_mountpoint $dn || return 1
|
|
|
|
|
check_partuuid $dn || return 1
|
|
|
|
|
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_data() {
|
|
|
|
|
check_publickey || return 1
|
|
|
|
|
check_mountdata || return 1
|
|
|
|
|
}
|
|
|
|
|
check_setup || eerror $"Calculate access is not setup"
|
|
|
|
|
|
|
|
|
|
prepare_authorized() {
|
|
|
|
|
local publickey=$STORAGE/id_rsa.pub
|
|
|
|
|
cat >>$ACCESSDIR/.ssh/authorized_keys <<EOF
|
|
|
|
|
command="~/bin/access-shell $id",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa $(cat $publickey)
|
|
|
|
|
EOF
|
|
|
|
|
}
|
|
|
|
|
[[ -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"
|
|
|
|
|
|
|
|
|
|
if [[ -z $infile ]] || [[ -z $id ]]
|
|
|
|
|
then
|
|
|
|
|
echo "Usage: $0 DATAFILE ID" 1>&2
|
|
|
|
|
exit 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
ACCESSDIR=/var/lib/calculate/calculate-access/
|
|
|
|
|
STORAGE=$ACCESSDIR/storage/$id
|
|
|
|
|
|
|
|
|
|
if [[ -e $STORAGE ]]
|
|
|
|
|
then
|
|
|
|
|
die "ID $id already exists!"
|
|
|
|
|
else
|
|
|
|
|
unpack_data
|
|
|
|
|
if ! check_data
|
|
|
|
|
then
|
|
|
|
|
rm -rf $STORAGE
|
|
|
|
|
die "Failed to append data"
|
|
|
|
|
else
|
|
|
|
|
prepare_authorized $id
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
[[ -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
|
|
|
|
|
|
|
|
|
|
id_not_exists $ID || ask_rewrite_sshkey
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
id_not_exists $ID && create_id $ID
|
|
|
|
|
|
|
|
|
|
create_record "$ID" "$HEADER" "$KEY" "$DEVICE" "$MOUNTPOINT"
|
|
|
|
|
|
|
|
|
|
[[ -n $SSHKEY ]] && update_sshkey $ID $SSHKEY
|
|
|
|
|
|
|
|
|
|
echo "Access data appended"
|
|
|
|
|
einfo "All OK!"
|
|
|
|
|