#!/bin/bash # # Author: Georg Voell - georg.voell@oracle.com # Version: @(#)key-management 3.0.2 25.06.2020 (c)2020 Oracle # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # #@ Manage the ssh keys. #@ #@Usage: key-management [options] action [action-parameter] #@ Options: #@ -h, --help : Displays helptext. #@ -v, --version : Displays the version of the script. #@ -u, --username : Name of user e.g. "name@org.com". #@ -p, --passphrase : Passphrase for key encryption. #@ Action: #@ list : List all local user with keys. #@ delete : Delete all the keys for user specified by username. #@ install : Install management software. #@ create [local] : Create private and public keypair for ssh and putty. If optional paramter "local" is given, don't use internet API. #@ change : Change old passphrase specified by option to new passphrase "newpass". #@ show : Display keys or fingerprint. Allowed values: "pub", "ssh", "api", "pk8", "ppk" and 'fp'. #@ check : Display type of key. #@ import : Import a private key (and create all ather key formats). #@ push : Copy keys to destination ("hostname" specified in ".ssh/config" with parameter "Host" e.g. "Linux7"). #@ Format: #@ pub: Display ssh public key. #@ ssh: Display ssh private key. #@ api: Display public key in PEM format (OCI API key). #@ pk8: Display private key in PEM format (PKCS#8). #@ ppk: Display putty private key (PPK). #@ fp : Display fingerprint of private key. #@ #@Examples: #@ key-management create --username "opc" #@ Create keys for user "opc" #@ key-management list #@ Show all user (which have keys created with this tool) #@ key-management show api --username "opc" #@ Display OCI API public key in PEM format. #@ key-management show ssh --username "opc" #@ Display ssh private key. #@ key-management show fp --username "opc" #@ Display fingerprint for ssh private key (needed by OCI). # # Exit codes: # 01: Unknown or wrong parameter. # 02: No username specified. # 03: Error while creating / changing /deleting keys. # 04: Key (or user) does not exist. # 05: No second parameter given. # 06: Could not copy keys to destination. # 07: Could not read keyfile. # 08: Could not import keyfile. # 09: Passphrase needed. # 99: User interrupt. # # See also: # **install-scripts**(1) # # ToDo: # # Known bugs: # # Update history: # # V 3.0.0 11.06.2020 New version # V 3.0.1 22.06.2020 Only use print-table if tcsh is available # V 3.0.2 25.06.2020 New funktion: Import private key # script=${0} # Name of this script progstr=`basename "$script"` # Basename of the script progdir=`dirname "$script"` # Dirname of the script source "${progdir}/lib.bash" # Include default bash library PATH="$WORKPATH" # Set PATH to something useful # Set some deaults keygenurl="https://atrona.de/ssh-keygen/keygen.pl" bits=4096 # 2048 is less secure sshstr=".ssh" authkeysstr="authorized_keys" configstr="config" keysstr="keys" infostr="info.txt" ppstr="passphrase.txt" keybasename="id_rsa" sshfolder="${REALHOME}/$sshstr" keysfolder="${sshfolder}/$keysstr" sshconfig="${sshfolder}/$configstr" ppfile="${keysfolder}/$ppstr" # Do extra cleanup function ExtraCleanup() { filecheck -rm ${scratchfile}.keys filecheck -rm ${scratchfile}.user filecheck -rm ${scratchfile}.fp } # Returns a URI string for passing to curl (or transfer) function UriEncode() { # Check if he have jq in path jq=`filecheck -x jq` # We can do translation only if we have jq in PATH if [ "$jq" != "" ]; then $jq -nr --arg v "$1" '$v|@uri' else echo "$1" fi } function KeyType() { keyfile=${1} keytype="UNKNOWN" # Possible results: # # UNKNOWN # OPENSSH-PRIVATE-KEY or INVALID-OPENSSH-PRIVATE-KEY # # RSA-PRIVATE-KEY or ENCRYPTED-RSA-PRIVATE-KEY # INVALID-RSA-PRIVATE-KEY or INVALID-ENCRYPTED-RSA-PRIVATE-KEY # # PEM-PRIVATE-KEY or INVALID-PEM-PRIVATE-KEY # PEM-ENCRYPTED-PRIVATE-KEY or INVALID-PEM-ENCRYPTED-PRIVATE-KEY # # PUTTY-PRIVATE-KEY or INVALID-PUTTY-PRIVATE-KEY # ENCRYPTED-PUTTY-PRIVATE-KEY or INVALID-PUTTY-PRIVATE-KEY # # RSA-PUBLIC-KEY or INVALID-RSA-PUBLIC-KEY # PEM-PUBLIC-KEY or INVALID-PEM-BUBLIC-KEY if [ -r "$keyfile" ]; then # Check for private key (ssh) keysgnature=`cat "$keyfile" | grep "^-----BEGIN OPENSSH PRIVATE KEY-----$"` if [ "$keysgnature" != "" ]; then # Check for end string result=`cat "$keyfile" | grep "^-----END OPENSSH PRIVATE KEY-----$"` if [ "$result" != "" ]; then keytype="OPENSSH-PRIVATE-KEY" else keytype="INVALID-OPENSSH-PRIVATE-KEY" fi else keysgnature=`cat "$keyfile" | grep "^-----BEGIN RSA PRIVATE KEY-----$"` if [ "$keysgnature" != "" ]; then # Check for end string result=`cat "$keyfile" | grep "^-----END RSA PRIVATE KEY-----$"` # Check for encryption encrypted=`cat "$keyfile" | grep "ENCRYPTED"` if [ "$encrypted" != "" ]; then keytype="ENCRYPTED-RSA-PRIVATE-KEY" else keytype="RSA-PRIVATE-KEY" fi if [ "$result" = "" ]; then keytype="INVALID-$keytype" fi else keysgnature=`cat "$keyfile" | grep "^-----BEGIN PRIVATE KEY-----$"` if [ "$keysgnature" != "" ]; then # Check for end string result=`cat "$keyfile" | grep "^-----END PRIVATE KEY-----$"` if [ "$result" != "" ]; then keytype="PEM-PRIVATE-KEY" else keytype="INVALID-PEM-PRIVATE-KEY" fi else keysgnature=`cat "$keyfile" | grep "^PuTTY-User-Key-File-2: ssh-rsa$"` if [ "$keysgnature" != "" ]; then comment=`cat "$keyfile" | grep "Comment: " | cut -d ' ' -f2-` encryption=`cat "$keyfile" | grep "Encryption: " | cut -d ' ' -f2-` privatemac=`cat "$keyfile" | grep "Private-MAC: " | cut -d ' ' -f2-` if [ "$privatemac" = "" ]; then keytype="INVALID-PUTTY-PRIVATE-KEY" else if [ "$encryption" = "none" ]; then keytype="PUTTY-PRIVATE-KEY" else keytype="ENCRYPTED-PUTTY-PRIVATE-KEY" fi fi else keysgnature=`cat "$keyfile" | grep "^ssh-rsa "` if [ "$keysgnature" != "" ]; then keybody=`echo "$keysgnature" | cut -d' ' -f2` keyuser=`echo "$keysgnature" | cut -d' ' -f3-` if [ "$keybody" = "" ]; then keytype="INVALID-RSA-PUBLIC-KEY" else keytype="RSA-PUBLIC-KEY" fi else keysgnature=`cat "$keyfile" | grep "^-----BEGIN PUBLIC KEY-----$"` if [ "$keysgnature" != "" ]; then # Check for end string result=`cat "$keyfile" | grep "^-----END PUBLIC KEY-----$"` if [ "$result" != "" ]; then keytype="PEM-BUBLIC-KEY" else keytype="INVALID-PEM-BUBLIC-KEY" fi else keysgnature=`cat "$keyfile" | grep "^-----BEGIN ENCRYPTED PRIVATE KEY-----$"` if [ "$keysgnature" != "" ]; then # Check for end string result=`cat "$keyfile" | grep "^-----END ENCRYPTED PRIVATE KEY-----$"` if [ "$result" != "" ]; then keytype="PEM-ENCRYPTED-PRIVATE-KEY" else keytype="INVALID-PEM-ENCRYPTED-PRIVATE-KEY" fi fi fi fi fi fi fi fi fi echo "$keytype" } # Get the fingerprint from private key function GetFingerprint() { locprivkey=${1} pp=${2} # Preset fp="" addparams="" if [ -r "$locprivkey" ]; then opensslinst=`filecheck -x openssl` if [ "$opensslinst" != "" ]; then sslversstr=`$opensslinst version` havefips=`echo "$sslversstr" | grep 'fips'` encrypted=`grep "ENCRYPTED" "$locprivkey"` if [ "$encrypted" != "" -a "$pp" != "" ]; then $opensslinst rsa -pubout -outform DER -passin "pass:$pp" -in "$locprivkey" -out "${scratchfile}.fp" > /dev/null 2>&1 else $opensslinst rsa -pubout -outform DER -in "$locprivkey" -out "${scratchfile}.fp" > /dev/null 2>&1 fi if [ -r "${scratchfile}.fp" ]; then if [ "$havefips" != "" ]; then addparams="-non-fips-allow" fi fp=`cat "${scratchfile}.fp" | $opensslinst md5 -c $addParams | sed 's|(stdin)= ||g'` fi filecheck -rm "${scratchfile}.fp" fi fi # Return result echo "$fp" echo "$fp" > /tmp/georg } # Change passphrae (if old and new passphrases differ) and convert key to RSA format function ChangePassphrase() { stat=0 locprivkey=${1} oldpassphrase=${2} newpassphrase=${3} sshkeygen=`filecheck -x ssh-keygen` if [ "$sshkeygen" != "" -a -r "$locprivkey" ]; then oldfp=`GetFingerprint "$locprivkey" "$oldpassphrase"` # Secure key with correct filerights chmod 600 "$locprivkey" # Change passphrase $sshkeygen -p -P "$oldpassphrase" -N "$newpassphrase" -m PEM -f "$locprivkey" > /dev/null 2>&1 stat=$? if [ $stat -eq 0 ]; then if [ "$oldfp" != "" ]; then newfp=`GetFingerprint "$locprivkey" "$newpassphrase"` if [ "$oldfp" != "$newfp" ]; then # Fingerprints are not the same - something went wrong stat=1 fi fi fi else stat=1 fi return $stat } # Create RSA private and public key pair function CreateRSAKeys() { stat=0 locprivkey=${1} comment=${2} pp=${3} sshkeygen=`filecheck -x ssh-keygen` if [ "$sshkeygen" != "" -a ! -f "$locprivkey" ]; then $sshkeygen -q -t rsa -N "$pp" -b $bits -C "$comment" -m PEM -f "$locprivkey" stat=$? else stat=1 fi return $stat } # Create RSA private and public key pair function CreateRSAPubKey() { stat=0 locprivkey=${1} comment=${2} pp=${3} sshkeygen=`filecheck -x ssh-keygen` if [ "$sshkeygen" != "" -a -f "$locprivkey" ]; then keystr=`$sshkeygen -y -P "$pp" -f "$locprivkey"` stat=$? if [ $stat -eq 0 ]; then printf "$keystr $comment\n" > "${locprivkey}.pub" fi else stat=1 fi return $stat } # Create an info file with all values function CreateInfoFile() { stat=0 user=${1} fp=${2} if [ "$user" != "" ]; then infofile="${keysfolder}/${user}/$infostr" keyfile="$keybasename" printf " Private Key file (ssh): '%s'\n" "$keyfile" > $infofile printf " Public Key file (ssh): '%s'\n\n" "${keyfile}.pub" >> $infofile printf "Private Key file (PKCS#8): '%s'\n" "${keyfile}.pk8" >> $infofile printf " Private Key file (putty): '%s'\n\n" "${keyfile}.ppk" >> $infofile printf "Public Key file (OCI-API): '%s'\n" "${keyfile}.pem" >> $infofile printf " Fingerprint: '%s'\n" "$fp" >> $infofile else stat=1 fi return $stat } # Create PK8, API and PPK keys function CreateSpecialKeys() { stat=0 locprivkey=${1} comment=${2} pp=${3} if [ -f "$locprivkey" ]; then openssl=`filecheck -x openssl` if [ "$openssl" != "" ]; then # Create the PKCS#8 private key if [ "$pp" != "" ]; then $openssl pkcs8 -topk8 -v2 aes128 -inform pem -in "$locprivkey" -passin "pass:$pp" -passout "pass:$pp" -outform PEM -out "${locprivkey}.pk8" stat=$? else $openssl pkcs8 -topk8 -inform pem -in "$locprivkey" -outform PEM -nocrypt -out "${locprivkey}.pk8" stat=$? fi if [ $stat -eq 0 ]; then chmod 600 "${locprivkey}.pk8" # Create the public key in pem format - needed by OCI - API Key if [ "$pp" != "" ]; then $openssl rsa -pubout -in "$locprivkey" -passin "pass:$pp" -outform PEM -out "${locprivkey}.pem" 2>/dev/null stat=$? else $openssl rsa -pubout -in "$locprivkey" -outform PEM -out "${locprivkey}.pem" 2>/dev/null stat=$? fi fi else stat=1 fi if [ $stat -eq 0 ]; then puttygen=`filecheck -x puttygen` if [ "$puttygen" != "" ]; then # Create the Putty Private Key if [ "$pp" != "" ]; then echo "$pp" > $scratchfile $puttygen -q -b $bits "$locprivkey" -P --old-passphrase $scratchfile --new-passphrase $scratchfile -C "$comment" -o "${locprivkey}.ppk" stat=$? rm -f $scratchfile else $puttygen -q -b $bits "$locprivkey" -C "$comment" -o "${locprivkey}.ppk" stat=$? fi else echo "WARNING: No 'puttygen' in PATH. Putty Private Keys can not be created or changed." fi fi if [ $stat -eq 0 ]; then fingerprint=`GetFingerprint "$locprivkey" "$pp"` CreateInfoFile "$comment" "$fingerprint" fi else stat=1 fi return $stat } # Write a new entrry to passphrase file function WriteToPassphraseFile() { username=${1} passphrase=${2} # Create passphrase file - if does not exists yet if [ ! -f "$ppfile" ]; then printf "username\tpassphrase\n" > "$ppfile" chmod 600 "$ppfile" fi # Write username and passphrase to ppfile printf "%s\t%s\n" "$username" "$passphrase" >> "$ppfile" } # Delete an entrry from passphrase file function DeleteFromPassphraseFile() { username=${1} if [ -r "$ppfile" ]; then mv -f "$ppfile" $scratchfile grep -v "^$username " $scratchfile > "$ppfile" rm -f $scratchfile chmod 600 "$ppfile" fi } # Get the passphrase from ppfile function GetPassphraseFromPassphraseFile() { username=${1} pp="" if [ "$username" != "" ]; then if [ -r "$ppfile" ]; then pp="`grep "^$username " "$ppfile" | cut -d' ' -f2`" fi fi echo "$pp" } # Get the fingerprint from private key function ImportPrivateKey() { stat=0 privkey=${1} username=${2} passphrase=${3} if [ "$username" = "" ]; then stat=2 else if [ -r "$privkey" ]; then needencryption="false" keytype=`KeyType "$privkey"` if [ "$keytype" = "ENCRYPTED-RSA-PRIVATE-KEY" ]; then needencryption="true" keytype="RSA-PRIVATE-KEY" else if [ "$keytype" = "PEM-ENCRYPTED-PRIVATE-KEY" ]; then needencryption="true" keytype="PEM-PRIVATE-KEY" else if [ "$keytype" = "OPENSSH-PRIVATE-KEY" ]; then cp "$privkey" $scratchfile ChangePassphrase "$scratchfile" "" "" stat=$? if [ $stat -gt 0 ]; then # Seems to be encrypted needencryption="true" filecheck -rm $scratchfile # Key is encrypted - delete the failed try fi fi fi fi # Check if we have a passphrase for encryption if [ "$needencryption" = "true" -a "$passphrase" = "" ]; then stat=9 else if [ "$keytype" != "OPENSSH-PRIVATE-KEY" -a "$keytype" != "RSA-PRIVATE-KEY" -a "$keytype" != "PEM-PRIVATE-KEY" ]; then stat=8 else if [ ! -d "${keysfolder}/$username" ]; then # User does not exist yet mkdir -m 0700 -p "${keysfolder}/$username" keyfile="${keysfolder}/${username}/$keybasename" if [ "$keytype" = "OPENSSH-PRIVATE-KEY" ]; then if [ "$needencryption" = "false" ]; then if [ -f "$scratchfile" ]; then mv "$scratchfile" "$keyfile" chmod 600 "$keyfile" else stat=8 fi else cp "$privkey" "$scratchfile" ChangePassphrase "$scratchfile" "$passphrase" "$passphrase" stat=$? # Compare fimgerprints if [ $stat -gt 0 ]; then stat=8 filecheck -rm $scratchfile # Second try to convert encrypted key with passphrase failed else if [ -f "$scratchfile" ]; then mv $scratchfile "$keyfile" chmod 600 "$keyfile" else stat=8 fi fi fi else if [ "$keytype" = "RSA-PRIVATE-KEY" ]; then if [ "$needencryption" = "false" ]; then cp "$privkey" "$keyfile" chmod 600 "$keyfile" else cp "$privkey" $scratchfile ChangePassphrase "$scratchfile" "$passphrase" "$passphrase" stat=$? if [ $stat -gt 0 ]; then stat=8 filecheck -rm $scratchfile else if [ -f "$scratchfile" ]; then mv $scratchfile "$keyfile" chmod 600 "$keyfile" else stat=8 fi fi fi else # PEM-PRIVATE-KEY (PK8) cp "$privkey" $scratchfile if [ "$needencryption" = "false" ]; then ChangePassphrase "$scratchfile" "" "" stat=$? else ChangePassphrase "$scratchfile" "$passphrase" "$passphrase" stat=$? fi if [ $stat -gt 0 ]; then stat=8 filecheck -rm $scratchfile else if [ -f "$scratchfile" ]; then mv $scratchfile "$keyfile" chmod 600 "$keyfile" else stat=8 fi fi fi fi if [ $stat -eq 0 ]; then # Create public key CreateRSAPubKey "$keyfile" "$username" "$passphrase" stat=$? if [ $stat -eq 0 ]; then CreateSpecialKeys "$keyfile" "$username" "$passphrase" stat=$? if [ $stat -eq 0 ]; then WriteToPassphraseFile "$username" "$passphrase" printf "Keys imported in folder '${keysfolder}/$username'.\n" fi fi fi if [ $stat -gt 0 ]; then # Key import wasn't successful - delete user key folder rm -fR "${keysfolder}/$username" fi else stat=8 fi fi fi else stat=7 fi fi return $stat } # Get the fingerprint from infofile function GetFingerprintFromInfo() { username=${1} fingerprint="" if [ "$username" != "" ]; then infofile="${keysfolder}/${username}/$infostr" if [ -r "$infofile" ]; then fingerprint=`grep "Fingerprint:" "$infofile" | cut -d':' -f2- | sed 's|^ *||' | tr -d "'"` fi fi echo "$fingerprint" } # Generate tab separated list with infos function WriteToKeylist() { username=${1} keyfile="${keysfolder}/${username}/$keybasename" if [ ! -r "$keyfile" ]; then keyfile="${keysfolder}/${username}/${keybasename}.pk8" fi if [ -r "$keyfile" ]; then fingerprint="`GetFingerprintFromInfo "$username"`" encrypted=`grep "ENCRYPTED" "$keyfile"` if [ "$encrypted" = "" ]; then havepassphrase="No" else havepassphrase="Yes" fi printf "%s\t%s\t%s\t%s\n" "$username" "$havepassphrase" "$fingerprint" "$keyfile" >> ${scratchfile}.keys fi } # Copy keys to another host function PushKeys() { username=${1} destination=${2} errcode=0 if [ ! -r "$sshconfig" ]; then printf "No '$sshconfig' found. Exiting.\n" errcode=6 else result=`cat "$sshconfig" | grep "^Host $destination$"` if [ "$result" = "" ]; then printf "Please specify the destination 'hostname' specified in '$sshconfig' with parameter 'Host'. Exiting.\n" errcode=5 else if [ "$username" != "" ]; then if [ -d "${keysfolder}/$username" ]; then # Copy user folder with keys to host scp -q -r "${keysfolder}/$username" "${destination}:/tmp" stat=$? if [ $stat -eq 0 ]; then # Create move script echo 'if [ ! -d "$HOME/'$sshstr'" ]; then mkdir -m 0700 -p "$HOME/'$sshstr'"; fi' > $scratchfile echo 'if [ ! -d "$HOME/'$sshstr'/'$keysstr'" ]; then mkdir -m 0700 "$HOME/'$sshstr'/'$keysstr'"; fi' >> $scratchfile echo 'if [ -d "$HOME/'$sshstr'/'$keysstr'/'$username'" ]; then' >> $scratchfile echo ' rm -fR "$HOME/'$sshstr'/'$keysstr'/'$username'"' >> $scratchfile echo 'fi' >> $scratchfile echo 'mv "/tmp/'$username'" "$HOME/'$sshstr'/'$keysstr'"' >> $scratchfile echo 'pubkey="`cat "$HOME/'$sshstr'/'$keysstr'/'$username'/'$keybasename'.pub"`"' >> $scratchfile echo 'result="`grep "$pubkey" "$HOME/'$sshstr'/'$authkeysstr'"`"' >> $scratchfile echo 'if [ "$result" = "" ]; then echo "$pubkey" >> "$HOME/'$sshstr'/'$authkeysstr'"; fi' >> $scratchfile echo "rm -f $scratchfile" >> $scratchfile scp -q "$scratchfile" "${destination}:$scratchfile" ssh "$destination" "cat $scratchfile | bash" stat=$? if [ $stat -ne 0 ]; then printf "Push keys (ssh) failed. Exiting.\n" errcode=6 fi else printf "Push keys (scp) failed. Exiting.\n" errcode=6 fi else printf "Keys do not exist in folder '${keysfolder}/$username'. Exiting.\n" errcode=4 fi else printf "Username not specified.\n" errcode=2 fi fi fi return $errcode } # Create keys if user folder doesn't exists function CreateKeys() { username=${1} passphrase=${2} errcode=0 if [ "$username" != "" ]; then if [ ! -d "${keysfolder}/$username" ]; then keyfile="${keysfolder}/${username}/$keybasename" myip=`get-ip ip` if [ "$ip" != "" -a "$param2" != "local" ]; then # We have internet access - get the keys from api uriusername=`UriEncode "$username"` if [ "$passphrase" != "" ]; then uripassphrase=`UriEncode "$passphrase"` myurl="${keygenurl}?username=${uriusername}&passphrase=${uripassphrase}" else myurl="${keygenurl}?username=${uriusername}" fi transfer --quiet "$myurl" -o "${keysfolder}/${username}.zip" stat=$? # If we got an error - remove zip file if it does exisits if [ $stat -ne 0 ]; then echo "transfer error" filecheck -rm "${keysfolder}/${username}.zip" fi # If we could download zip with keys - continue if [ -f "${keysfolder}/${username}.zip" ]; then unzip -q "${keysfolder}/${username}.zip" -d "$keysfolder" chmod 700 "${keysfolder}/$username" rm -f "${keysfolder}/${username}.zip" # Write username and passphrase to ppfile and create info file WriteToPassphraseFile "$username" "$passphrase" fingerprint=`GetFingerprint "$keyfile" "$passphrase"` CreateInfoFile "$comment" "$fingerprint" printf "Keys created in folder '${keysfolder}/$username'.\n" else printf "Keys could not be created.\n" errcode=3 fi else # No internet access - create the keys local # Create the user folder mkdir -m 0700 -p "${keysfolder}/$username" infofile="${keysfolder}/${username}/$infostr" CreateRSAKeys "$keyfile" "$username" "$passphrase" errcode=$? if [ $errcode -eq 0 ]; then CreateSpecialKeys "$keyfile" "$username" "$passphrase" errcode=$? if [ $errcode -eq 0 ]; then WriteToPassphraseFile "$username" "$passphrase" printf "Keys created local in folder '${keysfolder}/$username'.\n" fi fi if [ $errcode -gt 0 ]; then # Key creation wasn't successful - delete user key folder rm -fR "${keysfolder}/$username" printf "Keys could not be created.\n" errcode=3 fi fi else printf "Keys exists in folder '${keysfolder}/$username'. Leaving keys unchanged.\n" errcode=3 fi else printf "Username not specified.\n" errcode=2 fi return $errcode } # Preset param1="" param2="" username="" passphrase="" # Check parameters: Loop until all parameters are used up while [ $# -gt 0 ]; do pname=${1} case "$pname" in -u | --username) shift if [ "$1" != "" ]; then username=${1} shift else errstr="Please specify a username (e.g. 'name@org.com') after parameter '$pname'." fi ;; -p | --passphrase) shift if [ "$1" != "" ]; then passphrase=${1} shift else errstr="Please specify a passphrase (e.g. 'MySecret') after parameter '$pname'." fi ;; -v | --version) shift showversion=1 ;; -h | --help) shift showhelp=1 ;; *) paramck=`echo "$1" | grep '^-'` # Types don't begin with '-' if [ "$param1" = "" -a "$paramck" = "" ]; then param1=`echo "$1" | tr "[:upper:]" "[:lower:]"` else if [ "$param2" = "" -a "$paramck" = "" ]; then param2=${1} else errstr="Unknown parameter: '$1'." fi fi shift esac done # Plausibility check if [ "$passphrase" != "" ]; then pwlen=`echo -n "$passphrase" | wc -m` if [ $pwlen -lt 5 ]; then errstr="Passphrase has to have more then 4 chars." fi fi # Display help or error message DisplayHelp ### Main # Create ssh folder if it doesn't exists if [ ! -d "$sshfolder" ]; then mkdir -m 0700 -p "$sshfolder" fi # Create keys folder if it doesn't exists if [ ! -d "$keysfolder" ]; then mkdir -m 0700 "$keysfolder" fi # Create ssh config if it doesn't exists if [ ! -f "$sshconfig" ]; then printf "# Created by tool '$progstr'.\n\n" > "$sshconfig" printf "# Default settings\n" >> "$sshconfig" printf 'Host *\n' >> "$sshconfig" printf '\tForwardAgent no\n' >> "$sshconfig" printf '\tForwardX11 no\n' >> "$sshconfig" printf '\tForwardX11Trusted no\n' >> "$sshconfig" printf '\tPort 22\n' >> "$sshconfig" printf '\tProtocol 2\n' >> "$sshconfig" printf '\tServerAliveInterval 60\n' >> "$sshconfig" printf '\tServerAliveCountMax 30\n' >> "$sshconfig" printf '\tStrictHostKeyChecking no\n' >> "$sshconfig" printf '\tUserKnownHostsFile /dev/null\n' >> "$sshconfig" printf '\tLogLevel error\n' >> "$sshconfig" chmod 600 "$sshconfig" fi # Create a list with all existing users and check if user already exists stat=0 ls "$keysfolder" > ${scratchfile}.user haveuser=`filecheck -s ${scratchfile}.user` if [ "$haveuser" != "" -a "$username" != "" ]; then user="`grep "^$username$" ${scratchfile}.user`" else user="" fi # If we don't have an action specified - list all keys if [ "$param1" = "" ]; then param1="list" fi case "$param1" in check) if [ "$param2" = "" ]; then exitcode=5 errormsg $exitcode "($progstr) No keyfile specified." else if [ -r "$param2" ]; then # Check keys result=`KeyType "$param2"` echo "$result" else exitcode=7 errormsg $exitcode "($progstr) Could not read keyfile '$param2'." fi fi ;; import) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$param2" = "" ]; then exitcode=5 errormsg $exitcode "($progstr) No keyfile specified." else if [ -r "$param2" ]; then if [ "$username" = "$user" ]; then # Keys already exist for user confirm "Keys for username '$username' already exist. Do you want to renew?" --yes "y/yes" --no "n/[no]" exitcode=$? if [ $exitcode -eq 0 ]; then rm -fR "${keysfolder}/$username" DeleteFromPassphraseFile "$username" else printf "Leaving keys unchanged.\n" fi fi # Import key if [ $exitcode -eq 0 ]; then ImportPrivateKey "$param2" "$username" "$passphrase" exitcode=$? if [ $exitcode -gt 0 ]; then if [ $exitcode -eq 9 ]; then errormsg $exitcode "($progstr) Passphrase needed to import key: '$param2'." else errormsg $exitcode "($progstr) Could not import key: '$param2'." fi fi else exitcode=3 fi else exitcode=7 errormsg $exitcode "($progstr) Could not read keyfile '$param2'." fi fi fi ;; change) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$username" = "$user" ]; then # Keys exist for user if [ "$passphrase" = "" -a "$param2" = "" ]; then exitcode=1 errormsg $exitcode "($progstr) Passphrase and new passphrase are both empty. Leaving keys unchanged." else if [ "$param2" != "" ]; then pwlen=`echo -n "$param2" | wc -m` if [ $pwlen -lt 5 ]; then exitcode=1 errormsg $exitcode "($progstr) New passphrase has to have more then 4 chars. Leaving keys unchanged." fi fi if [ $exitcode -eq 0 ]; then keyfile="${keysfolder}/${username}/$keybasename" ChangePassphrase "$keyfile" "$passphrase" "$param2" exitcode=$? if [ $exitcode -eq 0 ]; then CreateSpecialKeys "$keyfile" "$username" "$param2" DeleteFromPassphraseFile "$username" WriteToPassphraseFile "$username" "$param2" printf "Passphrase in keys changed for user '$username'.\n" else exitcode=3 errormsg $exitcode "($progstr) Could not change passphrase. Leaving keys unchanged." fi fi fi else exitcode=4 errormsg $exitcode "($progstr) Keys do not exist for username '$username'." fi fi ;; delete) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$username" = "$user" ]; then # Keys exist for user confirm "Are you sure to delete all keys for username '$username'?" --yes "y/yes" --no "n/[no]" exitcode=$? if [ $exitcode -eq 0 ]; then rm -fR "${keysfolder}/$username" DeleteFromPassphraseFile "$username" else exitcode=3 printf "Leaving keys unchanged.\n" fi else exitcode=4 errormsg $exitcode "($progstr) Keys do not exist for username '$username'." fi fi ;; create) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$username" = "$user" ]; then # Keys already exist for user confirm "Keys for username '$username' already exist. Do you want to renew?" --yes "y/yes" --no "n/[no]" exitcode=$? if [ $exitcode -eq 0 ]; then rm -fR "${keysfolder}/$username" DeleteFromPassphraseFile "$username" else printf "Leaving keys unchanged.\n" fi fi if [ $exitcode -eq 0 ]; then CreateKeys "$username" "$passphrase" exitcode=$? else exitcode=3 fi fi ;; push) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$username" = "$user" ]; then # Keys exist for user PushKeys "$username" "$param2" exitcode=$? else exitcode=4 errormsg $exitcode "($progstr) Keys do not exist for username '$username'." fi fi ;; install) ;; list) if [ "$haveuser" != "" ]; then printf "username\tencrypted\tfingerprint\tprivate-key\n" > ${scratchfile}.keys if [ "$username" != "" ]; then if [ "$username" = "$user" ]; then WriteToKeylist "$username" else exitcode=4 errormsg $exitcode "($progstr) Keys do not exist for username '$username'." fi else # List all user while read -r username; do WriteToKeylist "$username" done < ${scratchfile}.user fi # Print result if [ $exitcode -eq 0 ]; then # Check if we have tcsh available tcsh=`filecheck -x tcsh` printf "\n" if [ "$tcsh" != "" ]; then print-table ${scratchfile}.keys else cat ${scratchfile}.keys fi printf "\n" fi else printf "No keys created yet.\n" fi ;; show) if [ "$username" = "" ]; then exitcode=2 errormsg $exitcode "($progstr) No username specified." else if [ "$username" = "$user" ]; then if [ "$param2" != "" ]; then # Keys exist for user case "$param2" in ssh) keyfile="${keysfolder}/${username}/$keybasename" if [ -r "$keyfile" ]; then printf "\n" cat "$keyfile" printf "\n" else exitcode=4 fi ;; api) keyfile="${keysfolder}/${username}/${keybasename}.pem" if [ -r "$keyfile" ]; then printf "\n" cat "$keyfile" printf "\n" else exitcode=4 fi ;; pub | pk8 | ppk) keyfile="${keysfolder}/${username}/${keybasename}.$param2" if [ -r "$keyfile" ]; then printf "\n" cat "$keyfile" printf "\n" else exitcode=4 fi ;; fp) fingerprint="`GetFingerprintFromInfo "$username"`" if [ "$fingerprint" != "" ]; then echo "$fingerprint" else keyfile="${keysfolder}/${username}/$keybasename" if [ ! -r "$keyfile" ]; then keyfile="${keysfolder}/${username}/${keybasename}.pk8" fi if [ -r "$keyfile" ]; then encrypted=`grep "ENCRYPTED" "$keyfile"` if [ "$encrypted" != "" ]; then mypassphrase="`GetPassphraseFromPPFile "$username"`" if [ "$mypassphrase" = "" ]; then mypassphrase="$passphrase" fi fingerprint=`GetFingerprint "$keyfile" "$mypassphrase"` else fingerprint=`GetFingerprint "$keyfile" ""` fi if [ "$fingerprint" != "" ]; then echo "$fingerprint" else exitcode=4 fi else exitcode=4 fi fi ;; *) errormsg 1 "($progstr) Unknown format '$param2'." esac else exitcode=5 errormsg $exitcode "($progstr) No format specified." fi else exitcode=4 errormsg $exitcode "($progstr) Keys do not exist for username '$username'." fi fi ;; *) errormsg 1 "($progstr) Unknown action '$param1'." esac # Cleanup and exit Cleanup exit $exitcode