Конфигурация безопасности на базе flow

Для демонстрации конфигурации безопасности на базе семейства политик flow потребуются следующие файлы:

security.cfg – конфигурация безопасности

Конфигурация безопасности в этом примере разрешает запуск всех сущностей и позволяет любой сущности обращаться к сущностям core и server. При этом вызовы методов сущности server контролируются с помощью политик семейства flow (модель конечного автомата).

Конечный автомат, описанный в конфигурации экземпляра request_state, имеет два состояния: ping_next и pong_next. Исходное состояние – ping_next. Разрешены только переходы из ping_next в pong_next и обратно.

При вызове методов Ping и Pong проверяется текущее состояние экземпляра request_state. В состоянии ping_next разрешен только вызов Ping, при этом состояние изменится на pong_next. Аналогично, в состоянии pong_next разрешен только вызов Pong, при этом состояние изменится на ping_next.

Таким образом, методы Ping и Pong разрешено вызывать только по очереди.

security.cfg

/* Конфигурация безопасности для демонстрации использования семейства "flow" в примере "ping". */

/* Определение execute-интерфейса. */

execute = execute.execute;

/* Импорт файла с объявлением базовых политик безопасности. */

#include <kss/server/base.cfg>

/* Импорт файла с объявлением политик семейства "flow". */

#include <kss/server/flow.cfg>

/* Создание экземпляра семейства "flow". Имя нового экземпляра: request_state. */

use family request_state = flow {

states : [ping_next, pong_next], /* множество состояний */

initial : ping_next, /* начальное состояние */

transitions : { /* таблица допустимых переходов между состояниями */

ping_next : [pong_next],

pong_next : [ping_next]

}

};

/* Отправка и получение запросов разрешены. */

request { grant; }

/* Отправка и получение ответов разрешены. */

response { grant; }

/* Запуск сущностей разрешен. */

execute { grant; }

/* Объявление сущностей. */

entity services.core;

entity einit;

entity client;

entity server;

/* Ядру разрешены обращения по интерфейсу безопасности. */

security src=services.core { grant; }

/* При запуске сущности "server" перевести request_state в начальное состояние. */

execute dst=server {

request_state.restart;

}

/* При вызове метода Ping проверить, что экземпляр "request_state" находится в состоянии "ping_next".

Если это так, разрешить вызов метода Ping и перевести экземпляр "request_state" в состояние "pong_next". */

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

request_state.allow [ping_next];

request_state.enter pong_next;

}

/* При вызове метода Pong проверить, что экземпляр "request_state" находится в состоянии "pong_next".

Если это так, разрешить вызов метода Pong и перевести экземпляр "request_state" в состояние "ping_next". */

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

request_state.allow [pong_next];

request_state.enter ping_next;

}

test.c – реализация функции test()

В функции test() выполняются вызовы методов Ping и Pong в различных последовательностях:

  1. Методы Ping и Pong поочередно в цикле.
  2. Метод Ping 2 раза подряд.
  3. Метод Pong 2 раза подряд.

test.c

#include <stdint.h>

#include "ping.idl.h"

void test(struct IPing *proxy)

{

uint32_t value;

int i;

/* Реализация функций ping() и ping() содержится в файле client.c. */

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

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

value = 0;

/* Вызываем методы Ping и Pong по очереди (разрешено). */

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

{

value = ping(proxy, value);

value = pong(proxy, value);

}

/* Вызываем метод Ping два раза подряд (не разрешено). */

value = ping(proxy, value);

value = ping(proxy, value); // В stderr будет выведено "Failed to call IPing.Ping"

/* Вызываем метод Pong два раза подряд (не разрешено). */

value = pong(proxy, value);

value = pong(proxy, value); // В stderr будет выведено "Failed to call IPing.Pong"

}

В начало