MeeGo 1.2 Harmattan Developer Documentation Develop for the Nokia N9

Aegis manifest file generation tool

The instructions in this section are only relevant for Scratchbox and MADDE, but the descriptions on the tool functionality are also relevant for the Qt SDK.

In Qt SDK, the Aegis manifest file generation tool is included with the Harmattan target and used automatically. In Platform SDK, you must have the following packages to use the Aegis manifest file generation tool:

  • aegis-manifest-dev package installed inside your development ARM target's file system
  • a recent version of Scratchbox devkit scratchbox-devkit-hashutils-squeeze-sdk or MADDE

After building your application, a manifest file is included in the resulting package if required tokens are detected. The resulting manifest files are named debian/<package name>.aegis.

In Harmattan, applications must announce which protected resources they provide and request. For instance, an application can access the cellular functionality or a service can provide location services. Only the processes that have the required security credentials can access protected resources. Moreover, software from different domains (sources of origin) may be blocked from accessing certain resources.

To announce that your application accesses protected resources, create the Aegis manifest file, which is an XML document that lists the security credentials required for the application. This optional file is delivered inside a Debian package. If the file does not exist or it does not list the correct credentials, accessing the protected resource fails.

The manifest of the package is loaded to a security system's internal database when the package is installed. When your application is launched, this information is passed on to the kernel. The credential is checked by either libcreds2 or D-Bus message passing. The security model does not require changes in your application's code. You only need to list the required tokens in the Aegis manifest file.

If the Aegis manifest file does not contain the necessary credentials, the most common indicator is the error message "Permission denied". Make sure that logging is enabled so that you can see which library or call is the source of the error message. For more information, see Developer tools for security analysis.

Using the Aegis manifest generation tool

The Aegis manifest generation tool automatically creates the manifest file for a package. The resulting manifest file is based on a static scan of compiled binaries and included QML files. The tool compares library functions found in ELF headers, the disassembly of the application's binaries and included QML files with a database of API requiring tokens. This database maps library funnctionality to required tokens.

The tool is delivered in the aegis-manifest-dev package, which also includes the API call to token mappings database (see target's /usr/share/aegis-manifest-dev/api). The package is meant to be installed inside an ARM target.

To check that you have this tool installed, run the following command inside your arm target (inside MADDE, run using mad aegis-):

$ aegis-manifest

The tool takes destination directory of a built binary package and output manifest file matching the package as arguments.

If arguments are not supplied, the tool expects it is run inside an armel source package directory as a part of or after running dpkg-buildpackage, and processes installation destdirs for packages listed in debian/control.

As the tool goes analyses your program, it detects when a token is needed by mapping the following types of API calls to required tokens:

  • Function call listed in ELF headers which maps to a token:
QMediaPlayer::QMediaPlayer
-> requires GRP::video
  • Function call with fixed integer literals which maps to a token:
socket (_,SOCK_RAW,_)
-> requires CAP::net_raw
  • Function call with string literal passed as QString&:
QDBusInterface::QDBusInterface (com.nokia.positongingd.client)
-> requires Location
  • Function call with string literal passed as char *:
dbus_g_proxy_new_for_name (com.nokia.positioningd.client)
-> requires Location
  • Module import statements found from QML files:
import QtMobility.Location 1.2
-> requires Location

Static scan only analyses compiled binaries and QML source code from your application binary package's installation directory. This excludes run-time token dependencies from being detected, such as opening a library with dlopen instead of linking to the library, setting D-Bus proxy object arguments in any other way than #define (such as reading from file or from other QString variable), or evaluating QML code which is not delivered readable with the package.

Furthermore, depending on the implementation details, such as how the tool parses the disassembly of your program headers, the program may miss functions which are in libraries linked using rpath (using hard-coded library file names). Since the tool matches the required tokens based on the D-Bus destination, it cannot detect tokens that are only required for individual method calls of that D-Bus object.

The tool recognizes QML source code found from plain text .qml files, contained in Qt resource archive .rcc files, and Qt resource archives which are compiled into the application binary. The tool matches the required tokens based on module imports. The tokens which are detected from import module version statements in QML code are inherited by each application binary in which uses symbols from QDeclarativeEngine or QDeclarativeView classes.

The QML source code must not be named with other than .qml suffix, compressed or obfuscated in any manner to be processed by this tool.

Integration with SDK

You can call the manifest generation tool directly from shell by running the command aegis-manifest inside your target, or invoke the tool indirectly from SDK tools during the package build process. Recent versions of Scratchbox and MADDE provide support for this tool.

When using Scratchbox, the devkit scratchbox-devkit-hashutils-squeeze-sdk supports adding manifest files in dpkg utilities dpkg-gencontrol and dpkg-deb. The command dpkg-gencontrol is usually invoked from Debhelper command dh_gencontrol, and this tool has been modified to call the manifest generation tool to produce debian/<package name>.aegis. This file is placed in <package installation directory>/DEBIAN/_aegis. The command dpkg-deb is usually invoked as the last step of package creation process from db_builddep, and it adds the manifest inside the resulting ar archive.

When using MADDE, the manifest generation tool is called from dpkg-deb. This command also places the manifest file inside the resulting Debian ar archive.

The manifest generation tool has the following dependencies:

  • Recent Scratchbox devkit hashutils-squeeze-sdk devkit
  • Recent MADDE version (version >= 0.7.23) (alternatively)
  • Developer target with aegis-manifest-dev package installed
  • Utilities that are delivered with the toolchain such as objdump
  • Perl interpreter (version >= 5.8)

An automatically generated manifest file contains a checksum inside a comment block for detecting if the file contains manual changes. When the manifest generation tool is invoked, it checks if the output file is already present and contains this checksum. If the checksum matches, the contents of the file have not been changed and there have been no manual changes. Thus, the manifest generation tool can update the file without user interaction.

If the checksum is not found or does not match the contents, the manifest generation tool does not update the file without forcing it. If you wish to replace an old file with a new one, run the command aegis-manifest with argument -f to force an overwrite.

If you supply your own debian/<package name>.aegis file, it is placed in the resulting package as is. Check that the file is a valid XML document. The tools do not check the validity of an existing manifest file.

If you place an empty (zero-length) debian/<package name>.aegis file into the source package, the tools do not create or add a manifest file to the resulting binary package.

Resulting Aegis manifest file

The resulting binary Debian package's control file contains the field Aegis-Manifest if the manifest generation tool was invoked as a part of the build process.

The Aegis-Manifest field has the following possible values:

  • Aegis-Manifest: included. The application package contains a manifest. The tool was run and required tokens were detected.
  • Aegis-Manifest: excluded. Adding a manifest was excluded with an empty (zero-length) manifest file.
  • Aegis-Manifest: empty. No required tokens were detected and no manifest file was supplied, and therefore the manifest should not be added. The tool was run and required tokens were not detected.

If the manifest should be included, the resulting Debian package should also contain the file _aegis inside the package's ar archive. Output from the command ar p <package name>.deb _aegis should match the manifest file debian/<package name>.aegis contents.

If your resulting Debian archive package does not contain this field, something is not up to date in your build environment. Check the following:

  • the aegis-manifest-dev package is installed inside your target
  • the appropriate SDK tools have been installed and configured for your target
  • you are building inside an arm target

Aegis manifest generation tool commands

The following generates Aegis manifests for binary packages based on a static scan:

[sbox-armv7: ~] > aegis-manifest -h
aegis-manifest: version harmattan

Based on the API calls known to require tokens, the Aegis manifest file lists the tokens the application requires to function.

The tool takes destination directory of a built binary package and output manifest file matching the package as arguments.

If arguments are not supplied, the tool expects it is run inside an armel source package directory as a part of or after running dpkg-buildpackage, and processes installation destdirs for packages listed in debian/control.

Options:
       -d       Print debug messages to stderr.
       -t PREFIX
                Path and prefix to toolchain utilities.
                ex. '-t /toolchain/path/arm-none-linux-gnueabi-'
                also environment AEGIS_TOOL_PREFIX
       -a PATH  Look for API definitions under this path.
                Default is /usr/share/aegis-manifest-dev/api
                also environment AEGIS_API_PATH
       -f       Overwrite existing Aegis manifest files.
       -h       Show this usage message. 

Arguments:
       DESTDIR  Input destination directory to scan.
       AEGIS    Output Aegis Manifest file.

Aegis manifest file example

The following example illustrates the contents of an Aegis manifest file:

<!-- Generated by aegis-manifest 0.20110128-1+harmattan on 2011-02-03. -->
<!-- To disable non-interactive creation of and updates to this file,
     and adding of the resulting Aegis manifest into a Debian package,
     replace this file with an empty (zero-length) file. -->
<!-- The checksum is used for detecting any manual changes of the <aegis>
     section. If the checksum is found and matches this section, file
     contents will be updated without user interaction.
     Modify the file or remove the checksum to disable this functionality. -->
<!-- modified-checksum:d79673df88ddd7c928c884a351458369 -->
<aegis>
        <request policy="add">
                <!-- Application uses QDeclarativeView or QDeclarativeEngine
                     and inherited tokens discovered from QML imports. -->

                <!-- import QtMobility.location 1.1 -->
                <credential name="Location" />

                <for path="/usr/bin/qmlgpstest />
        </request>
        <request policy="add">
                <!-- QMediaPlayer::QMediaPlayer -->
                <credential name="GRP::pulse-access" />
                <credential name="GRP::video" />

                <for path="/usr/bin/videotest" />
        </request>
        <request policy="add">
                <!-- Application accesses DBus libraries directly. 
                     Entries for these calls may need to be added manually. -->

                <!-- dbus_g_proxy_new_for_name ('com.nokia.positioningd.client') -->
                <credential name="Location" />

                <for path="/usr/bin/g_sendmessage" />
        </request>
        <request policy="add">
                <!-- Application accesses DBus libraries directly. 
                     Entries for these calls may need to be added manually. -->

                <!-- QDBusInterface::QDBusInterface ('com.nokia.positioningd.client') -->
                <credential name="Location" />

                <for path="/usr/bin/qt_sendmessage" />
        </request>
</aegis>