Skip to content

Commit

Permalink
feat(bin): age tools (#20)
Browse files Browse the repository at this point in the history
* wip: ae for encryption, ad for decryption
* feat: finished ad and ae, created a for both uses
  • Loading branch information
ivuorinen authored Dec 24, 2024
1 parent 910b29e commit ab34c14
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 0 deletions.
184 changes: 184 additions & 0 deletions local/bin/a
Original file line number Diff line number Diff line change
@@ -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 <<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
62 changes: 62 additions & 0 deletions local/bin/ad
Original file line number Diff line number Diff line change
@@ -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 <file-to-decrypt>"
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

60 changes: 60 additions & 0 deletions local/bin/ae
Original file line number Diff line number Diff line change
@@ -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 <file-to-encrypt>"
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

0 comments on commit ab34c14

Please sign in to comment.