| |
| #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 |
| } |
| |
| |
| |