blacklist.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Blacklist Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include "blacklist.h"
  9. #include <errno.h>
  10. #include <stdio.h>
  11. #include <assert.h>
  12. #include <stdint.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <arpa/inet.h>
  18. #include <netdb.h>
  19. #include "constraint.h"
  20. #include "logger.h"
  21. #include "xalloc.h"
  22. #define ADDR_DISALLOWED 0
  23. #define ADDR_ALLOWED 1
  24. typedef struct bl_linked_list {
  25. bl_cidr_node_t *first;
  26. bl_cidr_node_t *last;
  27. uint32_t len;
  28. } bl_ll_t;
  29. static constraint_t *constraint = NULL;
  30. // keep track of the prefixes we've tried to BL/WL
  31. // for logging purposes
  32. static bl_ll_t *blacklisted_cidrs = NULL;
  33. static bl_ll_t *whitelisted_cidrs = NULL;
  34. void bl_ll_add(bl_ll_t *l, struct in_addr addr, uint16_t p)
  35. {
  36. assert(l);
  37. bl_cidr_node_t *new = xmalloc(sizeof(bl_cidr_node_t));
  38. new->next = NULL;
  39. new->ip_address = addr.s_addr;
  40. new->prefix_len = p;
  41. if (!l->first) {
  42. l->first = new;
  43. } else {
  44. l->last->next = new;
  45. }
  46. l->last = new;
  47. l->len++;
  48. }
  49. bl_cidr_node_t *get_blacklisted_cidrs(void)
  50. {
  51. return blacklisted_cidrs->first;
  52. }
  53. bl_cidr_node_t *get_whitelisted_cidrs(void)
  54. {
  55. return whitelisted_cidrs->first;
  56. }
  57. uint32_t blacklist_lookup_index(uint64_t index) {
  58. return ntohl(constraint_lookup_index(constraint, index, ADDR_ALLOWED));
  59. }
  60. // check whether a single IP address is allowed to be scanned.
  61. // 1 => is allowed
  62. // 0 => is not allowed
  63. int blacklist_is_allowed(uint32_t s_addr) {
  64. return constraint_lookup_ip(constraint, ntohl(s_addr)) == ADDR_ALLOWED;
  65. }
  66. static void _add_constraint(struct in_addr addr, int prefix_len, int value)
  67. {
  68. constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value);
  69. if (value == ADDR_ALLOWED) {
  70. bl_ll_add(whitelisted_cidrs, addr, prefix_len);
  71. } else if (value == ADDR_DISALLOWED) {
  72. bl_ll_add(blacklisted_cidrs, addr, prefix_len);
  73. } else {
  74. log_fatal("blacklist", "unknown type of blacklist operation specified");
  75. }
  76. }
  77. // blacklist a CIDR network allocation
  78. // e.g. blacklist_add("128.255.134.0", 24)
  79. void blacklist_prefix(char *ip, int prefix_len)
  80. {
  81. struct in_addr addr;
  82. addr.s_addr = inet_addr(ip);
  83. _add_constraint(addr, prefix_len, ADDR_DISALLOWED);
  84. }
  85. // whitelist a CIDR network allocation
  86. void whitelist_prefix(char *ip, int prefix_len)
  87. {
  88. struct in_addr addr;
  89. addr.s_addr = inet_addr(ip);
  90. _add_constraint(addr, prefix_len, ADDR_ALLOWED);
  91. }
  92. static int init_from_string(char *ip, int value)
  93. {
  94. int prefix_len = 32;
  95. char *slash = strchr(ip, '/');
  96. if (slash) { // split apart network and prefix length
  97. *slash = '\0';
  98. char *end;
  99. char *len = slash+1;
  100. errno = 0;
  101. prefix_len = strtol(len, &end, 10);
  102. if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) {
  103. log_fatal("constraint", "'%s' is not a valid prefix length", len);
  104. return -1;
  105. }
  106. }
  107. struct in_addr addr;
  108. int ret = -1;
  109. if (inet_aton(ip, &addr) == 0) {
  110. // Not an IP and not a CIDR block, try dns resolution
  111. struct addrinfo hint, *res;
  112. memset(&hint, 0, sizeof(hint));
  113. hint.ai_family = PF_INET;
  114. int r = getaddrinfo(ip, NULL, &hint, &res);
  115. if (r) {
  116. log_error("constraint", "'%s' is not a valid IP "
  117. "address or hostname", ip);
  118. return -1;
  119. }
  120. // Got some addrinfo, let's see what happens
  121. for (struct addrinfo *aip = res; aip; aip = aip->ai_next) {
  122. if (aip->ai_family != AF_INET) {
  123. continue;
  124. }
  125. struct sockaddr_in *sa = (struct sockaddr_in *) aip->ai_addr;
  126. memcpy(&addr, &sa->sin_addr, sizeof(addr));
  127. log_debug("constraint", "%s retrieved by hostname",
  128. inet_ntoa(addr));
  129. ret = 0;
  130. _add_constraint(addr, prefix_len, value);
  131. }
  132. } else {
  133. _add_constraint(addr, prefix_len, value);
  134. return 0;
  135. }
  136. return ret;
  137. }
  138. static int init_from_file(char *file, const char *name, int value, int ignore_invalid_hosts)
  139. {
  140. FILE *fp;
  141. char line[1000];
  142. fp = fopen(file, "r");
  143. if (fp == NULL) {
  144. log_fatal(name, "unable to open %s file: %s: %s",
  145. name, file, strerror(errno));
  146. }
  147. while (fgets(line, sizeof(line), fp) != NULL) {
  148. char *comment = strchr(line, '#');
  149. if (comment) {
  150. *comment = '\0';
  151. }
  152. char ip[33];
  153. if ((sscanf(line, "%32s", ip)) == EOF) {
  154. continue;
  155. }
  156. if (init_from_string(ip, value)) {
  157. if (!ignore_invalid_hosts) {
  158. log_fatal(name, "unable to parse %s file: %s",
  159. name, file);
  160. }
  161. }
  162. }
  163. fclose(fp);
  164. return 0;
  165. }
  166. static void init_from_array(char **cidrs, size_t len, int value, int ignore_invalid_hosts)
  167. {
  168. for (int i=0; i < (int) len; i++) {
  169. int ret = init_from_string(cidrs[i], value);
  170. if (ret && !ignore_invalid_hosts) {
  171. log_fatal("constraint",
  172. "Unable to init from CIDR list");
  173. }
  174. }
  175. }
  176. uint64_t blacklist_count_allowed()
  177. {
  178. assert(constraint);
  179. return constraint_count_ips(constraint, ADDR_ALLOWED);
  180. }
  181. uint64_t blacklist_count_not_allowed()
  182. {
  183. assert(constraint);
  184. return constraint_count_ips(constraint, ADDR_DISALLOWED);
  185. }
  186. // Initialize address constraints from whitelist and blacklist files.
  187. // Either can be set to NULL to omit.
  188. int blacklist_init(char *whitelist_filename, char *blacklist_filename,
  189. char **whitelist_entries, size_t whitelist_entries_len,
  190. char **blacklist_entries, size_t blacklist_entries_len,
  191. int ignore_invalid_hosts)
  192. {
  193. assert(!constraint);
  194. blacklisted_cidrs = xcalloc(1, sizeof(bl_ll_t));
  195. whitelisted_cidrs = xcalloc(1, sizeof(bl_ll_t));
  196. if (whitelist_filename && whitelist_entries) {
  197. log_warn("whitelist", "both a whitelist file and destination addresses "
  198. "were specified. The union of these two sources "
  199. "will be utilized.");
  200. }
  201. if (whitelist_filename || whitelist_entries) {
  202. // using a whitelist, so default to allowing nothing
  203. constraint = constraint_init(ADDR_DISALLOWED);
  204. log_debug("constraint", "blacklisting 0.0.0.0/0");
  205. if (whitelist_filename) {
  206. init_from_file(whitelist_filename, "whitelist", ADDR_ALLOWED,
  207. ignore_invalid_hosts);
  208. }
  209. if (whitelist_entries) {
  210. init_from_array(whitelist_entries,
  211. whitelist_entries_len, ADDR_ALLOWED,
  212. ignore_invalid_hosts);
  213. }
  214. } else {
  215. // no whitelist, so default to allowing everything
  216. constraint = constraint_init(ADDR_ALLOWED);
  217. }
  218. if (blacklist_filename) {
  219. init_from_file(blacklist_filename, "blacklist",
  220. ADDR_DISALLOWED, ignore_invalid_hosts);
  221. }
  222. if (blacklist_entries) {
  223. init_from_array(blacklist_entries,
  224. blacklist_entries_len, ADDR_DISALLOWED,
  225. ignore_invalid_hosts);
  226. }
  227. init_from_string(strdup("0.0.0.0"), ADDR_DISALLOWED);
  228. constraint_paint_value(constraint, ADDR_ALLOWED);
  229. uint64_t allowed = blacklist_count_allowed();
  230. log_debug("constraint", "%lu addresses (%0.0f%% of address "
  231. "space) can be scanned",
  232. allowed, allowed*100./((long long int)1 << 32));
  233. if (!allowed) {
  234. log_error("blacklist", "no addresses are eligible to be scanned in the "
  235. "current configuration. This may be because the "
  236. "blacklist being used by ZMap (%s) prevents "
  237. "any addresses from receiving probe packets.",
  238. blacklist_filename
  239. );
  240. return EXIT_FAILURE;
  241. }
  242. return EXIT_SUCCESS;
  243. }