From 3f6f63ee421200fe014cfa2f2a081f27ca43a51c Mon Sep 17 00:00:00 2001 From: Shankho Boron Ghosh Date: Mon, 30 Nov 2020 01:25:22 +0530 Subject: [PATCH] Added Application Framework in Developer Guides Revised and added Application Framework as a part of Developer Guides. Bug-AGL: [SPEC-3633] Signed-off-by: Shankho Boron Ghosh Change-Id: I81c08edf722b3039c617c6bf50ae6cc9907a6116 Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/documentation/+/25662 Reviewed-by: Jan-Simon Moeller Tested-by: Jan-Simon Moeller --- .../1_Application_Framework/0_Introduction.md | 261 +++++++++ .../1_Application_Framework/1_afm-daemons.md | 649 +++++++++++++++++++++ .../1_Application_Framework/2_widgets.md | 11 + .../1_Application_Framework/3_widgets_overview.md | 158 +++++ .../4_Widget_configuration_file.md | 589 +++++++++++++++++++ .../1_Application_Framework/5_Permissions.md | 131 +++++ .../1_Application_Framework/6_Quick-Tutorial.md | 267 +++++++++ .../pictures/AppFW-APP_install_sequences.svg | 408 +++++++++++++ .../pictures/Security_model_history.svg | 149 +++++ .../pictures/afm-daemons.svg | 237 ++++++++ .../pictures/make-units.svg | 436 ++++++++++++++ 11 files changed, 3296 insertions(+) create mode 100644 docs/3_Developer_Guides/1_Application_Framework/0_Introduction.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/1_afm-daemons.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/2_widgets.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/3_widgets_overview.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/4_Widget_configuration_file.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/5_Permissions.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/6_Quick-Tutorial.md create mode 100644 docs/3_Developer_Guides/1_Application_Framework/pictures/AppFW-APP_install_sequences.svg create mode 100644 docs/3_Developer_Guides/1_Application_Framework/pictures/Security_model_history.svg create mode 100644 docs/3_Developer_Guides/1_Application_Framework/pictures/afm-daemons.svg create mode 100644 docs/3_Developer_Guides/1_Application_Framework/pictures/make-units.svg diff --git a/docs/3_Developer_Guides/1_Application_Framework/0_Introduction.md b/docs/3_Developer_Guides/1_Application_Framework/0_Introduction.md new file mode 100644 index 0000000..7aae18f --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/0_Introduction.md @@ -0,0 +1,261 @@ +--- +title: Introduction +--- + +## Foreword + +This document describes what we intend to do. +It may happen that our current implementation and the content of this document differ. + +In case of differences, it is assumed that this document is right and the implementation is wrong. + +## Introduction + +During the first works in having the security model of Tizen integrated in AGL +(Automotive Grade Linux) distribution, it became quickly obvious that the count +of components specific to Tizen to integrate was huge. + +Here is a minimal list of what was needed: + +- platform/appfw/app-installers +- platform/core/security/cert-svc +- platform/core/appfw/ail +- platform/core/appfw/aul-1 +- platform/core/appfw/libslp-db-util +- platform/core/appfw/pkgmgr-info +- platform/core/appfw/slp-pkgmgr + +But this list isn't complete because many dependencies are hidden. +Those hidden dependencies are including some common libraries but also many +tizen specific sub-components: + +- iniparser +- bundle +- dlog, +- libtzplatform-config +- db-util +- vconf-buxton +- ... + +This is an issue because AGL is not expected to be Tizen. +Taking it would either need to patch it for removing unwanted components or to take all of them. + +However, a careful study of the core components of the security framework +of Tizen showed that their dependencies to Tizen are light (and since some +of our work, there is no more dependency to tizen). +Those components are : + +- **cynara** +- **security-manager** +- **D-Bus aware of cynara** + +Luckily, these core security components of Tizen are provided +by [meta-intel-iot-security][meta-intel], a set of yocto layers. +These layers were created by Intel to isolate Tizen specific security +components from the initial port of Tizen to Yocto. +The 3 layers are providing components for: + +- Implementing Smack LSM +- Implementing Integrity Measurement Architecture +- Implementing Tizen Security Framework + +The figure below shows the history of these layers. + +![Security_model_history](./pictures/Security_model_history.svg) + +We took the decision to use these security layers that provide the +basis of the Tizen security, the security framework. + +For the components of the application framework, built top of +the security framework, instead of pulling the huge set of packages +from Tizen, we decided to refit it by developing a tiny set of +components that would implement the same behaviour but without all +the dependencies and with minor architectural improvements for AGL. + +These components are : + +- **afm-system-daemon** +- **afm-user-daemon** + +They provides infrastructure for installing, uninstalling, +launching, terminating, pausing and resuming applications in +a multi user secure environment. + +A third component exists in the framework, the binder **afb-daemon**. +The binder provides the easiest way to provide secured API for +any tier. +Currently, the use of the binder is not absolutely mandatory. + +This documentation explains the framework created by IoT.bzh +by rewriting the Tizen Application Framework. +Be aware of the previous foreword. + +## Overview + +The figure below shows the major components of the framework +and their interactions going through the following scenario: + +- APPLICATION installs an other application and then launch it. + ![AppFW-APP_install_sequences](./pictures/AppFW-APP_install_sequences.svg) + +Let follow the sequence of calls: + +1. APPLICATION calls its **binder** to install the OTHER application. + +1. The binding **afm-main-binding** of the **binder** calls, through + **D-Bus** system, the system daemon to install the OTHER application. + +1. The system **D-Bus** checks wether APPLICATION has the permission + or not to install applications by calling **CYNARA**. + +1. The system **D-Bus** transmits the request to **afm-system-daemon**. + + **afm-system-daemon** checks the application to install, its + signatures and rights and install it. + +1. **afm-system-daemon** calls **SECURITY-MANAGER** for fulfilling + security context of the installed application. + +1. **SECURITY-MANAGER** calls **CYNARA** to install initial permissions + for the application. + +1. APPLICATION call its binder to start the nearly installed OTHER application. + +1. The binding **afm-main-binding** of the **binder** calls, through + **D-Bus** session, the user daemon to launch the OTHER application. + +1. The session **D-Bus** checks wether APPLICATION has the permission + or not to start an application by calling **CYNARA**. + +1. The session **D-Bus** transmits the request to **afm-user-daemon**. + +1. **afm-user-daemon** checks wether APPLICATION has the permission + or not to start the OTHER application **CYNARA**. + +1. **afm-user-daemon** uses **SECURITY-MANAGER** features to set + the security context for the OTHER application. + +1. **afm-user-daemon** launches the OTHER application. + +This scenario does not cover all the features of the frameworks. +Shortly because details will be revealed in the next chapters, +the components are: + +- ***SECURITY-MANAGER***: in charge of setting Smack contexts and rules, + of setting groups, and, of creating initial content of *CYNARA* rules + for applications. + +- ***CYNARA***: in charge of handling API access permissions by users and by + applications. + +- ***D-Bus***: in charge of checking security of messaging. The usual D-Bus + security rules are enhanced by *CYNARA* checking rules. + +- ***afm-system-daemon***: in charge of installing and uninstalling applications. + +- ***afm-user-daemon***: in charge of listing applications, querying application details, + starting, terminating, pausing, resuming applications and their instances + for a given user context. + +- ***afb-binder***: in charge of serving resources and features through an + HTTP interface. + +- ***afm-main-binding***: This binding allows applications to use the API + of the AGL framework. + +## Links between the "Security framework" and the "Application framework" + +The security framework refers to the security model used to ensure +security and to the tools that are provided for implementing that model. + +The security model refers to how DAC (Discretionary Access Control), +MAC (Mandatory Access Control) and Capabilities are used by the system +to ensure security and privacy. +It also includes features of reporting using audit features and by managing +logs and alerts. + +The application framework manages the applications: + +- installing +- uninstalling +- starting +- pausing +- listing +- ... + +The application framework uses the security model/framework +to ensure the security and the privacy of the applications that +it manages. + +The application framework must be compliant with the underlying +security model/framework. +But it should hide it to the applications. + +## The security framework + +The implemented security model is the security model of Tizen 3. +This model is described [here][tizen-secu-3]. + +The security framework then comes from Tizen 3 but through +the [meta-intel]. +It includes: + +- **Security-Manager** +- **Cynara** +- **D-Bus** compliant to Cynara. + +Two patches are applied to the security-manager. +The goal of these patches is to remove specific dependencies with Tizen packages that are not needed by AGL. +None of these patches adds or removes any behaviour. + +**In theory, the security framework/model is an implementation details +that should not impact the layers above the application framework**. + +The security framework of Tizen provides "nice lad" a valuable component to +scan log files and analyse auditing. +This component is still in development. + +## The application framework + +The application framework on top of the security framework +provides the components to install and uninstall applications +and to run it in a secured environment. + +The goal is to manage applications and to hide the details of +the security framework to the applications. + +For the reasons explained in introduction, we did not used the +application framework of Tizen as is but used an adaptation of it. + +The basis is kept identical: + +- The applications are distributed in a digitally signed container that must + match the specifications of widgets (web applications). + +This is described by the technical recommendations [widgets] and +[widgets-digsig] of the W3 consortium. + +This model allows: + +- The distribution of HTML, QML and binary applications. +- The management of signatures of the widget packages. + +This basis is not meant as being rigid and it can be extended in the +future to include for example incremental delivery. + +[meta-intel]: https://github.com/01org/meta-intel-iot-security "A collection of layers providing security technologies" +[widgets]: http://www.w3.org/TR/widgets "Packaged Web Apps" +[widgets-digsig]: http://www.w3.org/TR/widgets-digsig "XML Digital Signatures for Widgets" +[libxml2]: http://xmlsoft.org/html/index.html "libxml2" +[openssl]: https://www.openssl.org "OpenSSL" +[xmlsec]: https://www.aleksey.com/xmlsec "XMLSec" +[json-c]: https://github.com/json-c/json-c "JSON-c" +[d-bus]: http://www.freedesktop.org/wiki/Software/dbus "D-Bus" +[libzip]: http://www.nih.at/libzip "libzip" +[cmake]: https://cmake.org "CMake" +[security-manager]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Security_Manager "Security-Manager" +[app-manifest]: http://www.w3.org/TR/appmanifest "Web App Manifest" +[tizen-security]: https://wiki.tizen.org/wiki/Security "Tizen security home page" +[tizen-secu-3]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Overview "Tizen 3 security overview" +[AppFW-APP_install_sequences]: pictures/AppFW-APP_install_sequences.svg +[Security_model_history]: pictures/Security_model_history.svg \ No newline at end of file diff --git a/docs/3_Developer_Guides/1_Application_Framework/1_afm-daemons.md b/docs/3_Developer_Guides/1_Application_Framework/1_afm-daemons.md new file mode 100644 index 0000000..2f7e2c0 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/1_afm-daemons.md @@ -0,0 +1,649 @@ +--- +title: The afm daemons +--- + +## Foreword + +This document describes application framework daemons +FCS (Fully Conform to Specification) implementation is still under development. +It may happen that current implementation somehow diverges with specifications. + +## Introduction + +Daemons ***afm-user-daemon*** and ***afm-system-daemon*** handle applications +life. +Understand that they will manage operations like: + +- ***installation*** +- ***uninstallation*** +- ***running*** +- ***suspend*** +- ***inventory*** +- ... + +In addition, they ensure that operations use the security framework as needed +and that applications are executed in the correct context. + +***D-Bus*** is in charge of transmitting orders to the appropriate daemon +depending upon ***D-Bus*** destination. + +The figure below summarizes the situation of both **afm-system-daemon** and +**afm-user-daemon** in the system. + +![afm-daemons][afm-daemons] + +## The D-Bus interface + +### Overview of the dbus interface + +The ***afm daemons*** takes theirs orders from the session instance +of D-Bus. +The use of D-Bus is great because it allows to implement +discovery and signaling. + +The dbus session is by default addressed by environment +variable *DBUS_SESSION_BUS_ADDRESS*. Using **systemd** +variable *DBUS_SESSION_BUS_ADDRESS* is automatically set for +user sessions. + +They are listening with the destination name ***org.AGL.afm.[user|system]*** +at the object of path ***/org/AGL/afm/[user|system]*** on the interface +***org.AGL.afm.[user|system]*** for the below detailed members for the +***afm-system-daemon***: + +- ***install*** +- ***uninstall*** + +And for ***afm-user-daemon***: + +- ***runnables*** +- ***detail*** +- ***start*** +- ***once*** +- ***terminate*** +- ***pause*** +- ***resume*** +- ***runners*** +- ***state*** +- ***install*** +- ***uninstall*** + +D-Bus is mainly used for signaling and discovery. +Its optimized typed protocol is not used except for transmitting + only one string in both directions. + +The client and the service are using JSON serialization to +exchange data. +Signature of any member of the D-Bus interface is +***string -> string*** for ***JSON -> JSON***. +This is the normal case, if there is an error, current implementation +returns a dbus error that is a string. + +Here are examples using *dbus-send*, here to install an application from a +widget file: + +```bash +dbus-send --session --print-reply \ + --dest=org.AGL.afm.system \ + /org/AGL/afm/system \ + org.AGL.afm.system.install 'string:"/tmp/appli.wgt" +``` + +And here, to query data on installed applications that can be run: + +```bash +dbus-send --session --print-reply \ + --dest=org.AGL.afm.user \ + /org/AGL/afm/user \ + org.AGL.afm.user.runnables string:true +``` + +### The protocol over D-Bus + +On all following sub-chapters we assume that we talk about either +***afm-system-daemon*** or ***afm-user-daemon***. Method and D-Bus parameters +are considered as self-explanatory. + +The D-Bus interface is defined by: + +- **DESTINATION**: org.AGL.afm.[user|system] +- **PATH**: /org/AGL/afm/[user|system] +- **INTERFACE**: org.AGL.afm.[user|system] + +#### Method org.AGL.afm.system.install + +**Description**: Install an application from a widget file. + +When an application with the same *id* and *version* already exists. Outside of +using *force=true* the application is not reinstalled. + +Applications are installed the subdirectories of applications common directory. +If *root* is specified, the application is installed under the +sub-directories of the *root* defined. + +Note that this methods is a simple accessor method of +***org.AGL.afm.system.install*** from ***afm-system-daemon***. + +After the installation and before returning to the sender, +***afm-system-daemon*** sends a signal ***org.AGL.afm.system.changed***. + +**Input**: The *path* of the widget file to install and, optionally, +a flag to *force* reinstallation, and, optionally, a *root* directory. + +Either just a string being the absolute path of the widget file: + +```bash +"/a/path/driving/to/the/widget" +``` + +Or an object: + +```json +{ + "wgt": "/a/path/to/the/widget", + "force": false, + "root": "/a/path/to/the/root" +} +``` + +"wgt" and "root" must be absolute paths. + +**output**: An object with the field "added" being the string for +the id of the added application. + +```json +{"added":"appli@x.y"} +``` + + + +#### Method org.AGL.afm.system.uninstall + +**Description**: Uninstall an application from its id. + +Note that this methods is a simple method accessor of +***org.AGL.afm.system.uninstall*** from ***afm-system-daemon***. + +After the uninstallation and before returning to the sender, +***afm-system-daemon*** sends a signal ***org.AGL.afm.system.changed***. + +**Input**: the *id* of the application and optionally the application *root* path. + +Either a string: + +```bash +"appli@x.y" +``` + +Or an object: + +```json +{ + "id": "appli@x.y", + "root": "/a/path/to/the/root" +} +``` + +**output**: the value 'true'. + + + +#### Method org.AGL.afm.user.detail + +**Description**: Get details about an application from its id. + +**Input**: the id of the application as below. + +Either just a string: + +```bash +"appli@x.y" +``` + +Or an object having the field "id" of type string: + +```json +{"id":"appli@x.y"} +``` + +**Output**: A JSON object describing the application containing +the fields described below. + +```json +{ + "id": string, the application id (id@version) + "version": string, the version of the application + "width": integer, requested width of the application + "height": integer, requested height of the application + "name": string, the name of the application + "description": string, the description of the application + "shortname": string, the short name of the application + "author": string, the author of the application +} +``` + + + +#### Method org.AGL.afm.user.runnables + +**Description**: Get the list of applications that can be run. + +**Input**: any valid json entry, can be anything except null. + +**output**: An array of description of the runnable applications. +Each item of the array contains an object containing the detail of +an application as described above for the method +*org.AGL.afm.user.detail*. + + + +#### Method org.AGL.afm.user.install + +**Description**: Install an application from its widget file. + +If an application of the same *id* and *version* exists, it is not +reinstalled except when *force=true*. + +Applications are installed in the subdirectories of the common directory +reserved for applications. +If *root* is specified, the application is installed under +sub-directories of defined *root*. + +Note that this methods is a simple accessor to the method +***org.AGL.afm.system.install*** of ***afm-system-daemon***. + +After the installation and before returning to the sender, +***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***. + +**Input**: The *path* of widget file to be installed. Optionally, +a flag to *force* reinstallation and/or a *root* directory. + +Simple form a simple string containing the absolute widget path: + +```bash +"/a/path/driving/to/the/widget" +``` + +Or an object: + +```json +{ + "wgt": "/a/path/to/the/widget", + "force": false, + "root": "/a/path/to/the/root" +} +``` + +***wgt*** and ***root*** MUST be absolute paths. + +**output**: An object containing field "added" to use as application ID. + +```json +{"added":"appli@x.y"} +``` + + + +#### Method org.AGL.afm.user.uninstall + +**Description**: Uninstall an application from its id. + +Note that this methods is a simple accessor to +***org.AGL.afm.system.uninstall*** method from ***afm-system-daemon***. + +After the uninstallation and before returning to the sender, +***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***. + +**Input**: the *id* of the application and, optionally, the path to +application *root*. + +Either a string: + +```bash +"appli@x.y" +``` + +Or an object: + +```json +{ + "id": "appli@x.y", + "root": "/a/path/to/the/root" +} +``` + +**output**: the value 'true'. + + + +#### Method org.AGL.afm.user.start + +**Description**: + +**Input**: the *id* of the application and, optionally, the +start *mode* as below. + +Either just a string: + +```bash +"appli@x.y" +``` + +Or an object containing field "id" of type string and +optionally a field mode: + +```json +{"id":"appli@x.y","mode":"local"} +``` + +The field "mode" is a string equal to either "local" or "remote". + +[Currently the mode is not available in the systemd version] + +**output**: The *runid* of the application launched. *runid* is an integer. + + + +#### Method org.AGL.afm.user.once + +**Description**: + +**Input**: the *id* of the application + +Either just a string: + +```bash +"appli@x.y" +``` + +Or an object containing field "id" of type string. + +```json +{"id":"appli@x.y"} +``` + +**output**: The *state* of the application retrieved or launched. +See *org.AGL.afm.user.state* to get a description of the returned +object. + + + +#### Method org.AGL.afm.user.terminate + +**Description**: Terminates the application attached to *runid*. + +**Input**: The *runid* (an integer) of running instance to terminate. + +**output**: the value 'true'. + + + +#### Method org.AGL.afm.user.stop + +Obsolete since 8th November 2016 (2016/11/08). +Kept for compatibility. + +Use **org.AGL.afm.user.pause** instead. + + + +#### Method org.AGL.afm.user.continue + +Obsolete since 8th November 2016 (2016/11/08). +Kept for compatibility. + +Use **org.AGL.afm.user.resume** instead. + + + +#### Method org.AGL.afm.user.pause + +[Currently not available in the systemd version] + +**Description**: Pauses the application attached to *runid* until terminate or resume. + +**Input**: The *runid* (integer) of the running instance to pause. + +**output**: the value 'true'. + + + +#### Method org.AGL.afm.user.resume + +[Currently not available in the systemd version] + +**Description**: Resumes the application attached to *runid* previously paused. + +**Input**: The *runid* (integer) of the running instance to resume. + +**output**: the value 'true'. + + + +#### Method org.AGL.afm.user.state + +**Description**: Get information about a running instance of *runid*. + +**Input**: The *runid* (integer) of the running instance inspected. + +**output**: An object describing instance state. +It contains: + +- the runid (integer) +- the pids of the processes as an array starting +- with the group leader +- the id of the running application (string) +- the state of the application (string either: "starting", "running", "paused"). + +Example of returned state: + +```json + { + "runid": 2, + "pids": [ 435, 436 ], + "state": "running", + "id": "appli@x.y" + } +``` + + + +#### Method org.AGL.afm.user.runners + +**Description**: Get the list of currently running instances. + +**Input**: anything. + +**output**: An array of states, one per running instance, as returned by +the method ***org.AGL.afm.user.state***. + +## Starting **afm daemons** + +***afm-system-daemon*** and ***afm-user-daemon*** are launched as systemd +services attached to system and user respectively. +Normally, service files are locatedat */lib/systemd/system/afm-system-daemon.service* and +*/usr/lib/systemd/user/afm-user-daemon.service*. + +### ***afm-system-daemon*** options + +The options for launching **afm-system-daemon** are: + +```bash + -r + --root directory + + Set the root application directory. + + Note that the default root directory is defined + to be /usr/share/afm/applications (may change). + + -d + --daemon + + Daemonizes the process. It is not needed by systemd. + + -q + --quiet + + Reduces the verbosity (can be repeated). + + -v + --verbose + + Increases the verbosity (can be repeated). + + -h + --help + + Prints a short help. +``` + +### ***afm-user-daemon*** options + +The options for launching **afm-user-daemon** are: + +```bash + -a + --application directory + + [Currently not available in the systemd version] + + Includes the given application directory to + the database base of applications. + + Can be repeated. + + -r + --root directory + + [Currently not available in the systemd version] + + Includes root application directory or directories when + passing multiple rootdir to + applications database. + + Note that default root directory for + applications is always added. In current version + /usr/share/afm/applications is used as default. + + -m + --mode (local|remote) + + [Currently not available in the systemd version] + + Set the default launch mode. + The default value is 'local' + + -d + --daemon + + Daemonizes the process. It is not needed by systemd. + + -q + --quiet + + Reduces the verbosity (can be repeated). + + -v + --verbose + + Increases the verbosity (can be repeated). + + -h + --help + + Prints a short help. +``` + +## Tasks of **afm-user-daemon** + +### Maintaining list of applications + +At start **afm-user-daemon** scans the directories containing +applications and load in memory a list of available applications +accessible by current user. + +When **afm-system-daemon** installs or removes an application. +On success it sends the signal *org.AGL.afm.system.changed*. +When receiving such a signal, **afm-user-daemon** rebuilds its +applications list. + +**afm-user-daemon** provides the data it collects about +applications to its clients. +Clients may either request the full list +of available applications or a more specific information about a +given application. + +### Launching application + +**afm-user-daemon** launches application by using systemd. +Systemd builds a secure environment for the application +before starting it. + +Once launched, running instances of application receive +a runid that identify them. +To make interface with systemd evident, the pid is the runid. + +### Managing instances of running applications + +**afm-user-daemon** manages the list of applications +that it launched. + +When owning the right permissions, a client can get the list +of running instances and details about a specific +running instance. +It can also terminate a given application. + +### Installing and uninstalling applications + +If the client own the right permissions, +**afm-user-daemon** delegates that task +to **afm-system-daemon**. + +## Using ***afm-util*** + +The command line tool ***afm-util*** uses dbus-send to send +orders to **afm-user-daemon**. +This small scripts allows to send command to ***afm-user-daemon*** either +interactively at shell prompt or scriptically. + +The syntax is simple: + +- it accept a command and when requires attached arguments. + +Here is the summary of ***afm-util***: + +- **afm-util runnables **: + list the runnable widgets installed + +- **afm-util install wgt **: + install the wgt file + +- **afm-util uninstall id **: + remove the installed widget of id + +- **afm-util detail id **: + print detail about the installed widget of id + +- **afm-util runners **: + list the running instance + +- **afm-util start id **: + start an instance of the widget of id + +- **afm-util once id **: + run once an instance of the widget of id + +- **afm-util terminate rid **: + terminate the running instance rid + +- **afm-util state rid **: + get status of the running instance rid + +Here is how to list applications using ***afm-util***: + +```bash + afm-util runnables +``` + +[afm-daemons]: pictures/afm-daemons.svg diff --git a/docs/3_Developer_Guides/1_Application_Framework/2_widgets.md b/docs/3_Developer_Guides/1_Application_Framework/2_widgets.md new file mode 100644 index 0000000..07edc52 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/2_widgets.md @@ -0,0 +1,11 @@ +--- +title: Widgets +--- + +# The widgets + +The widgets are described by the W3C's technical recommendations +[Packaged Web Apps (Widgets)](http://www.w3.org/TR/widgets) and [XML Digital Signatures for Widgets](http://www.w3.org/TR/widgets-digsig) + +In summary, **widgets are ZIP files that can be signed and +whose content is described by the file **. \ No newline at end of file diff --git a/docs/3_Developer_Guides/1_Application_Framework/3_widgets_overview.md b/docs/3_Developer_Guides/1_Application_Framework/3_widgets_overview.md new file mode 100644 index 0000000..28dbc60 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/3_widgets_overview.md @@ -0,0 +1,158 @@ +--- +title: Overview of widgets +--- + + +# Tools for managing widgets + +This project includes tools for managing widgets. +These tools are: + +- ***wgtpkg-info***: command line tool to display + informations about a widget file. + +- ***wgtpkg-install***: command line tool to + install a widget file. + +- ***wgtpkg-pack***: command line tool to create + a widget file from a widget directory. + +- ***wgtpkg-sign***: command line tool to add a signature + to a widget directory. + +For all these commands, a tiny help is available with +options **-h** or **--help**. + +There is no tool for unpacking a widget. +For doing such operation, you can use the command **unzip**. + +To list the files of a widget: + +```bash +unzip -l WIDGET +``` + +To extract a widget in some directory: + +```bash +unzip WIDGET -d DIRECTORY +``` + +*Note: that DIRECTORY will be created if needed*. + +## Getting data about a widget file + +The command **wgtpkg-info** opens a widget file, reads its **config.xml** +file and displays its content in a human readable way. + +## Signing and packing widget + +### Signing + +To sign a widget, you need a private key and its certificate. + +The tool **wgtpkg-sign** creates or replace a signature file in +the directory of the widget BEFORE its packaging. + +There are two types of signature files: author and distributor. + +Example 1: add an author signature + +```bash +wgtpkg-sign -a -k me.key.pem -c me.cert.pem DIRECTORY +``` + +Example 2: add a distributor signature + +```bash +wgtpkg-sign -k authority.key.pem -c authority.cert.pem DIRECTORY +``` + +### Packing + +This operation can be done using the command **zip** but +we provide the tool **wgtpkg-pack** that may add checking. + +Example: + +```bash +wgtpkg-pack DIRECTORY -o file.wgt +``` + +## Writing a widget + +### App directory organization + +There are few directories that are by default used in the binder. At the root +directory of the widget folder, here are the directories that could be used: + +- *lib* : default directory where lies external libraries needed for + the binding. Binding could be stored here too or in another directory of your + choice. +- *htdocs* : root HTTP directory if binding has web UI. + +### The steps for writing a widget + +1. make your application +2. create its configuration file **config.xml** +3. sign it +4. pack it + +Fairly easy, no? + +## Organization of directory of applications + +### Directory where are stored applications + +Applications can be installed in different places: + +- the system itself, extension device. + +On a phone application are typically installed on the sd card. + +This translates to: + +- /var/local/lib/afm/applications + +From here this path is referenced as: "APPDIR". + +The main path for applications is: APPDIR/PKGID/VER. + +Where: + +- APPDIR is as defined above +- PKGID is a directory whose name is the package identifier +- VER is the version of the package MAJOR.MINOR + +This organization has the advantage to allow several versions +to leave together. +This is needed for some good reasons (rolling back) and also for less good reasons (user habits). + +### Identity of installed files + +All files are installed as user "afm" and group "afm". +All files have rw(x) for user and r-(x) for group and others. + +This allows every user to read every file. + +### Labeling the directories of applications + +The data of a user are in its directory and are labelled by the security-manager using the application labels. + +[widgets]: http://www.w3.org/TR/widgets "Packaged Web Apps" +[widgets-digsig]: http://www.w3.org/TR/widgets-digsig "XML Digital Signatures for Widgets" +[app-manifest]: http://www.w3.org/TR/appmanifest "Web App Manifest" +[meta-intel]: https://github.com/01org/meta-intel-iot-security "A collection of layers providing security technologies" +[widgets]: http://www.w3.org/TR/widgets "Packaged Web Apps" +[widgets-digsig]: http://www.w3.org/TR/widgets-digsig "XML Digital Signatures for Widgets" +[libxml2]: http://xmlsoft.org/html/index.html "libxml2" +[openssl]: https://www.openssl.org "OpenSSL" +[xmlsec]: https://www.aleksey.com/xmlsec "XMLSec" +[json-c]: https://github.com/json-c/json-c "JSON-c" +[d-bus]: http://www.freedesktop.org/wiki/Software/dbus "D-Bus" +[libzip]: http://www.nih.at/libzip "libzip" +[cmake]: https://cmake.org "CMake" +[security-manager]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Security_Manager "Security-Manager" +[app-manifest]: http://www.w3.org/TR/appmanifest "Web App Manifest" +[tizen-security]: https://wiki.tizen.org/wiki/Security "Tizen security home page" +[tizen-secu-3]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Overview "Tizen 3 security overview" diff --git a/docs/3_Developer_Guides/1_Application_Framework/4_Widget_configuration_file.md b/docs/3_Developer_Guides/1_Application_Framework/4_Widget_configuration_file.md new file mode 100644 index 0000000..f7acb23 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/4_Widget_configuration_file.md @@ -0,0 +1,589 @@ +--- +title: Widget configuration file +--- + +# Configuration file - config.xml + +The widgets are described by the W3C's technical recommendations +[Packaged Web Apps (Widgets)][widgets] and [XML Digital Signatures for +Widgets][widgets-digsig] +that specifies the configuration file **config.xml**. + +## Overview + +The file **config.xml** describes important data of the application +to the framework: + +- the unique identifier of the application +- the name of the application +- the type of the application +- the icon of the application +- the permissions linked to the application +- the services and dependencies of the application + +The file MUST be at the root of the widget and MUST be case sensitively name +***config.xml***. + +The file **config.xml** is a XML file described by the document +[widgets]. + +Here is the example of the config file for the QML application SmartHome. + +```xml + + + SmartHome + + + This is the Smarthome QML demo application. It shows some user interfaces for controlling an +automated house. The user interface is completely done with QML. + Qt team + GPL + +``` + +The most important items are: + +- ****: gives the id of the widget. It must be unique. + +- ****: gives the version of the widget + +- ****: gives a path to the icon of the application + (can be repeated with different sizes) + +- ****: this indicates the entry point and its type. + +## Standard elements of "config.xml" + +### The element widget + +#### the attribute id of widget + +The attribute *id* is mandatory (for version 2.x, blowfish) and must be unique. + +Values for *id* are any non empty string containing only latin letters, +arabic digits, and the three characters '.' (dot), '-' (dash) and +'\_' (underscore). + +Authors can use a mnemonic id or can pick a unique id using +command **uuid** or **uuidgen**. + +### the attribute version of widget + +The attribute *version* is mandatory (for version 2.x, blowfish). + +Values for *version* are any non empty string containing only latin letters, +arabic digits, and the three characters '.' (dot), '-' (dash) and +'\_' (underscore). + +Version values are dot separated fields MAJOR.MINOR.REVISION. +Such version would preferably follow guidelines of +[semantic versioning][semantic-version]. + +### The element content + +The element *content* is mandatory (for version 2.x, blowfish) and must designate a file +(subject to localization) with its attribute *src*. + +The content designed depends on its type. See below for the known types. + +### The element icon + +The element *icon* is mandatory (for version 2.x, blowfish) and must +be unique. It must designate an image file with its attribute *src*. + +## AGL features + +The AGL framework uses the feature tag for specifying security and binding +requirement of the widget. + +Since the migration of the framework to leverage systemd power, +the features are of important use to: + +- declare more than just an application +- declare the expected dependencies +- declare the expected permissions +- declare the exported apis + +The specification of [widgets][widgets] is intended to describe +only one application. +In the present case, we expect to describe more than just an application. +For example, a publisher could provide a widget containing a service, +an application for tuning that service, an application that +leverage the service. +Here, the term of service means a background application that +runs without IHM and whose public api can be accessed by other +applications. + +So the features are used to describe each of the possible +units of widgets. +The "standard" unit in the meaning of [widgets][widgets] +is called the "main" unit. + +### required-api: feature name="urn:AGL:widget:required-api" + +List of the api required by the widget. + +Each required api must be explicit using a `` entry. + +Example: + +```xml + + + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json +"required-api": [ + { "name": "gps", "value": "auto" }, + { "name": "afm-main", "value": "link" } + ] +``` + +#### required-api: param name="#target" + +OPTIONAL + +Declares the name of the unit requiring the listed apis. +Only one instance of the param "#target" is allowed. +When there is not instance of this param, it behave as if +the target main was specified. + +#### required-api: param name=[required api name] + +The name is the name of the required API. + +The value describes how to connect to the required api. +It is either: + +- local: OBSOLETE SINCE FF (AGL6), PROVIDED FOR COMPATIBILITY + Use the feature **urn:AGL:widget:required-binding** instead. + The binding is a local shared object. + In that case, the name is the relative path of the + shared object to be loaded. + +- auto: + The framework set automatically the kind of + the connection to the API + +- ws: + The framework connect using internal websockets + +- dbus: [OBSOLETE, shouldn't be used currently] + The framework connect using internal dbus + +- tcp: + In that case, the name is the URI to access the service. + The framework connect using a URI of type + HOST:PORT/API + API gives the name of the imported api. + +- cloud: [PROPOSAL - NOT IMPLEMENTED] + The framework connect externally using websock. + In that case, the name includes data to access the service. + Example: `` + +### required-binding: feature name="urn:AGL:widget:required-binding" + +List of the bindings required by the widget. + +Note: Since AGL 6 (FF - Funky Flounder), +the binder implements bindings version 3 that allow the declaration +of 0, 1 or more APIs by one binding. In other words, the equivalency +one binding = one API is lost. At the same time the framework added +the ability to use bindings exported by other widgets. + +Each required binding must be explicit using a `` entry. + +Example: + +```xml + + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json +"required-binding": [ + { "name": "libexec/binding-gps.so", "value": "local" }, + { "name": "extra", "value": "extern" } + ] +``` + +#### required-binding: param name=[name or path] + +The name or the path of the required BINDING. + +The value describes how to connect to the required binding. +It is either: + +- local: + The binding is a local shared object. + In that case, the name is the relative path of the + shared object to be loaded. + +- extern: + The binding is external. The name is the exported binding name. + See provided-binding. + +### provided-binding: feature name="urn:AGL:widget:provided-binding" + +This feature allows to export a binding to other binders. +The bindings whose relative name is given as value is exported to +other binders under the given name. + +Each provided binding must be explicit using a `` entry. + +Example: + +```xml + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json +"provided-binding": [ + { "name": "extra", "value": "export/binding-gps.so" } + ] +``` + +#### provided-binding: param name=[exported name] + +Exports a local binding to other applications. + +The value must contain the path to the exported binding. + +### required-permission: feature name="urn:AGL:widget:required-permission" + +List of the permissions required by the unit. + +Each required permission must be explicit using a `` entry. + +Example: + +```xml + + + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json +"required-permission":{ + "urn:AGL:permission:real-time":{ + "name":"urn:AGL:permission:real-time", + "value":"required" + }, + "urn:AGL:permission:syscall:*":{ + "name":"urn:AGL:permission:syscall:*", + "value":"required" + } +} +``` + +#### required-permission: param name="#target" + +OPTIONAL + +Declares the name of the unit requiring the listed permissions. +Only one instance of the param "#target" is allowed. +When there is not instance of this param, it behave as if +the target main was specified. + +#### required-permission: param name=[required permission name] + +The value is either: + +- required: the permission is mandatorily needed except if the feature + isn't required (required="false") and in that case it is optional. +- optional: the permission is optional + +### provided-unit: feature name="urn:AGL:widget:provided-unit" + +This feature is made for declaring new units +for the widget. +Using this feature, a software publisher +can provide more than one application in the same widget. + +Example: + +```xml + + + + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json + { + "#target":"geoloc", + "description":"binding of name geoloc", + "content":{ + "src":"index.html", + "type":"application\/vnd.agl.service" + }, + ... + } +``` + +#### provided-unit: param name="#target" + +REQUIRED + +Declares the name of the unit. The default unit, the unit +of the main of the widget, has the name "main". +The value given here must be unique within the widget file. +It will be used in other places of the widget config.xml file to +designate the unit. + +Only one instance of the param "#target" is allowed. +The value can't be "main". + +#### provided-unit: param name="content.type" + +REQUIRED + +The mimetype of the provided unit. + +#### provided-unit: param name="content.src" + +A path to the source + +#### other parameters + +The items that can be set for the main unit +can also be set using the params if needed. + +- description +- name.content +- name.short +- ... + +### provided-api: feature name="urn:AGL:widget:provided-api" + +Use this feature for exporting one or more API of a unit +to other widgets of the platform. + +This feature is an important feature of the framework. + +Example: + +```xml + + + + + +``` + +This will be *virtually* translated for mustaches to the JSON + +```json + "provided-api":[ + { + "name":"geoloc", + "value":"auto" + }, + { + "name":"moonloc", + "value":"auto" + } + ], +``` + +#### provided-api: param name="#target" + +OPTIONAL + +Declares the name of the unit exporting the listed apis. +Only one instance of the param "#target" is allowed. +When there is not instance of this param, it behave as if +the target main was specified. + +#### provided-api: param name=[name of exported api] + +The name give the name of the api that is exported. + +The value is one of the following values: + +- ws: + export the api using UNIX websocket + +- dbus: [OBSOLETE, shouldn't be used currently] + export the API using dbus + +- auto: + export the api using the default method(s). + +- tcp: + In that case, the name is the URI used for exposing the service. + The URI is of type + HOST:PORT/API + API gives the name of the exported api. + +### file-properties: feature name="urn:AGL:widget:file-properties" + +Use this feature for setting properties to files of the widget. +At this time, this feature only allows to set executable flag +for making companion program executable explicitly. + +Example: + +```xml + + + + +``` + +#### file-properties: param name="path" + +The name is the relative path of the file whose property +must be set. + +The value must be "executable" to make the file executable. + +## Known content types + +The configuration file ***/etc/afm/afm-unit.conf*** defines +how to create systemd units for widgets. + +Known types for the type of content are: + +- ***text/html***: + HTML application, + content.src designates the home page of the application + +- ***application/vnd.agl.native*** + AGL compatible native, + content.src designates the relative path of the binary. + +- ***application/vnd.agl.service***: + AGL service, content.src is not used. + +- ***application/x-executable***: + Native application, + content.src designates the relative path of the binary. + For such application, only security setup is made. + +Adding more types is easy, it just need to edit the configuration +file ***afm-unit.conf***. + +### Older content type currently not supported at the moment + +This types were defined previously when the framework was not +leveraging systemd. +The transition to systemd let these types out at the moment. + +- ***application/vnd.agl.url*** +- ***text/vnd.qt.qml***, ***application/vnd.agl.qml*** +- ***application/vnd.agl.qml.hybrid*** +- ***application/vnd.agl.html.hybrid*** + +## The configuration file afm-unit.conf + +The integration of the framework with systemd +mainly consists of creating the systemd unit +files corresponding to the need and requirements +of the installed widgets. + +This configuration file named `afm-unit.conf` installed +on the system with the path `/etc/afm/afm-unit.conf` +describes how to generate all units from the *config.xml* +configuration files of widgets. +The description uses an extended version of the templating +formalism of [mustache][] to describes all the units. + +Let present how it works using the following diagram that +describes graphically the workflow of creating the unit +files for systemd `afm-unit.conf` from the configuration +file of the widget `config.xml`: + +![make-units](pictures/make-units.svg) + +In a first step, and because [mustache][] is intended +to work on JSON representations, the configuration file is +translated to an internal JSON representation. +This representation is shown along the examples of the documentation +of the config files of widgets. + +In a second step, the mustache template `afm-unit.conf` +is instantiated using the C library [mustach][] that follows +the rules of [mustache][mustache] and with all its available +extensions: + +- use of colon (:) for explicit substitution +- test of values with = or =! + +In a third step, the result of instantiating `afm-unit.conf` +for the widget is split in units. +To achieve that goal, the lines containing specific directives are searched. +Any directive occupy one full line. +The directives are: + +- %nl + Produce an empty line at the end +- %begin systemd-unit +- %end systemd-unit + Delimit the produced unit, its begin and its end +- %systemd-unit user +- %systemd-unit system + Tells the kind of unit (user/system) +- %systemd-unit service NAME +- %systemd-unit socket NAME + Gives the name and type (service or socket) of the unit. + The extension is automatically computed from the type + and must not be set in the name. +- %systemd-unit wanted-by NAME + Tells to install a link to the unit in the wants of NAME + +Then the computed units are then written to the filesystem +and inserted in systemd. + +The generated unit files will contain variables for internal +use of the framework. +These variables are starting with `X-AFM-`. +The variables starting with `X-AFM-` but not with `X-AFM--` are +the public variables. +These variables will be returned by the +framework as the details of an application (see **afm-util detail ...**). + +Variables starting with `X-AFM--` are private to the framework. +By example, the variable `X-AFM--http-port` is used to +record the allocated port for applications. + +[mustach]: https://gitlab.com/jobol/mustach "basic C implementation of mustache" +[mustache]: http://mustache.github.io/mustache.5.html "mustache - Logic-less templates" +[widgets]: http://www.w3.org/TR/widgets "Packaged Web Apps" +[widgets-digsig]: http://www.w3.org/TR/widgets-digsig "XML Digital Signatures for Widgets" +[libxml2]: http://xmlsoft.org/html/index.html "libxml2" +[app-manifest]: http://www.w3.org/TR/appmanifest "Web App Manifest" +[meta-intel]: https://github.com/01org/meta-intel-iot-security "A collection of layers providing security technologies" +[openssl]: https://www.openssl.org "OpenSSL" +[xmlsec]: https://www.aleksey.com/xmlsec "XMLSec" +[json-c]: https://github.com/json-c/json-c "JSON-c" +[d-bus]: http://www.freedesktop.org/wiki/Software/dbus "D-Bus" +[libzip]: http://www.nih.at/libzip "libzip" +[cmake]: https://cmake.org "CMake" +[security-manager]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Security_Manager "Security-Manager" +[tizen-security]: https://wiki.tizen.org/wiki/Security "Tizen security home page" +[tizen-secu-3]: https://wiki.tizen.org/wiki/Security/Tizen_3.X_Overview "Tizen 3 security overview" +[semantic-version]: http://semver.org/ "Semantic versioning" diff --git a/docs/3_Developer_Guides/1_Application_Framework/5_Permissions.md b/docs/3_Developer_Guides/1_Application_Framework/5_Permissions.md new file mode 100644 index 0000000..8b149c0 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/5_Permissions.md @@ -0,0 +1,131 @@ +--- +title: Permissions +--- + +## Permission's names + +The proposal here is to specify a naming scheme for permissions +that allows the system to be as stateless as possible. +The current specification includes in the naming of permissions either +the name of the bound binding when existing and the level of the +permission itself. +Doing this, there is no real need for the +framework to keep installed permissions in a database. + +The permission names are [URN][URN] of the form: + +```bash + urn:AGL:permission::: +``` + +where "AGL" is the NID (the namespace identifier) dedicated to AGL. +(note: a RFC should be produced to standardize this name space) + +The permission names are made of NSS (the namespace specific string) +starting with "permission:" and followed by colon separated +fields. +The 2 first fields are `` and `` and the remaining +fields are grouped to form the ``. + +```bash + ::= [ ] + + ::= 1* + + ::= | | | + + ::= "-" | "." | "_" | "@" +``` + +The field `` can be made of any valid character for NSS except +the characters colon and star (:*). +This field designates the api providing the permission. +This scheme is used to deduce binding requirements +from permission requirements. +The field `` can be the empty string when the permission +is defined by the AGL system itself. + +[PROPOSAL 1] The field `` if starting with the character "@" represents +a transversal/cross permission not bound to any binding. + +[PROPOSAL 2]The field `` if starting with the 2 characters "@@" +in addition to a permission not bound to any binding, represents a +permission that must be set at installation and that can not be +revoked later. + + ::= 1* + +The field `` is made only of letters in lower case. +The field `` can only take some predefined values: + +- system +- platform +- partner +- tiers +- owner +- public + +The field `` is made of `` separated +by colons. + + ::= 0*(":" ) + +The names at left are hierarchically grouping the +names at right. +This hierarchical behaviour is intended to +be used to request permissions using hierarchical grouping. + +## Permission value + +In some case, it could be worth to add a value to a permission. + +Currently, the framework allows it for permissions linked to +systemd. +But this not currently used. + +Conversely, permissions linked to cynara can't carry data +except in their name. + +Thus to have a simple and cleaner model, it is better to forbid +attachment of value to permission. + +## Example of permissions + +Here is a list of some possible permissions. +These permissions are available the 21th of May 2019. + +- urn:AGL:permission::platform:no-oom + Set OOMScoreAdjust=-500 to keep the out-of-memory + killer away. +- urn:AGL:permission::partner:real-time + Set IOSchedulingClass=realtime to give to the process + realtime scheduling. + Conversely, not having this permission set RestrictRealtime=on + to forbid realtime features. +- urn:AGL:permission::public:display + Adds the group "display" to the list of supplementary groups + of the process. +- urn:AGL:permission::public:syscall:clock + Without this permission SystemCallFilter=~@clock is set to + forfid call to clock. +- urn:AGL:permission::public:no-htdocs + The http directory served is not "htdocs" but "." +- urn:AGL:permission::public:applications:read + Allows to read data of installed applications (and to + access icons). +- urn:AGL:permission::partner:service:no-ws + Forbids services to provide its API through websocket. +- urn:AGL:permission::partner:service:no-dbus + Forbids services to provide its API through D-Bus. +- urn:AGL:permission::system:run-by-default + Starts automatically the application. Example: home-screen. +- urn:AGL:permission::partner:scope-platform + Install the service at the scope of the platform. +- urn:AGL:permission::system:capability:keep-all + Keep all capabilities for the service. Note that implementing + that permission is not mandatory or can be adapted for the given + system. +- + Permission to use D-Bus. + +[URN]: https://tools.ietf.org/rfc/rfc2141.txt "RFC 2141: URN Syntax" diff --git a/docs/3_Developer_Guides/1_Application_Framework/6_Quick-Tutorial.md b/docs/3_Developer_Guides/1_Application_Framework/6_Quick-Tutorial.md new file mode 100644 index 0000000..f031235 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/6_Quick-Tutorial.md @@ -0,0 +1,267 @@ +--- +title: Quick Tutorial +--- + +## Introduction + +This document proposes a quick tutorial to demonstrate the major +functionalities of the AGL Application Framework. +For more complete information, please refer to the inline documentation +available in the main git repository: + + - [https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main] + - [https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder] + +For more information on AGL, please visit: +[https://www.automotivelinux.org/] + +## Sample applications + +4 sample applications (.wgt files) are prebuilt and available at the following address: +[https://github.com/iotbzh/afm-widget-examples] + +You can get them by cloning this git repository on your desktop (will be useful later in this tutorial): + +```bash +git clone https://github.com/iotbzh/afm-widget-examples +``` + +## Using the CLI tool + +### Setup Environment + +Connect your AGL target board to the network and copy some sample widgets on it through SSH (set BOARDIP with your board IP address) : + +```bash +cd afm-widget-examples +BOARDIP=1.2.3.4 +scp *.wgt root@$BOARDIP:~/ +``` + +Connect through SSH on the target board and check for Application Framework daemons: + +```bash +$ ssh root@$BOARDIP +root@porter:~# ps -ef|grep bin/afm +afm 409 1 0 13:00 ? 00:00:00 /usr/bin/afm-system-daemon +root 505 499 0 13:01 ? 00:00:00 /usr/bin/afm-user-daemon +root 596 550 0 13:22 pts/0 00:00:00 grep afm +``` + +We can see that there are two daemons running: + +* **afm-system-daemon** runs with a system user 'afm' and is responsible for + installing/uninstalling packages +* **afm-user-daemon** runs as a user daemon (currently as root because it's the + only real user on the target board) and is responsible for the whole life + cycle of the applications running inside the user session. + +The application framework has a tool running on the +Command Line Interface (CLI). +Using the **afm-util** command, you can install, uninstall, list, run, pause ... applications. + +To begin, run '**afm-util help**' to get a quick help on commands: + +```bash +root@porter:~# afm-util help +usage: afm-util command [arg] +``` + +The commands are: + +```bash +list +runnables list the runnable widgets installed + +add wgt +install wgt install the wgt file + +remove id +uninstall id remove the installed widget of id + +info id +detail id print detail about the installed widget of id + +ps +runners list the running instance + +run id +start id start an instance of the widget of id + +kill rid +terminate rid terminate the running instance rid + +status rid +state rid get status of the running instance rid +``` + +### Install an application + +You can then install your first application: + +```bash +root@porter:~# afm-util install /home/root/annex.wgt +{ "added": "webapps-annex@0.0" } +``` + +Let's install a second application: + +```bash +root@porter:~# afm-util install /home/root/memory-match.wgt +{ "added": "webapps-memory-match@1.1" } +``` + +Note that usually, **afm-util** will return a **JSON result**, which is the common format for messages returned by the Application Framework daemons. + +### List installed applications + +You can then list all installed applications: + +```bash +root@porter:~# afm-util list +[ { "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt " }, +{ "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt " } ] +``` + +Here, we can see the two previously installed applications. + +### Get information about an application + +Let's get some details about the first application: + +```bash +root@porter:~# afm-util info webapps-annex@0.0 +{ "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt " } +``` + +Note: that AGL applications are mostly handled by afm-util through their IDs. +In our example, the application ID is 'webapps-annex@0.0'. + +### Start application + +Let's start the first application Annex: + +```bash +root@porter:~# afm-util start webapps-annex@0.0 +1 +``` + +As the application is a HTML5 game, you should then get a webview running with QML on the board display. + +### Security Context + +The application has been started in the user session, with a dedicated security context, enforced by SMACK. +To illustrate this, we can take a look at the running processes and their respective SMACK labels: + +```bash +root@porter:~# ps -efZ |grep webapps-annex | grep -v grep +User::App::webapps-annex root 716 491 0 13:19 ? 00:00:00 /usr/bin/afb-daemon --mode=local --readyfd=8 --alias=/icons /usr/share/afm/icons --port=12348 --rootdir=/usr/share/afm/applications/webapps-annex/0.0 --token=7D6D2F16 --sessiondir=/home/root/app-data/webapps-annex/.afb-daemon +User::App::webapps-annex root 717 491 0 13:19 ? 00:00:00 /usr/bin/qt5/qmlscene http://localhost:12348/index.html?token=7D6D2F16 /usr/bin/web-runtime-webkit.qml +``` + +In the previous result, we see that the application is composed of two processes: + +* the application binder (afb-daemon) +* the application UI (qmlscene ...) + +While most system processes run with the label 'System', we see that the +application runs with a specific SMACK label 'User::App::webapps-annex': this +label is used to force the application to follow +a Mandatory Access Control (MAC) scheme. +This means that those processes run in their own security context, +isolated from the rest of the system (and other applications). +Global security rules can then be applied to restrict access +to all other user or system resources. + +### Check running applications + +To check for running applications, just run: + +```bash +root@porter:~# afm-util ps +[ { "runid": 1, "state": "running", "id": "webapps-annex@0.0" } ] +``` + +The 'runid' is the application instance ID and is used as an argument for the +subcommands controlling the application runtime state (kill/pause/resume/status) + +### Uninstall application + +To uninstall an application, simply use its ID: + +```bash +root@porter:~# afm-util uninstall webapps-annex@0.0 +true +``` + +Then list the installed apps to confirm the removal: + +```bash +root@porter:~# afm-util list +[ { "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt " } ] +``` + +## afm-client: a sample HTML5 'Homescreen' + +**afm-client** is a HTML5 UI that allows to install/uninstall applications as well as starting/pausing them as already demonstrated with afm-util. + +The HTML5 UI is accessible remotely through this URL: + + +### Installing an application + +By clicking on the '**Upload**' button on the right, +you can send an application package (WGT file) and install it. +Select for example the file '**rabbit.wgt**' that was cloned initially + from the git repository afm-widget-examples. + +Then a popup requester ask for a confirmation: +'Upload Application rabbit.wgt ?'. Click on the '**Install**' button. + +You should then see some changes in the toolbar: +a new icon appeared, representing the freshly installed application. + +### Running an application + +In the toolbar, click on the button representing the Rabbit application. +You'll get a popup asking to: + +* start the application +* or get some info about it +* or uninstall it + +Click on the 'start' item: the application starts and should be visible + as a webview on the target board display. +Note that at this point, we could also run the application remotely, +that is in the same browser as the Homescreen app. +By default, the application framework is configured +to run applications 'locally' on the board display. + +### Uninstalling an application + +From the same popup menu, you can select 'uninstall' +to remove the application from the system. +As a consequence, the application icon should disappear from the toolbar. + +## afb-client: a template for Angular Applications + +Another package '**afb-client**' is also available for testing. +This is a sample HTML5 application demonstrating various basic +capabilities of the Binder daemon. +It can be used by developers as a template to start writing real AGL Applications. + +This application is not available as WGT file yet and it should be started manually without any specific security context: + +```bash +root@porter:~# /usr/bin/afb-daemon --port=1235 --token='' --sessiondir=/home/root/.afm-daemon --rootdir=/usr/share/agl/afb-client --alias=/icons:/usr/share/afm/icons +``` + +Then you can access it from a browser: + + +afb-client is a simple application to demonstrate the built-in capabilities of the binder daemon (handling sessions and security tokens, testing POSTs uploads...) and was used during the application framework development to validate the proposed features. + +[https://github.com/iotbzh/afm-widget-examples]: https://github.com/iotbzh/afm-widget-examples +[https://www.automotivelinux.org/]: https://www.automotivelinux.org/ +[https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder]: https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder +[https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main]: https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main diff --git a/docs/3_Developer_Guides/1_Application_Framework/pictures/AppFW-APP_install_sequences.svg b/docs/3_Developer_Guides/1_Application_Framework/pictures/AppFW-APP_install_sequences.svg new file mode 100644 index 0000000..fab8399 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/pictures/AppFW-APP_install_sequences.svg @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + System + + + + + + + + + + + + + + + User + + + + + + + + + + + D-Bus session + + + + + + + + + + SMACK isolatedother application + + + + + + + + + + SECURITY MANAGER + + + + + + + + + + afm-system-daemon + + + + + + + + + + CYNARA + + + + + + + + + + D-Bus system + + + + + + + + + + afm-user-daemon + + + + + + + + + + SMACK isolated Application + + + + + + + + + + + + + + + + + Application UI + + + + + + + + + + + binder afb-daemon + + + + + + + + + + afm-main-binding + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (1), (7) + + + + + + (2) + + + + + + (3) + + + + + + (4) + + + + + + (5) + + + + + + (6) + + + + + + (9) + + + + + + (11) + + + + + + (12) + + + + + + (10) + + + + + + (13) + + + + + + (8) + + + + + + + diff --git a/docs/3_Developer_Guides/1_Application_Framework/pictures/Security_model_history.svg b/docs/3_Developer_Guides/1_Application_Framework/pictures/Security_model_history.svg new file mode 100644 index 0000000..7935437 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/pictures/Security_model_history.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tizen OBS + + + + + + Tizen Yocto + + + + + + meta-intel-iot-security + + + + + + 2014 + + + + + + 2015 + + + + + + + \ No newline at end of file diff --git a/docs/3_Developer_Guides/1_Application_Framework/pictures/afm-daemons.svg b/docs/3_Developer_Guides/1_Application_Framework/pictures/afm-daemons.svg new file mode 100644 index 0000000..02b2c92 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/pictures/afm-daemons.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + System + + + + + + + + + + + + + + + User + + + + + + + + + + + D-Bus session + + + + + + + + + + SMACK isolatedApplication + + + + + + + + + + SECURITY MANAGER + + + + + + + + + + afm-system-daemon + + + + + + + + + + CYNARA + + + + + + + + + + D-Bus system + + + + + + + + + + afm-user-daemon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/3_Developer_Guides/1_Application_Framework/pictures/make-units.svg b/docs/3_Developer_Guides/1_Application_Framework/pictures/make-units.svg new file mode 100644 index 0000000..d52a8c7 --- /dev/null +++ b/docs/3_Developer_Guides/1_Application_Framework/pictures/make-units.svg @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <number> + + + + + + + + + + + + + + config.xml + + + + + + + /etc/afm/afm-unit.conf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + json description + + + + + + + + + Mustache engine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + units description + + + + + + + *.service + + + + + + + *.socket + + + + + + virtualdata + + + + + + + + + + + + + + + + + + + + + + + Unit installer + + + + + + + + + Config engine + + + + + + + ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + configurationfile + + + + + + systemdunits + + + + + + + \ No newline at end of file -- 2.16.6