Commit f8acd7ac authored by Marco Mariani's avatar Marco Mariani

backported security fix, hardcoded version #

parent 08f63135
......@@ -14,7 +14,7 @@ import re, os
# The current version of rdiff-backup
version = "$version"
version = "0.11.0-dev"
# If this is set, use this value in seconds as the current time
# instead of reading it from the clock.
......
# Copyright 2002 Ben Escoto
# vim: set nolist noet ts=4:
#
# This file is part of rdiff-backup.
#
......@@ -10,8 +11,9 @@
"""Functions to make sure remote requests are kosher"""
import sys, tempfile
import sys, tempfile, types
import Globals, Main
import rpath
from rpath import *
class Violation(Exception):
......@@ -27,6 +29,23 @@ allowed_requests = None
# set on the server.
disallowed_server_globals = ["server", "security_level", "restrict_path"]
# Some common file commands we may want to check to make sure they are
# in the right directory. Any commands accessing files that could be
# added to allowed_requests must be here. A few others have also been
# added---this is not a intended to be a complete list of course, just
# some support for the depreciated --restrict option when the
# security_level is "all" so you don't accidentally step out of the
# directory.
#
# The keys are files request, the value is the index of the argument
# taking a file.
file_requests = {'os.listdir':0, 'C.make_file_dict':0, 'os.chmod':0,
'os.chown':0, 'os.remove':0, 'os.removedirs':0,
'os.rename':0, 'os.renames':0, 'os.rmdir':0, 'os.unlink':0,
'os.utime':0, 'os.lchown':0, 'os.link':1, 'os.symlink':1,
'os.mkdir':0, 'os.lchown':0, 'os.getcwd': 0}
def initialize(action, cmdpairs):
"""Initialize allowable request list and chroot"""
global allowed_requests
......@@ -97,48 +116,97 @@ def set_security_level(action, cmdpairs):
def set_allowed_requests(sec_level):
"""Set the allowed requests list using the security level"""
global allowed_requests
if sec_level == "all": return
allowed_requests = ["VirtualFile.readfromid", "VirtualFile.closebyid",
"Globals.get", "Globals.is_not_None",
"Globals.get_dict_val",
"Log.open_logfile_allconn",
"Log.close_logfile_allconn",
"SetConnections.add_redirected_conn",
"RedirectedRun",
"sys.stdout.write"]
if sec_level == "minimal": pass
elif sec_level == "read-only" or sec_level == "update-only":
allowed_requests.extend(["C.make_file_dict",
"os.getuid",
"os.listdir",
"Time.setcurtime_local",
"Resume.ResumeCheck",
"HLSourceStruct.split_initial_dsiter",
"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",
"Log.close_logfile_allconn", "Log.log_to_file",
"SaveState.init_filenames",
"SaveState.touch_last_file",
"HLDestinationStruct.get_sigs",
"HLDestinationStruct.patch_w_datadir_writes",
"HLDestinationStruct.patch_and_finalize",
"HLDestinationStruct.patch_increment_and_finalize",
"Main.backup_touch_curmirror_local",
"Globals.ITRB.increment_stat"])
l = ["VirtualFile.readfromid", "VirtualFile.closebyid",
"Globals.get", "Globals.is_not_None", "Globals.get_dict_val",
"Log.open_logfile_allconn", "Log.close_logfile_allconn",
"Log.log_to_file", "FilenameMapping.set_init_quote_vals_local",
"SetConnections.add_redirected_conn", "RedirectedRun",
"sys.stdout.write", "robust.install_signal_handlers"]
if (sec_level == "read-only" or sec_level == "update-only" or
sec_level == "all"):
l.extend(["C.make_file_dict",
"rpath.ea_get",
"rpath.acl_get",
"rpath.setdata_local",
"Log.log_to_file",
"os.getuid",
"os.listdir",
"os.getcwd",
"HLSourceStruct.split_initial_dsiter",
"HLSourceStruct.get_diffs_and_finalize",
"RPathStatic.gzip_open_local_read",
"RPathStatic.open_local_read",
"Time.setcurtime_local",
"rpath.gzip_open_local_read",
"rpath.open_local_read",
"Hardlink.initialize_dictionaries",
"user_group.uid2uname",
"user_group.gid2gname",
"SaveState.init_filenames",
"SaveState.touch_last_file",
"HLDestinationStruct.get_sigs",
"HLDestinationStruct.patch_w_datadir_writes",
"HLDestinationStruct.patch_and_finalize",
"HLDestinationStruct.patch_increment_and_finalize",
"Main.backup_touch_curmirror_local",
"Globals.ITRB.increment_stat"])
if sec_level == "read-only" or sec_level == "all":
l.extend(["fs_abilities.get_fsabilities_readonly",
"fs_abilities.get_fsabilities_restoresource",
"restore.MirrorStruct.set_mirror_and_rest_times",
"restore.MirrorStruct.initialize_rf_cache",
"restore.MirrorStruct.close_rf_cache",
"restore.MirrorStruct.get_diffs",
"Resume.ResumeCheck",
"backup.SourceStruct.get_source_select",
"backup.SourceStruct.set_source_select",
"backup.SourceStruct.get_diffs"])
if sec_level == "update-only" or sec_level == "all":
l.extend(["Log.open_logfile_local", "Log.close_logfile_local",
"log.ErrorLog.open", "log.ErrorLog.isopen",
"log.ErrorLog.close",
"backup.DestinationStruct.set_rorp_cache",
"backup.DestinationStruct.get_sigs",
"backup.DestinationStruct.patch_and_increment",
"Main.backup_touch_curmirror_local",
"Main.backup_remove_curmirror_local",
"Globals.ITRB.increment_stat",
"statistics.record_error",
"log.ErrorLog.write_if_open",
"Resume.ResumeCheck",
"fs_abilities.get_fsabilities_readwrite"])
if sec_level == "all":
l.extend(["os.mkdir", "os.chown", "os.lchown", "os.rename",
"os.unlink", "os.remove", "os.chmod",
"backup.DestinationStruct.patch",
"restore.TargetStruct.get_initial_iter",
"restore.TargetStruct.patch",
"restore.TargetStruct.set_target_select",
"regress.Regress", "manage.delete_earlier_than_local"
])
if Globals.server:
allowed_requests.extend(["SetConnections.init_connection_remote",
"Log.setverbosity",
"Log.setterm_verbosity",
"Time.setprevtime_local",
"FilenameMapping.set_init_quote_vals_local",
"Globals.postset_regexp_local",
"Globals.set_select",
"HLSourceStruct.set_session_info",
"HLDestinationStruct.set_session_info"])
l.extend(["SetConnections.init_connection_remote",
"Log.setverbosity",
"Log.setterm_verbosity",
"Time.setprevtime_local",
"FilenameMapping.set_init_quote_vals_local",
"Globals.postset_regexp_local",
"Globals.set_select",
"HLSourceStruct.set_session_info",
"HLDestinationStruct.set_session_info"])
allowed_requests = {}
for req in l: allowed_requests[req] = None
def raise_violation(request, arglist):
"""Raise a security violation about given request"""
raise Violation("\nWarning Security Violation!\n"
"Bad request for function: %s\n"
"with arguments: %s\n" % (request.function_string,
arglist))
def vet_request(request, arglist):
"""Examine request for security violations"""
......@@ -147,15 +215,14 @@ def vet_request(request, arglist):
if Globals.restrict_path:
for arg in arglist:
if isinstance(arg, RPath): vet_rpath(arg)
if security_level == "all": return
if request.function_string in file_requests:
vet_filename(request, arglist)
if security_level == "override": return
if request.function_string in allowed_requests: return
if request.function_string == "Globals.set":
if Globals.server and arglist[0] not in disallowed_server_globals:
return
raise Violation("\nWarning Security Violation!\n"
"Bad request for function: %s\n"
"with arguments: %s\n" % (request.function_string,
arglist))
raise_violation(request, arglist)
def vet_rpath(rpath):
"""Require rpath not to step outside retricted directory"""
......@@ -172,6 +239,14 @@ def vet_rpath(rpath):
"which doesn't appear to be within "
"restrict path %s.\n" % (normalized, restrict))
def vet_filename(request, arglist):
"""Check to see if file operation is within the restrict_path"""
i = file_requests[request.function_string]
if len(arglist) <= i: raise_violation(request, arglist)
filename = arglist[i]
if type(filename) is not types.StringType:
raise_violation(request, arglist)
vet_rpath(rpath.RPath(Globals.local_connection, filename))
......@@ -12,6 +12,7 @@
from __future__ import generators
import types, os, tempfile, cPickle, shutil, traceback, pickle, socket
import rpath
class ConnectionError(Exception): pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment