backup.sh 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/bin/bash
  2. #
  3. # This script will perform encrypted backups of a bunch of files or a folder.
  4. #
  5. # A backup is defined as:
  6. # - A copy of a file that has been compressed as to occupy less space than the
  7. # original (an archive)
  8. # - A way of adding more files to said archive as you wish, thus allowing the
  9. # archive to grow as needed, depending on whether more files come in.
  10. #
  11. # It relies heavily upon GPG for its business
  12. #
  13. # Development roadmap:
  14. # - Allow opening an encrypted file, adding new content and closing it again
  15. # - Allow the distinction between files and folders for backup.
  16. # - Allow changing the recipient for the backup
  17. # - Allow a rudimentary versioning system.
  18. # - Implement a preferences system for the script, where a user can change the
  19. # default archive format (ex Zip, tar.bz2, 7z), etc.
  20. #
  21. #
  22. # Copyright (C) 2016 - Klaus Zimmermann - https://quitter.se/kzimmermann
  23. #
  24. # This program is free software: you can redistribute it and/or modify
  25. # it under the terms of the GNU General Public License as published by
  26. # the Free Software Foundation, either version 3 of the License, or
  27. # (at your option) any later version.
  28. #
  29. # This program is distributed in the hope that it will be useful,
  30. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  32. # GNU General Public License for more details.
  33. #
  34. # You should have received a copy of the GNU General Public License
  35. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  36. #
  37. # The software version:
  38. VERSION="0.4 - alpha"
  39. # We now use a config dotfile in the user's home folder:
  40. CONFIG="$HOME/.backuprc"
  41. if [[ ! -f "$CONFIG" ]]
  42. then
  43. echo "Error: configuration file not found at $CONFIG"
  44. echo "Please copy the backuprc file into your home folder and try again."
  45. exit 1
  46. fi
  47. while read line
  48. do
  49. if [[ -z $(echo "$line" | grep -E '^#' ) ]]
  50. then
  51. if [[ "$line" == "" ]]
  52. then
  53. continue
  54. else
  55. key=$(echo "$line" | cut -d "=" -f 1)
  56. case "$key" in
  57. "recipient" )
  58. recipient=$(echo "$line" | cut -d "=" -f 2)
  59. ;;
  60. "autosign" )
  61. SIGN=$(echo "$line" | cut -d "=" -f 2)
  62. ;;
  63. * )
  64. echo "Skipping unknown configuration option '$key'"
  65. ;;
  66. esac
  67. fi
  68. fi
  69. done < $CONFIG
  70. # State variables to be changed by the arguments. Do not edit manually.
  71. FILENAME=""
  72. ACTION=""
  73. # check dependencies just in case:
  74. if [[ -z "$(which gpg)" ]]
  75. then
  76. echo "Error: please install gpg to use this script"
  77. exit 1
  78. fi
  79. if [[ -z "$(which tar)" ]]
  80. then
  81. echo "Error: please install tar to use this script"
  82. exit 1
  83. fi
  84. if [[ -z "$recipient" ]]
  85. then
  86. echo "Error: no recipient specified."
  87. echo "Please indicate a recipient in the 'recipient= ' line and try again."
  88. echo "Note that this recipient must be listed in your GPG keyring"
  89. exit 1
  90. fi
  91. # Functions used by this script:
  92. helper() {
  93. cat <<EOF_HELPER
  94. Usage: $(basename $0) COMMAND FOLDER [OPTION]
  95. Commands are:
  96. -e, --encrypt: creates an encrypted archive from FOLDER to the recipient
  97. -d, --decrypt: attempts to decrypt the encrypted archive FOLDER
  98. Available options are:
  99. -h, --help: shows this help message
  100. -s, --sign: also signs the encrypted package with your main private key
  101. The recipient chosen must be listed in your GPG keyring as well.
  102. The current recipient is: $recipient
  103. EOF_HELPER
  104. gpg --list-keys $recipient
  105. echo "Version: $VERSION"
  106. }
  107. encrypt() {
  108. if [[ -z "$1" ]]
  109. then
  110. echo "Please select a folder to back up and encrypt."
  111. exit 1
  112. elif [[ ! -d "$1" ]]
  113. then
  114. echo "Error: '$1' either doesn't exist or isn't a folder. $(basename $0) can only back up folders."
  115. echo "Please put your desired files in a folder and try again with that folder."
  116. exit 1
  117. fi
  118. local filename="$(basename "$1")$(date +%Y%m%d).tar.gz"
  119. printf "Now encrypting folder '$1' to recipient $recipient ... "
  120. tar -czvf "$filename" $1
  121. if [[ "$SIGN" == true ]]
  122. then
  123. gpg -r "$recipient" --sign --encrypt "$filename"
  124. else
  125. gpg -r "$recipient" --encrypt "$filename"
  126. fi
  127. shred -u "$filename"
  128. printf "Finished\n"
  129. }
  130. decrypt() {
  131. local finalfilename=""
  132. local testname="$(echo ${1/.asc/})"
  133. if [[ "$1" == "$testname" ]]
  134. then
  135. # file might be .gpg
  136. finalfilename="$(echo ${1/.gpg/})"
  137. else
  138. finalfilename="$(echo ${1/.asc/})"
  139. fi
  140. echo "Attempting to decrypt file '$1' using $recipient's key..."
  141. gpg --decrypt "$1" > "$finalfilename" || echo "Failed to decrypt the file."
  142. tar -xzvf "$finalfilename"
  143. shred -u "$finalfilename"
  144. }
  145. # Check command-line arguments:
  146. if [[ "$#" == 0 ]]
  147. then
  148. echo "Missing arguments."
  149. helper
  150. exit 1
  151. else
  152. while [[ -n $1 ]]
  153. do
  154. case "$1" in
  155. "-h" | "--help" )
  156. helper; exit 0
  157. ;;
  158. "-e" | "--encrypt" )
  159. if [[ -z "$ACTION" ]]
  160. then
  161. ACTION="encrypt"
  162. shift
  163. FILENAME="$1"
  164. else
  165. echo "Error: cannot encrypt and decrypt at the same time!"
  166. exit 1
  167. fi
  168. ;;
  169. "-d" | "--decrypt" )
  170. if [[ -z "$ACTION" ]]
  171. then
  172. ACTION="decrypt"
  173. shift
  174. FILENAME="$1"
  175. else
  176. echo "Error: cannot encrypt and decrypt at the same time!"
  177. exit 1
  178. fi
  179. ;;
  180. "-s" | "--sign" )
  181. SIGN=true
  182. ;;
  183. * ) echo "Invalid arguments. Please see '$(basename $0) -h'" ;;
  184. esac
  185. shift
  186. done
  187. fi
  188. if [[ "$ACTION" == "encrypt" ]]
  189. then
  190. encrypt "$FILENAME"
  191. elif [[ "$ACTION" == "decrypt" ]]
  192. then
  193. decrypt "$FILENAME"
  194. else
  195. echo "Error: missing arguments."
  196. helper
  197. exit 1
  198. fi
  199. exit 0