summaryrefslogtreecommitdiffstats
path: root/README.md
blob: 49993bfa6eab8ca959d1945163308bc59f85482a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# afm-main

## Overview

This repository is named **afm-main** because
it stands for **AGL Framework Master - Main**.

It contains programs and services to create widgets,
to install widgets, to run widgets.

## How to compile?

This project uses CMAKE and C compiler suite to be compiled.

### Dependencies

This package requires the following libraries or modules:

- ***libxml-2.0***
- ***openssl***
- ***xmlsec1***
- ***xmlsec1-openssl***
- ***json-c***
- ***dbus-1***
- ***security-manager***

This package also requires either ***libzip*** (version >= 0.11)
or the binaries ***zip*** and ***unzip***. By default, it will
use ***libzip***.

### Compiling

The main scheme for compiling the project is:

> cmake .
>
> make
>
> sudo make install

By default, the installation is made in ***/usr***.
To change this behaviour, you should set the variable
CMAKE_INSTALL_PREFIX as in the below example:

> cmake -DCMAKE_INSTALL_PREFIX=/some/where .

You could check the documentation of the standard CMake module
[GNUInstallDirs](https://cmake.org/cmake/help/v3.4/module/GNUInstallDirs.html).

To forbid the use of ***libzip*** and replace it with the
use of programs ***zip*** and ***unzip***, type:

> cmake -DUSE_LIBZIP=0 .

### Evaluation on AGL using yocto

TO BE CONTINUED

## Content

This package content source files for several programs.
The installed programs are:

- ***afm-system-daemon***: D-Bus daemon to install,
  uninstall, list the widgets.

  It runs on the system bus.

- ***afm-user-daemon***: D-Bus daemon to list
  available widgets, to start, pause, resume, stop it.

  It runs on the user session bus.

- ***wgtpkg-info***: command line tool to display
  information about a widget file.

- ***wgtpkg-installer***: 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.

## Description

### Actors

The framework defined by afm-main is defining several actors:
the platform designer, the application developer, the distributor,
the user, the hacker.

The platform designer defines the AGL system and its security.

The application developer in link or not with hardware vendors
is creating applications, modules, libraries, services that will
be installed to the platform.

The hacker is a user that also develops application for
tuning its system.

The distributor is the mediator between the developer and the
user. It provides

The user is either the driver or a passenger of the car.

The application, libraries, services are available on the
platform. Some of them are in direct interaction with users.
Some others, like services, are used indirectly.


### Scenarii

#### Writing applications

The application will receive an identifier.
That identifier must have the following feature:

- it must be unique to identify the application and its revisions
- it should be short enough to be used with efficiency by
  security components of the system
- it can not be stolen by malicious applications that
  would like to spoof the application identity
- it can be sold to other company

The framework provide a facility to create an asymetric
key that will serve all the above purposes (it currently
doesn't).

Using its favorite environment, the developer
produces applications for the target.

Depending on its constraints either economic,
technical or human, the developer chooses the language
and the environment for developing the applications.

This step needs to test and to debug the application on
a target or on a simulator of the target.
In both cases, the code should be lively inspected and
changed, as well as the permissions and the security
aspects.

The framework will provide facilities for debugging
(it currently doesn't).

#### Packaging applications

Currently the framework expects widgets packaged as
specified by [Packaged Web Apps](http://www.w3.org/TR/widgets).

When the application is ready, the developer
creates a package for it. The creation of the package
is made of few steps:

- isolate the strict necessarily files and structure it
  to be children of only one root directory
- sign the application with the developer key
- sign the application with its application key
- pack the application using zip

The framework will provide facilities to package applications.

Parts of the job can be done with tools provided by afm-main:

- ***wgtpkg-sign*** is used to add signatures at root of the package
- ***wgtpkg-pack*** is used to create the package file (with wgt extension).

Currently, the ***config.xml*** file must be edited by hand.
See below [Writing the config.xml](#writing-config).

#### Distributing applications

Normally a store will distribute the application.
It will be the normal process. The distributor adds
a signature to the distributed application.

The added signature can allow more or less permission to
applications. For example, a critical application nested
in the system should have high level permissions allowing
it to do things that should normally not be done (changing
system configuration for example).
To allow such application, the distributor must sign
it using its secret private key that will unlock the
requested level of permissions.

Currently, the framework allows to make these steps manually
using ***unzip***, ***wgtpkg-sign*** and ***wgtpkg-pack*** utilities.

Applications of the store will then be available
for browsing and searching over HTTP/Internet.

#### Installing applications

The framework will provide an API for downloading and
installing an application from stores (it currently doesn't).

The current version of afm allows to install widgets
from local files (either pre-installed or downloaded).

To install a widget, you can use either the program
***wgtpkg-installer*** while being the framework user.

TO BE CONTINUED

#### Launching application

TO BE CONTINUED


## Writing the config.xml <a id="writing-config"/>

TO BE CONTINUED

For permissions: ***urn:agl:perm:...***

For plugins: ***urn:agl:plugin:...***


## Cryptography

The widgets are currently signed and checked using the library
[XMLSec](https://www.aleksey.com/xmlsec).

The current state isn't providing our keys.
Will be done soon.

TO BE CONTINUED

## Extension to the packaging specifications

The widgets are specified in that W3C recommendation:
[Packaged Web Apps](http://www.w3.org/TR/widgets).
This model was initially designed for HTML applications.
But it is well suited for other kind of applications.

It relies on this specification that is the master
piece of interest and the most useful part:
[XML Digital Signatures for Widgets](http://www.w3.org/TR/widgets-digsig).

An other specification exist that isn't either mature
nor suited for managing privileges:
[Web App Manifest](http://www.w3.org/TR/appmanifest).
However, it may become of actuallity in some future.

The main idea is to use the file ***config.xml*** as a switch
for several constants.
The current specifications for ***config.xml*** are allowing
to describe either HTML5, QML and native applications.
Using *feature*, it is also possible to define uses of
libraries.

For more advanced uses like:

- incremental updates
- multiple application packages
- system updates

The file ***config.xml*** may:

- either, contain a root different that *widget*
- or, not exist, being replaced with something else.

## Comparison with Tizen framework

This package is providing few less behaviour than
the following Tizen packages:

- 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



## Links

- [Packaged Web Apps](http://www.w3.org/TR/widgets)
- [XML Digital Signatures for Widgets](http://www.w3.org/TR/widgets-digsig)
- [libxml2](http://xmlsoft.org/html/index.html)
- [OpenSSL](https://www.openssl.org)
- [XMLSec](https://www.aleksey.com/xmlsec)
- [JSON-c](https://github.com/json-c/json-c)
- [D-Bus](http://www.freedesktop.org/wiki/Software/dbus)
- [libzip](http://www.nih.at/libzip)
- [CMake](https://cmake.org)
- [Security-Manager](https://wiki.tizen.org/wiki/Security/Tizen_3.X_Security_Manager)
- [Web App Manifest](http://www.w3.org/TR/appmanifest)
ey; GVariant *subValue; const gchar *pInterface; GList *list; pInterface = g_dbus_proxy_get_interface_name (proxy); if (0 != g_strcmp0(pInterface, LIGHTMEDIASCANNER_INTERFACE)) return; g_variant_iter_init (&iter, changed_properties); while (g_variant_iter_next (&iter, "{&sv}", &key, &subValue)) { gboolean val; if (0 == g_strcmp0(key,"IsScanning")) { g_variant_get(subValue, "b", &val); if (val == TRUE) return; } else if (0 == g_strcmp0(key, "WriteLocked")) { g_variant_get(subValue, "b", &val); if (val == TRUE) return; } } ListLock(); list = media_lightmediascanner_scan(); if (list != NULL && g_RegisterCallback.binding_device_added) g_RegisterCallback.binding_device_added(list); ListUnlock(); } static int MediaPlayerDBusInit(void) { GError *error = NULL; MediaPlayerManage.lms_proxy = scanner1_proxy_new_for_bus_sync( G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, LIGHTMEDIASCANNER_SERVICE, LIGHTMEDIASCANNER_PATH, NULL, &error); if (MediaPlayerManage.lms_proxy == NULL) { LOGE("Create LightMediaScanner Proxy failed\n"); return -1; } g_signal_connect (MediaPlayerManage.lms_proxy, "g-properties-changed", G_CALLBACK (on_interface_proxy_properties_changed), NULL); return 0; } static void *media_event_loop_thread(void *unused) { GMainLoop *loop = g_main_loop_new(NULL, FALSE); int ret; ret = MediaPlayerDBusInit(); if (ret == 0) { LOGD("g_main_loop_run\n"); g_main_loop_run(loop); } g_main_loop_unref(loop); return NULL; } void unmount_cb (GFileMonitor *mon, GFile *file, GFile *other_file, GFileMonitorEvent event, gpointer udata) { gchar *path = g_file_get_path(file); gchar *uri = g_strconcat("file://", path, NULL); g_free(path); ListLock(); if (g_RegisterCallback.binding_device_removed && event == G_FILE_MONITOR_EVENT_DELETED) { g_RegisterCallback.binding_device_removed(uri); } ListUnlock(); g_free(uri); } /* * Create MediaPlayer Manager Thread * Note: mediaplayer-api should do MediaPlayerManagerInit() before any other * API calls * Returns: 0 - success or error conditions */ int MediaPlayerManagerInit() { pthread_t thread_id; GFile *file; GFileMonitor *mon; g_mutex_init(&(MediaPlayerManage.m)); file = g_file_new_for_path("/media"); g_assert(file != NULL); mon = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); g_assert(mon != NULL); g_signal_connect (mon, "changed", G_CALLBACK(unmount_cb), NULL); pthread_create(&thread_id, NULL, media_event_loop_thread, NULL); return 0; } /* * Register MediaPlayer Manager Callback functions */ void BindingAPIRegister(const Binding_RegisterCallback_t* pstRegisterCallback) { if (NULL != pstRegisterCallback) { if (NULL != pstRegisterCallback->binding_device_added) { g_RegisterCallback.binding_device_added = pstRegisterCallback->binding_device_added; } if (NULL != pstRegisterCallback->binding_device_removed) { g_RegisterCallback.binding_device_removed = pstRegisterCallback->binding_device_removed; } } }