浏览代码

Merge pull request #612 from ThomasWaldmann/fix-544

borg serve: overwrite client's --restrict-to-path with forced command's …
TW 9 年之前
父节点
当前提交
9797ab0130
共有 2 个文件被更改,包括 37 次插入1 次删除
  1. 16 1
      borg/archiver.py
  2. 21 0
      borg/testsuite/archiver.py

+ 16 - 1
borg/archiver.py

@@ -7,6 +7,7 @@ import functools
 import inspect
 import io
 import os
+import shlex
 import signal
 import stat
 import sys
@@ -1338,6 +1339,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:
@@ -1413,7 +1428,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:

+ 21 - 0
borg/testsuite/archiver.py

@@ -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