Return-Path: X-Original-To: apmail-river-dev-archive@www.apache.org Delivered-To: apmail-river-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6DA4E7920 for ; Thu, 11 Aug 2011 08:44:18 +0000 (UTC) Received: (qmail 66415 invoked by uid 500); 11 Aug 2011 08:44:16 -0000 Delivered-To: apmail-river-dev-archive@river.apache.org Received: (qmail 66228 invoked by uid 500); 11 Aug 2011 08:44:01 -0000 Mailing-List: contact dev-help@river.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@river.apache.org Delivered-To: mailing list dev@river.apache.org Received: (qmail 66201 invoked by uid 99); 11 Aug 2011 08:43:57 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 11 Aug 2011 08:43:57 +0000 X-ASF-Spam-Status: No, hits=0.7 required=5.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; Thu, 11 Aug 2011 08:43:48 +0000 Received: from nskntotgx01p.mx.bigpond.com ([61.9.223.241]) by nskntmtas01p.mx.bigpond.com with ESMTP id <20110811084323.EOWJ24561.nskntmtas01p.mx.bigpond.com@nskntotgx01p.mx.bigpond.com> for ; Thu, 11 Aug 2011 08:43:23 +0000 Received: from [10.1.1.2] (really [61.9.223.241]) by nskntotgx01p.mx.bigpond.com with ESMTP id <20110811084323.EYEJ23205.nskntotgx01p.mx.bigpond.com@[10.1.1.2]> for ; Thu, 11 Aug 2011 08:43:23 +0000 Message-ID: <4E439455.30301@zeus.net.au> Date: Thu, 11 Aug 2011 18:35:33 +1000 From: Peter Firmstone User-Agent: Thunderbird 2.0.0.14 (X11/20080531) MIME-Version: 1.0 To: dev@river.apache.org Subject: Re: Ease of use, development & deployment References: <1312872800.2063.4.camel@Nokia-N900-51-1> <1312905515.2633.82.camel@cameron> In-Reply-To: <1312905515.2633.82.camel@cameron> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Greg Trasuk wrote: > I don't see separate releases solving anything. The security setup > should just be a matter of selecting a different Configuration file, > depending on what level and type of transport security and > confidentiality you want. I'd picture supplying a minimal-security > configuration and a maximal-lockdown config for Kerberos and SSL. > That makes perfect sense, the reason I was considering separation was more political than functional. Different developers have different focus points. > > >> Does anyone have any suggestions for annotations? So developers can weave in security later, allowing them to get up and running with River in a local network first, then learn security later? >> >> > > Some random thoughts: > - Security can be decomposed into > - Authentication > - Authorization > - Integrity of communications > - Confidentiality of communications > - Jeri does a great job with Authentication (can use Kerberos or X509 > certs), Cinfidentiality and Integrity (through SSL, https, Kerberos > endpoints). > - The SecurityPolicy model was originally intended to support > codebase-based security (i.e. permissions are applied to a > ProtectionDomain associated with the source of the code). > - JAAS extension glued on Subject-based decisions to the SecurityPolicy > model after-the-fact. > > I've been gradually becoming convinced that the JAAS security model > (i.e. SubjectDomainCombiner etc) is not very good for subject-based > authorization. The basic business need for a service is to answer the > question "Is Bob allowed to place a purchase order?", where Bob's > authorization might be subject to change over time, or might be subject > to additional business rules. Seems like in order to enforce that > decision using the SecurityPolicy model, we end up needing elaborate > constructs (e.g. revokable permissions, remote policy files, > classloader/protection domain magic, dynamic policy lookup, etc). > Sorry about the lengthy post: Yes you're right, this is the motivation behind my work, what we need is something that runs on top of these constructs to make it easy for application developers. OSGi has a different security model, that pre-dates the jre, using conditional permission's, if a condition isn't satisfied, then neither is the permission, it also delays some permission decisions. Eg in an embedded device, there might not be a user to ask to grant a permission. It supports permission addition and removal, it doesn't prevent security sensitive object references escaping further security checks, but it is more flexible. http://www.osgi.org/javadoc/r4v43/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.html You have to remember that Netscape was competing to implement a browser based security model at the time, so thing's could have been worse. Li didn't get to do all the things he wanted, it's still a testament to his efforts though. I like to keep a simple picture in my mind when performing security checks. The jvm maintains the context for each thread, a snapshot of the call stack, a Subject's principals are injected into the current call stack with SubjectDomainCombiner, so I like to think of a thread as representing a user (Subject) and a ProtectionDomain representing the code. Java security historically had a unique focus on code based security. Other enterprise software at the time focused on the user. The DomainCombiner concept is ok, but SubjectDomainCombiner is a bit clunky, it uses a separate cache for each object, it suffers from creating too many short lived ProtectionDomain objects (that don't implement equals or hashCode) causing garbage collection. Different Subject's can often have identical Principal's, especially if you're a Server with many clients. It would make sense to have a SubjectDomainCombiner with a static concurrent cache of ProtectionDomain's. SubjectDomainCombiner is non final so it could be re implemented, but you couldn't use any of Subject's static methods. But doing so is probably not worth the added complication of new api. I want to close up the proxy unmarshalling DOS attack hole by granting DownloadPermission to specific Certificate signer's, this answers the question: "Do I trust the code to unmarshall?" But I don't want to have to edit every node's policy files and I don't want the policy to be downloaded from a URL either. Also I've added a tool com.sun.jini.tool.ProfilingSecurityManager, that prints out Permissions required for each CodeSource during execution. These permission's can be either granted to Principal's or CodeSource's. So I'm now focusing on another tool that allows the developer to include a list of Permissions a proxy requires to execute locally, in the proxy's jar file. These can be dynamically granted by the user if permitted by the administrator (using GrantPermission). My use for RemotePolicy is; it allows an administrator to dynamically update permissions for an entire djinn group, where services joining the group decide if they want to subscribe to that group's policies. Since the administrator of the group must authenticate, and runs with the administrator subject, foreign clients participating in the group can limit the permissions they're prepared to grant to that groups administrator Subject with GrantPermission. You can't do this with existing URL based policy files. The administrator is notified of rejected Policy updates with a SecurityException wrapped in a RemoteException. The RemotePolicy update either succeeds or fails completely if a SecurityException occurs. This allows the administrator to be informed of policy failures and address them. In the environment I'm interested in deploying, I can't ignore the Code trust issue. But concurrency is a problem with existing Policy implementations. My recent development focus has been to improve the concurrency of security checks, The concurrent DynamicPolicyProvider at present is running (20 hours) through all qa tests (recently merged with the current trunk), it has passed all policy and security tests. The current focus is on correctness. I've got a new SecurityManager that caches the results of Permission checks for AccessControlContext, so if a lot of threads have identical AccessControlContext and are executed concurrently, then the security check is only performed once. Eg in an application with 16 threads, an Executor or something like that performing a computation task for a user, security checks won't be repeated for every thread, once a check has passed for the context, it first looks for a successful result from a previous call in the cache before performing the costly permission check. I have two different implementations of the SecurityManager at present, this will be narrowed down to one later. SubjectDomainCombiner is still a performance issue when the context changes though and you must ensure all threads share the same Subject and SubjectDomainCombiner, so they utilise identical == ProtectionDomains in their context. All the other work is low level platform stuff. Revocation and RemotePolicy won't be included in the net.jini namespace unless they become standardised. I've created the namespace org.apache.river.api.* as a staging area for new api, to indicate that it may be moved to net.jini at some point in future. We might decide to put some of the com.sun namespace there while trying to decide what should be standardised and whether any changes should be made before we do. DelegateSecurityManager is an interface that allows a SecurityManager to provide support for delegate objects, which are designed to encapsulate existing object's like Socket's and Streams, to allow permission to be revoked, eg a Principal no longer has access to a resource or a CodeSource has been found to have a vulnerability. (This isn't just about removing it from the policy, it's about stopping security sensitive object references escaping, avoiding further security checks). Allowing references to escape by only checking guards in constructors was probably a performance compromise. Delegates use Li Gong's method guard pattern. Once a user has a Socket reference (in the code he / she's using) they can continue using that Socket until they logout (because the security check is only performed when constructing the Socket). But with a delegate, as soon as they no longer have the DelegatePermission(SocketPermission perm), they can no longer utilise the socket. The delegate object creates a guard in it's constructor, which is checked on every method call, because the DelegateSecurityManager uses hash tables to cache permission check results, the performance impact isn't as great, so long as you have a sufficient buffer size (not checking every byte). If you're after ultimate performance, don't use the delegate, if you want to trial trust and stop attacks in progress, use a delegate. If a DelegateSecurityManager is not installed, then the delegates don't check the guard, instead the candidate Permission is checked during construction of the protected object without using doPrivileged. As far as the client and user is concerned, it's just an ordinary Socket. I'll be providing a SocketFactory and ServerSocketFactory, which accept any other type of SocketFactory's to enable the use of delegates with Sockets. This allows you to use delegates in your code and decide whether they should be enabled or not at runtime. You don't require a policy that supports revocation if you use principal based grants for DelegatePermissions. Revocation policy support is only required for codesource based or dynamic grant's for DelegatePermission. The candidate Permission is the Permission the DelegatePermission represents. The delegate object's privileged domain must have the candidate permission, it uses doPrivileged to perform the action on the user's behalf, the user must have the DelegatePermission or it's candidate Permission. A candidate Permission is any Permission that cannot be revoked because it lets a reference to a security sensitive object to escape. Not all java Permission's let references escape, eg PropertyPermission's are revocable and don't need delegates. Since existing Permission's can't be utilised (they let references escape) the DelegatePermission(Permission perm) constructor allow's it to represent another Permission, the DelegateSecurityManager when asked to check a DelegatePermission will also check if a ProtectionDomain has the candidate Permission. For example this allows you to make a temporary permission grant like SocketPermission using a delegate permission, a delegate object checks it's DelegatePermission Guard object, and doesn't let the Socket escape after the permission check, instead it encapsulates the Socket and continues to check the DelegatePermission guard with method invocations. This wouldn't be possible without a security manager that performs result caching. Cheers, Peter.