You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.9 KiB
134 lines
3.9 KiB
import os
|
|
import sys
|
|
|
|
|
|
class SoftChrootInitError(IOError):
|
|
"""Error during soft-chroot initialization"""
|
|
pass
|
|
|
|
class SoftChroot:
|
|
"""Soft Chroot module
|
|
|
|
Provides chroot feature for interation with Web-UI. Since it is not real chroot, so the name is SOFT CHROOT.
|
|
The module prevents access to entire file-system, allowing access only to subdirs of SOFT-CHROOT directory.
|
|
"""
|
|
def __init__(self):
|
|
self.enabled = None
|
|
self.chdir = None
|
|
|
|
def initialize(self, chdir):
|
|
""" initialize module, by setting soft-chroot-directory
|
|
|
|
Sets soft-chroot directory and 'enabled'-flag
|
|
|
|
Args:
|
|
self (SoftChroot) : self
|
|
chdir (string) : absolute path to soft-chroot
|
|
|
|
Raises:
|
|
SoftChrootInitError: when chdir doesn't exist
|
|
"""
|
|
|
|
orig_chdir = chdir
|
|
|
|
if chdir:
|
|
chdir = chdir.strip()
|
|
|
|
if (chdir):
|
|
# enabling soft-chroot:
|
|
if not os.path.isdir(chdir):
|
|
raise SoftChrootInitError(2, 'SOFT-CHROOT is requested, but the folder doesn\'t exist', orig_chdir)
|
|
|
|
self.enabled = True
|
|
self.chdir = chdir.rstrip(os.path.sep) + os.path.sep
|
|
else:
|
|
self.enabled = False
|
|
|
|
def get_chroot(self):
|
|
"""Returns root in chrooted environment
|
|
|
|
Raises:
|
|
RuntimeError: when `SoftChroot` is not initialized OR enabled
|
|
"""
|
|
if None == self.enabled:
|
|
raise RuntimeError('SoftChroot is not initialized')
|
|
if not self.enabled:
|
|
raise RuntimeError('SoftChroot is not enabled')
|
|
|
|
return self.chdir
|
|
|
|
def is_root_abs(self, abspath):
|
|
""" Checks whether absolute path @abspath is the root in the soft-chrooted environment"""
|
|
if None == self.enabled:
|
|
raise RuntimeError('SoftChroot is not initialized')
|
|
|
|
if None == abspath:
|
|
raise ValueError('abspath can not be None')
|
|
|
|
if not self.enabled:
|
|
# if not chroot environment : check, whether parent is the same dir:
|
|
parent = os.path.dirname(abspath.rstrip(os.path.sep))
|
|
return parent==abspath
|
|
|
|
# in soft-chrooted env: check, that path == chroot
|
|
path = abspath.rstrip(os.path.sep) + os.path.sep
|
|
return self.chdir == path
|
|
|
|
def is_subdir(self, abspath):
|
|
""" Checks whether @abspath is subdir (on any level) of soft-chroot"""
|
|
if None == self.enabled:
|
|
raise RuntimeError('SoftChroot is not initialized')
|
|
|
|
if None == abspath:
|
|
return False
|
|
|
|
if not self.enabled:
|
|
return True
|
|
|
|
if not abspath.endswith(os.path.sep):
|
|
abspath += os.path.sep
|
|
|
|
return abspath.startswith(self.chdir)
|
|
|
|
def chroot2abs(self, path):
|
|
""" Converts chrooted path to absolute path"""
|
|
|
|
if None == self.enabled:
|
|
raise RuntimeError('SoftChroot is not initialized')
|
|
if not self.enabled:
|
|
return path
|
|
|
|
if None == path or len(path)==0:
|
|
return self.chdir
|
|
|
|
if not path.startswith(os.path.sep):
|
|
path = os.path.sep + path
|
|
|
|
return self.chdir[:-1] + path
|
|
|
|
def abs2chroot(self, path, force = False):
|
|
""" Converts absolute path to chrooted path"""
|
|
|
|
if None == self.enabled:
|
|
raise RuntimeError('SoftChroot is not initialized')
|
|
|
|
if None == path:
|
|
raise ValueError('path is empty')
|
|
|
|
if not self.enabled:
|
|
return path
|
|
|
|
if path == self.chdir.rstrip(os.path.sep):
|
|
return '/'
|
|
|
|
resulst = None
|
|
if not path.startswith(self.chdir):
|
|
if (force):
|
|
result = self.get_chroot()
|
|
else:
|
|
raise ValueError("path must starts with 'chdir': %s" % path)
|
|
else:
|
|
l = len(self.chdir)-1
|
|
result = path[l:]
|
|
|
|
return result
|
|
|