From ab34c148a6c02289290be675d4854667303f0572 Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Tue, 24 Dec 2024 09:31:25 +0200 Subject: [PATCH] feat(bin): age tools (#20) * wip: ae for encryption, ad for decryption * feat: finished ad and ae, created a for both uses --- local/bin/a | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++ local/bin/ad | 62 +++++++++++++++++ local/bin/ae | 60 +++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100755 local/bin/a create mode 100755 local/bin/ad create mode 100755 local/bin/ae diff --git a/local/bin/a b/local/bin/a new file mode 100755 index 0000000..4139954 --- /dev/null +++ b/local/bin/a @@ -0,0 +1,184 @@ +#!/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 <" +} + +# 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 diff --git a/local/bin/ad b/local/bin/ad new file mode 100755 index 0000000..404640e --- /dev/null +++ b/local/bin/ad @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# age decrypt file with github keys + +# Use ENV or default values for keys file and source +KEYS_FILE="${AGE_KEYSFILE:-$HOME/.ssh/keys.txt}" +KEYS_SOURCE="${AGE_KEYSSOURCE:-https://github.com/ivuorinen.keys}" + +# Check for required commands +if ! command -v age &>/dev/null; then + echo "Error: age is not installed. Please install it to continue." + exit 1 +fi + +if ! command -v curl &>/dev/null; then + echo "Error: curl is not installed. Please install it to continue." + exit 1 +fi + +# Ensure a file is provided +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " + exit 1 +fi + +FILE="$1" +if [[ ! -f "$FILE" ]]; then + echo "Error: File '$FILE' does not exist." + exit 1 +fi + + +# Check if keys file exists, otherwise fetch it +if [[ ! -f "$KEYS_FILE" ]]; then + echo "Keys file '$KEYS_FILE' not found. Attempting to fetch from $KEYS_SOURCE..." + + # Create the directory if it doesn't exist + mkdir -p "$(dirname "$KEYS_FILE")" + + # Fetch the keys and save to the file + curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" + + if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then + echo "Error: Failed to fetch keys from $KEYS_SOURCE" + exit 1 + fi + + # Set permissions to 0400 + chmod 0400 "$KEYS_FILE" + echo "Keys file fetched and permissions set to 0400." +fi + +# Decrypt the file +OUTPUT_FILE="${FILE%.age}" +age -d -i "$KEYS_FILE" "$FILE" >"$OUTPUT_FILE" + +if [[ $? -eq 0 ]]; then + echo "File decrypted successfully: $OUTPUT_FILE" +else + echo "Error: Failed to decrypt file." + exit 1 +fi + diff --git a/local/bin/ae b/local/bin/ae new file mode 100755 index 0000000..7267579 --- /dev/null +++ b/local/bin/ae @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# age encrypt file with github keys + +# Use ENV or default values for keys file and source +KEYS_FILE="${AGE_KEYSFILE:-$HOME/.ssh/keys.txt}" +KEYS_SOURCE="${AGE_KEYSSOURCE:-https://github.com/ivuorinen.keys}" + +# Check for required commands +if ! command -v age &>/dev/null; then + echo "Error: age is not installed. Please install it to continue." + exit 1 +fi + +if ! command -v curl &>/dev/null; then + echo "Error: curl is not installed. Please install it to continue." + exit 1 +fi + +# Ensure a file is provided +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " + exit 1 +fi + +FILE="$1" +if [[ ! -f "$FILE" ]]; then + echo "Error: File '$FILE' does not exist." + exit 1 +fi + +# Check if keys file exists, otherwise fetch it +if [[ ! -f "$KEYS_FILE" ]]; then + echo "Keys file '$KEYS_FILE' not found. Attempting to fetch from $KEYS_SOURCE..." + + # Create the directory if it doesn't exist + mkdir -p "$(dirname "$KEYS_FILE")" + + # Fetch the keys and save to the file + curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" + + if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then + echo "Error: Failed to fetch keys from $KEYS_SOURCE" + exit 1 + fi + + # Set permissions to 0400 + chmod 0400 "$KEYS_FILE" + echo "Keys file fetched and permissions set to 0400." +fi + +# Encrypt the file +OUTPUT_FILE="${FILE}.age" +age -R "$KEYS_FILE" "$FILE" >"$OUTPUT_FILE" + +if [[ $? -eq 0 ]]; then + echo "File encrypted successfully: $OUTPUT_FILE" +else + echo "Error: Failed to encrypt file." + exit 1 +fi