Литмир - Электронная Библиотека
Содержание  
A
A

 92  memcpy(keyext + 1, keydata, keybits / 8);

 93  len += keyext->sadb_key_len * 8;

 94  p += keyext->sadb_key_len * 8;

 95  msg->sadb_msg_len = len / 8;

 96  printf("Sending add message:\n");

 97  print_sadb_msg(buf, len);

 98  Write(s, buf, len);

 99  printf("\nReply returned:\n");

100  /* считывание и вывод ответа SADB_ADD, игнорируя любые другие */

101  for (;;) {

102   int msglen;

103   struct sadb_msg *msgp;

104   msglen = Read(s, &buf, sizeof(buf));

105   msgp = (struct sadb_msg*)&buf;

106   if (msgp->sadb_msg_pid == mypid &&

107    msgp->sadb_msg_type == SADB_ADD) {

108    print_sadb_msg(msgp, msglen);

109    break;

110   }

111  }

112  close(s);

113 }

Открытие сокета PF_KEY и сохранение PID

55-56
 Как и в предыдущей программе, мы открываем сокет PF_KEY и сохраняем идентификатор нашего процесса для последующего его использования.

Формирование общего заголовка сообщений

47-56
 Мы формируем заголовок сообщения
SADB_ADD
. Поле
sadb_msg_len
устанавливается непосредственно перед отправкой сообщения, поскольку оно должно соответствовать истинной его длине. В переменной
len
хранится текущая длина сообщения, а указатель р всегда указывает на первый неиспользуемый байт буфера.

Добавление расширения SA

57-67
 Мы добавляем обязательное расширение
SA
(см. листинг 19.3). Поле
sadb_sa_spi
должно иметь сетевой порядок байтов, поэтому нам приходится применять функцию
htonl
к значению в порядке байтов узла. Мы отключаем защиту от повторов и устанавливаем состояние
SA
равным
SADB_SASTATE_MATURE
(см. табл. 19.4). Алгоритм аутентификации выбирается в соответствии с аргументом командной строки, а шифрование отключается при помощи константы
SADB_EALG_NONE
.

Добавление адреса отправителя

68-76
 К сообщению добавляется расширение
SADB_EXT_ADDRESS_SRC
, содержащее адрес отправителя для соглашения о безопасности.

Значение протокола устанавливается равным нулю, что подразумевает действительность соглашения для всех протоколов. Длина префикса устанавливается равной соответствующей длине версии IP (то есть 32 разряда для IPv4 и 128 разрядов для IPv6). При расчете значения поля длины мы добавляем к реальному значению число 7 перед делением на 8, что гарантирует выравнивание по 64-разрядной границе, обязательное для всех расширений, передаваемых через сокеты PF_KEY. Структура

sockaddr
копируется в буфер после заголовка расширения.

Добавление адреса получателя

77-85
 Адрес получателя добавляется в сообщение
SADB_EXT_ADDRESS_DST
. Процедура в точности совпадает с описанной выше.

Добавление ключа

86-94
 К сообщению добавляется расширение
SADB_EXT_KEY_AUTH
, содержащее ключ авторизации. Расчет поля длины производится точно так же, как и для обоих адресов. Ключ переменной длины требует соответствующего количества дополняющих нулей. Мы устанавливаем значение количества битов и копируем ключ вслед за заголовком расширения.

Запись сообщения в сокет

95-98
 Мы выводим сообщение на экран вызовом функции
print_sadb_msg
, после чего записываем его в сокет.

Считывание ответа

99-111
 Мы считываем все сообщения из сокета до тех пор, пока не будет получено сообщение, адресованное нашему процессу (проверяется по PID) и имеющее тип
SADB_ADD
. Это сообщение выводится на экран функций
print_sadb_msg
, после чего программа завершает работу.

Пример

Мы запускаем программу, требуя от нее установки соглашения о безопасности, касающегося трафика между узлами 127.0.0.1 и 127.0.0.1 (то есть локального трафика):

macosx % <b>add 127.0.0.1 127.0.0.1 HMAC-SHA-1-96 160 \</b>

<b> 0123456789abcdef0123456789abcdef01234567</b>

Sending add message:

SADB Message Add, errno 0, satype IPsec AH, seq 0, pid 6246

SA: SPI=39030 Replay Window=0 State=Mature

Authentication Algorithm: HMAC-SHA-1

Encryption Algorithm: None

Source address: 127.0.0.1/32

Dest address: 127.0.0.1/32

Authentication key. 160 bits: 0x0123456789abcdef0123456789abcdef01234567

Reply returned:

SADB Message Add, errno 0, satype IPsec AH, seq 0, pid 6246

SA: SPI=39030 Replay Window=0 State=Mature

Authentication Algorithm: HMAC-SHA-1

Encryption Algorithm: None

Source address: 127.0.0.1/32

Dest address: 127.0.0.1/32

Обратите внимание, что в ответе системы отсутствует ключ. Дело в том; что ответ направляется на все сокеты PF_KEY, которые, однако, могут принадлежать к разным доменам, а данные о ключах не должны передаваться между доменами. После добавления записи в базу данных мы даем команду

ping 127.0.0.1
, чтобы проверить, задействуется ли соглашение о безопасности, после чего запрашиваем дамп базы данных и смотрим, что в ней изменилось.

macosx % <b>dump</b>

216
{"b":"225366","o":1}