tst-resolv-network.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /* Test getnetbyname and getnetbyaddr.
  2. Copyright (C) 2016-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <netdb.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <support/check.h>
  19. #include <support/check_nss.h>
  20. #include <support/resolv_test.h>
  21. #include <support/support.h>
  22. #include <support/xmemstream.h>
  23. static void
  24. send_ptr (struct resolv_response_builder *b,
  25. const char *qname, uint16_t qclass, uint16_t qtype,
  26. const char *alias)
  27. {
  28. resolv_response_init (b, (struct resolv_response_flags) {});
  29. resolv_response_add_question (b, qname, qclass, qtype);
  30. resolv_response_section (b, ns_s_an);
  31. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  32. resolv_response_add_name (b, alias);
  33. resolv_response_close_record (b);
  34. }
  35. static void
  36. handle_code (const struct resolv_response_context *ctx,
  37. struct resolv_response_builder *b,
  38. const char *qname, uint16_t qclass, uint16_t qtype,
  39. int code)
  40. {
  41. switch (code)
  42. {
  43. case 1:
  44. send_ptr (b, qname, qclass, qtype, "1.in-addr.arpa");
  45. break;
  46. case 2:
  47. send_ptr (b, qname, qclass, qtype, "2.1.in-addr.arpa");
  48. break;
  49. case 3:
  50. send_ptr (b, qname, qclass, qtype, "3.2.1.in-addr.arpa");
  51. break;
  52. case 4:
  53. send_ptr (b, qname, qclass, qtype, "4.3.2.1.in-addr.arpa");
  54. break;
  55. case 5:
  56. /* Test multiple PTR records. */
  57. resolv_response_init (b, (struct resolv_response_flags) {});
  58. resolv_response_add_question (b, qname, qclass, qtype);
  59. resolv_response_section (b, ns_s_an);
  60. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  61. resolv_response_add_name (b, "127.in-addr.arpa");
  62. resolv_response_close_record (b);
  63. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  64. resolv_response_add_name (b, "0.in-addr.arpa");
  65. resolv_response_close_record (b);
  66. break;
  67. case 6:
  68. /* Test skipping of RRSIG record. */
  69. resolv_response_init (b, (struct resolv_response_flags) { });
  70. resolv_response_add_question (b, qname, qclass, qtype);
  71. resolv_response_section (b, ns_s_an);
  72. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  73. resolv_response_add_name (b, "127.in-addr.arpa");
  74. resolv_response_close_record (b);
  75. resolv_response_open_record (b, qname, qclass, 46 /* RRSIG */, 0);
  76. {
  77. char buf[500];
  78. memset (buf, 0x3f, sizeof (buf));
  79. resolv_response_add_data (b, buf, sizeof (buf));
  80. }
  81. resolv_response_close_record (b);
  82. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  83. resolv_response_add_name (b, "0.in-addr.arpa");
  84. resolv_response_close_record (b);
  85. break;
  86. case 7:
  87. /* Test CNAME handling. */
  88. resolv_response_init (b, (struct resolv_response_flags) { });
  89. resolv_response_add_question (b, qname, qclass, qtype);
  90. resolv_response_section (b, ns_s_an);
  91. resolv_response_open_record (b, qname, qclass, T_CNAME, 0);
  92. resolv_response_add_name (b, "cname.example");
  93. resolv_response_close_record (b);
  94. resolv_response_open_record (b, "cname.example", qclass, T_PTR, 0);
  95. resolv_response_add_name (b, "4.3.2.1.in-addr.arpa");
  96. resolv_response_close_record (b);
  97. break;
  98. case 100:
  99. resolv_response_init (b, (struct resolv_response_flags) { .rcode = 0, });
  100. resolv_response_add_question (b, qname, qclass, qtype);
  101. break;
  102. case 101:
  103. resolv_response_init (b, (struct resolv_response_flags)
  104. { .rcode = NXDOMAIN, });
  105. resolv_response_add_question (b, qname, qclass, qtype);
  106. break;
  107. case 102:
  108. resolv_response_init (b, (struct resolv_response_flags) {.rcode = SERVFAIL});
  109. resolv_response_add_question (b, qname, qclass, qtype);
  110. break;
  111. case 103:
  112. /* Check response length matching. */
  113. if (!ctx->tcp)
  114. {
  115. resolv_response_init (b, (struct resolv_response_flags) {.tc = true});
  116. resolv_response_add_question (b, qname, qclass, qtype);
  117. }
  118. else
  119. {
  120. resolv_response_init (b, (struct resolv_response_flags) {.ancount = 1});
  121. resolv_response_add_question (b, qname, qclass, qtype);
  122. resolv_response_section (b, ns_s_an);
  123. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  124. resolv_response_add_name (b, "127.in-addr.arpa");
  125. resolv_response_close_record (b);
  126. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  127. resolv_response_add_name (b, "example");
  128. resolv_response_close_record (b);
  129. resolv_response_open_record (b, qname, qclass, T_PTR, 0);
  130. size_t to_fill = 65535 - resolv_response_length (b)
  131. - 2 /* length, "n" */ - 2 /* compression reference */
  132. - 2 /* RR type */;
  133. for (size_t i = 0; i < to_fill; ++i)
  134. resolv_response_add_data (b, "", 1);
  135. resolv_response_close_record (b);
  136. resolv_response_add_name (b, "n.example");
  137. uint16_t rrtype = htons (T_PTR);
  138. resolv_response_add_data (b, &rrtype, sizeof (rrtype));
  139. }
  140. break;
  141. case 104:
  142. send_ptr (b, qname, qclass, qtype, "host.example");
  143. break;
  144. default:
  145. FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code);
  146. }
  147. }
  148. static void
  149. response (const struct resolv_response_context *ctx,
  150. struct resolv_response_builder *b,
  151. const char *qname, uint16_t qclass, uint16_t qtype)
  152. {
  153. int code;
  154. if (strstr (qname, "in-addr.arpa") == NULL)
  155. {
  156. char *tail;
  157. if (sscanf (qname, "code%d.%ms", &code, &tail) != 2
  158. || strcmp (tail, "example") != 0)
  159. FAIL_EXIT1 ("invalid QNAME: %s", qname);
  160. free (tail);
  161. handle_code (ctx, b, qname, qclass, qtype, code);
  162. }
  163. else
  164. {
  165. /* Reverse lookup. */
  166. int components[4];
  167. char *tail;
  168. if (sscanf (qname, "%d.%d.%d.%d.%ms",
  169. components, components + 1, components + 2, components + 3,
  170. &tail) != 5
  171. || strcmp (tail, "in-addr.arpa") != 0)
  172. FAIL_EXIT1 ("invalid QNAME: %s", qname);
  173. free (tail);
  174. handle_code (ctx, b, qname, qclass, qtype, components[3]);
  175. }
  176. }
  177. static void
  178. check_reverse (int code, const char *expected)
  179. {
  180. char *query = xasprintf ("code=%d", code);
  181. check_netent (query, getnetbyaddr (code, AF_INET), expected);
  182. free (query);
  183. }
  184. /* Test for CVE-2016-3075. */
  185. static void
  186. check_long_name (void)
  187. {
  188. struct xmemstream mem;
  189. xopen_memstream (&mem);
  190. char label[65];
  191. memset (label, 'x', 63);
  192. label[63] = '.';
  193. label[64] = '\0';
  194. for (unsigned i = 0; i < 64 * 1024 * 1024 / strlen (label); ++i)
  195. fprintf (mem.out, "%s", label);
  196. xfclose_memstream (&mem);
  197. check_netent ("long name", getnetbyname (mem.buffer),
  198. "error: NO_RECOVERY\n");
  199. free (mem.buffer);
  200. }
  201. static int
  202. do_test (void)
  203. {
  204. struct resolv_test *obj = resolv_test_start
  205. ((struct resolv_redirect_config)
  206. {
  207. .response_callback = response
  208. });
  209. /* Lookup by name, success cases. */
  210. check_netent ("code1.example", getnetbyname ("code1.example"),
  211. "alias: 1.in-addr.arpa\n"
  212. "net: 0x00000001\n");
  213. check_netent ("code2.example", getnetbyname ("code2.example"),
  214. "alias: 2.1.in-addr.arpa\n"
  215. "net: 0x00000102\n");
  216. check_netent ("code3.example", getnetbyname ("code3.example"),
  217. "alias: 3.2.1.in-addr.arpa\n"
  218. "net: 0x00010203\n");
  219. check_netent ("code4.example", getnetbyname ("code4.example"),
  220. "alias: 4.3.2.1.in-addr.arpa\n"
  221. "net: 0x01020304\n");
  222. check_netent ("code5.example", getnetbyname ("code5.example"),
  223. "alias: 127.in-addr.arpa\n"
  224. "alias: 0.in-addr.arpa\n"
  225. "net: 0x0000007f\n");
  226. check_netent ("code6.example", getnetbyname ("code6.example"),
  227. "alias: 127.in-addr.arpa\n"
  228. "alias: 0.in-addr.arpa\n"
  229. "net: 0x0000007f\n");
  230. check_netent ("code7.example", getnetbyname ("code7.example"),
  231. "alias: 4.3.2.1.in-addr.arpa\n"
  232. "net: 0x01020304\n");
  233. /* Lookup by name, failure cases. */
  234. check_netent ("code100.example", getnetbyname ("code100.example"),
  235. "error: NO_ADDRESS\n");
  236. check_netent ("code101.example", getnetbyname ("code101.example"),
  237. "error: HOST_NOT_FOUND\n");
  238. check_netent ("code102.example", getnetbyname ("code102.example"),
  239. "error: TRY_AGAIN\n");
  240. check_netent ("code103.example", getnetbyname ("code103.example"),
  241. "error: NO_RECOVERY\n");
  242. /* Test bug #17630. */
  243. check_netent ("code104.example", getnetbyname ("code104.example"),
  244. "error: TRY_AGAIN\n");
  245. /* Lookup by address, success cases. */
  246. check_reverse (1,
  247. "name: 1.in-addr.arpa\n"
  248. "net: 0x00000001\n");
  249. check_reverse (2,
  250. "name: 2.1.in-addr.arpa\n"
  251. "net: 0x00000002\n");
  252. check_reverse (3,
  253. "name: 3.2.1.in-addr.arpa\n"
  254. "net: 0x00000003\n");
  255. check_reverse (4,
  256. "name: 4.3.2.1.in-addr.arpa\n"
  257. "net: 0x00000004\n");
  258. check_reverse (5,
  259. "name: 127.in-addr.arpa\n"
  260. "alias: 0.in-addr.arpa\n"
  261. "net: 0x00000005\n");
  262. check_reverse (6,
  263. "name: 127.in-addr.arpa\n"
  264. "alias: 0.in-addr.arpa\n"
  265. "net: 0x00000006\n");
  266. check_reverse (7,
  267. "name: 4.3.2.1.in-addr.arpa\n"
  268. "net: 0x00000007\n");
  269. /* Lookup by address, failure cases. */
  270. check_reverse (100,
  271. "error: NO_ADDRESS\n");
  272. check_reverse (101,
  273. "error: HOST_NOT_FOUND\n");
  274. check_reverse (102,
  275. "error: TRY_AGAIN\n");
  276. check_reverse (103,
  277. "error: NO_RECOVERY\n");
  278. check_long_name ();
  279. resolv_test_end (obj);
  280. return 0;
  281. }
  282. #include <support/test-driver.c>