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
3.2 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. exname=$(basename "$0")
  5. mkdir -p /var/log/rsync
  6. LOG="/var/log/rsync/$exname.log"
  7. ssh_connection=(${SSH_CONNECTION})
  8. SSH_SOURCE_IP="${ssh_connection[0]}:${ssh_connection[1]}"
  9. log() {
  10. printf "%s [%s] %s - %s\n" \
  11. "$(date --rfc-3339=seconds)" "$$" "$SSH_SOURCE_IP" "$*" \
  12. >> "$LOG"
  13. }
  14. log "NEW ADMIN CONNECTION"
  15. if [ -z "$1" ] || ! [[ "$1" =~ ^[a-zA-Z0-9._-]+$ ]]; then
  16. log "INVALID SETUP, ARG IS: '$1'"
  17. echo "Your command has been rejected. Contact administrator."
  18. exit 1
  19. fi
  20. label="$1"
  21. reject() {
  22. log "REJECTED: $SSH_ORIGINAL_COMMAND"
  23. # echo "ORIG: $SSH_ORIGINAL_COMMAND" >&2
  24. echo "Your command has been rejected and reported to sys admin." >&2
  25. exit 1
  26. }
  27. if [[ "$SSH_ORIGINAL_COMMAND" =~ [\&\(\{\;\<\>\`\$\}] ]]; then
  28. log "BAD CHARS DETECTED"
  29. # echo "Bad chars: $SSH_ORIGINAL_COMMAND" >&2
  30. reject
  31. fi
  32. if [[ "$SSH_ORIGINAL_COMMAND" =~ ^"ssh-key add ssh-rsa "[a-zA-Z0-9/+]+" "[a-zA-Z0-9._-]+"@"[a-zA-Z0-9._-]+""$ ]]; then
  33. log "ACCEPTED: $SSH_ORIGINAL_COMMAND"
  34. ## Interpret \ to allow passing spaces (want to avoid possible issue with \n)
  35. #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}"
  36. ssh_args=(${SSH_ORIGINAL_COMMAND})
  37. # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2
  38. exec sudo /usr/local/sbin/ssh-key add "$label" "${ssh_args[@]:2}"
  39. elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"ssh-key ls"$ ]]; then
  40. log "ACCEPTED: $SSH_ORIGINAL_COMMAND"
  41. ## Interpret \ to allow passing spaces (want to avoid possible issue with \n)
  42. #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}"
  43. ssh_args=(${SSH_ORIGINAL_COMMAND})
  44. # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2
  45. exec /usr/local/sbin/ssh-key ls "$label" "${ssh_args[@]:2}"
  46. elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"ssh-key rm "[a-zA-Z0-9._-]+$ ]]; then
  47. log "ACCEPTED: $SSH_ORIGINAL_COMMAND"
  48. ## Interpret \ to allow passing spaces (want to avoid possible issue with \n)
  49. #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}"
  50. ssh_args=(${SSH_ORIGINAL_COMMAND})
  51. # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2
  52. exec sudo /usr/local/sbin/ssh-key rm "$label" "${ssh_args[@]:2}"
  53. elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^"request-recovery-key "[a-zA-Z0-9._-]+$ ]]; then
  54. log "ACCEPTED: $SSH_ORIGINAL_COMMAND"
  55. ## Interpret \ to allow passing spaces (want to avoid possible issue with \n)
  56. #read -a ssh_args <<< "${SSH_ORIGINAL_COMMAND}"
  57. ssh_args=(${SSH_ORIGINAL_COMMAND})
  58. # echo "Would accept: $SSH_ORIGINAL_COMMAND" >&2
  59. exec sudo /usr/local/sbin/request-recovery-key "$label" "${ssh_args[@]:1}"
  60. else
  61. log "NOT MATCHING ANY ALLOWED COMMAND"
  62. reject
  63. fi
  64. ## For other commands, like `find` or `md5`, that could be used to
  65. ## challenge the backups and check that archive is actually
  66. ## functional, I would suggest to write a simple command that takes no
  67. ## arguments, so as to prevent allowing wildcards or suspicious
  68. ## contents. Letting `find` go through is dangerous for instance
  69. ## because of the `-exec`. And path traversal can be done also when
  70. ## allowing /my/path/* by using '..'. This is why a fixed purpose
  71. ## embedded executable will be much simpler to handle, and to be honest
  72. ## we don't need much more.