Поля sadb_sa_auth
и sadb_sa_encrypt
определяют алгоритмы аутентификации и шифрования для данного соглашения. Возможные значения этих полей перечислены в табл. 19.5. Единственное значение поля sadb_sa_flags
определено в POSIX как константа SADB_SAFLAGS_PFS
. Этот флаг требует совершенной безопасности пересылки ( perfect forward security ), которая состоит в том утверждении, что значение ключа не должно зависеть от предыдущих подключений или какого-либо главного ключа. Флаг используется при запросе ключей у приложения, заведующего ими, но не при создании статических соглашений.
Следующее обязательное расширение команды SADB_ADD
должно содержать адреса отправителя и получателя, задаваемые константами SADB_EXT_ADDRESS_SRC
и SADB_EXT_ADDRESS_DST
. При необходимости может быть указан адрес прокси-сервера SADB_EXT_ADDRESS_PROXY
. Подробнее об обработке адресов прокси-серверов вы можете прочесть в RFC 2367 [73]. Адреса задаются в структуре sadb_address
, представленной в листинге 19.4. Поле sadb_address_exttype
определяет тип адреса (отправителя, получателя или прокси-сервера). Поле sadb_address_proto
позволяет выбрать протокол IP или произвольный протокол (значение 0). Поле sadb_address_prefixlen
описывает значимый префикс адреса. Это позволяет использовать одно соглашение для множества адресов. За структурой sadb_address
следует структура sockaddr
соответствующего семейства (например, sockaddr_in
или sockaddr_in6
). Номер порта из структуры sockaddr
используется только в том случае, если поле sadb_address_proto
задает протокол, поддерживающий номера портов (например, IPPROTO_TCP
).
Листинг 19.4. Структура sadb_address
struct sadb_address {
u_int16_t sadb_address_len; /* длина расширения с адресом / 8 */
u_int16_t sadb_address_exttype; /* SADB_EXT_ADDRESS_{SRC,DST,PROXY} */
u_int8_t sadb_address_proto; /* протокол IP или 0 (любой) */
u_int8_t sadb_address_prefixlen; /* # значащих битов адреса */
u_int16_t sadb_address_reserved; /* зарезервирован для послед. использования */
};
/* далее следует структура sockaddr соответствующего семейства */
Завершают список обязательных расширений сообщения SADB_ADD
ключи аутентификации и шифрования — расширения SADB_EXT_KEY_AUTH
и SADB_EXT_KEY_ENCRYPT
, описываемые структурой sadb_key
(листинг 19.5). Поле sadb_key_exttype
определяет тип ключа (ключ аутентификации или шифрования), поле sadb_key_bits
задает длину ключа в битах, а сам ключ следует за структурой sadb_key
.
Листинг 19.5. Структура sadb_key
struct sadb_key {
u_int16_t sadb_key_len; /* длина расширения с ключом / 8 */
u_int16_t sadb_key_exttype; /* SADB_EXT_KEY_{AUTH,ENCRYPT} */
u_int16_t sadb_key_bits; /* # битов в ключе */
u_int16_t sadb_key_reserved; /* зарезервировано для расширения */
};
/* далее следуют данные о самом ключе */
Программа, добавляющая статическую запись в базу данных безопасности, представлена в листинге 19.6.
Листинг 19.6. Программа, использующая команду SADB_ADD
//key/add с
33 void
34 sadb_add(struct sockaddr *src, struct sockaddr *dst, int type, int alg,
35 int spi, int keybits, unsigned char *keydata)
36 {
37 int s;
38 char buf[4096], *p; /* XXX */
39 struct sadb_msg *msg;
40 struct sadb_sa *saext;
41 struct sadb_address *addrext;
42 struct sadb_key *keyext;
43 int len;
44 int mypid;
45 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
46 mypid = getpid();
47 /* Формирование и запись запроса SADB_ADD */
48 bzero(&buf, sizeof(buf));
49 p = buf;
50 msg = (struct sadb_msg*)p;
51 msg->sadb_msg_version = PF_KEY_V2;
52 msg->sadb_msg_type = SADB_ADD;
53 msg->sadb_msg_satype = type;
54 msg->sadb_msg_pid = getpid();
55 len = sizeof(*msg);
56 p += sizeof(*msg);
57 saext = (struct sadb_sa*)p;
58 saext->sadb_sa_len = sizeof(*saext) / 8;
59 saext->sadb_sa_exttype = SADB_EXT_SA;
60 saext->sadb_sa_spi = htonl(spi);
61 saext->sadb_sa_replay = 0; /* статические ключи не защищают от повтора */
62 saext->sadb_sa_state = SADB_SASTATE_MATURE;
63 saext->sadb_sa_auth = alg;
64 saext->sadb_sa_encrypt = SADB_EALG_NONE;
65 saext->sadb_sa_flags = 0;
66 len += saext->sadb_sa_len * 8;
67 p += saext->sadb_sa_len * 8;
68 addrext = (struct sadb_address*)p;
69 addrext->sadb_address_len = (sizeof(*addrext) + salen(src) + 7) / 8;
70 addrext->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
71 addrext->sadb_address_proto = 0; /* any protocol */
72 addrext->sadb_address_prefixlen = prefix_all(src);
73 addrext->sadb_address_reserved = 0;
74 memcpy(addrext + 1, src, salen(src));
75 len += addrext->sadb_address_len * 8,
76 p += addrext->sadb_address_len * 8;
77 addrext = (struct sadb_address*)p;
78 addrext->sadb_address_len = (sizeof(*addrext) + salen(dst) + 7) / 8;
79 addrext->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
Читать дальше
Конец ознакомительного отрывка
Купить книгу