#!/bin/sh set -e UUID_KKEY="7930cd94-b56e-4395-8859-f34da77f29be" UUID_WKEY="9fcaf42a-86d5-4e70-828d-fd90aad2d964" CRYPT_NAME="usbkey" MOUNT_PATH="/media/usbkey" op_mount() { # First check if we have key drive if [ ! -e "/dev/disk/by-uuid/$UUID_KKEY" ]; then echo "Can't locate appropriate usb drive." >&2 exit 1 fi # Decrypt drive if [ -e "/dev/mapper/$CRYPT_NAME" ]; then echo "USB key seems to be already decrypted" >&2 else echo "Decrypting usb key" >&2 sudo -- cryptsetup open /dev/disk/by-uuid/"$UUID_KKEY" "$CRYPT_NAME" fi # Mount drive if mount | grep -q "$MOUNT_PATH"; then echo "USB key is already mounted" >&2 else echo "Mounting usb key" sudo -- mkdir -p "$MOUNT_PATH" sudo -- mount -o uid="$(id -u)",gid="$(id -g)" "/dev/mapper/$CRYPT_NAME" "$MOUNT_PATH" fi echo "USB key drive mounted" >&2 } op_unmount() { # Unmount if mount | grep -q "$MOUNT_PATH"; then echo "Unmounting usb key" >&2 sync "$MOUNT_PATH" sudo -- umount "$MOUNT_PATH" fi # Remove mount path [ ! -d "$MOUNT_PATH" ] || sudo -- rmdir "$MOUNT_PATH" # Close encryption if [ -e "/dev/mapper/$CRYPT_NAME" ]; then echo "Closing encryption on usb key" >&2 sudo -- cryptsetup close "$CRYPT_NAME" fi echo "USB key unmounted" >&2 } check_mount() { mount | grep "$MOUNT_PATH" | grep -q "/dev/mapper/$CRYPT_NAME" } op_sync() { local DOUNMOUNT=false if [ ! -e "/dev/disk/by-uuid/$UUID_WKEY" ]; then echo "USB backup key seems to not be inserted. Please do so." >&2 exit 1 fi if ! check_mount; then DOUNMOUNT=true op_mount fi # Mount backup usb sudo -- cryptsetup open "/dev/disk/by-uuid/$UUID_WKEY" "$CRYPT_NAME-backup" sudo -- mkdir -p "$MOUNT_PATH-backup" sudo -- mount -o uid="$(id -u)",gid="$(id -g)" "/dev/mapper/$CRYPT_NAME-backup" "$MOUNT_PATH-backup" # Sync them rsync -ax --delete --progress "$MOUNT_PATH/" "$MOUNT_PATH-backup/" # Unmount it sudo -- umount "$MOUNT_PATH-backup" sudo -- rmdir "$MOUNT_PATH-backup" sudo -- cryptsetup close "$CRYPT_NAME-backup" if $DOUNMOUNT; then op_unmount fi echo "Sync process finished." >&2 } op_gpg_import() { # TODO true } op_ssh_list() { check_mount || op_mount for KEY in $(find "$MOUNT_PATH/ssh" -name '*.pub'); do local N="${KEY#$MOUNT_PATH/ssh/}" echo -n "${N%.pub}: " sed -n 's/ssh-rsa .* \(.*\)/\1/p' "$KEY" done } check_name() { if [ -z "$NAME" ]; then echo "You have to specify key name!" >&2 exit 1 fi } op_ssh_generate() { check_name check_mount || op_mount if [ -f "$MOUNT_PATH/ssh/$NAME" ]; then echo "Key $NAME seems to already exists." >&2 exit 1 fi echo -n "Please enter comment: " read COMMENT ssh-keygen -f "$MOUNT_PATH/ssh/$NAME" -C "$COMMENT" echo "SSH key $NAME was generated." >&2 } op_ssh_import() { check_name check_mount || op_mount if [ -f "$MOUNT_PATH/ssh/$NAME" ] && [ -f "$MOUNT_PATH/ssh/$NAME.pub" ]; then echo "There is no key named $NAME" >&2 exit 1 fi cp "$MOUNT_PATH/ssh/$NAME" ~/.ssh/ cp "$MOUNT_PATH/ssh/$NAME.pub" ~/.ssh/ echo "SSH key $NAME copied to local .ssh directory." >&2 } # Note OpenVPN: CA generated using following command # openssl req -nodes -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf op_openvpn_list() { check_mount || op_mount for KEY in $(find "$MOUNT_PATH/openvpn" -name 'ca.crt' -o -name '*.crt' -print); do local N="${KEY#$MOUNT_PATH/openvpn/}" echo "${N%.crt}" done } op_openvpn_get() { check_name check_mount || op_mount if [ ! -f "$MOUNT_PATH/openvpn/$NAME.key" ] || [ ! -f "$MOUNT_PATH/openvpn/$NAME.crt" ]; then echo "There is no OpenVPN key $NAME" >&2 exit 1 fi mkdir "openvpn-$NAME" cp "$MOUNT_PATH/openvpn/$NAME.key" "openvpn-$NAME/" cp "$MOUNT_PATH/openvpn/$NAME.crl" "openvpn-$NAME/" cp "$MOUNT_PATH/openvpn/ca.crt" "openvpn-$NAME/" cp "$MOUNT_PATH/openvpn/ta.key" "openvpn-$NAME/" echo "OpenVPN key $NAME copied to openvpn-$NAME directory." >&2 } op_openvpn_generate() { check_name check_mount || op_mount if [ -f "$MOUNT_PATH/openvpn/$NAME.key" ] && [ -f "$MOUNT_PATH/openvpn/$NAME.crt" ]; then echo "OpenVPN key $NAME seems to already exists" >&2 exit 1 fi ( cd "$MOUNT_PATH/openvpn" # Build request openssl req -batch -days 3650 -nodes -new -config "openssl.cnf" \ -keyout "$NAME.key" -out "$NAME.csr" # Sign request openssl ca -days 3650 -config "openssl.cnf" \ -out "$NAME.crt" -in "$NAME.csr" ) echo "OpenVPN key $NAME was generated." >&2 } unknown_argument() { echo "Unknown argument: $1" exit 1 } # Parse operation (operation have to be first) case "$1" in -h|--help) echo "Usb key manager" echo "Usage: usbkey OPERATION ..." echo echo "Operations:" echo " mount: Mount key of usb driver" echo " unmount: Unmount usb driver" echo " sync: Synchronize drive to bakup drive" echo " gpg-import: Import gpg key" echo " ssh-import: Import ssh key" echo " ssh-generate: Generate new ssh key" echo " ssh-list: List all ssh keys in store" echo " openvpn-list: List all openvpn keys" echo " openvpn-get: Get openvpn keys for some host" echo " openvpn-generate: Generate openvpn key for new host" exit 0 ;; mount|unmount|sync|gpg-import|ssh-import|ssh-generate|ssh-list|openvpn-list|openvpn-get|openvpn-generate) OPERATION="$1" ;; *) unknown_argument "$1" ;; esac shift # Parse rest of the arguments while [ $# -gt 0 ]; do case "$1" in -h|--help) echo "Usb key manager" case "$OPERATION" in mount|unmount|sync|ssh-list|openvn-list) echo "Usage: usbkey $OPERATION [-h]" ;; ssh-*|openvpn-*) echo "Usage: usbkey $OPERATION NAME [-h]" ;; # TODO esac exit 0 ;; *) if [ -z "$NAME" ] && \ [ "$OPERATION" = "ssh-import" -o "$OPERATION" = "ssh-generate" -o \ "$OPERATION" = "openvpn-get" -o "$OPERATION" = "openvpn-generate" ] \ ; then NAME="$1" else unknown_argument "$1" fi ;; esac shift done # Go to operation handler eval "op_$(echo "$OPERATION" | tr '-' '_')"