Return-Path: Delivered-To: apmail-incubator-river-dev-archive@minotaur.apache.org Received: (qmail 44046 invoked from network); 21 Jul 2010 23:55:15 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 21 Jul 2010 23:55:15 -0000 Received: (qmail 32548 invoked by uid 500); 21 Jul 2010 23:55:15 -0000 Delivered-To: apmail-incubator-river-dev-archive@incubator.apache.org Received: (qmail 32468 invoked by uid 500); 21 Jul 2010 23:55:14 -0000 Mailing-List: contact river-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: river-dev@incubator.apache.org Delivered-To: mailing list river-dev@incubator.apache.org Received: (qmail 32458 invoked by uid 99); 21 Jul 2010 23:55:14 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Jul 2010 23:55:14 +0000 X-ASF-Spam-Status: No, hits=0.7 required=10.0 tests=RCVD_IN_DNSWL_NONE,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [61.9.168.137] (HELO nskntmtas01p.mx.bigpond.com) (61.9.168.137) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Jul 2010 23:55:04 +0000 Received: from nskntotgx03p.mx.bigpond.com ([58.171.224.248]) by nskntmtas01p.mx.bigpond.com with ESMTP id <20100721235439.GELD13611.nskntmtas01p.mx.bigpond.com@nskntotgx03p.mx.bigpond.com> for ; Wed, 21 Jul 2010 23:54:39 +0000 Received: from [10.154.2.77] (really [58.171.224.248]) by nskntotgx03p.mx.bigpond.com with ESMTP id <20100721235436.RGTB13584.nskntotgx03p.mx.bigpond.com@[10.154.2.77]> for ; Wed, 21 Jul 2010 23:54:36 +0000 Message-ID: <4C4788BA.6060607@zeus.net.au> Date: Thu, 22 Jul 2010 09:54:34 +1000 From: Peter Firmstone Organization: Zeus Project Services User-Agent: Thunderbird 2.0.0.24 (Windows/20100228) MIME-Version: 1.0 To: river-dev@incubator.apache.org Subject: Untrusted Networks: Security, Policy's and Services - Peer review of code needed. References: <4C43E08A.8040108@acm.org> In-Reply-To: <4C43E08A.8040108@acm.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-RPD-ScanID: Class unknown; VirusThreatLevel unknown, RefID str=0001.0A090202.4C4788BF.001A,ss=1,fgs=0 X-Virus-Checked: Checked by ClamAV on apache.org If your interested, I could use some peer code review. I recently created ConcurrentDynamicPolicyProvider, motivated by Gregg's identification of a DynamicPolicyProvider concurrency bottleneck, here's some background: Previous Policy implementations, including DynamicPolicyProvider (the original implementation was renamed to org.apache.river.imp.security.cdc.DynamicPolicyProviderImp) are a bottleneck to multi threaded performance. Every check via the AccessController or SecurityManager results in checks of every ProtectionDomain within the context of the current thread (or defined AccessControlContext, which may of course be expanded or changed by the DomainCombiner). implies(Permission) is called on each ProtectionDomain, the ProtectionDomain (if created with the dynamic constructor) then asks the Policy, if it implies(Permission), if it does, it returns true, if false, it checks it's internal PermissionCollection. This makes the Policy provider an obvious point for lock contention between threads. And all this is just for one security check! The new ConcurrentDynamicPolicyProvider also implements a new interface called RevokeableDynamicPolicy, which supersedes DynamicPolicy. DynamicPolicy is an interface for Policy Providers to implement that allow dynamic permission grants, or more accurately, the delay of permission grants until runtime, it's used in the proxy verification process (see net.jini.security.Security). DynamicPolicy grant Permission's to a ClassLoader domain, this grant may cover multiple ProtectionDomain's. Dynamic grant's could not be revoked, trust once granted, couldn't be removed. One of our goals for Apache River is to continue the push into untrusted networks that Jini 2.0 started. One of the problems that Project Neuromancer highlighted was that for a remote reference implementation that utilised a distributed hashtable based object registry, there was an issue with proxy trust, once a proxy's server has moved, a proxy can no longer be trusted (for the remote reference proxy implementation that is), but the proxy itself had to be given a thread of control to discover the new location of it's referent (server). This might seem peculiar, but the reason is that the server is involved with trust verification; the client asks the server if it trusts the proxy. The client can authenticate the server and the server can authenticate the client, the connection having been severed requires the process to repeat itself, this cannot be done without first revoking trust. One could change the AccessControlContext, by adding a ProtectionDomain that had limited Permission, then run a method on the proxy to allow it to retrieve a new referent, but it would be a hack, it isn't the solution if the proxy is used from another thread, it still has elevated permissions. Trust for the client can be broken down into two components: * Do I trust the downloaded code? (Proxy Verification) * Do I trust the Service's Principal? (Authentication) The foundation of RevokeableDynamicPolicy, is that trust may change at runtime, due to many factors, such as that mentioned above, or it may be due to a vulnerability found in a CodeSource, but for whatever reason, the ability to Grant some trust as well as Revoke it is important. (Note in order to be able to revoke, the Policy must not be allowed to provide the dynamic permission grant's PermissionCollection's to the ProtectionDomain, otherwise these will become merged into the ProtectionDomain's private PermissionCollection, resulting in implies() returning true by the ProtectionDomain, even though the Policy may have returned false). Dynamic Grants, are currently applied to a ClassLoader domain, where a proxy is loaded, so they may cover multiple ProtectionDomain's within that ClassLoader space. I've decided to expand the scope of grant possibilities to allow runtime Permission grant's to apply: 1. To a specific CodeSource, no matter what it's ClassLoader, 2. A ProtectionDomain (more accurately, a CodeSource within a Particular ClassLoader **), 3. Or Certificate based grant's, which require certain developers having signed the CodeSource, no matter what CodeSource. The above grants can all be restricted to a set of Pricipal[]'s, for instances where Authentication is also required. **At the time of the AccessController Permission check, the SubjectDomainCombiner creates copies of the ProtectionDomain's from the stack of the current thread's context, so the actual ProtectionDomain grant also applies to ProtectionDomain's with an identical CodeSource and ClassLoader. In a RevokeableDynamicPolicy, the dynamic grant is known as a PermissionGrant, which is an interface for which many implementations are permitted to exist. The code involved in the PermissionGrant must also be able to satisfy Permission checks, before the grant will be accepted by the Policy implementation for obvious security reasons. It is the implementation of PermissionGrant which determines both the scope and how the grant applies. I created another Policy, called ConcurrentPolicyFile, to replace the standard file based PolicyFile provided by the JRE. To make it easier I borrowed some code from Harmony, used to parse Java policy files, an interface called PolicyParser. DefaultPolicyParser, has been refactored to generate PermissionGrant's from the standard java policy file syntax which ConcurrentPolicyFile utilises. Custom Policy Parsers and Scanners may be written by implementers also, for example to parse the OSGi bundle Permission's text file syntax. The PolicyParser may also retrieve policy files via URL from across the network, enabling centralised deployment of dynamic grant security policies if required. This allows another new possibility, that of utilising the existing Java policy file syntax, to store the Dynamic PermissionGrant's for the proxy in a jar file. By permitting the standard java policy file syntax, it also allows the proxy to utilise other third party jar files or libraries and specify the Permissions required for each of those too. Furthermore, PermissionGrant's could be utilised as Service Entry's to advertise the Permission client's are expected to grant, a client can then decide if the PermissionGrant is acceptable (by querying it's Permission's) before unmarshalling a proxy ,using the new StreamServiceRegistrar with delayed unmarshalling ( the implementation of StreamServiceRegistrar pending interface peer review). We can implement Apache River framework utility classes that create the Entry from the jar file for Service deployment. A client having decided that the Permission's required by a Service, can then go through the process of Proxy Verification, knowing precisely the grant's required, the client can create a new instance of the PermissionGrant with additional Principals and make the Permission's specific to the ClassLoader and CodeSources, the proxy will be using. At any time, the client may revoke the permission, it may do this directly after discarding the service, or it may revoke some permission based on the discovery of a new security vulnerability, thereby eliminating it. In essence, the developer decides the required Permission's, the deployment framework obtains the PermissionGrant's from the jar's policy file and the client decides if they are acceptable. I also recall Gregg needing a method of determining the Constraint's a Service requires, perhaps Constraints could be advertised via a Constraint Entry, to allow filtering of Services which have restraint's that cannot be satisfied. To summarise recent discussions regarding Entry's we could have standard: Codebase Entry's (as per Patrick's suggestion for provisioning) PermissionGrant Entry's Constraint Entry's Any suggestions for the Entry format's would be most welcome. This renewed focus on Security is intended to make it easier to deploy Services over the internet. If Apache River is to succeed on the internet, it will need to be robust from a security perspective, to have a significant advantage in order to replace current protocol based internet applications. Apache River won't restrict internet based applications to Java. Perhaps if we can succeed in making River run on the internet, we could create a River Service Browser Firefox Plugin. There's plenty of new code in need of peer review, if you have some free time to assist, please SVN the latest source and browse under trunk/src/org/apache/river/ Best Regards, Peter Firmstone.