mirror of
https://github.com/ivuorinen/dotfiles.git
synced 2026-01-26 11:14:08 +00:00
192 lines
4.4 KiB
Bash
Executable File
192 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# A script for encrypting and decrypting files or directories with age and SSH keys
|
|
|
|
VERSION="1.0.0"
|
|
|
|
# Default ENV values
|
|
KEYS_FILE="${AGE_KEYSFILE:-$HOME/.ssh/keys.txt}"
|
|
KEYS_SOURCE="${AGE_KEYSSOURCE:-https://github.com/ivuorinen.keys}"
|
|
LOG_FILE="${AGE_LOGFILE:-$HOME/.cache/a.log}"
|
|
|
|
VERBOSE=false
|
|
|
|
# Parse flags for verbosity
|
|
for arg in "$@"; do
|
|
if [[ "$arg" == "-v" || "$arg" == "--verbose" ]]; then
|
|
VERBOSE=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Ensure log directory and file exist with correct permissions
|
|
prepare_log_file()
|
|
{
|
|
local log_dir
|
|
log_dir=$(dirname "$LOG_FILE")
|
|
|
|
# Create log directory if it does not exist
|
|
if [[ ! -d "$log_dir" ]]; then
|
|
mkdir -p "$log_dir"
|
|
fi
|
|
|
|
# Create log file if it does not exist
|
|
if [[ ! -f "$LOG_FILE" ]]; then
|
|
touch "$LOG_FILE"
|
|
fi
|
|
|
|
# Set permissions to 0600
|
|
chmod 0600 "$LOG_FILE"
|
|
}
|
|
|
|
prepare_log_file
|
|
|
|
# Logging function
|
|
log_message()
|
|
{
|
|
local message="$1"
|
|
echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE"
|
|
|
|
# Print to user if verbose flag is set
|
|
if [[ "$VERBOSE" == true ]]; then
|
|
echo "$message"
|
|
fi
|
|
}
|
|
|
|
# Function to print usage
|
|
print_help()
|
|
{
|
|
cat << EOF
|
|
Usage: a [command] [file_or_directory] [options]
|
|
|
|
Commands:
|
|
e, enc, encrypt Encrypt the specified file or directory
|
|
d, dec, decrypt Decrypt the specified file or directory
|
|
help, --help Show this help message
|
|
version, --version Show version information
|
|
|
|
Options:
|
|
-v, --verbose Print log messages to console in addition to writing to log file
|
|
|
|
Environment Variables:
|
|
AGE_KEYSFILE Path to the SSH keys file (default: $HOME/.ssh/keys.txt)
|
|
AGE_KEYSSOURCE URL to fetch SSH keys if keys file does not exist
|
|
AGE_LOGFILE Path to the log file (default: $HOME/.cache/a.log)
|
|
|
|
Examples:
|
|
Encrypt a file:
|
|
a e file.txt
|
|
|
|
Encrypt a directory:
|
|
a e /path/to/directory
|
|
|
|
Decrypt a file:
|
|
a d file.txt.age
|
|
|
|
Specify a custom keys file:
|
|
AGE_KEYSFILE=/path/to/keys.txt a e file.txt
|
|
|
|
Specify a custom keys source and log file:
|
|
AGE_KEYSSOURCE=https://example.com/keys.txt AGE_LOGFILE=/tmp/a.log a d file.txt.age
|
|
EOF
|
|
}
|
|
|
|
# Function to print version
|
|
print_version()
|
|
{
|
|
echo "a version $VERSION"
|
|
echo "Created by Ismo Vuorinen <https://github.com/ivuorinen>"
|
|
}
|
|
|
|
# Function to fetch keys if missing
|
|
fetch_keys_if_missing()
|
|
{
|
|
if [[ ! -f "$KEYS_FILE" ]]; then
|
|
log_message "Keys file '$KEYS_FILE' not found. Attempting to fetch from $KEYS_SOURCE..."
|
|
mkdir -p "$(dirname "$KEYS_FILE")"
|
|
curl -s "$KEYS_SOURCE" -o "$KEYS_FILE"
|
|
|
|
if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then
|
|
log_message "Error: Failed to fetch keys from $KEYS_SOURCE"
|
|
exit 1
|
|
fi
|
|
|
|
chmod 0400 "$KEYS_FILE"
|
|
log_message "Keys file fetched and permissions set to 0400."
|
|
fi
|
|
}
|
|
|
|
# Function to encrypt files or directories
|
|
encrypt_file_or_directory()
|
|
{
|
|
local file="$1"
|
|
if [[ -d "$file" ]]; then
|
|
for f in "$file"/*; do
|
|
encrypt_file_or_directory "$f"
|
|
done
|
|
elif [[ -f "$file" ]]; then
|
|
fetch_keys_if_missing
|
|
local output_file="${file}.age"
|
|
age -R "$KEYS_FILE" "$file" > "$output_file"
|
|
if [[ $? -eq 0 ]]; then
|
|
log_message "File encrypted successfully: $output_file"
|
|
else
|
|
log_message "Error: Failed to encrypt file '$file'."
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Function to decrypt files or directories
|
|
decrypt_file_or_directory()
|
|
{
|
|
local file="$1"
|
|
if [[ -d "$file" ]]; then
|
|
for f in "$file"/*.age; do
|
|
decrypt_file_or_directory "$f"
|
|
done
|
|
elif [[ -f "$file" ]]; then
|
|
fetch_keys_if_missing
|
|
local output_file="${file%.age}"
|
|
age -d -i "$KEYS_FILE" "$file" > "$output_file"
|
|
if [[ $? -eq 0 ]]; then
|
|
log_message "File decrypted successfully: $output_file"
|
|
else
|
|
log_message "Error: Failed to decrypt file '$file'."
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Main logic
|
|
case "$1" in
|
|
e | enc | encrypt)
|
|
if [[ $# -lt 2 ]]; then
|
|
log_message "Error: No file or directory specified for encryption."
|
|
print_help
|
|
exit 1
|
|
fi
|
|
encrypt_file_or_directory "$2"
|
|
;;
|
|
d | dec | decrypt)
|
|
if [[ $# -lt 2 ]]; then
|
|
log_message "Error: No file or directory specified for decryption."
|
|
print_help
|
|
exit 1
|
|
fi
|
|
decrypt_file_or_directory "$2"
|
|
;;
|
|
help | --help)
|
|
print_help
|
|
;;
|
|
version | --version)
|
|
print_version
|
|
;;
|
|
*)
|
|
log_message "Error: Unknown command '$1'"
|
|
print_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# vim: ft=bash:syn=sh:ts=2:sw=2:et:ai:nowrap
|