static int init_rules(const char *path) { int rc = -1; FILE *fp; char line[LINE_SIZE]; if ((fp = fopen(path, "r")) == NULL) { (void) fprintf(stderr, "%s: %s (%d)\n", path, strerror(errno), errno); goto error0; } pattern_path = path; listInit(&pattern_rules); while (fgets(line, sizeof (line), fp) != NULL) { /* Ignore all lines except those starting with a pattern. */ if (*line == '/') { if (init_rule(line)) goto error1; } } rc = 0; error1: (void) fclose(fp); error0: return rc; }
int init_acl(const char *path) { // initialize ipset ipset_init_library(); ipset_init(&white_list_ipv4); ipset_init(&white_list_ipv6); ipset_init(&black_list_ipv4); ipset_init(&black_list_ipv6); ipset_init(&outbound_block_list_ipv4); ipset_init(&outbound_block_list_ipv6); cork_dllist_init(&black_list_rules); cork_dllist_init(&white_list_rules); cork_dllist_init(&outbound_block_list_rules); struct ip_set *list_ipv4 = &black_list_ipv4; struct ip_set *list_ipv6 = &black_list_ipv6; struct cork_dllist *rules = &black_list_rules; FILE *f = fopen(path, "r"); if (f == NULL) { LOGE("Invalid acl path."); return -1; } char buf[257]; while (!feof(f)) if (fgets(buf, 256, f)) { // Trim the newline int len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') { buf[len - 1] = '\0'; } char *comment = strchr(buf, '#'); if (comment) { *comment = '\0'; } char *line = trimwhitespace(buf); if (strlen(line) == 0) { continue; } if (strcmp(line, "[outbound_block_list]") == 0) { list_ipv4 = &outbound_block_list_ipv4; list_ipv6 = &outbound_block_list_ipv6; rules = &outbound_block_list_rules; continue; } else if (strcmp(line, "[black_list]") == 0 || strcmp(line, "[bypass_list]") == 0) { list_ipv4 = &black_list_ipv4; list_ipv6 = &black_list_ipv6; rules = &black_list_rules; continue; } else if (strcmp(line, "[white_list]") == 0 || strcmp(line, "[proxy_list]") == 0) { list_ipv4 = &white_list_ipv4; list_ipv6 = &white_list_ipv6; rules = &white_list_rules; continue; } else if (strcmp(line, "[reject_all]") == 0 || strcmp(line, "[bypass_all]") == 0) { acl_mode = WHITE_LIST; continue; } else if (strcmp(line, "[accept_all]") == 0 || strcmp(line, "[proxy_all]") == 0) { acl_mode = BLACK_LIST; continue; } else if (strcmp(line, "[remote_dns]") == 0) { continue; } char host[257]; int cidr; parse_addr_cidr(line, host, &cidr); struct cork_ip addr; int err = cork_ip_init(&addr, host); if (!err) { if (addr.version == 4) { if (cidr >= 0) { ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr); } else { ipset_ipv4_add(list_ipv4, &(addr.ip.v4)); } } else if (addr.version == 6) { if (cidr >= 0) { ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr); } else { ipset_ipv6_add(list_ipv6, &(addr.ip.v6)); } } } else { rule_t *rule = new_rule(); accept_rule_arg(rule, line); init_rule(rule); add_rule(rules, rule); } } fclose(f); return 0; }