qubes.RestoreById 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/bin/sh
  2. set -e
  3. REGISTRY_DIR="$XDG_RUNTIME_DIR/qubes-backup-location"
  4. backup_location_id="$1"
  5. if [ -z "$backup_location_id" ]; then
  6. echo "Missing backup location ID argument" >&2
  7. exit 1
  8. fi
  9. if ! [ -e "$REGISTRY_DIR/$backup_location_id" ]; then
  10. echo "Invalid location ID" >&2
  11. exit 1
  12. fi
  13. while true; do
  14. read -r check_pid check_starttime
  15. read -r backup_location
  16. break
  17. done < "$REGISTRY_DIR/$backup_location_id"
  18. if ! [ -e "/proc/$check_pid" ]; then
  19. echo "Invalid location ID" >&2
  20. exit 1
  21. fi
  22. pid_starttime=$(cut -f 22 -d ' ' "/proc/$check_pid/stat")
  23. if [ "$check_starttime" != "$pid_starttime" ]; then
  24. echo "Invalid location ID" >&2
  25. exit 1
  26. fi
  27. # now $backup_location is verified to be still valid
  28. echo Starting Restorecopy >&2
  29. read -r untrusted_paths
  30. echo "Backup location: $backup_location" >&2
  31. echo "Paths: $untrusted_paths" >&2
  32. if [ -f "$backup_location" ] ; then
  33. echo "Performing restore from backup file $backup_location" >&2
  34. TARGET="$backup_location"
  35. echo "Copying $TARGET to STDOUT" >&2
  36. # tar2qfile always use argv[1] for input path and the rest for selecting
  37. # paths to extract - no other options are supported, so passing
  38. # untrusted_paths directly is fine
  39. # shellcheck disable=SC2086
  40. /usr/lib/qubes/tar2qfile "$TARGET" $untrusted_paths
  41. else
  42. echo "Checking if arguments is matching a command" >&2
  43. COMMAND=$(echo "$backup_location" | cut -d ' ' -f 1)
  44. if command -v "$COMMAND" >/dev/null; then
  45. tmpdir=$(mktemp -d)
  46. mkfifo "$tmpdir/backup-data"
  47. echo "Redirecting $backup_location to STDOUT" >&2
  48. # Parsing args to handle quotes correctly
  49. # Dangerous method if args are uncontrolled
  50. eval "set -- $backup_location"
  51. # Use named pipe to pass original stdin to tar2file
  52. "$@" > "$tmpdir/backup-data" < /dev/null &
  53. # shellcheck disable=SC2086
  54. # tar2qfile always use argv[1] for input path and the rest for selecting
  55. # paths to extract - no other options are supported, so passing
  56. # untrusted_paths directly is fine
  57. /usr/lib/qubes/tar2qfile "$tmpdir/backup-data" $untrusted_paths
  58. # Restoration may be terminated earlier because of selected files. This
  59. # will be seen as EPIPE to the retrieving process, which may cause retcode
  60. # other than 0 in some cases - which would be incorrectly treated as backup
  61. # restore error. So instead of that, use tar2qfile exit code (and have dom0
  62. # detect if anything wrong with actual data)
  63. retcode=$?
  64. wait $!
  65. rm "$tmpdir/backup-data"
  66. rmdir "$tmpdir"
  67. exit "$retcode"
  68. else
  69. echo "Invalid command $COMMAND" >&2
  70. exit 2
  71. fi
  72. fi