borg serve: overwrite client's --restrict-to-path with forced command's option value, fixes #544

we also make sure the client is not cheating, like giving another subcommand or his own --restrict-to-path.
This commit is contained in:
Thomas Waldmann 2016-01-28 21:59:24 +01:00
parent 824e548b9f
commit 7ea2404048
2 changed files with 37 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import functools
import inspect
import io
import os
import shlex
import signal
import stat
import sys
@ -1332,6 +1333,20 @@ class Archiver:
help='hex object ID(s) to delete from the repo')
return parser
def get_args(self, argv, cmd):
"""usually, just returns argv, except if we deal with a ssh forced command for borg serve."""
result = self.parse_args(argv[1:])
if cmd is not None and result.func == self.do_serve:
forced_result = result
argv = shlex.split(cmd)
result = self.parse_args(argv[1:])
if result.func != forced_result.func:
# someone is trying to execute a different borg subcommand, don't do that!
return forced_result
# the only thing we take from the forced "borg serve" ssh command is --restrict-to-path
result.restrict_to_paths = forced_result.restrict_to_paths
return result
def parse_args(self, args=None):
# We can't use argparse for "serve" since we don't want it to show up in "Available commands"
if args:
@ -1407,7 +1422,7 @@ def main(): # pragma: no cover
setup_signal_handlers()
archiver = Archiver()
msg = None
args = archiver.parse_args(sys.argv[1:])
args = archiver.get_args(sys.argv, os.environ.get('SSH_ORIGINAL_COMMAND'))
try:
exit_code = archiver.run(args)
except Error as e:

View File

@ -1129,3 +1129,24 @@ class RemoteArchiverTestCase(ArchiverTestCase):
@unittest.skip('only works locally')
def test_debug_put_get_delete_obj(self):
pass
def test_get_args():
archiver = Archiver()
# everything normal:
# first param is argv as produced by ssh forced command,
# second param is like from SSH_ORIGINAL_COMMAND env variable
args = archiver.get_args(['borg', 'serve', '--restrict-to-path=/p1', '--restrict-to-path=/p2', ],
'borg serve --info --umask=0027')
assert args.func == archiver.do_serve
assert args.restrict_to_paths == ['/p1', '/p2']
assert args.umask == 0o027
assert args.log_level == 'info'
# trying to cheat - break out of path restriction
args = archiver.get_args(['borg', 'serve', '--restrict-to-path=/p1', '--restrict-to-path=/p2', ],
'borg serve --restrict-to-path=/')
assert args.restrict_to_paths == ['/p1', '/p2']
# trying to cheat - try to execute different subcommand
args = archiver.get_args(['borg', 'serve', '--restrict-to-path=/p1', '--restrict-to-path=/p2', ],
'borg init /')
assert args.func == archiver.do_serve