#!/bin/bash # LibrePortal-managed SSH key store for backup locations. Each location's # private key lives at configs/backup/locations//ssh.key. Public key # is derived on the fly via ssh-keygen -y, so we never persist it # separately. The CFG_BACKUP_LOC__SSH_AUTH selector (key|password) # is the only ssh-related value in the location.config file. # Refresh locations.json so the editor reflects new key state (public key / # "key set" status) right after a mutation. No-op if the generator isn't loaded. backupSshKeyRefreshUi() { declare -f webuiGenerateBackupLocations >/dev/null 2>&1 && webuiGenerateBackupLocations >/dev/null 2>&1 return 0 } backupSshKeyFile() { local idx="$1" backupLocationSshKey "$idx" } backupSshKeyExists() { local idx="$1" [[ -f "$(backupSshKeyFile "$idx")" ]] } # Decode a base64-encoded private key and write it to the location's key # file. The frontend base64-encodes pasted multi-line keys so we can ship # them through the existing single-line task command pipeline. backupSshKeySet() { local idx="$1" local key_b64="$2" if [[ -z "$idx" || -z "$key_b64" ]]; then isError "backupSshKeySet requires " return 1 fi backupLocationEnsureDir "$idx" local owner owner=$(backupLocationOwner) local key_file key_file=$(backupSshKeyFile "$idx") local decoded decoded=$(echo "$key_b64" | base64 -d 2>/dev/null) if [[ -z "$decoded" ]]; then isError "Failed to base64-decode the supplied key" return 1 fi echo "$decoded" | runFileWrite "$key_file" >/dev/null runFileOp chown "$owner":"$owner" "$key_file" runFileOp chmod 0600 "$key_file" if ! sudo -u "$owner" ssh-keygen -y -f "$key_file" >/dev/null 2>&1; then isError "Key written but ssh-keygen can't read it — check the format (OpenSSH PEM: ed25519, rsa, ecdsa)" return 1 fi isSuccessful "SSH key saved for location $idx" backupSshKeyRefreshUi } backupSshKeyGenerate() { local idx="$1" if [[ -z "$idx" ]]; then isError "backupSshKeyGenerate requires " return 1 fi backupLocationEnsureDir "$idx" local owner owner=$(backupLocationOwner) local key_file key_file=$(backupSshKeyFile "$idx") if [[ -f "$key_file" ]]; then runFileOp rm -f "$key_file" "${key_file}.pub" fi sudo -u "$owner" ssh-keygen -t ed25519 -f "$key_file" -N "" -C "libreportal-loc-${idx}" -q runFileOp chmod 0600 "$key_file" [[ -f "${key_file}.pub" ]] && runFileOp rm -f "${key_file}.pub" # we re-derive when needed isSuccessful "Generated ed25519 keypair for location $idx" isNotice "Public key (paste into the remote host's ~/.ssh/authorized_keys):" backupSshKeyPublic "$idx" backupSshKeyRefreshUi } backupSshKeyPublic() { local idx="$1" local key_file key_file=$(backupSshKeyFile "$idx") [[ -f "$key_file" ]] || return 1 sudo -u "$(backupLocationOwner)" ssh-keygen -y -f "$key_file" 2>/dev/null } backupSshKeyDelete() { local idx="$1" local key_file key_file=$(backupSshKeyFile "$idx") [[ -f "$key_file" ]] && runFileOp rm -f "$key_file" "${key_file}.pub" isSuccessful "SSH key removed for location $idx" backupSshKeyRefreshUi }