diff --git a/NEWS b/NEWS index 10b8e1a4..1cf99426 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ https://torsion.org/borgmatic/reference/command-line/logging/#systemd-journal * SECURITY: Prevent shell injection attacks via constant interpolation in command hooks. (This was already implemented for deprecated "before_*"/"after_*" command hooks.) + * Fix for an error in the "key import" action when importing a key from stdin. * Promote the ZFS, LVM, and Btrfs hooks from beta features to stable. 2.0.13 diff --git a/borgmatic/borg/import_key.py b/borgmatic/borg/import_key.py index 1d0945bf..3a9595c7 100644 --- a/borgmatic/borg/import_key.py +++ b/borgmatic/borg/import_key.py @@ -4,7 +4,7 @@ import shlex import borgmatic.config.paths from borgmatic.borg import environment, flags -from borgmatic.execute import DO_NOT_CAPTURE, execute_command +from borgmatic.execute import execute_command logger = logging.getLogger(__name__) @@ -32,13 +32,12 @@ def import_key( working_directory = borgmatic.config.paths.get_working_directory(config) extra_borg_options = config.get('extra_borg_options', {}).get('key_import', '') - if import_arguments.path and import_arguments.path != '-': - if not os.path.exists(os.path.join(working_directory or '', import_arguments.path)): - raise ValueError(f'Path {import_arguments.path} does not exist. Aborting.') - - input_file = None - else: - input_file = DO_NOT_CAPTURE + if ( + import_arguments.path + and import_arguments.path != '-' + and not os.path.exists(os.path.join(working_directory or '', import_arguments.path)) + ): + raise ValueError(f'Path {import_arguments.path} does not exist. Aborting.') full_command = ( (local_path, 'key', 'import') @@ -54,7 +53,7 @@ def import_key( repository_path, local_borg_version, ) - + ((import_arguments.path,) if input_file is None else ()) + + (import_arguments.path or '-',) ) if global_arguments.dry_run: @@ -63,7 +62,6 @@ def import_key( execute_command( full_command, - input_file=input_file, output_log_level=logging.INFO, environment=environment.make_environment(config), working_directory=working_directory, diff --git a/tests/unit/borg/test_import_key.py b/tests/unit/borg/test_import_key.py index d7d11ae7..3bd9fc58 100644 --- a/tests/unit/borg/test_import_key.py +++ b/tests/unit/borg/test_import_key.py @@ -10,7 +10,6 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( command, - input_file=module.DO_NOT_CAPTURE, working_directory=None, borg_exit_codes=None, ): @@ -20,7 +19,6 @@ def insert_execute_command_mock( ) flexmock(module).should_receive('execute_command').with_args( command, - input_file=input_file, output_log_level=module.logging.INFO, environment=None, working_directory=working_directory, @@ -33,7 +31,7 @@ def test_import_key_calls_borg_with_required_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--log-json', 'repo')) + insert_execute_command_mock(('borg', 'key', 'import', '--log-json', 'repo', '-')) module.import_key( repository_path='repo', @@ -48,7 +46,7 @@ def test_import_key_calls_borg_with_local_path(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg1', 'key', 'import', '--log-json', 'repo')) + insert_execute_command_mock(('borg1', 'key', 'import', '--log-json', 'repo', '-')) module.import_key( repository_path='repo', @@ -66,7 +64,7 @@ def test_import_key_calls_borg_using_exit_codes(): flexmock(module.os.path).should_receive('exists').never() borg_exit_codes = flexmock() insert_execute_command_mock( - ('borg', 'key', 'import', '--log-json', 'repo'), borg_exit_codes=borg_exit_codes + ('borg', 'key', 'import', '--log-json', 'repo', '-'), borg_exit_codes=borg_exit_codes ) module.import_key( @@ -83,7 +81,7 @@ def test_import_key_calls_borg_with_remote_path_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() insert_execute_command_mock( - ('borg', 'key', 'import', '--remote-path', 'borg1', '--log-json', 'repo') + ('borg', 'key', 'import', '--remote-path', 'borg1', '--log-json', 'repo', '-') ) module.import_key( @@ -100,7 +98,9 @@ def test_import_key_calls_borg_with_umask_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--umask', '0770', '--log-json', 'repo')) + insert_execute_command_mock( + ('borg', 'key', 'import', '--umask', '0770', '--log-json', 'repo', '-') + ) module.import_key( repository_path='repo', @@ -115,7 +115,9 @@ def test_import_key_calls_borg_with_lock_wait_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--log-json', '--lock-wait', '5', 'repo')) + insert_execute_command_mock( + ('borg', 'key', 'import', '--log-json', '--lock-wait', '5', 'repo', '-') + ) module.import_key( repository_path='repo', @@ -131,7 +133,7 @@ def test_import_key_calls_borg_with_extra_borg_options(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() insert_execute_command_mock( - ('borg', 'key', 'import', '--log-json', '--extra', 'value with space', 'repo') + ('borg', 'key', 'import', '--log-json', '--extra', 'value with space', 'repo', '-') ) module.import_key( @@ -147,7 +149,7 @@ def test_import_key_with_log_info_calls_borg_with_info_parameter(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--log-json', '--info', 'repo')) + insert_execute_command_mock(('borg', 'key', 'import', '--log-json', '--info', 'repo', '-')) insert_logging_mock(logging.INFO) module.import_key( @@ -164,7 +166,7 @@ def test_import_key_with_log_debug_calls_borg_with_debug_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() insert_execute_command_mock( - ('borg', 'key', 'import', '--log-json', '--debug', '--show-rc', 'repo') + ('borg', 'key', 'import', '--log-json', '--debug', '--show-rc', 'repo', '-') ) insert_logging_mock(logging.DEBUG) @@ -181,7 +183,7 @@ def test_import_key_calls_borg_with_paper_flags(): flexmock(module.flags).should_receive('make_flags').and_return(('--paper',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--log-json', '--paper', 'repo')) + insert_execute_command_mock(('borg', 'key', 'import', '--log-json', '--paper', 'repo', '-')) module.import_key( repository_path='repo', @@ -197,7 +199,7 @@ def test_import_key_calls_borg_with_path_argument(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').with_args('source').and_return(True) insert_execute_command_mock( - ('borg', 'key', 'import', '--log-json', 'repo', 'source'), input_file=None + ('borg', 'key', 'import', '--log-json', 'repo', 'source'), ) module.import_key( @@ -229,7 +231,7 @@ def test_import_key_with_stdin_path_calls_borg_without_path_argument(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() - insert_execute_command_mock(('borg', 'key', 'import', '--log-json', 'repo')) + insert_execute_command_mock(('borg', 'key', 'import', '--log-json', 'repo', '-')) module.import_key( repository_path='repo', @@ -260,7 +262,7 @@ def test_import_key_calls_borg_with_working_directory(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').never() insert_execute_command_mock( - ('borg', 'key', 'import', '--log-json', 'repo'), working_directory='/working/dir' + ('borg', 'key', 'import', '--log-json', 'repo', '-'), working_directory='/working/dir' ) module.import_key( @@ -280,7 +282,6 @@ def test_import_key_calls_borg_with_path_argument_and_working_directory(): ).once() insert_execute_command_mock( ('borg', 'key', 'import', '--log-json', 'repo', 'source'), - input_file=None, working_directory='/working/dir', )