Книга: UNIX: разработка сетевых приложений
19.3. Дамп базы соглашений о безопасности
Разделы на этой странице:
19.3. Дамп базы соглашений о безопасности
Для дампа текущей базы соглашений о безопасности используется сообщение SADB_DUMP
. Это самое простое из сообщений, поскольку оно не требует никаких расширений, а состоит только из 16-байтового заголовка sadb_msg
. Когда процесс отправляет сообщение SADB_DUMP
ядру через сокет управления ключами, ядро отвечает последовательностью сообщений SADB_DUMP
по тому же сокету. В каждом сообщении содержится одна запись базы SADB. Конец последовательности обозначается сообщением со значением 0 в поле sadb_msg_seq
.
Поле sadb_msg_satype
позволяет запросить только записи определенного типа. Значения этого поля следует брать из табл. 19.2. При указании значения SADB_SATYPE_UNSPEC
возвращаются все записи базы. Не все типы соглашений о безопасности поддерживаются всеми реализациями. Реализация KAME поддерживает только соглашения, относящиеся к IPSec (SADB_SATYPE_AH
и SADB_SATYPE_ESP
), поэтому при попытке получить дамп записей SADB_SATYPE_RIPV2
будет возвращена ошибка EINVAL
. Если же записей, относящихся к запрошенному типу, в таблице нет (но они поддерживаются), функция возвращает ошибку ENOENT
.
Программа, получающая записи из базы данных безопасности, приведена в листинге 19.2.
Листинг 19.2. Дамп базы соглашений о безопасности
//key/dump.c
1 void
2 sadb_dump(int type)
3 {
4 int s;
5 char buf[4096];
6 struct sadb_msg msg;
7 int goteof;
8 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
9 /* формирование и отправка запроса SADB_DUMP */
10 bzero(&msg, sizeof(msg));
11 msg.sadb_msg_version = PF_KEY_V2;
12 msg.sadb_msg_type = SADB_DUMP;
13 msg.sadb_msg_satype = type;
14 msg.sadb_msg_len = sizeof(msg) / 8;
15 msg.sadb_msg_pid = getpid();
16 printf("Sending dump message:n");
17 print_sadb_msg(&msg, sizeof(msg));
18 Write(s, &msg, sizeof(msg));
19 printf("nMessages returned:n");
20 /* считывание и вывод всех ответов SADB_DUMP */
21 goteof = 0;
22 while (goteof == 0) {
23 int msglen;
24 struct sadb_msg *msgp;
25 msglen = Read(s, &buf, sizeof(buf));
26 msgp = (struct sadb_msg*)&buf;
27 print_sadb_msg(msgp, msglen);
28 if (msgp->sadb_msg_seq == 0)
29 goteof = 1;
30 }
31 close(s);
32 }
33 int
34 main(int argc, char **argv)
35 {
36 int satype = SADB_SATYPE_UNSPEC;
37 int c;
38 opterr = 0; /* отключение записи в stderr для getopt() */
39 while ((c = getopt(argc, argv, "t:")) != -1) {
40 switch (c) {
41 case 't':
42 if ((satype = getsatypebyname(optarg)) == -1)
43 err_quit("invalid -t option %s", optarg);
44 break;
45 default:
46 err_quit("unrecognized option: %c", c);
47 }
48 }
49 sadb_dump(satype);
50 }
В этом листинге мы впервые встречаемся с функцией getopt
, определяемой стандартом POSIX. Третий аргумент представляет собой строку символов, которые могут быть приняты в качестве аргументов командной строки: в нашем случае только t
. За символом следует двоеточие, означающее, что за ключом должно быть указано численное значение. В программах, которые могут принимать несколько аргументов, эти аргументы должны объединяться. Например, в листинге 29.3 соответствующая строка имеет вид 0i:l:v
. Это означает, что ключи i
и l
сопровождаются дополнительными аргументами, а 0
и v
— не сопровождаются.
Эта функция работает с четырьмя глобальными переменными, определенными в заголовочном файле <unistd.h>
.
extern char *optarg;
extern int optind, opterr, optopt;
Перед вызовом getopt
мы устанавливаем opterr
в нуль, чтобы функция не направляла сообщений об ошибках в стандартный поток вывода этих сообщений, потому что мы хотим обрабатывать их самостоятельно. В стандарте POSIX говорится, что если первый символ третьего аргумента функции — двоеточие, то это тоже должно отключать вывод сообщений в стандартный поток сообщений об ошибках, однако не все реализации в настоящий момент выполняют данное требование.
Открытие сокета PF_KEY
1-8
Сначала мы открываем сокет PF_KEY
. Для этого требуются определенные привилегии, поскольку сокет дает доступ к управлению ключами.
Формирование запроса SADB_DUMP
9-15
Мы начинаем с обнуления структуры sadb_msg
, что позволяет нам не инициализировать поля, которые должны остаться нулевыми. Затем мы заполняем все интересующие нас поля по отдельности.
Если при открытии сокета в качестве третьего аргумента использовалась константа PF_KEY_V2
, все сообщения, направляемые в такой сокет, должны иметь версию PF_KEY_V2
. Нужный нам тип сообщения — SADB_DUMP
. Длина сообщения устанавливается равной длине заголовка без расширений, поскольку для запроса дампа расширения не нужны. Наконец, идентификатор процесса устанавливается равным идентификатору нашего процесса. Это обязательное условие для всех сообщений.
Отображение и отправка сообщения SADB_DUMP
16-18
Мы отображаем сообщение при помощи функции print_sadb_msg
. Мы не приводим листинг этой функции, потому что он достаточно длинный и не представляет особого интереса, однако он включен в набор свободно распространяемых программ, доступный для скачивания с сайта этой книги. Функция принимает сообщение, подготовленное к отправке или полученное от ядра, и выводит всю содержащуюся в этом сообщении информацию в удобной для чтения форме.
После вызова функции подготовленное сообщение записывается в сокет.
Чтение ответов
19-30
Программа считывает сообщения и выводит их в цикле при помощи функции print_sadb_msg
. Последнее сообщение последовательности имеет порядковый номер 0, что мы трактуем как «конец файла».
Закрытие сокета PF_KEY
31
Мы закрываем открытый в начале работы сокет управления ключами.
Обработка аргументов командной строки
38-48
На долю функции main
остается не так уж много работы. Программа принимает единственный аргумент — тип соглашений о безопасности, которые должны быть запрошены из базы. По умолчанию тип равен SADB_SATYPE_UNSPEC
. Указав другой тип в аргументе командной строки, пользователь может выбрать интересующие его записи. Наша программа вызывает нашу же функцию getsatypebyname
, возвращающую значение типа (константу) по его названию.
Вызов функции sadb_dump
49
Наконец, мы вызываем функцию sadb_dump
, которая уже была описана.
Пробный запуск
Ниже приведен пример выполнения программы дампа базы данных безопасности в системе с двумя статическими соглашениями о безопасности.
macosx % dump Sending dump message:
SADB Message Dump, errno 0, satype Unspecified, seq 0, pid 20623
Messages returned:
SADB Message Dump, errno 0. satype IPsec AH, seq 1, pid 20623
SA: SPI=258 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:28:11 2003, never used
Source address: 2.3.4.5/128 (IP proto 255)
Dest address: 6.7.8.9/128 (IP proto 255)
Authentication key. 128 bits: 0x20202020202020200202020202020202
SADB Message Dump, errno 0, satype IPsec AH, seq 0, pid 20623
SA: SPI=257 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:26:24 2003, never used
Source address: 1.2.3.4/128 (IP proto 255)
Dest address: 5.6.7.8/128 (IP proto 255)
Authentication key, 128 bits: 0x10101010101010100101010101010101
- Резервное копирование базы данных InterBase
- Владелец базы данных
- Перевод базы данных InterBase 6.x на 3-й диалект
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных
- Восстановление поврежденной базы данных
- Спасение данных из поврежденной базы данных
- Статистика базы данных InterBase
- Кеш базы данных
- Размер страницы базы данных
- Система безопасности InterBase