Для демонстрации конфигурации безопасности на базе семейства политик flow потребуются следующие файлы:
security.cfg – конфигурация безопасности на базе семейства flow;test.c – реализация функции test(), которая будет вызвана сущностью client.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 в различных последовательностях:
Ping и Pong поочередно в цикле.Ping 2 раза подряд.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"
}
В начало