#!/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 " } # 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