From 3cb5d1a936eccc1d626cbc71518a5643f6a7df11 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Wed, 7 Jan 2026 10:20:34 -0500 Subject: [PATCH] backups: Migrate to SSH key auth when mounting Tests: - On main branch, add a remote repository with SSH password. Unmount the remote location. - Switch to branch with this change. Mount the remote location. Logs show that it is migrated from password to key authentication. Plinth database no longer contains password for this remote. Signed-off-by: James Valleroy --- plinth/modules/backups/repository.py | 1 + plinth/modules/backups/views.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py index 53dc0ee8c..77e2aac1f 100644 --- a/plinth/modules/backups/repository.py +++ b/plinth/modules/backups/repository.py @@ -357,6 +357,7 @@ class SshBorgRepository(BaseBorgRepository): """Add SSH keyfile credential and delete stored password.""" self.credentials['ssh_keyfile'] = keyfile_path self.credentials.pop('ssh_password', None) + self.save() def initialize(self): """Initialize the repository after mounting the target directory.""" diff --git a/plinth/modules/backups/views.py b/plinth/modules/backups/views.py index 52bfe4255..02491871b 100644 --- a/plinth/modules/backups/views.py +++ b/plinth/modules/backups/views.py @@ -587,6 +587,23 @@ def mount_repository(request, uuid): return redirect('backups:verify-ssh-hostkey', uuid=uuid) repository = SshBorgRepository.load(uuid) + if repository.ssh_password: + logger.info('Migrating from SSH password to key authentication...') + generate_ssh_client_auth_key() + result, message = copy_ssh_client_public_key(repository.hostname, + repository.username, + repository.ssh_password) + if result: + logger.info("Copied SSH client public key to remote host's " + "authorized keys.") + _pubkey_path, key_path = get_ssh_client_auth_key_paths() + repository.replace_ssh_password_with_keyfile(str(key_path)) + else: + logger.warning('Failed to copy SSH client public key: %s', message) + messages.error( + request, + _('Failed to copy SSH client public key: %s') % message) + try: repository.mount() except Exception as err: