#!/bin/sh # Add APT key script # Version : 1.1.3-8 # Release : 2022-12-09 # Author : Artur Meinild # Initial configuration variables keypath="/etc/apt/keyrings/" verbosity="No" removetmp="No" # Include configuration file if [ -f "/usr/local/etc/add-apt-key.conf" ]; then . "/usr/local/etc/add-apt-key.conf" fi # Convert strings to lowercase verbosity=$(echo "$verbosity" | tr '[:upper:]' '[:lower:]') removetmp=$(echo "$removetmp" | tr '[:upper:]' '[:lower:]') # Local function definition exit_error() { echo "Error: $1" exit 1 } # Start script # Check if script is run as root if [ "$(id -u)" != "0" ]; then exit_error "must run as root" fi # Check if there is argument if [ "$1" = "" ]; then exit_error "need a keyfile (or --help) as argument" fi # Check if argument is --help if [ "$1" = "--help" ]; then echo "This script will help with installing PGP keys for APT repositories." echo "" echo "This script supports up to 2 arguments:" echo " - 1st argument is input file. This can be either:" echo " - An URL - key will be downloaded into current path (using wget or curl)" echo " - A filename - reads an existing key in current path" echo " - A path and a filename - reads an existing key in given path" echo " - 2nd argument is key output path and output name. This can be either:" echo " - Only filename - output path is set in config, saved as given filename" echo " - A path and a filename - output path is given here, saved as given filename" echo " - Only a path (end with /) - output path is given here, filename is taken from existing key" echo " - Empty - output path is set in config, filename is taken from existing key" echo "" echo "This script has a config file /usr/local/etc/add-apt-key.conf, where the following variables can be set:" echo " - keypath : path to store converted key - default is /etc/apt/keyrings" echo " - verbosity : if set to Yes - displays extra output" echo " - removetmp : if set to Yes - remove input (non-converted) file" echo "" echo "Example 1: (PWD=/root)" echo " sudo add-apt-key https://mariadb.org/mariadb_release_signing_key.asc /usr/share/keyrings/" echo "Will download key in /root, convert it and store as /usr/share/keyrings/mariadb_release_signing_key.gpg" echo "" echo "Example 2: (PWD=/home/user)" echo " sudo add-apt-key /root/mariadb_release_signing_key.asc /usr/share/keyrings/mariadbkey" echo "Will use existing key in /root, convert it and store as /usr/share/keyrings/mariadbkey.gpg" echo "" echo "Example 3: (PWD=/home/user)" echo " sudo add-apt-key mariadb_release_signing_key.asc mariadbkey" echo "Will use existing key in /home/user, convert it and store as /etc/apt/keyrings/mariadbkey.gpg" echo "" echo "After installing the PGP key, it is also possible to add the key and repository to /etc/apt/sources.list" echo " - The choice to add this will be presented in the script as the first input option" echo " - If Yes is chosen, the repository string must be pasted as the second input option" echo "" echo "This completes the key installation by adding the corresponding repository line to /etc/apt/sources.list" exit 0 fi # Check argument 2 for keypath case "$2" in # $2 is a path /*) keypath="${2%/*}" ;; esac # Check if keypath exist [ "$verbosity" = "yes" ] && echo "Keypath: $keypath" if [ ! -d "$keypath" ]; then exit_error "keypath does not exist" fi # Check if argument 1 is an URL or a path case "$1" in # If $1 is an URL http*) echo "Downloading keyfile .." tmppath="$PWD" tmpfile="${1##*/}" if [ "$(command -v wget)" ]; then # Use wget if wget -q --method=HEAD "$1"; then wget -qO "$tmppath/$tmpfile" "$1" else exit_error "keyfile can't be downloaded" fi elif [ "$(command -v curl)" ]; then # Use curl if curl -s --output /dev/null --head --fail "$1"; then curl -so "$tmppath/$tmpfile" "$1" else exit_error "keyfile can't be downloaded" fi else # Exit with error if neither is installed exit_error "wget or curl must be installed to download" fi ;; # If $1 is a filepath *) case "$1" in # $1 is only a path (ending with /) /*/) exit_error "need a keyfile (or --help) as argument" ;; # $1 is a path and a filename /*) tmppath="${1%/*}" tmpfile="${1##*/}" ;; # $1 is only filename *) tmppath="$PWD" tmpfile="$1" ;; esac ;; esac # Check if tmpfile exist [ "$verbosity" = "yes" ] && echo "Tmppath: $tmppath" [ "$verbosity" = "yes" ] && echo "Tmpfile: $tmpfile" echo "Verifying keyfile .." if [ ! -f "$tmppath/$tmpfile" ]; then exit_error "keyfile does not exist" fi # Check argument 2 for filename case "$2" in # $2 is only a path (ending with /) /*/) filename="${tmpfile%%.*}" ;; # $2 is a path and a filename /*) filename="${2##*/}" ;; # $2 is only filename (or empty) *) if [ "${#2}" != 0 ]; then filename="$2" else filename="${tmpfile%%.*}" fi ;; esac [ "$verbosity" = "yes" ] && echo "Keyfile: $filename.gpg" # Check tmpfile type and convert echo "Converting keyfile .." case $(file "$tmppath/$tmpfile") in # ASCII armored (old) *'PGP public key block Public-Key (old)') gpg --batch --yes --dearmor --keyring=gnupg-ring "$tmppath/$tmpfile" ;; # Secret key *'PGP public key block Secret-Key') gpg --batch --yes --no-default-keyring --keyring=gnupg-ring:"$tmppath/temp-keyring.gpg" --quiet --import "$tmppath/$tmpfile" gpg --batch --yes --no-default-keyring --keyring=gnupg-ring:"$tmppath/temp-keyring.gpg" --export --output "$tmppath/$tmpfile.gpg" rm "$tmppath/temp-keyring.gpg" [ -f "$tmppath/temp-keyring.gpg~" ] && rm "$tmppath/temp-keyring.gpg~" ;; # Public ring (v4) *'OpenPGP Public Key Version 4'*) cp "$tmppath/$tmpfile" "$tmppath/$tmpfile.gpg" ;; *) exit_error "invalid input keyfile format" ;; esac # Check if keyfile exist if [ ! -f "$tmppath/$tmpfile.gpg" ]; then exit_error "keyfile does not exist" fi # Check if keyfile is the right type keyfiletype=$(file "$tmppath/$tmpfile.gpg" | grep -c 'OpenPGP Public Key Version 4') if [ "$keyfiletype" -eq 0 ]; then exit_error "keyfile is not a PGP/GPG key public ring" fi # Move keyfile to "$keypath" echo "Moving keyfile to $keypath .." mv "$tmppath/$tmpfile.gpg" "$keypath/$filename.gpg" # Remove tmpfile if removetmp="Yes" if [ "$removetmp" = "yes" ]; then echo "Removing tmpfile .." rm -f "$tmppath/$tmpfile" fi # Prompt for option to add key and repo to sources.list echo "" echo "Would you like to add the PGP key and repository to /etc/apt/sources.list? (yes/no)" read -r answer echo "" # Convert answer to lowercase answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') # Check answer and prompt/perform as designated if [ ! "$answer" = "yes" ] then [ ! "$answer" = "no" ] && echo "Invalid answer - exiting." && echo "" # Print message for manual repo installation echo "Please finish the installation manually by adding the following line to /etc/apt/sources.list:" echo "deb [signed-by=$keypath/$filename.gpg] https://sdn.domain.tdn/path/repo distribution components" else # Prompt for repository string (URL distribution components) echo "Please paste the repository string (URL distribution components - e.g. https://mirrors.dotsrc.org/mariadb/repo/10.6/ubuntu focal main):" read -r repostring echo "" # Adding the repo to "/etc/apt/sources.list" echo "" >> /etc/apt/sources.list echo "deb [signed-by=$keypath/$filename.gpg] $repostring" >> /etc/apt/sources.list # Print message for script repo installation echo "The installation has now been finished by adding the following line to /etc/apt/sources.list:" echo "deb [signed-by=$keypath/$filename.gpg] $repostring" fi