Setting Permissions and Configure OGEMA for Secure Operation

Last modified by David Nestle on 2018/01/10 17:13

Application permissions

OGEMA uses Java security to restrict applications from accessing sensitive data (e.g. files, resources, system properties) or performing malicious actions (to a certain extent). Applications must specify the permissions they need, and upon installation, the user can decide whether to grant the requested permission or to refuse/restrict it. There are three groups of permission types relevant to OGEMA: standard Java permissions (e.g. file access), OSGi permissions (e.g. service permissions) and OGEMA-specific permissions (e.g. Resource permissions). During development, it is possible (and recommended, to begin with), to disable OGEMA security. Once an app is operational, the SDK can be used to automatically generate the permission demands. Depending on the app, some further manual adaptations may be necessary, however, and some hints on how to deal with tpyical use cases are given below. The permissions demanded by an application are listed in a permissions.perm file, located at

src/main/resources/OSGI-INF/permissions.perm

within the app directory. Typical permission demands required by almost all apps are (these standard permissions are usually taken care of by the SDK):

  • Package permissions: when classes from another bundle are used (imported) in the app, then a corresponding package permission is required. Example
    (org.osgi.framework.PackagePermission "org.ogema.core.*" "import")
    If this permission is granted to an app (in fact, the package permissions for the OGEMA API, including org.ogema.core.*, will be granted to all apps), it will be able to import all classes in packages starting with "org.ogema.core.". Note however, that the this does not include "org.ogema.core" itself, the asterix serves as a wildcard for subpackages only. Custom resource types declared by an app need to be made available to the framework, which is accomplished by means of a package export permission:
    (org.osgi.framework.PackagePermission "com.example.app.template.config" "exportonly")
  • Resource permissions: these are required for accessing the OGEMA resource tree. They can be specified in terms of resource types, resource paths, or both. A permission to access a specific resource is inherited by all direct subresources, but not by those connected via references. An example looks like this:
    (org.ogema.accesscontrol.ResourcePermission "type=com.example.app.template.config.TemplateConfig, path=uniqueTemplateConfigResource" "read,write,addsub,create,activity,delete")
    Resource permissions should be demanded in the most specific way possible. For instance, if your app only needs read access to a specific resource, drop the "write,addsub,create,activity,delete" arguments from the sample permission.
  • Service permissions: this is an OSGi-specific permission type. It should only be relevant to your application if you need to use OSGi-services beyond the standard OGEMA services (in particular every app needs to register a service of type Application.class). Typical uses in OGEMA:
    (org.osgi.framework.ServicePermission "org.ogema.core.application.Application" "register")
    (org.osgi.framework.ServicePermission "org.ogema.gui.api.OgemaGuiService" "get")

Many additional permission types are defined in the Java specification, and they often guard sensitive functions that should not normally be available to OGEMA applications. For instance, a permission is required to use reflections, which is never granted by OGEMA. In addition, OSGi and OGEMA both define their own admin permission, which gives you access to the user administration of the framework and other sensitive interfaces. You should only need to declare such a permission request if you are developing your own framework extension. Applications that shall be made available through the public OGEMA appstore need a particular certification if they demand an admin permission, otherwise they are refused. This applies to several other critical permission types as well.

Some hints for specific permissions:

  • System properties: access to system properties is guarded by permissions as well. System properties may be useful during development, but should not be used in productive systems. Instead, configurations should be done via a user interface and stored in a resource (or alternatively, a file, an OSGi configuration, in memory, etc.).
  • File access: OSGi reserves a specific area on the hard disk for each bundle, the so-called "storage area". Nevertheless, a permission demand must be declared in order to access this storage area. It can take the form
    (java.io.FilePermission "<<ALL FILES>>" "read, write, execute, delete")
    Actually, this way the app requests access to all files, as the id suggests, but such generic requests are refused by default, and only access to the bundle storage area is granted. Requests for other files, not in the bundle storage area, are deemed a security risk and should be avoided.
  • Native libraries: hardware drivers often need access to libraries that include native code. This is critical from a security point of view, since native code is not restricted by Java security. Therefore, a specific permission is needed:
    (java.lang.RuntimePermission "loadLibrary.rxtxSerial")
  • Channel access: relevant to drivers using the OGEMA ChannelManager concept
    (org.ogema.accesscontrol.ChannelPermission "busid=COM*" "read,write")
  • OSGi context access: for using OSGi-specific mechanisms:
    (org.osgi.framework.AdminPermission "*" "context")
  • Admin permission: for OGEMA framework extensions
    (org.ogema.accesscontrol.AdminPermission "system,user")

A detailed explanation on permissions can be found in the OGEMA wiki: https://www.ogema-source.net/wiki/display/OGEMA/Security+Technical+Notes#SecurityTechnicalNotes-system-permissions. 

The following page provides an evaluation of the security impact of several Java permissions. Most of the listed permissions are denied by default for OGEMA apps, except the ones listed above: http://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html

Generate permissions declaration

OGEMA SDK

The OGEMA SDK takes care of a great deal of standard permission declarations. The permission.perm file provided with new applications generated with the SDK contain all basic permissions required for typical applications. To automatically update additional required PackagePermissions and ResourcePermissions in the SDK, open the context menu of the respective project in the Package Explorer of the SDK (Eclipse). Go to OGEMA -> Update OGEMA permissions to generate the permissions.perm file for your app, and you are done. If you need to add permissions manually make sure you add them before the statement "#Automated Generation Below:" in the permission.perm file as everything below will be overwritten by the SDK when the permissions are updated automatically.

Run OGEMA with security enabled as described below. If you get exceptions regarding missing dependencies you might miss an important statement. If you get an exception that a permission is missing you should add the permission manually - or check, whether the code could be changed to avoid the permission required.

Hint: If you an application is missing an import package permission and you do not know from wich bundle, you can try to check Maven Central for it (search fc:<package name>). If a bundle is just installed, not active you can try to restart it and check the exception.

Maven / BND

Another mechanism that can be helpful here is automated generation of import, export and service permission via bnd: In the pom.xml file of the application there should be an entry for the maven-bundle-plugin, which has to be extended by the line

<Include-Resource>{OSGI-INF/permissions.perm=src/main/resources/OSGI-INF/permissions.perm}</Include-Resource>

The entire statement could look like this (probably containing more entries that shoud be maintained):

   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.felix</groupId>
               <artifactId>maven-scr-plugin</artifactId>
           </plugin>
           <plugin>
               <groupId>org.apache.felix</groupId>
               <artifactId>maven-bundle-plugin</artifactId>
               <configuration>
                  <instructions>
                       <Include-Resource>
                            {maven-resources},
                            {OSGI-INF/permissions.perm=src/main/resources/OSGI-INF/permissions.perm}
                       </Include-Resource>
                  </instructions>
               </configuration>
           </plugin>
       </plugins>
   </build>

In the permissions.perm file you have to add the line

${permissions;packages;services;capabilities}

At this place permissions will be inserted during the build process (you do not see them in the source code, but you can check them with printLocalPermissions / checkLocalPermissions, see below).

Run OGEMA with security enabled

Once you have set the permissions for your app, you can test its operation in a secure framework. In order to start OGEMA with security enabled, you first need to copy all required bundle jar-files to the bin-folder of the rundir, by running the default_build start configuration. Then launch the default_security_clean configuration for the actual secure framework start. If you want to change a bundle during development you should build the adapted bundle as you would do without security, you have to build the rundir again. Afterwards you can restart with clean or update the bundle as described in Lifecycle management using the OSGi shell.

By default, all requested permissions are granted to the app. It is possible, however, to restrict the set of granted permissions, e.g. to test the app behaviour in a setting where the user (or framework) denies parts of the permissions. For this purpose, add the following line to the file <RUNDIR>/config/ogema.policy:

deny { [org.osgi.service.condpermadmin.BundleLocationCondition "file:./bin/apps/com.example.app.my.app-*"] (org.ogema.accesscontrol.ResourcePermission "type=com.example.app.template.config.TemplateConfig" "write") } "myApp"

Adapt the bundle location to the filename of your app in the rundir, and replace the resource permission (the part in round brackets) by the permission you want to deny. The "myApp" part here is an id, which must be unique throughout the ogema.policy file.

To run the apps with enabled security on your OGEMA Gateway see the next step of the tutorial.

Checking permissions on the OSGi console

  • ogm:printLocalPermissions <bundleId>: Writes content of the permissions.perm file to console
  • ogm:checkLocalPermissions <bundleId>: Trys to create permission object and checks whether it is accepted also by system permissions (recommended to be used to see effective permissions)
  • ogm:bundlepermissions <bundleId>: Writes system permissions, should usually reply
    allow { (java.security.AllPermission) } "all"
    as the app permissions are usually restricted by local permissions

Permission Classification

When a developer asks for additional permissions compared to the standard permissions provided by the template application a user needs to evaluation whether the request is acceptable or whether a permission would give an application too much possibilties to perform harmful operations. In this assessment the source of the application will be quite important. From a fully trusted source any permission would be acceptable (for instance, the OGEMA framework itself requires extensive permissions for proper operation), but for applications from a non-trusted sources permissions should be granted with care. A certification process for apps is planned to be established, where apps requiring critical permissions will be checked against misuse. For the time being, it is recommended for developers to restrict the set of demanded permissions to the absolutely required ones, and for users to carefully check the set of permissions demanded by an application.

In fact most of the Java permissions are critical, that's why exist in the first place. So all permission not listed below should be considered critical. Some permissions that only would be relevant to OGEMA apps in very rare circumstances are not listed here, although they might be acceptable with certain arguments. Some permissions that are acceptable with certain arguments even from non-trusted sources are listed below:

PermissionAccetable Arguments and Risks Remarks
 org.osgi.framework.PackagePermissionimport: Import statements are usually required by applications to access third-party libraries. Such libraries may be part of the standard OGEMA rundir. In this case usually no additional risk is imposed by such an important statement. When an application wants to load an additional third-party library into the system this library should be checked with great care
exportonly: Export of packages should normally only be required for custom OGEMA types. These packages must be exported. It is important that the package name is specific enough to ensure no collisions can occur. Standard package names, e.g. starting with "org.ogema." or any of the packages provided by standard OGEMA dependencies are prohibited. A warning should be required when a package exported by a non-trusted / non-system app would be imported by another non-trusted / non-system app.
 
 org.ogema.accesscontrol.ResourcePermissionResource permissions should be checked based on the question whether the access requested is required for the functionalty of the app. For typical applications write,addsub,create,activity,delete arguments should only be granted to a single configuration resource of the custom configuration resource type; in particular, the permission demand should specify a non-wildcard path and a non-wildcard type. Read access will be required from more resources and is not as critical, especially if the application cannot transfer the data outside the OGEMA system.
For drivers, write permissions might have to be much broader, especially for generic drivers that e.g. write into any FloatResource that has been configured. Such a driver is potentially harmful, of course, and should only be installed from trusted sources (e.g. certified drivers).
 
 org.osgi.framework.ServicePermissionFor most applications the standard service permissions should be sufficient (register Application, get OgemaGuiService). Direct access to other OSGi services is potentially critical, but not always avoidable. Only if the service requested is fully trusted the permission is acceptable for non-trusted applications. Permission to access special internal OGEMA services will be denied by default. 
 java.util.PropertyPermissionProperty read permissions should not be necessary except in some special cases, and should be denied. Write permissions will be denied by default. 
 java.net.SocketPermissionThe permission is critical as it allows to transfer data from/to other systems. It is required by many OGEMA drivers, though. The recommendation here is to use only trusted drivers. 
java.io.FilePermissionFilePermission should only be required for the bundle storage area of the app, which is granted for apps demanding a FilePermission for <<ALL_FILES>>.
Otherwise this is a critical permission. A read argument may be acceptable if the application is not able to transfer data outside the OGEMA system. If the destination file/directory is not critical for writing/deleting content etc. also a write argument may be acceptable. Note that a delete argument is not very different from a write argument as writing implies the permission to over-write any existing content.
 

Additional information

From OGEMA 2.1.2 widget apps need the following permission statement in their permissions-perm file (which has to be added to apps generated with any previous SDK):

(org.ogema.accesscontrol.WebAccessPermission "name=de.iwes.widgets.ogema-js-bundle")

Next


Tags:
Created by Jan Lapp on 2016/12/28 12:00