系统使用netlink和木码扫描程序通信,系统使用的木马扫描程序ossec是用户态下的程序,而可信计算是内核态的,现在需要内核态象用户态程序发消息,系统使用netlink,因为netlink具有广泛的适用性,甚至可以是在中断上下文中和用户态程序通信,系统使用广播的方式向用户态程序发消息,在这里需要在内核和用户态下添加共同的netlink标记头,它的定义是在/linux-2.6.20-secos/include/linux/netlink.h目录下,定义如下:
#define NETLINK_IMA 20
定义共同的
netlink
头
NETLINK_IMA,
我们可以在程序中引用我们所定义的这个协议类型。 在用户空间,我们使用socket()函数来定义一个netlink 套接字,但是在内核空间我们下面的函数:
imanl= netlink_kernel_create(NETLINK_IMA, 1, NULL,NULL,THIS_MODULE);
if ((imanl) == NULL)
panic("IMA: Cannot create netlink socket.");
接下来就是定义发送的信息结构,系统需要发给应用程序的是度量实体的名字和它的计算指纹值,系统将它定义在一个packet_info结构体里面:
struct packet_info{
u8 name[255];
u8 digest[21];
};
定义完发送信息结构体后,最主要要实现的就是如何将内核信息发送到用户空间函数,函数定义如下:
int send_to_user(struct packet_info *info)
{
struct sk_buff *skb;
unsigned char *old_tail;
int size;
struct nlmsghdr *nlh;
struct packet_info *packet;
size=NLMSG_SPACE(sizeof(*info));
skb=alloc_skb(size, GFP_ATOMIC);//分配sk_buff结构体
old_tail=skb->tail;
nlh=NLMSG_PUT(skb, 0, 0, 1, size-sizeof(*nlh));
packet=NLMSG_DATA(nlh);
memset(packet,0,sizeof(struct packet_info));
packet->digest=info->digest;
packet->name=info->name;//将packet结构和发送结构体结合
nlh->nlmsg_len=skb->tail-old_tail;
NETLINK_CB(skb).dst_group=1;//由于是广播所以设置为1
netlink_broadcast(imanl, skb, 0, 1, GFP_ATOMIC);//具体的广播发送行为
return 0;
nlmsg_failure:
printk("erro in send netlink meassage!/n");//当发送失败
return -1;
}
具体发送到用户空间的时机就是在系统新的度量实体到来,该度量实体的内容不再可信数据库中,则需要将该度量实体的文件名和计算得到的指纹值以网络包的形式发送到用户空间,发送的具体实现如下:
if(!first_add&&!ima_lookup_tustdb_entry(new_entry->file_name)){
info=kmalloc(sizeof(struct packet_info),GFP_ATOMIC);//为发送信息结构分配空间
if(info==NULL){
printk(KERN_ALERT "erro alloc new memory for packet_info!!/n");
return ;
}
printk(KERN_ALERT "begin send to user task!/n");
memcpy(info->digest,new_entry->digest,20);
memcpy(info->name,new_entry->file_name,strlen(new_entry->file_name));//初始化发送信息结构
info->digest[20]='/0';
info->name[strlen(new_entry->file_name)]='/0';
send_to_user(info);//发送信息结构到用户空间
kfree(info);