File check-for-expired-apt-key-and-rename-it of Package kimi-utils-ubuntu
#!/bin/bash
LANG=C
# Parse options
NO_COLORS=0
DEBUG=0 # default: hide detailed per-file checks; set to 1 with --debug
for arg in "$@"; do
case "$arg" in
--no-colors) NO_COLORS=1 ;;
--debug) DEBUG=1 ;;
*) ;;
esac
done
# Helper to conditionally print detailed info (shown only when --debug is passed)
dprint() {
if [[ $DEBUG -eq 1 ]]; then
echo "$@"
fi
}
dprinte() {
if [[ $DEBUG -eq 1 ]]; then
echo "$@" >&2
fi
}
# ANSI color codes (disabled if --no-colors passed)
if [[ $NO_COLORS -eq 0 ]] && [[ -t 1 ]] && tput setaf 1 &> /dev/null; then
RED=$(tput setaf 1) # Red for "expired"
GREEN=$(tput setaf 2) # Green for paths
NC=$(tput sgr0) # Reset to default color
else
RED=""
GREEN=""
NC=""
fi
readonly KEYRING_DIRS=(
"/etc/apt/trusted.gpg.d"
"/etc/apt/keyrings"
"/usr/share/keyrings"
)
# Check for expired APT keys
expired_keys=()
for KEYRING_DIR in "${KEYRING_DIRS[@]}"; do
for keyfile in "$KEYRING_DIR"/*.gpg; do
if [ -f "$keyfile" ]; then
# retrieve key data
key_data=$(gpg --with-colons --show-keys "$keyfile" 2>/dev/null)
if [[ $? -ne 0 || -z "$key_data" ]]; then
dprinte "Failed to retrieve key data from $keyfile."
continue
fi
# --- Detailed per-file output (shown only with --debug) ---
# Get unique numeric, non-empty pub expiration epochs
mapfile -t expiration_dates < <(
echo "$key_data" \
| awk -F: '$1 == "pub" && $7 ~ /^[0-9]+$/ {print $7}' \
| sort -n -u
)
# Compute earliest non-zero timestamp (min_ts==0 => never)
min_ts=0
for ed in "${expiration_dates[@]}"; do
if [[ -n "$ed" && "$ed" -ne 0 ]]; then
if [[ $min_ts -eq 0 || $ed -lt $min_ts ]]; then
min_ts=$ed
fi
fi
done
# Print header once (conditionally shown)
dprint "Checking key file: $keyfile"
# No expiration found
if [[ ${#expiration_dates[@]} -eq 0 ]] || [[ $min_ts -eq 0 ]]; then
dprint -e "${NC}${GREEN}No expiration${NC}"
continue
fi
# Single authoritative line using min_ts only (date as YYYY-MM-DD)
now=$(date +%s)
expiry_short=$(date -d "@$min_ts" '+%Y-%m-%d')
expiry_full=$(date -d "@$min_ts" '+%Y-%m-%d %H:%M:%S')
if (( now > min_ts )); then
days_ago=$(( (now - min_ts) / 86400 ))
dprint -e "${NC}${RED}Expired:${NC} $expiry_short, ${RED}$days_ago day(s) ago${NC}"
expired_keys+=("$keyfile ${NC}(${RED}Expired${NC} on $expiry_full, ${RED}$days_ago day(s) ago${NC})")
else
days_left=$(( (min_ts - now) / 86400 ))
dprint -e "Valid until: $expiry_short, ${NC}${GREEN}$days_left day(s) left${NC}"
fi
# Also list each individual expiration (conditionally shown)
for expiration_date in "${expiration_dates[@]}"; do
if [[ -z "$expiration_date" || "$expiration_date" -eq 0 ]]; then
dprint "${NC}(${GREEN}No expiration${NC})"
continue
fi
now=$(date +%s)
expiry_human=$(date -d "@$expiration_date" '+%Y-%m-%d %H:%M:%S')
if (( now > expiration_date )); then
days_ago=$(( (now - expiration_date) / 86400 ))
# add to expired list (always collected)
expired_keys+=("$keyfile ${NC}(${RED}Expired${NC} on $expiry_human, ${RED}$days_ago day(s) ago${NC})")
else
days_left=$(( (expiration_date - now) / 86400 ))
dprint "${NC}(${GREEN}Valid until${NC}: $expiry_human, $days_left day(s) left)"
fi
done
# --- End detailed block ---
fi
done
done
# Check if any expired keys were found
if [[ ${#expired_keys[@]} -eq 0 ]]; then
echo "No expired APT keys found."
exit 0
fi
# Final summary (always shown) and rename handling
echo -e "Expired APT keys found:"
# Check if running as root
is_root=0
print_root_message=0
if [[ "$(id -u)" -ne 0 ]]; then
print_root_message=1
else
is_root=1
fi
# De-duplicate expired_keys entries by filename (keep first occurrence)
declare -A _seen
_unique_expired=()
for entry in "${expired_keys[@]}"; do
fname=${entry%%[[:space:]]*}
if [[ -z "${_seen[$fname]}" ]]; then
_seen[$fname]=1
_unique_expired+=("$entry")
fi
done
expired_keys=("${_unique_expired[@]}")
# Process output (always shown)
for line in "${expired_keys[@]}"; do
echo -e "${GREEN}${line}${NC}"
if (( is_root )); then
original_path=$(echo "$line" | awk '{print $1}')
new_path="${original_path}~"
while [[ -e "$new_path" ]]; do
timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
new_path="${original_path}.${timestamp}~"
done
mv "$original_path" "$new_path"
echo "Successfully renamed: $original_path to $new_path"
fi
done
if (( print_root_message )); then
echo
echo "You need to be root to rename the expired keys"
echo "so that they do not interfere with updates."
fi