0

I am facing issue while trying to implement a security policy management agent using ConditionalPermissionAdmin to check for custom permission

I referred chapter-14 of OSGi in Action book. It was great help. Below is my setup and I am facing below issue (described at the end)

**** Karaf version
karaf@root> version
2.3.6

**** Added below in etc/custom.properties:
org.osgi.framework.security=osgi
com.security.policy.file=${karaf.base}/etc/security.policy

**** Added all permission policy file <KARAF_BASE>/etc/all.policy with below content:
grant { permission java.security.AllPermission; };

**** Added below in etc/system.properties:
java.security.policy=${karaf.base}/etc/all.policy
felix.keystore=file:${karaf.base}/etc/my_cert.ks   
felix.keystore.pass=welcome1
felix.keystore.type=jks

**** Downloaded and copied security framework provider bundle jar (org.apache.felix.framework.security-2.4.0.jar)  to the <KARAF_BASE>/system folder
<KARAF_BASE>/system/org/apache/felix/org.apache.felix.framework/security/2.4.0/org.apache.felix.framework.security-2.4.0.jar    

**** Made the security provider framework jar as part of startup bundles, by adding to etc/startup.properties with below entry
org/apache/felix/org.apache.felix.framework/security/2.4.0/org.apache.felix.framework.security-2.4.0.jar=5

**** Created a custom policy file <KARAF_BASE>/etc/security.policy (with below content) for the 
security policy management agent to read and enforce using ConditionalPermissionAdmin

ALLOW {
    [ org.osgi.service.condpermadmin.BundleSignerCondition "CN=core, O=core, C=IN" ]
    (com.security.MyResourceAccessPermission "allow" "user1")  
} "Bundles Signed by core are allowed to access the resource for user1"
ALLOW {
    ( java.security.AllPermission "*" "*")
} "Give all other not denied permissions to all bundles"

Note: MyResourceAccessPermission is a custom permission along with its MyResourceAccessPermissionCollection class to implement resource access only for specific users. So in the java code, user name would come as a argument which would be passed for access check like below

public void foo(String user, ...) {
    AccessController.checkPermission(new MyResourceAccessPermission(MyResourceAccessPermission.ALLOW, user));
    connectToResource(...);
}

**** Created an Activator (with same code as in chapter-14 of OSGi in Action) to read above custom policy file
**** I have two bundles 
1) SecurityAgent.jar - the security agent management bundle that reads and initializes the ConditionalPermissionAdmin
2) MyResource.jar - this checks for MyResourceAccessPermission and access the protected resource called by the clients 
3) MyResourceClient.jar - client bundle which uses MyResource.jar bundle to access the resource by passing the user name

**** Issue
When I deploy and start the above bundles, I dont see MyResourceAccessPermission being created.
But, MyResourceAccessPermissionCollection does get called for the implies() method. 
Since, it does not have any MyResourceAccessPermission objects to check against, it always 
returns true which always passess the security check.
Even if I pass different user name than the one defined in the policy file, it passed the security check

It looks like the listed MyResourceAccessPermission entries in custom poilcy file (security.policy) 
are not getting added to (MyResourceAccessPermissionCollection) by the security manager

I have tested MyResourceAccessPermission and MyResourceAccessPermissionCollection as standalone java application with
standard security policy like below which works as expected, but I am having trouble working this in OSGi env (Karaf)

    grant {    
        com.security.MyResourceAccessPermission "allow" "user1"
    };

I am not sure what I am missing. I have beeing trying to solve this for few days, but no luck. 
Any help would be great

1 Answers1

0

I got it working. Below were the issues.

1) BundleSignerCondition condition string was wrong, so the MyResourceAccessPermission was not at all checked

2) After I fixed first issue, i had to fix the policy entries like below:

    ALLOW {
        [ org.osgi.service.condpermadmin.BundleSignerCondition "CN=core, OU=core,   O=core, L=core, S=KA, C=IN" ]
        (com.security.MyResourceAccessPermission "allow" "user1")  
    } "Bundles Signed by core are allowed to access the resource for user1"
    DENY {
        [ org.osgi.service.condpermadmin.BundleSignerCondition "CN=core, OU=core, O=core, L=core, S=KA, C=IN" ]
        (com.security.MyResourceAccessPermission "*" "*")  
    } "Deny all user access"
    ALLOW {
        ( java.security.AllPermission "*" "*")
    } "Give all other not denied permissions to all bundles"

Below are my findings:

  1. The CPA (ConditionalPermissionAdmin) evaluates the policy in the given order

  2. If a policy does not imply (implies=false), it does not throw an exception, rather it tries to evaluate the next policy in the order This is very important to understand. If there is no other policy in the list which implies this access (implies=true), then it is assumed that there is no matching policy defined; hence access check goes through due to the last AllPermission policy

  3. Either there should be a specific policy defined to imply [true=allow(implies=true)] a required permission or deny a non-required permission [true=deny(implied=false)]
  4. If you want to allow only certain permission, then define all allowed policies first and then define all the denied policies. So that, if an access is not allowed, it'll get caught in the denied policies.