KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Уильям Стивенс - UNIX: разработка сетевых приложений

Уильям Стивенс - UNIX: разработка сетевых приложений

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Уильям Стивенс, "UNIX: разработка сетевых приложений" бесплатно, без регистрации.
Перейти на страницу:

Таблица 19.2. Типы соглашений о безопасности

Тип соглашения Описание SADB_SATYPE_AH Аутентифицирующий заголовок IPSec SADB_SATYPE_ESP ESP IPSec SADB_SATYPE_MIP Идентификация мобильных пользователей (Mobile IP) SADB_SATYPE_OSPFV2 Аутентификация OSPFv2 SADB_SATYPE_RIPV2 Аутентификация RIPv2 SADB_SATYPE_RSVP Аутентификация RSVP SADB_SATYPE_UNSPECIFIED He определен

Таблица 19.3. Типы расширений PF_KEY

Тип заголовка расширения Описание Структура SADB_EXT_ADDRESS_DST Адрес получателя SA sadb_address SADB_EXT_ADDRESS_PROXY Адрес прокси-сервера SA sadb_address SADB_EXT_ADDRESS_SRC Адрес отправителя SA sadb_address SADB_EXT_IDENTITY_DST Личность получателя sadb_ident SADB_EXT_IDENTITY_SRC Личность отправителя sadb_ident SADB_EXT_KEY_AUTH Ключ аутентификации sadb_key SADB_EXT_KEY_ENCRYPT Ключ шифрования sadb_key SADB_EXT_LIFETIME_CURRENT Текущее время жизни SA sadb_lifetime SADB_EXT_LIFETIME_HARD Жесткое ограничение на время жизни SA sadb_lifetime SADB_EXT_LIFETIME_SOFT Гибкое ограничение на время жизни SA sadb_lifetime SADB_EXT_PROPOSAL Предлагаемая ситуация sadb_prop SADB_EXT_SA Соглашение о безопасности sadb_sa SADB_EXT_SENSITIVITY Важность SA sadb_sens SADB_EXT_SPIRANGE Диапазон допустимых значений SPI sadb_spirange SADB_EXT_SUPPORTED_AUTH Поддерживаемые алгоритмы аутентификации sadb_supported SADB_EXT_SUPPORTED_ENCRYPT Поддерживаемые алгоритмы шифрования sadb_supported

Рассмотрим несколько примеров сообщений и расширений, используемых в типичных операциях с сокетами управления ключами.

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. Мы не приводим листинг этой функции, потому что он достаточно длинный и не представляет особого интереса, однако он включен в набор свободно распространяемых программ, доступный для скачивания с сайта этой книги. Функция принимает сообщение, подготовленное к отправке или полученное от ядра, и выводит всю содержащуюся в этом сообщении информацию в удобной для чтения форме.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*