From 57fd9d0abb3eef387d8b194ea330762f0ee4b5a2 Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Tue, 4 May 2021 18:39:49 +0200 Subject: [PATCH] fix: [rsync-backup-target] disallow using same key for different ident in any admin account As key will map authorization to a specified directory, we can't allow having 2 keys pointing to 2 different directories. This must be enforced. Signed-off-by: Valentin Lab --- .../build/src/usr/local/sbin/ssh-key | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/rsync-backup-target/build/src/usr/local/sbin/ssh-key b/rsync-backup-target/build/src/usr/local/sbin/ssh-key index bf8599b..5588919 100755 --- a/rsync-backup-target/build/src/usr/local/sbin/ssh-key +++ b/rsync-backup-target/build/src/usr/local/sbin/ssh-key @@ -65,19 +65,45 @@ ssh-key-add() { ## ident are unique by construction (they are struct keys) ## but keys need to be also unique declare -A keys - mkdir -p "${RSYNC_KEY_PATH}/backup/$label" content="$type $key $email" ident="${email##*@}" target="${RSYNC_KEY_PATH}/backup/$label/$ident.pub" - if [ -e "$target" ]; then - old_content=$(cat "$target") - if [ "$content" == "$old_content" ]; then - echo "Provided key already present for '$ident'." >&2 - return 0 + + ## is key used already ? As key give access to a specified subdir, + ## we need to make sure it is unique. + + for key_file in "${RSYNC_KEY_PATH}/backup/"*/*.pub; do + [ -e "$key_file" ] || continue + key_content=$(cat "$key_file") + if [ "$type $key" == "${key_content% *}" ]; then + if [ "$key_file" == "$target" ]; then + echo "Provided key already present for '$ident'." >&2 + return 0 + elif [[ "$key_file" == "${RSYNC_KEY_PATH}/"*"/$label/"*.pub ]]; then + type=${key_file#"${RSYNC_KEY_PATH}/"} + type=${type%"/$label/"*.pub} + key_ident=${key_file##*/} + key_ident=${key_ident%.pub} + echo "Provided key already used as $type key for '$key_ident'." >&2 + return 1 + else + olabel=${key_file#"${RSYNC_KEY_PATH}/"*/} + olabel=${olabel%/*.pub} + echo "Specified key is already used by '$olabel' account, please pick another one." >&2 + return 1 + fi fi + done + + mkdir -p "${target%/*}" + if [ -e "$target" ]; then echo "Replacing key for '$ident'." >&2 - elif [ -e "${RSYNC_KEY_PATH}/backup/"*"/$ident.pub" ]; then - echo "ident '$ident' is already reserved, please pick another one." >&2 + elif [ -e "${RSYNC_KEY_PATH}/"*"/"*"/$ident.pub" ]; then + olabel=("${RSYNC_KEY_PATH}/"*"/"*"/$ident.pub") + olabel="${olabel[0]}" + olabel=${olabel#"${RSYNC_KEY_PATH}/"*/} + olabel=${olabel%/*.pub} + echo "ident '$ident' is already reserved by '$olabel', please pick another one." >&2 return 1 fi echo "$content" > "$target"