日期:2014-05-16 浏览次数:20426 次
基于openswan klips的IPsec VPN实现分析(六)SADB操作
转载请注明出处:http://blog.csdn.net/rosetta
这里的操作是指由openswan的密钥管理守护进程pluto对于内核SADB的操作。如下来至rfc2367的密钥关联程序和PF_KEY的关系图。
+----------------+ |密钥管理守护进程| +----------------+ | | | | | | 应用程序 ======[PF_KEY]====[PF_INET]========================== | | 系统内核 +------------+ +-----------------+ | 密钥引擎 | | TCP/IP | | 或者 |---| 包括 | | SADB | | IPsec | +------------+ +-----------------+ | +----------+ | 网络接口 | +----------+ 图1:密钥关联程序和PF_KEY的关系
pluto第二阶段协商成功收尾时,在发起方的quick_inR1_outI2()函数里调用install_ipsec_sa()增加SA。
增加SA函数调用过程:
quick_inR1_outI2(), install_ipsec_sa(),setup_half_ipsec_sa(),kernel_ops->add_sa()(kernel_ops的成员赋值在《应用层和内核通信》一节讲,klips的add_sa指向的函数是pfkey_add_sa())。
删除SA函数调用过程:
在删除隧道或者SA过期等情况下调用相关删除函数,delete_ipsec_sa(),del_spi(),kernel_ops->del_sa()。
如果存在多个SA的情况下,归组SA,即放到SA结构体数组中:
setup_half_ipsec_sa(),kernel_ops->grp_sa()。
传说中的安全联盟SA概貌如斯:
struct kernel_sa {
const ip_address *src; //源地址
const ip_address *dst; //目的地址
const ip_subnet *src_client;//源保护子网
const ip_subnet *dst_client;//目的保护子网
ipsec_spi_t spi; //spi
unsigned proto; //安全协议
unsigned satype; //安全联盟类型,比如ESP,AH,IPIP,IPCOMP等
unsigned replay_window;//重放窗口
unsigned reqid; //请求ID
unsigned authalg; //认证算法
unsigned authkeylen; //认证算法密钥长度
char *authkey; //认证密钥
unsigned encalg; //加密算法
unsigned enckeylen; //加密算法密钥长度
char *enckey; //加密密钥
int encapsulation;//封装
const char *text_said;
};
应用层构造SADB发送给内核,构造过程看似复杂,其实它只利用了一个指针数组做为中间buf,然后把此buf中的数据拷到pfkey_msg中,最后把pfkey_msg通过write pfkeyfd套接字把消息传给内核,最后释放指针和空间。
static bool pfkey_add_sa(const structkernel_sa *sa, bool replace)
{
struct sadb_ext *extensions[SADB_EXT_MAX + 1]; //构造SADB临时使用的指针数组。
boolsuccess = FALSE;
//构造消息头结构体structsadb_msg信息。
s