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.

97 lines
2.5 KiB

  1. #!/bin/bash
  2. ## Note that the shebang is not used, but it's the login shell that
  3. ## will execute this command.
  4. RSYNC_KEY_PATH=/etc/rsync/keys
  5. RECOVER_KEY_PATH=${RSYNC_KEY_PATH}/recover
  6. exname=$(basename "$0")
  7. mkdir -p /var/log/rsync
  8. LOG="/var/log/rsync/$exname.log"
  9. ssh_connection=(${SSH_CONNECTION})
  10. SSH_SOURCE_IP="${ssh_connection[0]}:${ssh_connection[1]}"
  11. log() {
  12. printf "%s [%s] %s - %s\n" \
  13. "$(date --rfc-3339=seconds)" "$$" "$SSH_SOURCE_IP" "$*" \
  14. >> "$LOG"
  15. }
  16. log "NEW RECOVER CONNECTION"
  17. if [ -z "$1" ] || ! [[ "$1" =~ ^[a-z0-9]+$ ]]; then
  18. log "INVALID SETUP, ARG 1 SHOULD BE MD5 AND IS: '$1'"
  19. echo "Your command has been rejected. Contact administrator."
  20. exit 1
  21. fi
  22. md5="$1"
  23. log "RECOVER KEY $md5"
  24. if [ -z "$2" ] || ! [[ "$2" =~ ^[a-zA-Z0-9._-]+$ ]]; then
  25. log "INVALID SETUP, IDENT IS: '$1'"
  26. echo "Your command has been rejected. Contact administrator."
  27. exit 1
  28. fi
  29. ident="$2"
  30. log "IDENTIFIED AS $ident"
  31. reject() {
  32. log "REJECTED: $SSH_ORIGINAL_COMMAND"
  33. # echo "ORIG: $SSH_ORIGINAL_COMMAND" >&2
  34. echo "Your command has been rejected and reported to sys admin." >&2
  35. exit 1
  36. }
  37. if [[ "$SSH_ORIGINAL_COMMAND" =~ [\&\(\{\;\<\>\`\$\}] ]]; then
  38. log "BAD CHARS DETECTED"
  39. # echo "Bad chars: $SSH_ORIGINAL_COMMAND" >&2
  40. reject
  41. fi
  42. if [[ "$SSH_ORIGINAL_COMMAND" =~ ^"rsync --server --sender -"[vnldHogDtpArRze\.iLsfxC]+(" --"[a-z=%-]+|" --partial-dir .rsync-partial")*" . /var/mirror/$ident"(|/.*)$ ]]; then
  43. ## Interpret \ to allow passing spaces (want to avoid possible issue with \n)
  44. #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}"
  45. ssh_args=(${SSH_ORIGINAL_COMMAND})
  46. last_arg="${ssh_args[@]: -1:1}"
  47. if ! new_path=$(realpath "$last_arg" 2>/dev/null); then
  48. log "FINAL PATH INVALID"
  49. reject
  50. fi
  51. if [[ "$new_path" != "$last_arg" ]] &&
  52. [[ "$new_path" != "/var/mirror/$ident/"* ]] &&
  53. [[ "$new_path" != "/var/mirror/$ident" ]]; then
  54. log "FINAL PATH SUSPICIOUS"
  55. reject
  56. fi
  57. sudo /usr/local/sbin/ssh-update-keys
  58. if ! [ -e "${RECOVER_KEY_PATH}/$md5" ]; then
  59. log "RECOVERY KEY $md5 JUST EXPIRED"
  60. reject
  61. fi
  62. log "ACCEPTED RECOVER COMMAND: $SSH_ORIGINAL_COMMAND"
  63. sudo "${ssh_args[@]}"
  64. errlvl="$?"
  65. for key_file in "${RECOVER_KEY_PATH}/$md5"{,.pub}; do
  66. [ -e "$key_file" ] || continue
  67. sudo touch "$key_file" ## Update modified time to keep key longer
  68. done
  69. exit "$errlvl"
  70. else
  71. log "REFUSED COMMAND AS IT DOESN'T MATCH ANY EXPECTED COMMAND"
  72. reject
  73. fi