[//]: # " "
[//]: # " Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. "
[//]: # " "
[//]: # " This program and the accompanying materials are made available under the "
[//]: # " terms of the Eclipse Public License v. 2.0, which is available at "
[//]: # " http://www.eclipse.org/legal/epl-2.0. "
[//]: # " "
[//]: # " This Source Code may also be made available under the following Secondary "
[//]: # " Licenses when the conditions for such availability set forth in the "
[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, "
[//]: # " version 2 with the GNU Classpath Exception, which is available at "
[//]: # " https://www.gnu.org/software/classpath/license.html. "
[//]: # " "
[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "
[//]: # " "

* TOC
{:toc}

# Security Lockdown Example

In this example we will show how to check every injection, lookup, bind
and unbind operation against a set of J2SE security permissions.  In order
to do so we have constructed four projects who have a different set of
permissions in the system.  Lets take a brief glimpse of each project
in the example, to get an overview of what they do and how they interact
with the system.  

The first project is the runner project, which is nothing more than a set of
junit tests which run various scenarios, showing how security is either granted
or denied to the other projects.

The next project is the system project, which is considered to be secure and
trusted system code.  This code will receive AllPermission and therefor is able
to manipulate any object in the system and perform any action.  The system code
contains things like the security validation service itself, along with other
secure code such as security services.

Another project is called "Alice."  Alice is an application provider that is
able to access security services.  Alice will not attempt to do anything bad, but
will remain within the confines of the permissions granted her.  However, Alice
does not have AllPermission, and therefore could not perform some operations even
if she tried (however, she never tries to do anything she shouldn't).

Mallory is the last project.  Mallory is another application provider, who also
has some access to system resources.  In fact, Mallory has access to the Alice application.
Mallory usually sticks to the bounds of what he is allowed to do, but sometimes will attempt
to perform operations that he is not allowed to perform.  We shall see that when he attempts
to do so he is rebuffed by the security operations of the system.

Lets take a look in detail at how this total security lockdown of the system occurs.
 
## The System Project

The system project has some resources it would like to give out to some applications,
but not to others.  It would also like to be able to prevent applications from
binding or unbinding services from the service registry (embodied by the [ServiceLocator][servicelocator].

In order to do this, the system project must decide on a protection scheme.  Therefore the
decision is made that only code with java.lang.AllPermission shall be able to bind or unbind
services.  In order to protect lookup and injection services the decision is made to use
the java.lang.RuntimePermission called "accessClassInPackage".  This permission is used to allow
code to access classes in a particular package, and so seems appropriate for also protecting services
that are from that particular package.

It should be noted that the above decisions were made arbitrarily for this example, and real system
code can use whatever permission scheme it desires, including creating and using its own Permission
classes.

Lets first take a look at the resource that the system project would like to protect.  You will see
in the package "org.acme.security" that there is a service called AuditService.  AuditService is an
extremely simple secure auditing service.  The system code would like to allow some applications access
to this service, and other applications to NOT be allowed to directly use this service.  It should be noted
that the code that CAN access the service may be able to use that service on behalf of the callers of that
service.  That sort of thing will all work according to the normal J2SE security model.  Here is the AuditService,
a service that should be protected:
 
```java
@Service @Singleton
public class AuditService {
    ...
}
```

The most important thing to notice about this service is that there is nothing at all special about it.  It is
not annotated with any sort of special annotation or indication that it is a secure or protected service.  This
is because in some environments this service may be protected, while in other environments it may not be protected.
It is up to the environment to decide which resources need to be protected, and which do not.  In this way the
burden of deciding which resources are to be protected and which are not are taken away from the developers of the
resource and put into the hands of the definition of the particular environment in which those resources run.  This
is a good thing, as it puts the burden of deciding which resources are to be protected into the hands of those who
can better make that decision.
 
But how *does* the environment decide which resources are protected, and which are not?  In HK2 the answer is a
system defined service called the [ValidationService][validationservice].
The [ValidationService][validationservice] has two functions.  The first
function is to decide which resources should be protected.  The second is to provide code that must be run in
order to protect the resources which are protected.
 
In this example, the system has decided that every resource must be protected.  Hence the name "security-lockdown"
example.  Every injection point, lookup and bind will first run through a
[Validator][validator] to decide whether or not that operation should be allowed
to proceed.  But before the [Validator][validator] is run on anything first the
[ValidationService][validationservice] must tell the system that all resources
are to be protected.
 
In order to do this the system project must implement the
[ValidationService][validationservice].  In doing so it must implement
the getLookupFilter API, which returns a [Filter][filter] to
the system.  The system will use this filter to determine which resources are protected.  If the filter returns
true about any resource, then that resource will have the [Validator][validator]
run over it whenever it is looked up or injected.  Note that bind and unbind operations are always run through
all registered validators, as these operations are rare and can have serious effects on the state of the system.

In our example, where we want to protect every resource, we implement the getLookupFilter in this way:
 
```java
@Service @Singleton
public class ValidationServiceImpl implements ValidationService {
    ...
    
    @Override
    public Filter getLookupFilter() {
        return BuilderHelper.allFilter();
    }
    
    ...
}
```

The[BuilderHelper][buildhelper] allFilter method returns a [Filter][filter] that always returns true.
In this way we have assured that every lookup and injection in the system will be run through the implementation of 
[Validator][validator], which is also returned by out implementation of [ValidationService][validationservice]:
 
```java
@Service @Singleton
public class ValidationServiceImpl implements ValidationService {
    private final ValidatorImpl validator = new ValidatorImpl();
    
    ...

    @Override
    public Validator getValidator() {
        return validator;
    }
}
```

Note that since the ValidationService is a Singleton service that the ValidatorImpl will only be created once,
and the same one will be returned to the system every time the getValidator method is called.

However, the most important thing about the system code is how it protects the resources it has been charged
to protect.  That is the job of the ValidatorImpl.  The ValidatorImpl is responsible for determining
how to validate the BIND, UNBIND and LOOKUP operations.
Here is the implementation of the [Validator][validator] validate method:
 
```java
public class ValidatorImpl implements Validator {
    ...
    
    @Override
    public boolean validate(ValidationInformation info) {
        switch(info.getOperation()) {
        case BIND:
        case UNBIND:
            return validateBindAndUnbind();
        case LOOKUP:
            return validateLookup(info.getCandidate(), info.getInjectee());
        default:
            return false;
        }
    }
    
    ...
    
}
```

It is very important to understand the context in which these calls are made.  In that way it can be determined
how to check the permission being granted.  In the BIND, UNBIND, and in any LOOKUP that is *not* an injection
the call frame will be the Java protection domain to check.  In the case of the
BIND and UNBIND operations this will include the code that called commit on the [DynamicConfiguration][dynamicconfiguration].
In the case of the non-inject lookup, this will contain the user that is attempting to look up a service.

Since the BIND and UNBIND cases are fairly strait-forward in our example, lets see how this permission
check is performed.  First, we make a checkPermission call that returns true or false depending on whether
or not the permission is granted or not.  Here it is:
 
```java
    private static boolean checkPerm(Permission p) {
        try {
            AccessController.checkPermission(p);
            return true;
        }
        catch (AccessControlException ace) {
            return false;
        }
    }
```

This converts any AccessControlException (an indication that the permission was NOT granted) into a simple
false value.  Otherwise, if the checkPermission call is successful this method will return true.  It should
be noted that using the checkPermission in this way will only work properly when the code to be checked is
on the call stack, and that every piece of code on the call-stack must have the permission being asked for.
For the BIND and UNBIND operations then, the check is easy, since the caller is on the stack and this method
is easy to use:

```java
    private boolean validateBindAndUnbind() {
        return checkPerm(new AllPermission());
    }
```

This is very simple and ensures that anyone who tries to BIND or UNBIND service descriptions into the system
must have AllPermission!

Now lets talk about the LOOKUP case.  The LOOKUP case can be broken down into two cases, the LOOKUP via an API
case and the injection case.  Both are doing a lookup of a service.  However in the first case (pure lookup) the
caller is directly on the stack.  In the second case there may be no other software on the stack other than the
system software.  Therefore in that case more information may be needed in order to perform our security check.
That extra information comes in the form of the [Injectee][injectee].  Using the combination of the candidate
[ActiveDescriptor][activedescriptor] and the
place that descriptor would be injecting into (the
[Injectee][injectee]) a security decision can be made about the
injection point.
 
Lets look at the method that handles the both LOOKUP cases:
 
```java
    private boolean validateLookup(ActiveDescriptor<?> candidate, Injectee injectee) {
        if (injectee == null) {
            return validateLookupAPI(candidate);
        }
        
        return validateInjection(candidate, injectee);
    }
```

As you can see from the above code, the lookup has been broken into two cases, the
lookup with the API case, and the lookup based on the injection point case.  The
lookup with the API case is similar to the BIND and UNBIND cases, since the permission
check simply goes against the current call stack.

Before we look at how validateLookupAPI is implemented,  lets look at how we create the
set of permissions that are necessary for the caller to be allowed to use the lookup API.
Firstly, we create a RuntimePermission for a particular package by calling this
method:
 
```java
    private final static String ACCESS_IN_PACKAGE = "accessClassInPackage.";
    
    private static Permission getLookupPermission(String packName) {
        RuntimePermission retVal = new RuntimePermission(ACCESS_IN_PACKAGE + packName);
        
        return retVal;
    }
```

The above code will create the Permission that needs to be checked to see if the
caller should have access to the passed in package.

When dealing with an [ActiveDescriptor][activedescriptor],
we want to be sure that the caller has the right to access all of the contracts which
that service advertises.  Hence we create a method that returns all of the permissions
that must be checked based on all of the contracts that the
[ActiveDescriptor][activedescriptor] advertises.
Here is the implementation of a method that returns a list of all permissions that
must be allowed in order to access that [ActiveDescriptor][activedescriptor]:
 
```java
    private static List<Permission> getLookupPermissions(ActiveDescriptor<?> ad) {
        LinkedList<Permission> retVal = new LinkedList<Permission>();
        
        for (String contract : ad.getAdvertisedContracts()) {
            int index = contract.lastIndexOf('.');
            String packName = contract.substring(0, index);
            retVal.add(getLookupPermission(packName));
        }
        
        return retVal;
    }
```

Forearmed with the above methods, we can now look at how the method which
checks whether or not the lookup should be authorized.  Here is the implementation
of validateLookupAPI:
 
```java
    private boolean validateLookupAPI(ActiveDescriptor<?> candidate) {
        List<Permission> lookupPermissions = getLookupPermissions(candidate);
     
        for (Permission lookupPermission : lookupPermissions) {
            if (!checkPerm(lookupPermission)) {
                if (VERBOSE) {
                    System.out.println("candidate " + candidate +
                        " LOOKUP FAILED the security check for permission " + lookupPermission);
                }
                return false;
            }
        }
        
        return true;
    }
```

This is a strait-forward implementation, simply ensuring with the checkPerm call that
the caller is allowed to access all of the contracts offered by the given candidate
[ActiveDescriptor][activedescriptor].

That leaves us with the case of the lookup being performed on behalf of an injection
point.  This sort of lookup might be done because of some system code, or on the behalf
of a chain of instantiations being done due to a dependency chain.  Hence, it may
not be the case that the proper protection domain is on the calling stack.  So
in this case we must use the protection domain of the injection point in order to
see whether or not the code representing the injection point itself has the
proper permissions.

Here is the implementation of the validateInjection method:
  
```java
    private boolean validateInjection(ActiveDescriptor<?> candidate, Injectee injectee) {
        List<Permission> lookupPermissions = getLookupPermissions(candidate);
        
        // If this is an Inject, get the protection domain of the injectee
        final Class<?> injecteeClass = injectee.getInjecteeClass();
        
        ProtectionDomain pd = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {

            @Override
            public ProtectionDomain run() {
                return injecteeClass.getProtectionDomain();
            }
            
        });
        
        for (Permission lookupPermission : lookupPermissions) {
            if (!pd.implies(lookupPermission)) {
                if (VERBOSE) {
                    System.out.println("candidate " + candidate + " injectee " + injectee +
                        " LOOKUP FAILED the security check for " + lookupPermission);
                }
                
                return false;
            }
        }
        
        return true;
    }
```

This method first gets the set of permissions that the protection domain must have using
the getLookupPermissions method.  It then gets the ProtectionDomain of the injectee
by getting the ProtectionDomain from the Class of the injection point.  It should be noted
that getting the ProtectionDomain from the Class is itself a priviliged operation, and hence
must be done inside a doPrivileged block, in order to ensure that only the rights of the
system software are checked when getting the protection domain.

The code then runs through the list of permissions that the ProtectionDomain of the [Injectee][injectee] must have in order for
the injection to use an object produced by the [ActiveDescriptor][activedescriptor].

This is the entire implementation of the security-lockdown validator, which will ensure that
only those that have the rights to specific packages will be able to inject or lookup
services from those packages, and that only those who have AllPermission will be able
to bind or unbind services from the system.

Note that the System Project has the following grant:
 
```
grant codeBase "file:${build.dir}/../../system/target/-" {
  permission java.security.AllPermission;
};
```
 
Now lets take a closer look at Alice and Mallory.
 
### Alice

Alice is a simple application that has a limited set of privileges.  Here are the exact
priviliges that Alice is granted:
 
```
grant codeBase "file:${build.dir}/../../alice/target/-" {
  permission java.lang.RuntimePermission "accessClassInPackage.javax.inject";
  permission java.lang.RuntimePermission "accessClassInPackage.com.alice.application";
  permission java.lang.RuntimePermission "accessClassInPackage.org.jvnet.hk2.annotations";
  permission java.lang.RuntimePermission "accessClassInPackage.org.acme.security";
};
```

One thing that will distinguish Alice from Mallory is that Alice has access to the
org.acme.security package, whereas Mallory does not.  The means that Alice can
inject the org.acme.security.AuditService into its services, while Mallory cannot.
Here is the very simple AliceApp, which injects the AuditService:
 
```java
@Service @Singleton
public class AliceApp {
    @Inject
    private AuditService auditor;
    
    /**
     * This service makes use of the auditor service directly, which
     * should be allowed as Alice itself has the ability to use the
     * audit service
     * 
     * @param fromMe
     */
    public void doAuditedService(String fromMe) {
        auditor.auditLog("Alice performed an audit for " + fromMe);
    }
}
```

The injection point for the AuditService will pass the validator code because Alice
has access to org.acme.service package.  Now lets look at Mallory.
 
### Mallory

Mallory is another application, but unlike Alice, Mallory will sometimes attempt to do
things which it is not allowed to do.  Since Mallory is less trusted by the administrator,
Mallory has different grants:

```
grant codeBase "file:${build.dir}/../../mallory/target/-" {
  permission java.lang.RuntimePermission "accessClassInPackage.javax.inject";
  permission java.lang.RuntimePermission "accessClassInPackage.com.mallory.application";
  permission java.lang.RuntimePermission "accessClassInPackage.com.alice.application";
  permission java.lang.RuntimePermission "accessClassInPackage.org.jvnet.hk2.annotations";
  permission java.lang.RuntimePermission "accessClassInPackage.org.glassfish.hk2.api";
};
```

Note that Mallory does NOT have access to the org.acme.security package, and hence should
not be able to inject or lookup anything from that package.

Note that sometimes Mallory acts according to the rules, and other times he acts against the
rules.  Lets look at the times Mallory acts according to the rules:
 
```java
@Service
public class MalloryApp {
    @Inject
    private AliceApp alice;
    
    @Inject
    private ServiceLocator locator;
    
    ...
    
    public void doAnApprovedOperation() {
        alice.doAuditedService("Mallory");
    }
    
    ...
}
```

Mallory injects both the ServiceLocator itself as well as the AliceApp.  Since Mallory has
been granted those rights, these injections are Validated by the Validator and found to be
perfectly OK.  Hence this service can properly be instantiated.

Now lets see what Mallory might try to do that it shouldn't.  In this case, Mallory attempts
to look up the AuditService, which he should not be allowed to do:
 
```java
    /**
     * Mallory cannot however lookup the AuditService himself!
     */
    public void tryToGetTheAuditServiceMyself() {
        Object auditService = locator.getBestDescriptor(BuilderHelper.createContractFilter(
            "org.acme.security.AuditService"));
        auditService.toString();  // This should NPE!
    }
```

Note that in this code that tricky fellow Mallory used a pure string representation of the
fully qualified class name of the AuditService, since the system would not have allowed him
access to the AuditService otherwise.  The code above will NPE when the auditService.toString()
method is called.  As far as this lookup is concerned, it acts as though there is no AuditService
to be had, rather than throwing some other form of exception (which might tell Mallory something
about the system).

In this method, Mallory will attempt to advertise a service:
 
```java
    /**
     * Mallory cannot advertise the EvilService
     */
    public void tryToAdvertiseAService() {
        DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
        DynamicConfiguration config = dcs.createDynamicConfiguration();
        
        config.addActiveDescriptor(EvilService.class);
        
        config.commit();  // This will throw a MultiException
    }
```

Since Mallory does not have the rights to advertise a service the commit call will throw
an exception.

In this method, Mallory will attempt to unadvertise the ServiceLocator itself!!!  That
can't be allowed, or the very fabric of space-time could be threatened:
 
```java
    /**
     * Mallory cannot un-advertise ServiceLocator!
     */
    public void tryToUnAdvertiseAService() {
        final Descriptor locatorService = locator.getBestDescriptor(
            BuilderHelper.createContractFilter(ServiceLocator.class.getName()));
        
        // This filter matches ServiceLocator itself!
        Filter unbindFilter = new Filter() {

            @Override
            public boolean matches(Descriptor d) {
                if (d.getServiceId().equals(locatorService.getServiceId())) {
                    if (d.getLocatorId().equals(locator.getLocatorId())) {
                        return true;
                    }
                }
                
                return false;
            }
            
        };
        
        DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
        DynamicConfiguration config = dcs.createDynamicConfiguration();
        
        config.addUnbindFilter(unbindFilter);
        
        config.commit();  // This will throw a MultiException
    }
```

Again, since Mallory does not have the right to unbind services from the registry, the
commit method will throw an exception and the entire operation will fail.

In the next act of evil that Mallory attempts to perpetrate, it will try to instantiate this
service:
 
```java
@Service @Singleton
public class EvilInjectedService {
    @Inject
    private AuditService auditor;
    
    public EvilInjectedService() {
        throw new AssertionError("This should never get called since AuditService is not available");
    }

}
```

In this case Mallory is not doing a direct API lookup of the AuditService, but rather the
EvilInjectedService is trying to simply inject the service into itself, hoping that this
mode of access would be allowed.  Unfortunately, Mallory has no such luck in this method
of MalloryApp:
 
```java
    /**
     * Tries to instantiate a service with an illegal injection point
     */
    public void tryToInstantiateAServiceWithABadInjectionPoint() {
        locator.getService(EvilInjectedService.class);  // Will throw MultiException
    }
```

In this case the system will attempt to instatiate the EvilInjectedService and will fail,
since the EvilInjectedService does not have the rights to inject the AuditService.

That's it for Mallory!  Mallory was allowed to perform the operations he was allowed to
perform, and was not allowed to perform the operations for which it does not have the
proper set of priviliges.

The last project in the example is the runner.
 
## The Runner Project

The Runner project runs a set of junit tests that ensures that the System project, the Alice
project and the Mallory project runs as expected.  The test case ensures that both the
AliceApp and MalloryApp come up, and that when Mallory tries to do things that he should not
do that he is properly rebuffed.  The most interesting thing in the Runner project is in the
pom.xml, which gives the information that is needed to run the security-lockdown example
with the java security manager enabled.  This is from the pom.xml:
 
```xml
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>-Dlocal.repo=${settings.localRepository}
             -Dbuild.dir=${project.build.directory}
             -Djava.security.manager
             -Djava.security.policy=${project.build.directory}/test-classes/policy.txt
    </argLine>
    <!-- -Djava.security.debug=access,failure,domain -->
    </configuration>
</plugin>
```

The other interesting file in the Runner project is the policy.txt, which gives the full
set of grants necessary to run this test properly.
 
## Conclusion

This example shows how a secure system can be built in HK2 given the tools provided.  In
a real use case other decisions can be made about how to validate the operations being
performed.  This example is here to illustrate how those decisions can be put into effect, not
what those decisions should be.

[servicelocator]: apidocs/org/glassfish/hk2/api/ServiceLocator.html
[validationservice]: apidocs/org/glassfish/hk2/api/ValidationService.html
[validator]: apidocs/org/glassfish/hk2/api/Validator.html
[filter]: apidocs/org/glassfish/hk2/api/Filter.html
[buildhelper]: apidocs/org/glassfish/hk2/utilities/BuilderHelper.html
[dynamicconfiguration]: apidocs/org/glassfish/hk2/api/DynamicConfiguration.html
[activedescriptor]: apidocs/org/glassfish/hk2/api/ActiveDescriptor.html
