Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
86fa36cb
Commit
86fa36cb
authored
Nov 30, 2005
by
Tres Seaver
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
My original patch, with tests.
parent
efb30bfa
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
273 additions
and
51 deletions
+273
-51
lib/python/AccessControl/ImplPython.py
lib/python/AccessControl/ImplPython.py
+21
-2
lib/python/AccessControl/cAccessControl.c
lib/python/AccessControl/cAccessControl.c
+182
-43
lib/python/AccessControl/interfaces.py
lib/python/AccessControl/interfaces.py
+30
-1
lib/python/AccessControl/tests/testZopeSecurityPolicy.py
lib/python/AccessControl/tests/testZopeSecurityPolicy.py
+40
-5
No files found.
lib/python/AccessControl/ImplPython.py
View file @
86fa36cb
...
...
@@ -34,6 +34,7 @@ except ImportError:
from
AccessControl
import
SecurityManagement
from
AccessControl
import
Unauthorized
from
AccessControl.interfaces
import
ISecurityPolicy
from
AccessControl.interfaces
import
ISecurityManager
from
AccessControl.SimpleObjectPolicies
import
Containers
,
_noroles
from
AccessControl.ZopeGuards
import
guarded_getitem
...
...
@@ -199,6 +200,8 @@ from AccessControl.ZopeSecurityPolicy import getRoles # XXX
class
ZopeSecurityPolicy
:
implements
(
ISecurityPolicy
)
def
__init__
(
self
,
ownerous
=
1
,
authenticated
=
1
,
verbose
=
0
):
"""Create a Zope security policy.
...
...
@@ -459,12 +462,28 @@ class ZopeSecurityPolicy:
raise
Unauthorized
(
name
,
value
)
def
checkPermission
(
self
,
permission
,
object
,
context
):
# XXX proxy roles and executable owner are not checked
roles
=
rolesForPermissionOn
(
permission
,
object
)
if
isinstance
(
roles
,
basestring
):
roles
=
[
roles
]
re
turn
context
.
user
.
allowed
(
object
,
roles
)
re
sult
=
context
.
user
.
allowed
(
object
,
roles
)
# check executable owner and proxy roles
stack
=
context
.
stack
if
stack
:
eo
=
stack
[
-
1
]
if
self
.
_ownerous
:
owner
=
eo
.
getOwner
()
if
(
owner
is
not
None
)
and
not
owner
.
allowed
(
object
,
roles
):
return
0
proxy_roles
=
getattr
(
eo
,
'_proxy_roles'
,
None
)
if
proxy_roles
:
if
object
is
not
aq_base
(
object
):
if
not
owner
.
_check_context
(
object
):
return
0
for
r
in
proxy_roles
:
if
r
in
roles
:
return
1
return
result
# AccessControl.SecurityManager
# -----------------------------
...
...
lib/python/AccessControl/cAccessControl.c
View file @
86fa36cb
...
...
@@ -1292,61 +1292,200 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
*/
static
PyObject
*
ZopeSecurityPolicy_checkPermission
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
permission
=
NULL
;
PyObject
*
object
=
NULL
;
PyObject
*
context
=
NULL
;
PyObject
*
roles
;
PyObject
*
result
=
NULL
;
PyObject
*
user
;
/*| def checkPermission(self, permission, object, context)
*/
if
(
unpacktuple3
(
args
,
"checkPermission"
,
3
,
PyObject
*
args
)
{
/* return value */
PyObject
*
rval
=
NULL
;
/* arguments, not increfe'd */
PyObject
*
permission
=
NULL
;
PyObject
*
object
=
NULL
;
PyObject
*
context
=
NULL
;
/* locals, XDECREF at exit */
PyObject
*
roles
=
NULL
;
PyObject
*
user
=
NULL
;
PyObject
*
stack
=
NULL
;
PyObject
*
eo
=
NULL
;
PyObject
*
owner
=
NULL
;
PyObject
*
proxy_roles
=
NULL
;
PyObject
*
method
=
NULL
;
PyObject
*
wrappedowner
=
NULL
;
PyObject
*
objectbase
=
NULL
;
PyObject
*
incontext
=
NULL
;
int
contains
=
0
;
int
iRole
;
int
length
;
/*| def checkPermission(self, permission, object, context)
*/
if
(
unpacktuple3
(
args
,
"checkPermission"
,
3
,
&
permission
,
&
object
,
&
context
)
<
0
)
return
NULL
;
return
NULL
;
/*| roles = rolesForPermissionOn(permission, object)
*/
/*| roles = rolesForPermissionOn(permission, object)
*/
roles
=
c_rolesForPermissionOn
(
permission
,
object
,
NULL
,
NULL
);
if
(
roles
==
NULL
)
roles
=
c_rolesForPermissionOn
(
permission
,
object
,
NULL
,
NULL
);
if
(
roles
==
NULL
)
return
NULL
;
/*| if type(roles) in (StringType, UnicodeType):
**|
roles = [roles]
*/
/*| if type(roles) in (StringType, UnicodeType):
**|
roles = [roles]
*/
if
(
PyString_Check
(
roles
)
||
PyUnicode_Check
(
roles
)
)
{
PyObject
*
r
;
if
(
PyString_Check
(
roles
)
||
PyUnicode_Check
(
roles
)
)
{
PyObject
*
r
ole_list
;
r
=
PyList_New
(
1
);
if
(
r
==
NULL
)
{
Py_DECREF
(
roles
);
return
NULL
;
}
role_list
=
PyList_New
(
1
);
if
(
role_list
==
NULL
)
goto
cP_done
;
/* Note: ref to roles is passed to the list object. */
PyList_SET_ITEM
(
r
,
0
,
roles
);
roles
=
r
;
}
PyList_SET_ITEM
(
r
ole_list
,
0
,
roles
);
roles
=
r
ole_list
;
}
/*| return
context.user.allowed(object, roles)
*/
/*| result =
context.user.allowed(object, roles)
*/
user
=
PyObject_GetAttr
(
context
,
user_str
);
if
(
user
!=
NULL
)
{
ASSIGN
(
user
,
PyObject_GetAttr
(
user
,
allowed_str
));
if
(
user
!=
NULL
)
{
result
=
callfunction2
(
user
,
object
,
roles
);
Py_DECREF
(
user
);
}
}
user
=
PyObject_GetAttr
(
context
,
user_str
);
if
(
user
!=
NULL
)
{
ASSIGN
(
user
,
PyObject_GetAttr
(
user
,
allowed_str
));
if
(
user
!=
NULL
)
{
rval
=
callfunction2
(
user
,
object
,
roles
);
}
}
Py_DECREF
(
roles
);
/*| # Check executable security
**| stack = context.stack
**| if stack:
*/
stack
=
PyObject_GetAttr
(
context
,
stack_str
);
if
(
stack
==
NULL
)
goto
cP_done
;
if
(
PyObject_IsTrue
(
stack
))
{
/*| eo = stack[-1]
**| # If the executable had an owner, can it execute?
**| owner = eo.getOwner()
**| if (owner is not None) and not owner.allowed(object, roles)
**| # We don't want someone to acquire if they can't
**| # get an unacquired!
**| return 0
*/
eo
=
PySequence_GetItem
(
stack
,
-
1
);
if
(
eo
==
NULL
)
goto
cP_done
;
if
(
ownerous
)
{
owner
=
PyObject_GetAttr
(
eo
,
getOwner_str
);
if
(
owner
)
ASSIGN
(
owner
,
PyObject_CallObject
(
owner
,
NULL
));
if
(
owner
==
NULL
)
goto
cP_done
;
if
(
owner
!=
Py_None
)
{
ASSIGN
(
owner
,
PyObject_GetAttr
(
owner
,
allowed_str
));
if
(
owner
)
ASSIGN
(
owner
,
callfunction2
(
owner
,
object
,
roles
));
if
(
owner
==
NULL
)
goto
cP_done
;
if
(
!
PyObject_IsTrue
(
owner
))
{
rval
=
0
;
goto
cP_done
;
}
}
}
/*| # Proxy roles, which are a lot safer now
**| proxy_roles = getattr(eo, "_proxy_roles", None)
**| if proxy_roles:
**| # Verify that the owner actually can state the proxy role
**| # in the context of the accessed item; users in subfolders
**| # should not be able to use proxy roles to access items
**| # above their subfolder!
**| owner = eo.getWrappedOwner()
**|
**| if owner is not None:
**| if object is not aq_base(object):
**| if not owner._check_context(object):
**| # object is higher up than the owner,
**| # deny access
**| return 0
**|
**| for r in proxy_roles:
**| if r in roles:
**| return 1
**|
**| return result
*/
proxy_roles
=
PyObject_GetAttr
(
eo
,
_proxy_roles_str
);
if
(
proxy_roles
==
NULL
)
{
PyErr_Clear
();
goto
cP_done
;
}
return
result
;
if
(
PyObject_IsTrue
(
proxy_roles
))
{
method
=
PyObject_GetAttr
(
eo
,
getWrappedOwner_str
);
if
(
method
==
NULL
)
goto
cP_done
;
wrappedowner
=
PyObject_CallObject
(
method
,
NULL
);
if
(
wrappedowner
==
NULL
)
goto
cP_done
;
if
(
wrappedowner
!=
Py_None
)
{
objectbase
=
aq_base
(
object
);
if
(
object
!=
objectbase
)
{
incontext
=
callmethod1
(
wrappedowner
,
_check_context_str
,
object
);
if
(
incontext
==
NULL
)
goto
cP_done
;
}
if
(
!
PyObject_IsTrue
(
incontext
))
goto
cP_done
;
}
}
if
(
PyTuple_Check
(
proxy_roles
))
{
PyObject
*
proxy_role
;
length
=
PyTuple_GET_SIZE
(
proxy_roles
);
for
(
iRole
=
0
;
iRole
<
length
;
iRole
++
)
{
proxy_role
=
PyTuple_GET_ITEM
(
proxy_roles
,
iRole
);
/* proxy_role is not increfed */
if
((
contains
=
PySequence_Contains
(
roles
,
proxy_role
)))
break
;
}
}
else
{
PyObject
*
proxy_role
;
length
=
PySequence_Size
(
proxy_roles
);
if
(
length
<
0
)
contains
=
-
1
;
for
(
iRole
=
0
;
contains
==
0
&&
iRole
<
length
;
iRole
++
)
{
proxy_role
=
PySequence_GetItem
(
proxy_roles
,
iRole
);
if
(
proxy_role
==
NULL
)
goto
cP_done
;
/* proxy_role is increfed */
contains
=
PySequence_Contains
(
roles
,
proxy_role
);
Py_DECREF
(
proxy_role
);
}
}
if
(
contains
>
0
)
rval
=
PyInt_FromLong
(
contains
);
}
/* End of stack check */
cP_done:
Py_XDECREF
(
roles
);
Py_XDECREF
(
user
);
Py_XDECREF
(
stack
);
Py_XDECREF
(
eo
);
Py_XDECREF
(
owner
);
Py_XDECREF
(
proxy_roles
);
Py_XDECREF
(
method
);
Py_XDECREF
(
wrappedowner
);
Py_XDECREF
(
objectbase
);
Py_XDECREF
(
incontext
);
return
rval
;
}
/*
...
...
lib/python/AccessControl/interfaces.py
View file @
86fa36cb
...
...
@@ -17,8 +17,37 @@ from AccessControl.SimpleObjectPolicies import _noroles
from
zope.interface
import
Interface
from
zope.interface
import
Attribute
class
ISecurityPolicy
(
Interface
):
"""Plug-in policy for checking access to objects within untrusted code.
"""
def
validate
(
accessed
,
container
,
name
,
value
,
context
,
roles
=
_noroles
):
"""Check that the current user (from context) has access.
o Raise Unauthorized if access is not allowed; otherwise, return
a true value.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
context -- the security context (normally supplied by the security
manager).
roles -- The roles of the object if already known.
"""
def
checkPermission
(
permission
,
object
,
context
):
"""Check whether the current user has a permission w.r.t. an object.
"""
class
ISecurityManager
(
Interface
):
"""Check
s
access and manages executable context and policies.
"""Check access and manages executable context and policies.
"""
_policy
=
Attribute
(
u'Current Security Policy'
)
...
...
lib/python/AccessControl/tests/testZopeSecurityPolicy.py
View file @
86fa36cb
...
...
@@ -23,7 +23,6 @@ try:
from
zExceptions
import
Unauthorized
except
ImportError
:
Unauthorized
=
'Unauthorized'
from
AccessControl.ZopeSecurityPolicy
import
ZopeSecurityPolicy
from
AccessControl.User
import
UserFolder
from
AccessControl.SecurityManagement
import
SecurityContext
from
Acquisition
import
Implicit
,
Explicit
,
aq_base
...
...
@@ -152,9 +151,7 @@ class SimpleClass:
attr
=
1
class
ZopeSecurityPolicyTests
(
unittest
.
TestCase
):
policy
=
ZopeSecurityPolicy
()
class
ZopeSecurityPolicyTestBase
(
unittest
.
TestCase
):
def
setUp
(
self
):
a
=
App
()
...
...
@@ -174,6 +171,10 @@ class ZopeSecurityPolicyTests (unittest.TestCase):
self
.
user
=
user
context
=
SecurityContext
(
user
)
self
.
context
=
context
self
.
policy
=
self
.
_makeOne
()
def
_makeOne
(
self
,
*
args
,
**
kw
):
return
self
.
_getTargetClass
()(
*
args
,
**
kw
)
def
assertPolicyAllows
(
self
,
ob
,
attrname
):
res
=
self
.
policy
.
validate
(
ob
,
ob
,
attrname
,
getattr
(
ob
,
attrname
),
...
...
@@ -276,6 +277,17 @@ class ZopeSecurityPolicyTests (unittest.TestCase):
v
=
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
o_context
)
self
.
assert_
(
v
,
'_View_Permission should grant access to theowner'
)
def
test_checkPermission_respects_proxy_roles
(
self
):
r_item
=
self
.
a
.
r_item
context
=
self
.
context
self
.
failIf
(
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
))
o_context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'joe'
))
# Push an executable with proxy roles on the stack
eo
=
OwnedSetuidMethod
().
__of__
(
r_item
)
eo
.
_proxy_roles
=
eo_roles
context
.
stack
.
append
(
eo
)
self
.
failUnless
(
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
))
def
testUnicodeRolesForPermission
(
self
):
r_item
=
self
.
a
.
r_item
context
=
self
.
context
...
...
@@ -351,6 +363,27 @@ class ZopeSecurityPolicyTests (unittest.TestCase):
self
.
fail
(
'Policy accepted bad __roles__'
)
class
ISecurityPolicyConformance
:
def
test_conforms_to_ISecurityPolicy
(
self
):
from
AccessControl.interfaces
import
ISecurityPolicy
from
zope.interface.verify
import
verifyClass
verifyClass
(
ISecurityPolicy
,
self
.
_getTargetClass
())
class
Python_ZSPTests
(
ZopeSecurityPolicyTestBase
,
ISecurityPolicyConformance
,
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplPython
import
ZopeSecurityPolicy
return
ZopeSecurityPolicy
class
C_ZSPTests
(
ZopeSecurityPolicyTestBase
,
# ISecurityPolicyConformance, #XXX C version, how?
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplC
import
ZopeSecurityPolicy
return
ZopeSecurityPolicy
def
test_getRoles
():
"""
...
...
@@ -445,6 +478,7 @@ def test_getRoles():
def
test_zsp_gets_right_roles_for_methods
():
"""
>>> from AccessControl.ZopeSecurityPolicy import ZopeSecurityPolicy
>>> zsp = ZopeSecurityPolicy()
>>> from ExtensionClass import Base
>>> class C(Base):
...
...
@@ -499,7 +533,8 @@ from zope.testing.doctest import DocTestSuite
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
ZopeSecurityPolicyTests
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
Python_ZSPTests
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
C_ZSPTests
,
'test'
))
suite
.
addTest
(
DocTestSuite
())
return
suite
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment