Beispiel #1
0
ikspak *
iks_packet (iks *x)
{
	ikspak *pak;
	ikstack *s;
	char *tmp;

	s = iks_stack (x);
	pak = iks_stack_alloc (s, sizeof (ikspak));
	if (!pak) return NULL;
	memset (pak, 0, sizeof (ikspak));
	pak->x = x;
	tmp = iks_find_attrib (x, "from");
	if (tmp) pak->from = iks_id_new (s, tmp);
	pak->id = iks_find_attrib (x, "id");

	tmp = iks_find_attrib (x, "type");
	if (strcmp (iks_name (x), "message") == 0) {
		pak->type = IKS_PAK_MESSAGE;
		if (tmp) {
			if (strcmp (tmp, "chat") == 0)
				pak->subtype = IKS_TYPE_CHAT;
			else if (strcmp (tmp, "groupchat") == 0)
				pak->subtype = IKS_TYPE_GROUPCHAT;
			else if (strcmp (tmp, "headline") == 0)
				pak->subtype = IKS_TYPE_HEADLINE;
			else if (strcmp (tmp, "error") == 0)
				pak->subtype = IKS_TYPE_ERROR;
		}
	} else if (strcmp (iks_name (x), "presence") == 0) {
		pak->type = IKS_PAK_S10N;
		if (tmp) {
			if (strcmp (tmp, "unavailable") == 0) {
				pak->type = IKS_PAK_PRESENCE;
				pak->subtype = IKS_TYPE_UNAVAILABLE;
				pak->show = IKS_SHOW_UNAVAILABLE;
			} else if (strcmp (tmp, "probe") == 0) {
				pak->type = IKS_PAK_PRESENCE;
				pak->subtype = IKS_TYPE_PROBE;
			} else if(strcmp(tmp, "subscribe") == 0)
				pak->subtype = IKS_TYPE_SUBSCRIBE;
			else if(strcmp(tmp, "subscribed") == 0)
				pak->subtype = IKS_TYPE_SUBSCRIBED;
			else if(strcmp(tmp, "unsubscribe") == 0)
				pak->subtype = IKS_TYPE_UNSUBSCRIBE;
			else if(strcmp(tmp, "unsubscribed") == 0)
				pak->subtype = IKS_TYPE_UNSUBSCRIBED;
			else if(strcmp(tmp, "error") == 0)
				pak->subtype = IKS_TYPE_ERROR;
		} else {
			pak->type = IKS_PAK_PRESENCE;
			pak->subtype = IKS_TYPE_AVAILABLE;
			tmp = iks_find_cdata (x, "show");
			pak->show = IKS_SHOW_AVAILABLE;
			if (tmp) {
				if (strcmp (tmp, "chat") == 0)
					pak->show = IKS_SHOW_CHAT;
				else if (strcmp (tmp, "away") == 0)
					pak->show = IKS_SHOW_AWAY;
				else if (strcmp (tmp, "xa") == 0)
					pak->show = IKS_SHOW_XA;
				else if (strcmp (tmp, "dnd") == 0)
					pak->show = IKS_SHOW_DND;
			}
		}
	} else if (strcmp (iks_name (x), "iq") == 0) {
		iks *q;
		pak->type = IKS_PAK_IQ;
		if (tmp) {
			if (strcmp (tmp, "get") == 0)
				pak->subtype = IKS_TYPE_GET;
			else if (strcmp (tmp, "set") == 0)
				pak->subtype = IKS_TYPE_SET;
			else if (strcmp (tmp, "result") == 0)
				pak->subtype = IKS_TYPE_RESULT;
			else if (strcmp (tmp, "error") == 0)
				pak->subtype = IKS_TYPE_ERROR;
		}
		for (q = iks_child (x); q; q = iks_next (q)) {
			if (IKS_TAG == iks_type (q)) {
				char *ns;
				ns = iks_find_attrib (q, "xmlns");
				if (ns) {
					pak->query = q;
					pak->ns = ns;
					break;
				}
			}
		}
	}
	return pak;
}
Beispiel #2
0
// 客户端解析服务器响应的协商包,从协商包中解析出临时密钥,并使用自己的私钥进行解密
// 服务器端解析客户端发来的协商包,并填充服务器包解析器
int pkg_talk_parse(packet_parser_t *pkg, const char* xml)
{
	iks *x, *e, *c;
	int result=0;
	int dest_len;

	if(NULL==xml) return NULL_ERROR;

	x =	iks_tree (xml, 0, &result);
	if(!x) return NULL_ERROR;
	if(result != IKS_OK)
	{
		iks_delete(x);
		return IKS_BADXML;
	}

	if(0 == iks_strcmp("connection",iks_name(x)))
	{
		char* tmp = NULL;
		char *tempkey;
		char *output;

		tmp = iks_find_attrib(x, "type");
		if(NULL != tmp){
			if(strcmp(tmp, "create")==0)
				set_talk_type(1, pkg); //说明为服务端
			else
				set_talk_type(0, pkg); //说明为客户端
		}

		if(1 == pkg->talk_type)
		{
			//说明本端为服务端
			tmp = iks_find_cdata(x, "client-id");
			set_client_id(tmp, pkg);

			tmp = iks_find_cdata(x, "public-key");
			if(SUCCESS != set_talk_crt_public_key(tmp, pkg))
				return SET_TALK_CRT_KEY_ERROR;

			tmp = iks_find_attrib(iks_find(x,"public-key"), "type");
			if(SUCCESS != set_talk_crt_type(tmp, pkg))
				return SET_TALK_CRT_TYPE_ERROR;

			e = iks_find(x,"encryption");
			while( e ){
				tmp = iks_find_cdata(e, "allow");
				if(SUCCESS == set_transfer_crt_type(tmp, pkg)) break;
				e = iks_next(e);
			}
			// 服务器端设置传输数据使用的临时密钥
			set_transfer_crt_key(TRANSFERKEY, pkg);

			c = iks_find(x,"compression");
			while( c ){
				tmp = iks_find_cdata(c, "allow");
				if(SUCCESS == set_cps_type(tmp, pkg)) break;
				c = iks_next(c);
			}
		}
		else if(0 == pkg->talk_type)
		{
			// 说明本端为客户端
			tempkey = iks_find_cdata(x,"encryption");
			output = (char *)calloc(strlen(tempkey)/2+1, 1);
			hex2byte(tempkey, strlen(tempkey), (unsigned char *)output);
			if (pkg->asym_encrypt_hook == NULL)
			{
				tempkey = (char *)rsa_encrypt((unsigned char *)output, strlen(tempkey)/2, &dest_len, pkg->curr_ert.ert_keys[1], CRYPT_TYPE_DECRYPT);
			}
			else
			{
				tempkey = (char *)pkg->asym_encrypt_hook((unsigned char *)output, strlen(tempkey)/2, &dest_len, pkg->curr_ert.ert_keys[1], CRYPT_TYPE_DECRYPT);
			}
			free(output);
			// 比较服务器端响应的压缩加密方式与客户端请求的是否相同
			if( SUCCESS != set_transfer_crt_key(tempkey, pkg))
				return SET_TRANSFER_ERT_KEY_ERROR;
			free(tempkey);
			if( SUCCESS != cmp_transfer_crt_type(iks_find_attrib(iks_find(x, "encryption"), "type"), pkg) )
				return CMP_TRANSFER_CRT_TYPE_ERROR;
			if( SUCCESS != cmp_cps_type(iks_find_cdata(x, "compression"), pkg) )
				return CMP_CPS_TYPE_ERROR;
			set_heatbeat("client", iks_find_attrib(iks_find(x, "heartbeat"), "seconds"), pkg);
		}	
	} 
	
	//iks_parser_delete (p);
	iks_delete(x);
	return SUCCESS;
}