flow-based security configuration

To demonstrate a security configuration based on the flow policy family, the following files are required:

security.cfg – security configuration

The security configuration in this example allows you to run all entities, and any entity, to call the core and server entities. Calls to server entity methods are controlled using flow family policies (finite-state machine model).

The finite-state machine described in the request_state instance configuration has two states: ping_next and pong_next. The initial state is ping_next. Only transitions from ping_next to pong_next and the reverse are allowed.

When the Ping and Pong methods are called, the current state of the request_state instance is checked. In the ping_next state, only a Ping call is allowed, in which case the state changes to pong_next. Likewise, in the pong_next state, only a Pong call is allowed, in which case the state changes to ping_next.

Therefore, the Ping and Pong methods can be called only in succession.

security.cfg

/* Security configuration for demonstrating the use of the "flow" family in the "ping" example. */

/* Define execute interface. */

execute = execute.execute;

/* Import file with declaration of basic security policies. */

#include <kss/server/base.cfg>

/* Import file with declaration of "flow" family policies. */

#include <kss/server/flow.cfg>

/* Create instance of "flow" family. New instance name: request_state. */

use family request_state = flow {

states : [ping_next, pong_next], /* multiple states */

initial : ping_next, /* initial state */

transitions : { /* table of permissible transitions between states */

ping_next : [pong_next],

pong_next : [ping_next]

}

};

/* Sending and receiving requests is allowed. */

request { grant; }

/* Sending and receiving responses is allowed. */

response { grant; }

/* Startup of entities is allowed. */

execute { grant; }

/* Declaration of entities. */

entity services.core;

entity einit;

entity client;

entity server;

/* The kernel is allowed to send queries via the security interface. */

security src=services.core { grant; }

/* When the server entity is started, switch the request_state to its initial state. */

execute dst=server {

request_state.restart;

}

/* When the Ping method is called, verify that the "request_state" instance has a "ping_next" state.

If it does, allow the call to the Ping method and transition the "request_state" instance into the "pong_next" state. */

request dst=server, endpoint=ping_comp.ping_impl, method=Ping {

request_state.allow [ping_next];

request_state.enter pong_next;

}

/* When the Pong method is called, verify that the "request_state" instance has a "pong_next" state.

If it does, allow the call to the Pong method and transition the "request_state" instance into the "ping_next" state. */

request dst=server, endpoint=ping_comp.ping_impl, method=Pong {

request_state.allow [pong_next];

request_state.enter ping_next;

}

test.c: implementation of the test() function

In the test() function, the Ping and Pong methods are called in different sequences:

  1. The Ping and Pong alternate in a loop.
  2. Ping method 2 times consecutively.
  3. Pong method 2 times consecutively.

test.c

#include <stdint.h>

#include "ping.idl.h"

void test(struct IPing *proxy)

{

uint32_t value;

int i;

/* Implementation of the ping() and ping() functions is in the client.c file. */

uint32_t ping(struct IPing *proxy, uint32_t value);

uint32_t pong(struct IPing *proxy, uint32_t value);

value = 0;

/* Call the Ping and Pong methods in succession (allowed). */

for (i = 0; i < 5; ++i)

{

value = ping(proxy, value);

value = pong(proxy, value);

}

/* Call the Ping method two times consecutively (not allowed). */

value = ping(proxy, value);

value = ping(proxy, value); // "Failed to call IPing.Ping” will be printed to stderr

/* Call the Pong method two times consecutively (not allowed). */

value = pong(proxy, value);

value = pong(proxy, value); // "Failed to call IPing.Pong" will be printed to stderr

}

Page top