summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorben <ben@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2002-08-18 17:43:20 +0000
committerben <ben@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2002-08-18 17:43:20 +0000
commit138291d78ab8fbf63f3a5a299afcc186641e45ba (patch)
treea2ff44dca2f714422eece5d7f58921cb28057694
parent5165ed8454768cae04330ac3b060f66b6595a17d (diff)
downloadrdiff-backup-138291d78ab8fbf63f3a5a299afcc186641e45ba.tar.gz
Fixed the remote destination restore and no increment restore bugs.
git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@184 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
-rw-r--r--rdiff-backup/rdiff_backup/Main.py5
-rw-r--r--rdiff-backup/rdiff_backup/Security.py13
-rw-r--r--rdiff-backup/rdiff_backup/restore.py1
-rw-r--r--rdiff-backup/rdiff_backup/rpath.py42
-rw-r--r--rdiff-backup/src/Main.py5
-rw-r--r--rdiff-backup/src/Security.py13
-rw-r--r--rdiff-backup/src/restore.py1
-rw-r--r--rdiff-backup/src/rpath.py42
8 files changed, 96 insertions, 26 deletions
diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py
index a7c9ecf..76c652a 100644
--- a/rdiff-backup/rdiff_backup/Main.py
+++ b/rdiff-backup/rdiff_backup/Main.py
@@ -509,7 +509,8 @@ def RemoveOlderThan(rootrp):
"\nIf you want to delete multiple increments in this way, "
"use the --force." % (len(times_in_secs), inc_pretty_time))
- Log("Deleting increment%sat times:\n%s" %
- (len(times_in_secs) == 1 and " " or "s ", inc_pretty_time), 3)
+ if len(times_in_secs) == 1:
+ Log("Deleting increment at time:\n" + inc_pretty_time, 3)
+ else: Log("Deleting increments at times:\n" + inc_pretty_time, 3)
Manage.delete_earlier_than(datadir, time)
diff --git a/rdiff-backup/rdiff_backup/Security.py b/rdiff-backup/rdiff_backup/Security.py
index 7f193aa..95b8296 100644
--- a/rdiff-backup/rdiff_backup/Security.py
+++ b/rdiff-backup/rdiff_backup/Security.py
@@ -10,8 +10,8 @@
"""Functions to make sure remote requests are kosher"""
-import sys
-import Globals, tempfile
+import sys, tempfile
+import Globals, Main
from rpath import *
class Violation(Exception):
@@ -67,6 +67,8 @@ def set_security_level(action, cmdpairs):
rdir = tempfile.gettempdir()
elif islocal(cp1):
sec_level = "read-only"
+ rdir = Main.restore_get_root(RPath(Globals.local_connection,
+ getpath(cp1)))[0].path
else:
assert islocal(cp2)
sec_level = "all"
@@ -89,7 +91,8 @@ def set_security_level(action, cmdpairs):
else: assert 0, "Unknown action %s" % action
Globals.security_level = sec_level
- Globals.restrict_path = rdir
+ Globals.restrict_path = RPath(Globals.local_connection,
+ rdir).normalize().path
def set_allowed_requests(sec_level):
"""Set the allowed requests list using the security level"""
@@ -111,7 +114,9 @@ def set_allowed_requests(sec_level):
"Time.setcurtime_local",
"Resume.ResumeCheck",
"HLSourceStruct.split_initial_dsiter",
- "HLSourceStruct.get_diffs_and_finalize"])
+ "HLSourceStruct.get_diffs_and_finalize",
+ "RPathStatic.gzip_open_local_read",
+ "RPathStatic.open_local_read"])
if sec_level == "update-only":
allowed_requests. \
extend(["Log.open_logfile_local", "Log.close_logfile_local",
diff --git a/rdiff-backup/rdiff_backup/restore.py b/rdiff-backup/rdiff_backup/restore.py
index 4d57b4d..432f9cc 100644
--- a/rdiff-backup/rdiff_backup/restore.py
+++ b/rdiff-backup/rdiff_backup/restore.py
@@ -79,6 +79,7 @@ class Restore:
"""Returns increments with given base"""
dirname, basename = inc_rpath.dirsplit()
parent_dir = RPath(inc_rpath.conn, dirname, ())
+ if not parent_dir.isdir(): return [] # inc directory not created yet
index = inc_rpath.index
if index:
diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py
index 4fffcfb..7365f14 100644
--- a/rdiff-backup/rdiff_backup/rpath.py
+++ b/rdiff-backup/rdiff_backup/rpath.py
@@ -200,10 +200,26 @@ class RPathStatic:
try: return tuple(os.lstat(filename))
except os.error: return None
- def make_socket(path):
- """Make a local socket at the given path"""
+ def make_socket_local(rpath):
+ """Make a local socket at the given path
+
+ This takes an rpath so that it will be checked by Security.
+ (Miscellaneous strings will not be.)
+
+ """
+ assert rpath.conn is Globals.local_connection
s = socket.socket(socket.AF_UNIX)
- s.bind(path)
+ s.bind(rpath.path)
+
+ def gzip_open_local_read(rpath):
+ """Return open GzipFile. See security note directly above"""
+ assert rpath.conn is Globals.local_connection
+ return gzip.GzipFile(rpath.path, "rb")
+
+ def open_local_read(rpath):
+ """Return open file (provided for security reasons)"""
+ assert rpath.conn is Globals.local_connection
+ return open(rpath.path, "rb")
MakeStatic(RPathStatic)
@@ -587,7 +603,7 @@ class RPath(RORPath):
def mksock(self):
"""Make a socket at self.path"""
- self.conn.RPathStatic.make_socket(self.path)
+ self.conn.RPathStatic.make_socket_local(self)
self.setdata()
assert self.issock()
@@ -700,11 +716,23 @@ class RPath(RORPath):
"""Return open file. Supports modes "w" and "r".
If compress is true, data written/read will be gzip
- compressed/decompressed on the fly.
+ compressed/decompressed on the fly. The extra complications
+ below are for security reasons - try to make the extent of the
+ risk apparent from the remote call.
"""
- if compress: return self.conn.gzip.GzipFile(self.path, mode)
- else: return self.conn.open(self.path, mode)
+ if self.conn is Globals.local_connection:
+ if compress: return gzip.GzipFile(self.path, mode)
+ else: return open(self.path, mode)
+
+ if compress:
+ if mode == "r" or mode == "rb":
+ return self.conn.RPathStatic.gzip_open_local_read(self)
+ else: return self.conn.gzip.GzipFile(self.path, mode)
+ else:
+ if mode == "r" or mode == "rb":
+ return self.conn.RPathStatic.open_local_read(self)
+ else: return self.conn.open(self.path, mode)
def write_from_fileobj(self, fp, compress = None):
"""Reads fp and writes to self.path. Closes both when done
diff --git a/rdiff-backup/src/Main.py b/rdiff-backup/src/Main.py
index a7c9ecf..76c652a 100644
--- a/rdiff-backup/src/Main.py
+++ b/rdiff-backup/src/Main.py
@@ -509,7 +509,8 @@ def RemoveOlderThan(rootrp):
"\nIf you want to delete multiple increments in this way, "
"use the --force." % (len(times_in_secs), inc_pretty_time))
- Log("Deleting increment%sat times:\n%s" %
- (len(times_in_secs) == 1 and " " or "s ", inc_pretty_time), 3)
+ if len(times_in_secs) == 1:
+ Log("Deleting increment at time:\n" + inc_pretty_time, 3)
+ else: Log("Deleting increments at times:\n" + inc_pretty_time, 3)
Manage.delete_earlier_than(datadir, time)
diff --git a/rdiff-backup/src/Security.py b/rdiff-backup/src/Security.py
index 7f193aa..95b8296 100644
--- a/rdiff-backup/src/Security.py
+++ b/rdiff-backup/src/Security.py
@@ -10,8 +10,8 @@
"""Functions to make sure remote requests are kosher"""
-import sys
-import Globals, tempfile
+import sys, tempfile
+import Globals, Main
from rpath import *
class Violation(Exception):
@@ -67,6 +67,8 @@ def set_security_level(action, cmdpairs):
rdir = tempfile.gettempdir()
elif islocal(cp1):
sec_level = "read-only"
+ rdir = Main.restore_get_root(RPath(Globals.local_connection,
+ getpath(cp1)))[0].path
else:
assert islocal(cp2)
sec_level = "all"
@@ -89,7 +91,8 @@ def set_security_level(action, cmdpairs):
else: assert 0, "Unknown action %s" % action
Globals.security_level = sec_level
- Globals.restrict_path = rdir
+ Globals.restrict_path = RPath(Globals.local_connection,
+ rdir).normalize().path
def set_allowed_requests(sec_level):
"""Set the allowed requests list using the security level"""
@@ -111,7 +114,9 @@ def set_allowed_requests(sec_level):
"Time.setcurtime_local",
"Resume.ResumeCheck",
"HLSourceStruct.split_initial_dsiter",
- "HLSourceStruct.get_diffs_and_finalize"])
+ "HLSourceStruct.get_diffs_and_finalize",
+ "RPathStatic.gzip_open_local_read",
+ "RPathStatic.open_local_read"])
if sec_level == "update-only":
allowed_requests. \
extend(["Log.open_logfile_local", "Log.close_logfile_local",
diff --git a/rdiff-backup/src/restore.py b/rdiff-backup/src/restore.py
index 4d57b4d..432f9cc 100644
--- a/rdiff-backup/src/restore.py
+++ b/rdiff-backup/src/restore.py
@@ -79,6 +79,7 @@ class Restore:
"""Returns increments with given base"""
dirname, basename = inc_rpath.dirsplit()
parent_dir = RPath(inc_rpath.conn, dirname, ())
+ if not parent_dir.isdir(): return [] # inc directory not created yet
index = inc_rpath.index
if index:
diff --git a/rdiff-backup/src/rpath.py b/rdiff-backup/src/rpath.py
index 4fffcfb..7365f14 100644
--- a/rdiff-backup/src/rpath.py
+++ b/rdiff-backup/src/rpath.py
@@ -200,10 +200,26 @@ class RPathStatic:
try: return tuple(os.lstat(filename))
except os.error: return None
- def make_socket(path):
- """Make a local socket at the given path"""
+ def make_socket_local(rpath):
+ """Make a local socket at the given path
+
+ This takes an rpath so that it will be checked by Security.
+ (Miscellaneous strings will not be.)
+
+ """
+ assert rpath.conn is Globals.local_connection
s = socket.socket(socket.AF_UNIX)
- s.bind(path)
+ s.bind(rpath.path)
+
+ def gzip_open_local_read(rpath):
+ """Return open GzipFile. See security note directly above"""
+ assert rpath.conn is Globals.local_connection
+ return gzip.GzipFile(rpath.path, "rb")
+
+ def open_local_read(rpath):
+ """Return open file (provided for security reasons)"""
+ assert rpath.conn is Globals.local_connection
+ return open(rpath.path, "rb")
MakeStatic(RPathStatic)
@@ -587,7 +603,7 @@ class RPath(RORPath):
def mksock(self):
"""Make a socket at self.path"""
- self.conn.RPathStatic.make_socket(self.path)
+ self.conn.RPathStatic.make_socket_local(self)
self.setdata()
assert self.issock()
@@ -700,11 +716,23 @@ class RPath(RORPath):
"""Return open file. Supports modes "w" and "r".
If compress is true, data written/read will be gzip
- compressed/decompressed on the fly.
+ compressed/decompressed on the fly. The extra complications
+ below are for security reasons - try to make the extent of the
+ risk apparent from the remote call.
"""
- if compress: return self.conn.gzip.GzipFile(self.path, mode)
- else: return self.conn.open(self.path, mode)
+ if self.conn is Globals.local_connection:
+ if compress: return gzip.GzipFile(self.path, mode)
+ else: return open(self.path, mode)
+
+ if compress:
+ if mode == "r" or mode == "rb":
+ return self.conn.RPathStatic.gzip_open_local_read(self)
+ else: return self.conn.gzip.GzipFile(self.path, mode)
+ else:
+ if mode == "r" or mode == "rb":
+ return self.conn.RPathStatic.open_local_read(self)
+ else: return self.conn.open(self.path, mode)
def write_from_fileobj(self, fp, compress = None):
"""Reads fp and writes to self.path. Closes both when done