|  | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 | #include <ctype.h> | 
 | #include <unistd.h> | 
 | #include <errno.h> | 
 | #include <netdb.h> | 
 | #include <fcntl.h> | 
 | #include <dirent.h> | 
 | #include <time.h> | 
 | #include <linux/capability.h> | 
 | #include <sys/capability.h> | 
 | #include <cutils/properties.h> | 
 | #include "setkey_fileio.h" | 
 | #include "utils_xfrm.h" | 
 | #include "setkey_xfrm_parse.h" | 
 | #define LOG_TAG "setkey" | 
 | #include <log/log.h> | 
 | #include <cutils/log.h> | 
 |  | 
 |  | 
 | const struct typeent xfrmproto_types[]= { | 
 | 	{ "esp", IPPROTO_ESP }, { "ah", IPPROTO_AH }, { "comp", IPPROTO_COMP }, | 
 | 	{ "route2", IPPROTO_ROUTING }, { "hao", IPPROTO_DSTOPTS }, | 
 | 	{ "ipsec-any", IPSEC_PROTO_ANY }, | 
 | 	{ NULL, -1 } | 
 | }; | 
 |  | 
 |  | 
 | int xfrm_xfrmproto_getbyname(char *name) | 
 | { | 
 | 	int i; | 
 |  | 
 | 	for (i = 0; ; i++) { | 
 | 		const struct typeent *t = &xfrmproto_types[i]; | 
 | 		if (!t->t_name || t->t_type == -1) | 
 | 			break; | 
 |  | 
 | 		if (strcmp(t->t_name, name) == 0) | 
 | 			return t->t_type; | 
 | 	} | 
 |  | 
 | 	return -1; | 
 | } | 
 |  | 
 |  | 
 | int xfrm_id_parse(xfrm_address_t *saddr_xfrm, struct xfrm_id *id, __u16 *family, | 
 | 		 char * src,char * dst,char * ipsec_type) | 
 | { | 
 |  | 
 | 	inet_prefix dst_prefix; | 
 | 	inet_prefix src_prefix; | 
 |  | 
 | 	memset(&dst_prefix, 0, sizeof(dst_prefix)); | 
 | 	memset(&src_prefix, 0, sizeof(src_prefix)); | 
 |  | 
 | 	get_prefix(&src_prefix, src, AF_UNSPEC); | 
 | 	if (family) | 
 | 		*family = src_prefix.family; | 
 | 	memcpy(saddr_xfrm, &src_prefix.data, sizeof(*saddr_xfrm)); | 
 | 	get_prefix(&dst_prefix, dst, AF_UNSPEC); | 
 | 	memcpy(&id->daddr, &dst_prefix.data, sizeof(id->daddr)); | 
 |  | 
 | 	int ret = xfrm_xfrmproto_getbyname(ipsec_type); | 
 | 	if(ret<0) | 
 | 	{ | 
 | 		ALOGD("xfrm_id_parse %s is wrong\n",ipsec_type); | 
 | 		return -1; | 
 | 	} | 
 | 	id->proto = (__u8)ret; | 
 |  | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | void xfrm_encry_algo_parse(char * encry_src, char *name) | 
 | { | 
 | 	if(encry_src == NULL) | 
 | 		memcpy(name,"ecb(cipher_null)",strlen("ecb(cipher_null)")); | 
 | 	else 	if(strcmp(encry_src,"des-cbc")==0) | 
 | 		memcpy(name,"cbc(des)",strlen("cbc(des)")); | 
 | 	else 	if(strcmp(encry_src,"des-ede3-cbc")==0) | 
 | 		memcpy(name,"cbc(des3_ede)",strlen("cbc(des3_ede)")); | 
 | 	else 	if(strcmp(encry_src,"3des-cbc")==0) | 
 | 		memcpy(name,"cbc(des3_ede)",strlen("cbc(des3_ede)")); | 
 | 	else 	if(strcmp(encry_src,"cast5-cbc")==0) | 
 | 		memcpy(name,"cbc(cast5)",strlen("cbc(cast5)")); | 
 | 	else 	if(strcmp(encry_src,"blowfish-cbc")==0) | 
 | 		memcpy(name,"cbc(blowfish)",strlen("cbc(blowfish)")); | 
 | 	else 	if(strcmp(encry_src,"aes-cbc")==0) | 
 | 		memcpy(name,"cbc(aes)",strlen("cbc(aes)")); | 
 | 	else 	if(strcmp(encry_src,"serpent-cbc")==0) | 
 | 		memcpy(name,"cbc(serpent)",strlen("cbc(serpent)")); | 
 | 	else 	if(strcmp(encry_src,"camellia-cbc")==0) | 
 | 		memcpy(name,"cbc(camellia)",strlen("cbc(camellia)")); | 
 | 	else 	if(strcmp(encry_src,"twofish-cbc")==0) | 
 | 		memcpy(name,"cbc(twofish)",strlen("cbc(twofish)")); | 
 | 	else 	if(strcmp(encry_src,"aes-ctr-rfc3686")==0) | 
 | 		memcpy(name,"rfc3686(ctr(aes))",strlen("rfc3686(ctr(aes))")); | 
 | 	else    if(strcmp(encry_src,"null")==0) | 
 | 		memcpy(name,"ecb(cipher_null)",strlen("ecb(cipher_null)")); | 
 | 	else | 
 | 	{ | 
 | 		memcpy(name,"not-supported",strlen("not-supported")); | 
 | 		ALOGD("xfrm_encry_algo_parse not supported algorithm--%s\n",encry_src); | 
 | 	} | 
 | } | 
 |  | 
 | void xfrm_interg_algo_parse(char * interg_src, char *name) | 
 | { | 
 | 	if(interg_src == NULL) | 
 | 		memcpy(name,"digest_null",strlen("digest_null")); | 
 | 	else 	if(strcmp(interg_src,"hmac-md5")==0) | 
 | 		memcpy(name,"hmac(md5)",strlen("hmac(md5)")); | 
 | 	else 	if(strcmp(interg_src,"hmac-sha1")==0) | 
 | 		memcpy(name,"hmac(sha1)",strlen("hmac(sha1)")); | 
 | 	else 	if(strcmp(interg_src,"hmac-sha256")==0) | 
 | 		memcpy(name,"hmac(sha256)",strlen("hmac(sha256)")); | 
 | 	else 	if(strcmp(interg_src,"hmac-sha384)")==0) | 
 | 		memcpy(name,"hmac(sha384)",strlen("hmac(sha384)")); | 
 | 	else 	if(strcmp(interg_src,"hmac-sha512")==0) | 
 | 		memcpy(name,"hmac(sha512)",strlen("hmac(sha512)")); | 
 | 	else 	if(strcmp(interg_src,"hmac-rmd160")==0) | 
 | 		memcpy(name,"hmac(rmd160)",strlen("hmac(rmd160)")); | 
 | 	else 	if(strcmp(interg_src,"aes-xcbc")==0) | 
 | 		memcpy(name,"xcbc(aes)",strlen("xcbc(aes)")); | 
 | 	else 	if(strcmp(interg_src,"cmac(aes)")==0) | 
 | 		memcpy(name,"aes-cmac",strlen("aes-cmac")); | 
 | 	else 	if(strcmp(interg_src,"null")==0) | 
 | 		memcpy(name,"digest_null",strlen("digest_null")); | 
 | 	else | 
 | 	{ | 
 | 		memcpy(name,"not-supported",strlen("not-supported")); | 
 | 		ALOGD("xfrm_interg_algo_parse not supported algorithm--%s\n",interg_src); | 
 | 	} | 
 | } | 
 |  | 
 |  | 
 | int xfrm_algo_parse(struct xfrm_algo *alg, char *name, char *key, char *buf, int max) | 
 | { | 
 | 	int len; | 
 | 	int slen = strlen(key); | 
 |  | 
 | 	strncpy(alg->alg_name, name, sizeof(alg->alg_name)); | 
 |  | 
 | 	if (slen > 2 && strncmp(key, "0x", 2) == 0) { | 
 | 		/* split two chars "0x" from the top */ | 
 | 		char *p = key + 2; | 
 | 		int plen = slen - 2; | 
 | 		int i; | 
 | 		int j; | 
 |  | 
 | 		/* Converting hexadecimal numbered string into real key; | 
 | 		 * Convert each two chars into one char(value). If number | 
 | 		 * of the length is odd, add zero on the top for rounding. | 
 | 		 */ | 
 |  | 
 | 		/* calculate length of the converted values(real key) */ | 
 | 		len = (plen + 1) / 2; | 
 | 		if (len > max) | 
 | 		{ | 
 | 			ALOGD("xfrm_algo_parse key(len:%d) makes buffer overflow\n",len); | 
 | 			return -1; | 
 | 		} | 
 |  | 
 | 		for (i = - (plen % 2), j = 0; j < len; i += 2, j++) { | 
 | 			char vbuf[3]; | 
 | 			__u8 val; | 
 |  | 
 | 			vbuf[0] = i >= 0 ? p[i] : '0'; | 
 | 			vbuf[1] = p[i + 1]; | 
 | 			vbuf[2] = '\0'; | 
 |  | 
 | 			if (get_u8(&val, vbuf, 16)) | 
 | 			{ | 
 | 				ALOGD("xfrm_algo_parse key(len:%s) is invalid\n",key); | 
 | 				return -1; | 
 | 			} | 
 | 			buf[j] = val; | 
 | 		} | 
 | 	} else { | 
 | 		len = slen; | 
 | 		if (len > 0) { | 
 | 			if (len > max) | 
 | 			{ | 
 | 				ALOGD("xfrm_algo_parse key(len:%d) makes buffer overflow\n",len); | 
 | 				return -1; | 
 | 			} | 
 |  | 
 | 			strncpy(buf, key, len); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	alg->alg_key_len = len * 8; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | __u8 xfrm_dir_parse(char * dir_str) | 
 | { | 
 | 	__u8 dir; | 
 | 	if(strcmp(dir_str,"out")==0) | 
 | 		dir = XFRM_POLICY_OUT; | 
 | 	else if(strcmp(dir_str,"in")==0) | 
 | 		dir = XFRM_POLICY_IN; | 
 | 	else if(strcmp(dir_str,"fwd")==0) | 
 | 		dir = XFRM_POLICY_FWD; | 
 | 	else | 
 | 		dir = XFRM_POLICY_ERROR; | 
 | 	return dir; | 
 | } | 
 |  | 
 | int xfrm_mode_parse(__u8 *mode, char * mode_str) | 
 | { | 
 |  | 
 |  | 
 | 	if (strcmp(mode_str, "transport") == 0) | 
 | 		*mode = XFRM_MODE_TRANSPORT; | 
 | 	else if (strcmp(mode_str, "tunnel") == 0) | 
 | 		*mode = XFRM_MODE_TUNNEL; | 
 | 	else if (strcmp(mode_str, "ro") == 0) | 
 | 		*mode = XFRM_MODE_ROUTEOPTIMIZATION; | 
 | 	else if (strcmp(mode_str, "in_trigger") == 0) | 
 | 		*mode = XFRM_MODE_IN_TRIGGER; | 
 | 	else if (strcmp(mode_str, "beet") == 0) | 
 | 		*mode = XFRM_MODE_BEET; | 
 | 	else | 
 | 		return -1; | 
 |  | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | void xfrm_selector_parse(struct xfrm_selector *sel, char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port) | 
 | { | 
 |  | 
 | 	inet_prefix dst_prefix; | 
 | 	inet_prefix src_prefix; | 
 |  | 
 | 	memset(&dst_prefix, 0, sizeof(dst_prefix)); | 
 | 	memset(&src_prefix, 0, sizeof(src_prefix)); | 
 |  | 
 |  | 
 | 	get_prefix(&src_prefix, src, AF_UNSPEC); | 
 | 	memcpy(&sel->saddr, &src_prefix.data, sizeof(sel->saddr)); | 
 | 	sel->prefixlen_s = src_prefix.bitlen; | 
 |  | 
 | 	get_prefix(&dst_prefix, dst, AF_UNSPEC); | 
 | 	memcpy(&sel->daddr, &dst_prefix.data, sizeof(sel->daddr)); | 
 | 	sel->prefixlen_d = dst_prefix.bitlen; | 
 |  | 
 | 	sel->family = dst_prefix.family; | 
 |  | 
 | 	sel->sport = htons(atoi(src_port)); | 
 | 	sel->dport = htons(atoi(dst_port)); | 
 | 	sel->dport_mask = ~((__u16)0); | 
 | 	sel->sport_mask = ~((__u16)0); | 
 |  | 
 | 	sel->user = getpid(); | 
 |  | 
 | 	sel->proto = protocol; | 
 | #ifdef INIT_ENG_BUILD | 
 | 	if(sel->family == AF_INET) | 
 | 	ALOGD("xfrm_selector_parse family:%u,prefix_d:%u,prefix_s:%u,daddr:0x%x,saddr:0x%x,sel->sport:%d,sel->dport:%d,proto:%u,user:%u\n",sel->family,sel->prefixlen_d,sel->prefixlen_s,sel->daddr.a4,sel->daddr.a4,sel->sport,sel->dport,sel->proto,sel->user); | 
 | 	else | 
 | 	ALOGD("xfrm_selector_parse family:%u,prefix_d:%u,prefix_s:%u,daddr:0x%x %x %x %x,saddr:0x%x %x %x %x ,sel->sport:%d,sel->dport:%d,proto:%u,user:%u\n",sel->family,sel->prefixlen_d,sel->prefixlen_s,sel->daddr.a6[0],sel->daddr.a6[1],sel->daddr.a6[2],sel->daddr.a6[3],sel->saddr.a6[0],sel->saddr.a6[1],sel->saddr.a6[2],sel->saddr.a6[3],sel->sport,sel->dport,sel->proto,sel->user); | 
 | #endif | 
 | } | 
 |  | 
 |  | 
 |  |