Example of use for checking permission within zephyr
The permission check extension, named PREM-CHECK is intended
to bring the permission check feature of AFB framework to clients
that are not inserted in the framework but that trust to use it
for permission checking.
So let’s explore that example.
Description of the example
An edge equipment is running a on an MCU too small to handle permission logic. That equipment is securely connected using a trusted connection to a server that can check the permissions using cynagora service.
In that example, the MCU leverages afb-zephyr items that natively integrates redpesk framework permission checking. That native permission check is compiled in a such way that instead of calling directly cynagora service it calls a redpesk API for checking the permission.
Because redpesk APIs can be distributed across machines, the effective service of permission check is done on the remote machine by querying cynagora service and by transferring the answer to the original requester.
Below figure shows that:
Zephyr (TLS)
application afb-zephyr NETWORK afb-binder afb-perm-check-ext cynagora
: : / / : : :
: 1.check perm : \ \ : : :
:---------------->: 2.perm/check / / : : :
: :---------------\ \ 2.perm/check : : :
: : / /-------------->: 3.process : :
: : \ \ :-------------->: 4.check :
: : \ \ : :--------------->:
: : / / : :<---------------:
: : / / :<--------------: :
: : \ \<--------------: :
: :<--------------/ / :
:<----------------: \ \
In detail:
-
The original query is either: (a) an automatic query resulting from the declaration of a required permission for a verb, or (b) an explicit query performed using framework API (
afb_req_check_permission) -
When the framework library afb-zephyr receives the request to check the permission, it translates the request to a call to the API
perm, VERBcheck. The API is implemented as a remote service call through a TLS connection to the service running in a binder. -
The request is received and processed by the loadable binder extension
afb-perm-check-ext. -
The extension uses
afb-libafbinternals to check the permission usingcynagora.
The remaining of this document explains four things:
-
What are redpesk permissions, how they are used and what they expect
-
Compiling the zephyr example
-
Setting up the example
-
Testing and playing with the example
Dealing with redpesk permissions
Within redpesk, checking the permissions implies that the client is trusted. When running on redpesk, the client is identified by its SMACK label that is guaranteed by Linux kernel.
When the client runs on a remote platform, it can not be trusted using SMACK
labels. Instead, the client must identify itself with a token and that token
must be validated by the permission framework cynagora. This is achieved by checking
that the permission urn:redpesk:token:valid is granted to the token used as cynagora
session. In other words, a client presenting the token TOKEN is trusted if a cynagora
rule * TOKEN * urn:redpesk:token:valid yes exists.
When the client is trusted, the permissions are checked using the same principles. When the client runs on the same redpesk OS, the SMACK label can be used. Otherwise, the token is used as a session for checking the permissions.
Compiling the zephyr example
The project afb-zephyr-samples contains sample applications for integration of redpesk framework and zephyr OS.
The example remote-io-control when compiled with CHECK_PERM defined to be 1
(see file remote-io-control/src/main.c line 63) adds feature to check the client permission
when the client calls the verb login.
Instead of using DNS, the example use a fixed IP address. That address is
controlled by the macro PREM_CHECK_IP and can be set near line 70 of
file remote-io-control/src/main.c
Compilation of the zephyr samples is described in README files. It requires the zephyr module afb-zephyr
Setting up the example
That section helps to setup: cynagora service, permission checker service, zephyr example.
Start cynagora daemon
The permission manager cynagora runs as a server. That server can be launched using command cynagorad.
The command cynagorad is provided by redpesk SDK.
It can also be compiled from sources.
In all cases, it also provides the command cynagora-admin used below.
To start it, either call cynagorad or, for dumping activity, cynagorad log on.
Add the permissions required by the demo
When cynagora service runs (cynagorad), the permissions can be added
using the admin command cynagora-admin.
cynagora-admin set '*' CANREAD '*' urn:redpesk:token:valid yes
cynagora-admin set '*' CANWRITE '*' urn:redpesk:token:valid yes
cynagora-admin set '*' CANWRITE '*' urn:redpesk:zephyr:partner:writer yes
The session serves as security token so the client identifier and the user identifier can be anything. That is the meaning of the stars. Take care that stars might be expanded by the shell to the list of files in the current directory and as such must be in quotes.
Start the permission checker service
The command afb-binder is the redpesk binder, it is provided by redpesk SDK.
The service that checks permissions is here ran in a separate instance, showing that the management of permissions can be on an instance different than the client instance.
The permission checker runs as a binder extension. It must be compiled from
the present project. It is loaded in the binder using the option --extension.
By default, it provides the API perm with the single verb check. That API is
exported in RPC on TCP port 4444 using the option --rpc-server.
afb-binder -p 3333 --extension libafb-perm-check-ext.so --rpc-server 'tcp:*:4444/perm'
Start zephyr
Once you have compiled zephyr example (see above), you should flash
it to the target board (using west flash).
Then to start zephyr, simply reset or boot the board.
Testing and playing the example
Because today, the program afb-client does not support
RPC protocol, it is needed to start a redpesk binder that
serves as relay between the command line tool afb-client
and zephyr application.
Start the relay binder, client of zephyr
The relay to zephyr application is done using the command below:
afb-binder --port 1111 --rpc-client=tcp:XXXXXX:1234/zephyr
Where XXXXXX is the IP of the board.
This command tells to export as API zephyr the API replying in RPC protocol on port 1234 of IP XXXXXX.
The binder then serves using protocol WSAPI at port 1111 and forwards to
the board at tcp:XXXXXX:1234 the calls to API zephyr.
Test and play the example
To play with the example, we use the program afb-client that connects
to the relay binder. This is done using the command below:
afb-client -t TOKEN localhost:1111/api
Where TOKEN is the security token that presents the client.
That token is used when checking permissions.
So to play the example, we should use the predefined tokens
CANREAD for being allowed to read, or CANWRITE for being
allowed to write, or any other value (like CANT) that cannot
do anything.
For example:
- without permissions:
afb-client -t CANT localhost:1111/api - can read:
afb-client -t CANREAD localhost:1111/api - can read and write:
afb-client -t CANWRITE localhost:1111/api
Then once connected, afb-client expects command inputs from the user.
The commands are of the form: api verb arg. So we will try the following
commands and see want happens:
zephyr login
zephyr state
zephyr led toggle
zephyr logoff
The verb state require to be trusted. It just needs the permission urn:redpesk:token:valid.
The verb led with the argument toggle requires to be trusted
(permission urn:redpesk:token:valid) and to have the permission
urn:redpesk:zephyr:partner:writer.
The test of permission urn:redpesk:zephyr:partner:writer is done when the user
calls login.
Exercice
The connection between zephyr application and permission checker service isn’t secured because it is done without any protection. It is not difficult to use a TLS connection instead.
How would do it using AFB settings?
Useful links:
- afb-binder manual https://docs.redpesk.bzh/docs/en/master/redpesk-os/afb-binder/afb-binder.1.html
- call-extern-api example https://github.com/redpesk-samples/afb-zephyr-samples/tree/master/call-extern-api