Commit c26d31f9 authored by Shane Hathaway's avatar Shane Hathaway

Denial of access to acquired attributes through guarded_getattr() should

result in an Unauthorized error rather than AttributeError.  Added a test
to ensure the bug stays fixed.
parent fb4df500
......@@ -11,7 +11,7 @@
#
##############################################################################
__version__='$Revision: 1.14 $'[11:-2]
__version__='$Revision: 1.15 $'[11:-2]
from RestrictedPython.Guards import safe_builtins, _full_read_guard, \
full_write_guard
......@@ -55,7 +55,12 @@ except ImportError:
validate = getSecurityManager().validate
# Filter out the objects we can't access.
if hasattr(inst, 'aq_acquire'):
return inst.aq_acquire(name, aq_validate, validate)
try:
return inst.aq_acquire(name, aq_validate, validate)
except AttributeError:
# A denial of access was converted into an
# AttributeError. Convert it back.
raise Unauthorized, name
# Or just try to get the attribute directly.
if validate(inst, inst, name, v):
return v
......
......@@ -36,7 +36,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
$Id: cAccessControl.c,v 1.18 2002/12/16 19:13:00 chrism Exp $
$Id: cAccessControl.c,v 1.19 2003/01/14 15:03:05 shane Exp $
If you have questions regarding this software,
contact:
......@@ -2011,12 +2011,24 @@ guarded_getattr(PyObject *inst, PyObject *name, PyObject *default_,
/*
# Filter out the objects we can't access.
if hasattr(inst, 'aq_acquire'):
return inst.aq_acquire(name, aq_validate, validate)
try:
return inst.aq_acquire(name, aq_validate, validate)
except AttributeError:
# A denial of access was converted into an
# AttributeError. Convert it back.
raise Unauthorized, name
*/
if (aq_isWrapper(inst))
{
ASSIGN(v, aq_Acquire(inst, name, aq_validate, validate, 1, NULL, 0));
return v;
t = aq_Acquire(inst, name, aq_validate, validate, 1, NULL, 0);
if (t == NULL && PyErr_Occurred() == PyExc_AttributeError)
{
PyErr_Clear();
unauthErr(name, v);
goto err;
}
Py_DECREF(v);
return t;
}
/*
......@@ -2138,7 +2150,7 @@ void initcAccessControl(void) {
module = Py_InitModule3("cAccessControl",
cAccessControl_methods,
"$Id: cAccessControl.c,v 1.18 2002/12/16 19:13:00 chrism Exp $\n");
"$Id: cAccessControl.c,v 1.19 2003/01/14 15:03:05 shane Exp $\n");
aq_init(); /* For Python <= 2.1.1, aq_init() should be after
Py_InitModule(). */
......
......@@ -16,18 +16,20 @@ import os, sys, unittest
import string, cStringIO, re
import ZODB, Acquisition
from Acquisition import aq_base
from OFS.Application import Application
from OFS.Folder import manage_addFolder
from OFS.Image import manage_addFile
from OFS.SimpleItem import SimpleItem
from Testing.makerequest import makerequest
from AccessControl import SecurityManager
from AccessControl import SecurityManager, Unauthorized
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from mimetools import Message
from multifile import MultiFile
class UnitTestSecurityPolicy:
"""
Stub out the existing security policy for unit testing purposes.
......@@ -49,6 +51,22 @@ class UnitTestSecurityPolicy:
def checkPermission( self, permission, object, context) :
return 1
class CruelSecurityPolicy:
"""Denies everything
"""
#
# Standard SecurityPolicy interface
#
def validate(self, accessed, container, name, value, *args):
if aq_base(accessed) is aq_base(container):
raise Unauthorized, name
return 0
def checkPermission( self, permission, object, context) :
return 0
class UnitTestUser( Acquisition.Implicit ):
"""
Stubbed out manager for unit testing purposes.
......@@ -79,6 +97,7 @@ def makeConnection():
s = DemoStorage(quota=(1<<20))
return ZODB.DB( s ).open()
class TestTraverse( unittest.TestCase ):
def setUp( self ):
......@@ -162,6 +181,18 @@ class TestTraverse( unittest.TestCase ):
self.failUnlessRaises(KeyError, bb.restrictedTraverse, 'notfound')
bb.restrictedTraverse('bb_subitem')
def testAcquiredAttributeDenial(self):
# Verify that restrictedTraverse raises the right kind of exception
# on denial of access to an acquired attribute. If it raises
# AttributeError instead of Unauthorized, the user may never
# be prompted for HTTP credentials.
noSecurityManager()
SecurityManager.setSecurityPolicy(CruelSecurityPolicy())
newSecurityManager( None, UnitTestUser().__of__( self.root ) )
self.root.stuff = 'stuff here'
self.failUnlessRaises(Unauthorized,
self.root.folder1.restrictedTraverse, 'stuff')
def test_suite():
suite = unittest.TestSuite()
......@@ -169,7 +200,7 @@ def test_suite():
return suite
def main():
unittest.TextTestRunner().run(test_suite())
unittest.main(defaultTest='test_suite')
if __name__ == '__main__':
main()
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