Commit b5bccc4b authored by Evan Simpson's avatar Evan Simpson

Merge evan-modsec_fix-branch

parent 7a2792d8
...@@ -207,7 +207,23 @@ def secureModule(mname, *imp): ...@@ -207,7 +207,23 @@ def secureModule(mname, *imp):
modsec.apply(module.__dict__) modsec.apply(module.__dict__)
return module return module
class ModuleSecurityInfo(SecurityInfo): def ModuleSecurityInfo(module_name=None):
if module_name is not None:
modsec = _moduleSecurity.get(module_name, None)
if modsec is not None:
return modsec
dot = module_name.rfind('.')
if dot > 0:
# If the module is in a package, recursively make sure
# there are security declarations for the package steps
# leading to the module
modname = module_name[dot + 1:]
pmodsec = ModuleSecurityInfo(module_name[:dot])
if not pmodsec.names.has_key(modname):
pmodsec.declarePublic(modname)
return _ModuleSecurityInfo(module_name)
class _ModuleSecurityInfo(SecurityInfo):
"""Encapsulate security information for modules.""" """Encapsulate security information for modules."""
__roles__ = ACCESS_PRIVATE __roles__ = ACCESS_PRIVATE
...@@ -255,3 +271,25 @@ class ModuleSecurityInfo(SecurityInfo): ...@@ -255,3 +271,25 @@ class ModuleSecurityInfo(SecurityInfo):
"""Cannot set default roles for permissions in a module.""" """Cannot set default roles for permissions in a module."""
pass pass
# Handy little utility functions
def allow_module(module_name):
"""Allow a module and all its contents to be used from a
restricted Script. The argument module_name may be a simple
or dotted module or package name. Note that if a package
path is given, all modules in the path will be available."""
ModuleSecurityInfo(module_name).setDefaultAccess(1)
dot = module_name.find('.')
while dot > 0:
ModuleSecurityInfo(module_name[:dot]).setDefaultAccess(1)
dot = module_name.find('.', dot + 1)
def allow_class(Class):
"""Allow a class and all of its methods to be used from a
restricted Script. The argument Class must be a class."""
Class._security = sec = ClassSecurityInfo()
sec.declareObjectPublic()
sec.setDefaultAccess(1)
sec.apply(Class)
from Globals import InitializeClass
InitializeClass(Class)
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
############################################################################## ##############################################################################
__doc__='''Collect rules for access to objects that don\'t have roles. __doc__='''Collect rules for access to objects that don\'t have roles.
$Id: SimpleObjectPolicies.py,v 1.9 2001/11/28 15:50:51 matt Exp $''' $Id: SimpleObjectPolicies.py,v 1.10 2002/01/11 17:14:27 evan Exp $'''
__version__='$Revision: 1.9 $'[11:-2] __version__='$Revision: 1.10 $'[11:-2]
_noroles=[] # this is imported from various places _noroles=[] # this is imported from various places
...@@ -46,3 +46,16 @@ except: ...@@ -46,3 +46,16 @@ except:
pass pass
Containers=ContainerAssertions.get Containers=ContainerAssertions.get
from types import IntType, DictType, TypeType
def allow_type(Type, allowed=1):
"""Allow a type and all of its methods and attributes to be used from
restricted code. The argument Type must be a type."""
if type(Type) is not TypeType:
raise ValueError, "%s is not a type" % `Type`
if hasattr(Type, '__roles__'):
raise ValueError, "%s handles its own security" % `Type`
if not (isinstance(allowed, IntType) or isinstance(allowed, DictType)):
raise ValueError, "The 'allowed' argument must be an int or dict."
ContainerAssertions.update(Type, allowed)
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.9 $'[11:-2] __version__='$Revision: 1.10 $'[11:-2]
from RestrictedPython.Guards import safe_builtins, _full_read_guard, \ from RestrictedPython.Guards import safe_builtins, _full_read_guard, \
full_write_guard full_write_guard
...@@ -130,7 +130,6 @@ def guarded_import(mname, globals={}, locals={}, fromlist=None): ...@@ -130,7 +130,6 @@ def guarded_import(mname, globals={}, locals={}, fromlist=None):
validate = getSecurityManager().validate validate = getSecurityManager().validate
module = load_module(None, None, mnameparts, validate, globals, locals) module = load_module(None, None, mnameparts, validate, globals, locals)
if module is not None: if module is not None:
mtype = type(module)
if fromlist is None: if fromlist is None:
fromlist = () fromlist = ()
try: try:
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
__doc__='''Define Zope\'s default security policy __doc__='''Define Zope\'s default security policy
$Id: ZopeSecurityPolicy.py,v 1.17 2001/12/13 14:25:19 andreasjung Exp $''' $Id: ZopeSecurityPolicy.py,v 1.18 2002/01/11 17:14:27 evan Exp $'''
__version__='$Revision: 1.17 $'[11:-2] __version__='$Revision: 1.18 $'[11:-2]
_use_python_impl = 0 _use_python_impl = 0
...@@ -79,7 +79,7 @@ if _use_python_impl: ...@@ -79,7 +79,7 @@ if _use_python_impl:
DictType=type({}), getattr=getattr, _noroles=_noroles, DictType=type({}), getattr=getattr, _noroles=_noroles,
StringType=type(''), StringType=type(''),
Containers=SimpleObjectPolicies.Containers, Containers=SimpleObjectPolicies.Containers,
valid_aq_=('aq_parent','aq_explicit')): valid_aq_=('aq_parent','aq_inner', 'aq_explicit')):
############################################################ ############################################################
......
...@@ -21,7 +21,8 @@ from SecurityInfo import ClassSecurityInfo, ModuleSecurityInfo ...@@ -21,7 +21,8 @@ from SecurityInfo import ClassSecurityInfo, ModuleSecurityInfo
from SecurityInfo import ACCESS_PRIVATE from SecurityInfo import ACCESS_PRIVATE
from SecurityInfo import ACCESS_PUBLIC from SecurityInfo import ACCESS_PUBLIC
from SecurityInfo import ACCESS_NONE from SecurityInfo import ACCESS_NONE
from SecurityInfo import secureModule from SecurityInfo import secureModule, allow_module, allow_class
from SimpleObjectPolicies import allow_type
from ZopeGuards import full_read_guard, full_write_guard, safe_builtins from ZopeGuards import full_read_guard, full_write_guard, safe_builtins
ModuleSecurityInfo('AccessControl').declarePublic('getSecurityManager') ModuleSecurityInfo('AccessControl').declarePublic('getSecurityManager')
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. DAMAGE.
$Id: cAccessControl.c,v 1.12 2001/10/26 16:07:50 matt Exp $ $Id: cAccessControl.c,v 1.13 2002/01/11 17:14:27 evan Exp $
If you have questions regarding this software, If you have questions regarding this software,
contact: contact:
...@@ -763,6 +763,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) { ...@@ -763,6 +763,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
sname = PyString_AS_STRING(name); sname = PyString_AS_STRING(name);
if (*sname == 'a' && sname[1]=='q' && sname[2]=='_') { if (*sname == 'a' && sname[1]=='q' && sname[2]=='_') {
if (strcmp(sname,"aq_parent") != 0 && if (strcmp(sname,"aq_parent") != 0 &&
strcmp(sname,"aq_inner") != 0 &&
strcmp(sname,"aq_explicit") != 0) { strcmp(sname,"aq_explicit") != 0) {
/* Access control violation, return 0 */ /* Access control violation, return 0 */
return PyInt_FromLong(0); return PyInt_FromLong(0);
...@@ -2075,7 +2076,7 @@ static struct PyMethodDef dtml_methods[] = { ...@@ -2075,7 +2076,7 @@ static struct PyMethodDef dtml_methods[] = {
void initcAccessControl(void) { void initcAccessControl(void) {
PyObject *module; PyObject *module;
PyObject *dict; PyObject *dict;
char *rev = "$Revision: 1.12 $"; char *rev = "$Revision: 1.13 $";
PURE_MIXIN_CLASS(RestrictedDTMLMixin, PURE_MIXIN_CLASS(RestrictedDTMLMixin,
"A mix-in for derivatives of DT_String.String " "A mix-in for derivatives of DT_String.String "
"that adds Zope security." "that adds Zope security."
...@@ -2096,7 +2097,7 @@ void initcAccessControl(void) { ...@@ -2096,7 +2097,7 @@ void initcAccessControl(void) {
module = Py_InitModule3("cAccessControl", module = Py_InitModule3("cAccessControl",
cAccessControl_methods, cAccessControl_methods,
"$Id: cAccessControl.c,v 1.12 2001/10/26 16:07:50 matt Exp $\n"); "$Id: cAccessControl.c,v 1.13 2002/01/11 17:14:27 evan Exp $\n");
aq_init(); /* For Python <= 2.1.1, aq_init() should be after aq_init(); /* For Python <= 2.1.1, aq_init() should be after
Py_InitModule(). */ Py_InitModule(). */
......
# test module, partially private
def priv():
pass
def pub():
pass
# test module, all private
def priv():
pass
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Module Import Tests
"""
__rcs_id__='$Id: testModuleSecurity.py,v 1.2 2002/01/11 17:14:27 evan Exp $'
__version__='$Revision: 1.2 $'[11:-2]
import os, sys, unittest
import ZODB
from AccessControl import Unauthorized, ModuleSecurityInfo
from AccessControl.ZopeGuards import guarded_import
ModuleSecurityInfo('AccessControl.tests.mixed_module').declarePublic('pub')
ModuleSecurityInfo('AccessControl.tests.public_module').declarePublic('pub')
ModuleSecurityInfo('AccessControl.tests.public_module.submodule'
).declarePublic('pub')
class SecurityTests(unittest.TestCase):
def assertUnauth(self, module, fromlist):
try:
guarded_import(module, fromlist=fromlist)
except (Unauthorized, ImportError):
# Passed the test.
pass
else:
assert 0, ('Did not protect module instance %s, %s' %
(`module`, `fromlist`))
def assertAuth(self, module, fromlist):
try:
guarded_import(module, fromlist=fromlist)
except (Unauthorized, ImportError):
assert 0, ('Did not expose module instance %s, %s' %
(`module`, `fromlist`))
def testPrivateModule(self):
for name in '', '.submodule':
for fromlist in (), ('priv',):
self.assertUnauth(
'AccessControl.tests.private_module%s' % name,
fromlist)
def testMixedModule(self):
self.assertAuth('AccessControl.tests.mixed_module', ())
self.assertAuth('AccessControl.tests.mixed_module', ('pub',))
self.assertUnauth('AccessControl.tests.mixed_module', ('priv',))
self.assertUnauth('AccessControl.tests.mixed_module.submodule', ())
def testPublicModule(self):
for name in '', '.submodule':
for fromlist in (), ('pub',):
self.assertAuth(
'AccessControl.tests.public_module%s' % name,
fromlist)
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( SecurityTests ) )
return suite
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
"""Tests of ZopeSecurityPolicy """Tests of ZopeSecurityPolicy
""" """
__rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.3 2001/11/28 15:50:52 matt Exp $' __rcs_id__='$Id: testZopeSecurityPolicy.py,v 1.4 2002/01/11 17:14:27 evan Exp $'
__version__='$Revision: 1.3 $'[11:-2] __version__='$Revision: 1.4 $'[11:-2]
import os, sys, unittest import os, sys, unittest
...@@ -223,6 +223,7 @@ class ZopeSecurityPolicyTests (unittest.TestCase): ...@@ -223,6 +223,7 @@ class ZopeSecurityPolicyTests (unittest.TestCase):
assert not policy.validate('', '', 'aq_base', '', None) assert not policy.validate('', '', 'aq_base', '', None)
assert policy.validate('', '', 'aq_parent', '', None) assert policy.validate('', '', 'aq_parent', '', None)
assert policy.validate('', '', 'aq_explicit', '', None) assert policy.validate('', '', 'aq_explicit', '', None)
assert policy.validate('', '', 'aq_inner', '', None)
if 0: if 0:
# This test purposely generates a log entry. # This test purposely generates a log entry.
......
...@@ -13,29 +13,8 @@ ...@@ -13,29 +13,8 @@
"""Utility module for making simple security assertions for """Utility module for making simple security assertions for
Python scripts.""" Python scripts."""
__version__='$Revision: 1.4 $'[11:-2] __version__='$Revision: 1.5 $'[11:-2]
from AccessControl import ModuleSecurityInfo, ClassSecurityInfo # These have been relocated, and should be imported from AccessControl
from Globals import InitializeClass
import string
def allow_module(module_name):
"""Allow a module and all its contents to be used from a
restricted Script. The argument module_name may be a simple
or dotted module or package name. Note that if a package
path is given, all modules in the path will be available."""
ModuleSecurityInfo(module_name).setDefaultAccess(1)
dot = string.find(module_name, '.')
while dot > 0:
ModuleSecurityInfo(module_name[:dot]).setDefaultAccess(1)
dot = string.find(module_name, '.', dot + 1)
def allow_class(Class):
"""Allow a class and all of its methods to be used from a
restricted Script. The argument Class must be a class."""
Class._security = sec = ClassSecurityInfo()
sec.declareObjectPublic()
sec.setDefaultAccess(1)
sec.apply(Class)
InitializeClass(Class)
from AccessControl import allow_module, allow_class
...@@ -15,7 +15,7 @@ modules that are not listed below. The list is not comprehensive, ...@@ -15,7 +15,7 @@ modules that are not listed below. The list is not comprehensive,
but is provided as a decent cross-section of modules. but is provided as a decent cross-section of modules.
''' '''
from Products.PythonScripts.Utility import allow_module, allow_class from AccessControl import allow_module, allow_class, allow_type
from AccessControl import ModuleSecurityInfo, ClassSecurityInfo from AccessControl import ModuleSecurityInfo, ClassSecurityInfo
from Globals import InitializeClass from Globals import InitializeClass
...@@ -42,9 +42,9 @@ from Globals import InitializeClass ...@@ -42,9 +42,9 @@ from Globals import InitializeClass
# ModuleSecurityInfo('re').declarePublic('compile', 'findall', # ModuleSecurityInfo('re').declarePublic('compile', 'findall',
# 'match', 'search', 'split', 'sub', 'subn', 'error', # 'match', 'search', 'split', 'sub', 'subn', 'error',
# 'I', 'L', 'M', 'S', 'X') # 'I', 'L', 'M', 'S', 'X')
# from re import RegexObject, MatchObject # import re
# allow_class(RegexObject) # allow_type(type(re.compile('')))
# allow_class(MatchObject) # allow_type(type(re.match('x','x')))
# ModuleSecurityInfo('StringIO').declarePublic('StringIO') # ModuleSecurityInfo('StringIO').declarePublic('StringIO')
......
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