/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 498 lines · 346 code · 106 blank · 46 comment · 69 complexity · 09ce19535454d75a9dea1d2ae25d163e MD5 · raw file

  1. /*
  2. * Copyright (C) 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /* $Id$ */
  17. #ifndef RDATA_GENERIC_IPSECKEY_45_C
  18. #define RDATA_GENERIC_IPSECKEY_45_C
  19. #include <string.h>
  20. #include <isc/net.h>
  21. #define RRTYPE_IPSECKEY_ATTRIBUTES (0)
  22. static inline isc_result_t
  23. fromtext_ipseckey(ARGS_FROMTEXT) {
  24. isc_token_t token;
  25. dns_name_t name;
  26. isc_buffer_t buffer;
  27. unsigned int gateway;
  28. struct in_addr addr;
  29. unsigned char addr6[16];
  30. isc_region_t region;
  31. REQUIRE(type == 45);
  32. UNUSED(type);
  33. UNUSED(rdclass);
  34. UNUSED(callbacks);
  35. /*
  36. * Precedence.
  37. */
  38. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  39. ISC_FALSE));
  40. if (token.value.as_ulong > 0xffU)
  41. RETTOK(ISC_R_RANGE);
  42. RETERR(uint8_tobuffer(token.value.as_ulong, target));
  43. /*
  44. * Gateway type.
  45. */
  46. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  47. ISC_FALSE));
  48. if (token.value.as_ulong > 0x3U)
  49. RETTOK(ISC_R_RANGE);
  50. RETERR(uint8_tobuffer(token.value.as_ulong, target));
  51. gateway = token.value.as_ulong;
  52. /*
  53. * Algorithm.
  54. */
  55. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  56. ISC_FALSE));
  57. if (token.value.as_ulong > 0xffU)
  58. RETTOK(ISC_R_RANGE);
  59. RETERR(uint8_tobuffer(token.value.as_ulong, target));
  60. /*
  61. * Gateway.
  62. */
  63. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  64. ISC_FALSE));
  65. switch (gateway) {
  66. case 0:
  67. if (strcmp(DNS_AS_STR(token), ".") != 0)
  68. RETTOK(DNS_R_SYNTAX);
  69. break;
  70. case 1:
  71. if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
  72. RETTOK(DNS_R_BADDOTTEDQUAD);
  73. isc_buffer_availableregion(target, &region);
  74. if (region.length < 4)
  75. return (ISC_R_NOSPACE);
  76. memcpy(region.base, &addr, 4);
  77. isc_buffer_add(target, 4);
  78. break;
  79. case 2:
  80. if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1)
  81. RETTOK(DNS_R_BADAAAA);
  82. isc_buffer_availableregion(target, &region);
  83. if (region.length < 16)
  84. return (ISC_R_NOSPACE);
  85. memcpy(region.base, addr6, 16);
  86. isc_buffer_add(target, 16);
  87. break;
  88. case 3:
  89. dns_name_init(&name, NULL);
  90. buffer_fromregion(&buffer, &token.value.as_region);
  91. origin = (origin != NULL) ? origin : dns_rootname;
  92. RETTOK(dns_name_fromtext(&name, &buffer, origin,
  93. options, target));
  94. break;
  95. }
  96. /*
  97. * Public key.
  98. */
  99. return (isc_base64_tobuffer(lexer, target, -1));
  100. }
  101. static inline isc_result_t
  102. totext_ipseckey(ARGS_TOTEXT) {
  103. isc_region_t region;
  104. dns_name_t name;
  105. char buf[sizeof("255 ")];
  106. unsigned short num;
  107. unsigned short gateway;
  108. REQUIRE(rdata->type == 45);
  109. REQUIRE(rdata->length >= 3);
  110. dns_name_init(&name, NULL);
  111. if (rdata->data[1] > 3U)
  112. return (ISC_R_NOTIMPLEMENTED);
  113. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  114. RETERR(str_totext("( ", target));
  115. /*
  116. * Precedence.
  117. */
  118. dns_rdata_toregion(rdata, &region);
  119. num = uint8_fromregion(&region);
  120. isc_region_consume(&region, 1);
  121. sprintf(buf, "%u ", num);
  122. RETERR(str_totext(buf, target));
  123. /*
  124. * Gateway type.
  125. */
  126. gateway = uint8_fromregion(&region);
  127. isc_region_consume(&region, 1);
  128. sprintf(buf, "%u ", gateway);
  129. RETERR(str_totext(buf, target));
  130. /*
  131. * Algorithm.
  132. */
  133. num = uint8_fromregion(&region);
  134. isc_region_consume(&region, 1);
  135. sprintf(buf, "%u ", num);
  136. RETERR(str_totext(buf, target));
  137. /*
  138. * Gateway.
  139. */
  140. switch (gateway) {
  141. case 0:
  142. RETERR(str_totext(".", target));
  143. break;
  144. case 1:
  145. RETERR(inet_totext(AF_INET, &region, target));
  146. isc_region_consume(&region, 4);
  147. break;
  148. case 2:
  149. RETERR(inet_totext(AF_INET6, &region, target));
  150. isc_region_consume(&region, 16);
  151. break;
  152. case 3:
  153. dns_name_fromregion(&name, &region);
  154. RETERR(dns_name_totext(&name, ISC_FALSE, target));
  155. isc_region_consume(&region, name_length(&name));
  156. break;
  157. }
  158. /*
  159. * Key.
  160. */
  161. if (region.length > 0U) {
  162. RETERR(str_totext(tctx->linebreak, target));
  163. RETERR(isc_base64_totext(&region, tctx->width - 2,
  164. tctx->linebreak, target));
  165. }
  166. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  167. RETERR(str_totext(" )", target));
  168. return (ISC_R_SUCCESS);
  169. }
  170. static inline isc_result_t
  171. fromwire_ipseckey(ARGS_FROMWIRE) {
  172. dns_name_t name;
  173. isc_region_t region;
  174. REQUIRE(type == 45);
  175. UNUSED(type);
  176. UNUSED(rdclass);
  177. dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
  178. dns_name_init(&name, NULL);
  179. isc_buffer_activeregion(source, &region);
  180. if (region.length < 3)
  181. return (ISC_R_UNEXPECTEDEND);
  182. switch (region.base[1]) {
  183. case 0:
  184. isc_buffer_forward(source, region.length);
  185. return (mem_tobuffer(target, region.base, region.length));
  186. case 1:
  187. if (region.length < 7)
  188. return (ISC_R_UNEXPECTEDEND);
  189. isc_buffer_forward(source, region.length);
  190. return (mem_tobuffer(target, region.base, region.length));
  191. case 2:
  192. if (region.length < 19)
  193. return (ISC_R_UNEXPECTEDEND);
  194. isc_buffer_forward(source, region.length);
  195. return (mem_tobuffer(target, region.base, region.length));
  196. case 3:
  197. RETERR(mem_tobuffer(target, region.base, 3));
  198. isc_buffer_forward(source, 3);
  199. RETERR(dns_name_fromwire(&name, source, dctx, options, target));
  200. isc_buffer_activeregion(source, &region);
  201. isc_buffer_forward(source, region.length);
  202. return(mem_tobuffer(target, region.base, region.length));
  203. default:
  204. return (ISC_R_NOTIMPLEMENTED);
  205. }
  206. }
  207. static inline isc_result_t
  208. towire_ipseckey(ARGS_TOWIRE) {
  209. isc_region_t region;
  210. REQUIRE(rdata->type == 45);
  211. REQUIRE(rdata->length != 0);
  212. UNUSED(cctx);
  213. dns_rdata_toregion(rdata, &region);
  214. return (mem_tobuffer(target, region.base, region.length));
  215. }
  216. static inline int
  217. compare_ipseckey(ARGS_COMPARE) {
  218. isc_region_t region1;
  219. isc_region_t region2;
  220. REQUIRE(rdata1->type == rdata2->type);
  221. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  222. REQUIRE(rdata1->type == 45);
  223. REQUIRE(rdata1->length >= 3);
  224. REQUIRE(rdata2->length >= 3);
  225. dns_rdata_toregion(rdata1, &region1);
  226. dns_rdata_toregion(rdata2, &region2);
  227. return (isc_region_compare(&region1, &region2));
  228. }
  229. static inline isc_result_t
  230. fromstruct_ipseckey(ARGS_FROMSTRUCT) {
  231. dns_rdata_ipseckey_t *ipseckey = source;
  232. isc_region_t region;
  233. isc_uint32_t n;
  234. REQUIRE(type == 45);
  235. REQUIRE(source != NULL);
  236. REQUIRE(ipseckey->common.rdtype == type);
  237. REQUIRE(ipseckey->common.rdclass == rdclass);
  238. UNUSED(type);
  239. UNUSED(rdclass);
  240. if (ipseckey->gateway_type > 3U)
  241. return (ISC_R_NOTIMPLEMENTED);
  242. RETERR(uint8_tobuffer(ipseckey->precedence, target));
  243. RETERR(uint8_tobuffer(ipseckey->gateway_type, target));
  244. RETERR(uint8_tobuffer(ipseckey->algorithm, target));
  245. switch (ipseckey->gateway_type) {
  246. case 0:
  247. break;
  248. case 1:
  249. n = ntohl(ipseckey->in_addr.s_addr);
  250. RETERR(uint32_tobuffer(n, target));
  251. break;
  252. case 2:
  253. RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16));
  254. break;
  255. case 3:
  256. dns_name_toregion(&ipseckey->gateway, &region);
  257. RETERR(isc_buffer_copyregion(target, &region));
  258. break;
  259. }
  260. return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength));
  261. }
  262. static inline isc_result_t
  263. tostruct_ipseckey(ARGS_TOSTRUCT) {
  264. isc_region_t region;
  265. dns_rdata_ipseckey_t *ipseckey = target;
  266. dns_name_t name;
  267. isc_uint32_t n;
  268. REQUIRE(rdata->type == 45);
  269. REQUIRE(target != NULL);
  270. REQUIRE(rdata->length >= 3);
  271. if (rdata->data[1] > 3U)
  272. return (ISC_R_NOTIMPLEMENTED);
  273. ipseckey->common.rdclass = rdata->rdclass;
  274. ipseckey->common.rdtype = rdata->type;
  275. ISC_LINK_INIT(&ipseckey->common, link);
  276. dns_name_init(&name, NULL);
  277. dns_rdata_toregion(rdata, &region);
  278. ipseckey->precedence = uint8_fromregion(&region);
  279. isc_region_consume(&region, 1);
  280. ipseckey->gateway_type = uint8_fromregion(&region);
  281. isc_region_consume(&region, 1);
  282. ipseckey->algorithm = uint8_fromregion(&region);
  283. isc_region_consume(&region, 1);
  284. switch (ipseckey->gateway_type) {
  285. case 0:
  286. break;
  287. case 1:
  288. n = uint32_fromregion(&region);
  289. ipseckey->in_addr.s_addr = htonl(n);
  290. isc_region_consume(&region, 4);
  291. break;
  292. case 2:
  293. memcpy(ipseckey->in6_addr.s6_addr, region.base, 16);
  294. isc_region_consume(&region, 16);
  295. break;
  296. case 3:
  297. dns_name_init(&ipseckey->gateway, NULL);
  298. dns_name_fromregion(&name, &region);
  299. RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
  300. isc_region_consume(&region, name_length(&name));
  301. break;
  302. }
  303. ipseckey->keylength = region.length;
  304. if (ipseckey->keylength != 0U) {
  305. ipseckey->key = mem_maybedup(mctx, region.base,
  306. ipseckey->keylength);
  307. if (ipseckey->key == NULL) {
  308. if (ipseckey->gateway_type == 3)
  309. dns_name_free(&ipseckey->gateway,
  310. ipseckey->mctx);
  311. return (ISC_R_NOMEMORY);
  312. }
  313. } else
  314. ipseckey->key = NULL;
  315. ipseckey->mctx = mctx;
  316. return (ISC_R_SUCCESS);
  317. }
  318. static inline void
  319. freestruct_ipseckey(ARGS_FREESTRUCT) {
  320. dns_rdata_ipseckey_t *ipseckey = source;
  321. REQUIRE(source != NULL);
  322. REQUIRE(ipseckey->common.rdtype == 45);
  323. if (ipseckey->mctx == NULL)
  324. return;
  325. if (ipseckey->gateway_type == 3)
  326. dns_name_free(&ipseckey->gateway, ipseckey->mctx);
  327. if (ipseckey->key != NULL)
  328. isc_mem_free(ipseckey->mctx, ipseckey->key);
  329. ipseckey->mctx = NULL;
  330. }
  331. static inline isc_result_t
  332. additionaldata_ipseckey(ARGS_ADDLDATA) {
  333. REQUIRE(rdata->type == 45);
  334. UNUSED(rdata);
  335. UNUSED(add);
  336. UNUSED(arg);
  337. return (ISC_R_SUCCESS);
  338. }
  339. static inline isc_result_t
  340. digest_ipseckey(ARGS_DIGEST) {
  341. isc_region_t region;
  342. REQUIRE(rdata->type == 45);
  343. dns_rdata_toregion(rdata, &region);
  344. return ((digest)(arg, &region));
  345. }
  346. static inline isc_boolean_t
  347. checkowner_ipseckey(ARGS_CHECKOWNER) {
  348. REQUIRE(type == 45);
  349. UNUSED(name);
  350. UNUSED(type);
  351. UNUSED(rdclass);
  352. UNUSED(wildcard);
  353. return (ISC_TRUE);
  354. }
  355. static inline isc_boolean_t
  356. checknames_ipseckey(ARGS_CHECKNAMES) {
  357. REQUIRE(rdata->type == 45);
  358. UNUSED(rdata);
  359. UNUSED(owner);
  360. UNUSED(bad);
  361. return (ISC_TRUE);
  362. }
  363. static inline int
  364. casecompare_ipseckey(ARGS_COMPARE) {
  365. isc_region_t region1;
  366. isc_region_t region2;
  367. dns_name_t name1;
  368. dns_name_t name2;
  369. int order;
  370. REQUIRE(rdata1->type == rdata2->type);
  371. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  372. REQUIRE(rdata1->type == 45);
  373. REQUIRE(rdata1->length >= 3);
  374. REQUIRE(rdata2->length >= 3);
  375. dns_rdata_toregion(rdata1, &region1);
  376. dns_rdata_toregion(rdata2, &region2);
  377. if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3)
  378. return (isc_region_compare(&region1, &region2));
  379. dns_name_init(&name1, NULL);
  380. dns_name_init(&name2, NULL);
  381. isc_region_consume(&region1, 3);
  382. isc_region_consume(&region2, 3);
  383. dns_name_fromregion(&name1, &region1);
  384. dns_name_fromregion(&name2, &region2);
  385. order = dns_name_rdatacompare(&name1, &name2);
  386. if (order != 0)
  387. return (order);
  388. isc_region_consume(&region1, name_length(&name1));
  389. isc_region_consume(&region2, name_length(&name2));
  390. return (isc_region_compare(&region1, &region2));
  391. }
  392. #endif /* RDATA_GENERIC_IPSECKEY_45_C */