diff options
-rwxr-xr-x | bin/crypted-backups | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/bin/crypted-backups b/bin/crypted-backups new file mode 100755 index 0000000..d0c80aa --- /dev/null +++ b/bin/crypted-backups @@ -0,0 +1,286 @@ +#!/usr/bin/env bash +set -e -u + +. /etc/crypted-backups +user_mode="" +source_mode="" +verbose='' + +test_source="/tmp/test" +test_destination="/home/dave/Downloads/test" + + +function notification_source_to_destination () { + local source_directory=$1 + local destination_directory=$2 + if [ $source_directory != "" -a $destination_directory != "" ];then + echo "$source_directory -> $destination_directory" + return 0 + else + echo "Source ($source_directory) or destination ($destination_directory) directory not given!" + return 1 + fi +} + +function generate_timestamp () { + local timestamp="$(date +"%Y%m%d-%H%M%S")-" + echo ${timestamp} + return 0 +} + +# Adds trailing slash, if missing +# Fails when path is not absolute, or not within user home, when not root +function sanitize_pathname () { + local path=$1 + if [ ${#path} -ne 0 ]; then + if [ ${path:0:1} = "/" -o ${path:0:2} = "~/" -a $(id -u) -ne 0 ]; then + if [ ${path:${#path}-1} != "/" ]; then + echo "$path/" + return 0 + else + echo "$path" + return 0 + fi + else + echo "Directory must be absolute!" + return 1 + fi + else + echo "Directory can not be empty!" + return 1 + fi +} + +function check_directory_exists () { + local destination=$1 + if [ ! -d $destination ]; then + echo "Directory \"$destination\" does not exist yet. Creating..." + mkdir -p $destination + else + return 0 + fi +} + +function check_directory_permission_root () { + if [ -w $1 ]; then + return 0 + else + echo "Directory not writable: $1." + return 1 + fi +} + +function check_directory_writable_user () { + if [ -w $1 ]; then + return 0 + else + echo "Directory not writable: $1." + return 1 + fi +} + +function check_directory_owner_user() { + if [ ! -O $1 ]; then + echo "Directory not owned by user $(whoami): $1" + return 1 + else + return 0 + fi +} + +function check_user_directory () { + local directory=$1 + check_directory_exists $directory + check_directory_writable_user $directory + return 0 +} + +function check_root_directory () { + local directory=$1 + check_directory_exists $directory + check_directory_permission_root $directory + return 0 +} + +function get_parent_directory () { + local directory=$1 + local parent="" + parent=$(dirname $directory) + parent=$(sanitize_pathname $parent) + echo "$parent" + return 0 +} + +function get_basename_directory () { + local directory=$1 + local base=$(basename $directory) + echo "$base" + return 0 +} + +function compress_directory () { + local source_directory=$1 + local tmp_file=$2 + echo "Compressing source directory ($source_directory) to temporary file ($tmp_file)." + case $tar_suffix in + ".tar.tbz") + tar cfj "$tmp_file" $source_directory + ;; + ".tar.tgz") + tar cfz "$tmp_file" $source_directory + ;; + ".tar.tlz") + tar --lzma -cf "$tmp_file" $source_directory + ;; + ".tar.xz") + tar cfJ "$tmp_file" $source_directory + ;; + *) + echo "Using \"$tar_suffix\" as \$tar_suffix is not supported." + return 1 + ;; + esac + return 0 +} + +function encrypt_tmp_file () { + local tmp_file=$1 + local destination_file=$2 + echo "Encrypting $tmp_file to $destination_file." + gpg -e \ + -r "$gpg_public_key" \ + -o "$destination_file" \ + "$tmp_file" + echo "Removing $tmp_file." + rm -f "$tmp_file" + return 0 +} + +function backup_single_directory () { + local source_directory=$1 + local source_directory_basename=$(get_basename_directory $source_directory) + local source_parent_directory=$(get_parent_directory $source_directory) + local tmp_directory=$(sanitize_pathname $tmp) + local destination_directory=$(sanitize_pathname $2) + local timestamp=$(generate_timestamp) + local tmp_file="$tmp_directory$timestamp$source_directory_basename$tar_suffix" + local destination_file="$destination_directory$timestamp$source_directory_basename$tar_suffix$gpg_suffix" + notification_source_to_destination "$source_parent_directory$source_directory_basename" $destination_file + echo "Going to $source_directory_basename's parent directory: $source_parent_directory." + cd $source_parent_directory + + check_directory_exists $source_directory + "check_"$user_mode"_directory" $tmp_directory + "check_"$user_mode"_directory" $destination_directory + compress_directory $source_directory_basename $tmp_file + encrypt_tmp_file $tmp_file $destination_file +} + +function backup_multiple_directories () { + local source_directory=$(sanitize_pathname $1) + local destination_directory=$(sanitize_pathname $2) + "check_"$user_mode"_directory" $destination_directory + for sub_directory in $source_directory* + do + if [ -d $sub_directory ];then + "check_"$user_mode"_directory" $sub_directory + backup_single_directory $sub_directory $destination_directory + fi + done + +} + +function set_user_mode () { + if [ $(id -u) -eq 0 ]; then + user_mode="root" + else + user_mode="user" + fi + return 0 +} + +function check_gpg_set () { + if [ -z "$gpg_public_key" ];then + echo "Error. gpg_public_key not set!" + exit 1 + fi +} + +function print_help () { + echo "help" + exit 0 +} + +#TODO: Add function to delete compressed data in working directory (also after fail) +#TODO: Add function for database backups +#TODO: Add function to cleanup backups +#TODO: Add function to mirror backups +#TODO: Add function to automatically add key to keyring, if not found +#TODO: Create logic to distinguish between different backups +#TODO: Add verbose flag + + +check_gpg_set +set_user_mode + +if [ ${#@} -gt 0 ]; then + while getopts 'c:hr:s:v' flag; do + case "${flag}" in + c) + echo "Cleanup" + ;; + h) + print_help + ;; + r) + echo "recall" + ;; + s) + source_mode="${OPTARG}" + ;; + v) + verbose='true' + ;; + *) + echo "Error. Unrecognized option: ${flag}." + exit 1 + ;; + esac + done +else + print_help +fi + +if [ -n "$source_mode" ];then + case $source_mode in + aura) + ;; + bitlbee) + ;; + etc) + backup_single_directory $etc_source $etc_destination + ;; + git) + ;; + mail) + ;; + mailman) + ;; + mariadb) + ;; + logs) + ;; + websites) + ;; + firefox) + ;; + thunderbird) + ;; + weechat) + ;; + *) + echo "Error. $source_mode is not a valid backup option." + exit 1 + esac +fi + |