PageRenderTime 81ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/libcharon/encoding/payloads/id_payload.c

https://gitlab.com/freedmpure/strongswan
C | 469 lines | 307 code | 47 blank | 115 comment | 41 complexity | 36f51d75802fd81ce16cae7505d9448c MD5 | raw file
  1. /*
  2. * Copyright (C) 2005-2011 Martin Willi
  3. * Copyright (C) 2010 revosec AG
  4. * Copyright (C) 2007-2011 Tobias Brunner
  5. * Copyright (C) 2005 Jan Hutter
  6. * Hochschule fuer Technik Rapperswil
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  16. * for more details.
  17. */
  18. #include <stddef.h>
  19. #include "id_payload.h"
  20. #include <daemon.h>
  21. #include <encoding/payloads/encodings.h>
  22. typedef struct private_id_payload_t private_id_payload_t;
  23. /**
  24. * Private data of an id_payload_t object.
  25. */
  26. struct private_id_payload_t {
  27. /**
  28. * Public id_payload_t interface.
  29. */
  30. id_payload_t public;
  31. /**
  32. * Next payload type.
  33. */
  34. uint8_t next_payload;
  35. /**
  36. * Critical flag.
  37. */
  38. bool critical;
  39. /**
  40. * Reserved bits
  41. */
  42. bool reserved_bit[7];
  43. /**
  44. * Reserved bytes
  45. */
  46. uint8_t reserved_byte[3];
  47. /**
  48. * Length of this payload.
  49. */
  50. uint16_t payload_length;
  51. /**
  52. * Type of the ID Data.
  53. */
  54. uint8_t id_type;
  55. /**
  56. * The contained id data value.
  57. */
  58. chunk_t id_data;
  59. /**
  60. * Tunneled protocol ID for IKEv1 quick modes.
  61. */
  62. uint8_t protocol_id;
  63. /**
  64. * Tunneled port for IKEv1 quick modes.
  65. */
  66. uint16_t port;
  67. /**
  68. * one of PLV2_ID_INITIATOR, PLV2_ID_RESPONDER, IDv1 and PLV1_NAT_OA
  69. */
  70. payload_type_t type;
  71. };
  72. /**
  73. * Encoding rules for an IKEv2 ID payload
  74. */
  75. static encoding_rule_t encodings_v2[] = {
  76. /* 1 Byte next payload type, stored in the field next_payload */
  77. { U_INT_8, offsetof(private_id_payload_t, next_payload) },
  78. /* the critical bit */
  79. { FLAG, offsetof(private_id_payload_t, critical) },
  80. /* 7 Bit reserved bits */
  81. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[0]) },
  82. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[1]) },
  83. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[2]) },
  84. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[3]) },
  85. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[4]) },
  86. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[5]) },
  87. { RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[6]) },
  88. /* Length of the whole payload*/
  89. { PAYLOAD_LENGTH, offsetof(private_id_payload_t, payload_length) },
  90. /* 1 Byte ID type*/
  91. { U_INT_8, offsetof(private_id_payload_t, id_type) },
  92. /* 3 reserved bytes */
  93. { RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[0])},
  94. { RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[1])},
  95. { RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[2])},
  96. /* some id data bytes, length is defined in PAYLOAD_LENGTH */
  97. { CHUNK_DATA, offsetof(private_id_payload_t, id_data) },
  98. };
  99. /*
  100. 1 2 3
  101. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  102. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  103. ! Next Payload !C! RESERVED ! Payload Length !
  104. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  105. ! ID Type ! RESERVED |
  106. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  107. ! !
  108. ~ Identification Data ~
  109. ! !
  110. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  111. */
  112. /**
  113. * Encoding rules for an IKEv1 ID payload
  114. */
  115. static encoding_rule_t encodings_v1[] = {
  116. /* 1 Byte next payload type, stored in the field next_payload */
  117. { U_INT_8, offsetof(private_id_payload_t, next_payload) },
  118. /* Reserved Byte is skipped */
  119. { RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[0])},
  120. /* Length of the whole payload*/
  121. { PAYLOAD_LENGTH, offsetof(private_id_payload_t, payload_length) },
  122. /* 1 Byte ID type*/
  123. { U_INT_8, offsetof(private_id_payload_t, id_type) },
  124. { U_INT_8, offsetof(private_id_payload_t, protocol_id) },
  125. { U_INT_16, offsetof(private_id_payload_t, port) },
  126. /* some id data bytes, length is defined in PAYLOAD_LENGTH */
  127. { CHUNK_DATA, offsetof(private_id_payload_t, id_data) },
  128. };
  129. /*
  130. 1 2 3
  131. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  132. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  133. ! Next Payload ! RESERVED ! Payload Length !
  134. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  135. ! ID Type ! Protocol ID ! Port |
  136. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  137. ! !
  138. ~ Identification Data ~
  139. ! !
  140. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  141. */
  142. METHOD(payload_t, verify, status_t,
  143. private_id_payload_t *this)
  144. {
  145. bool bad_length = FALSE;
  146. if ((this->type == PLV1_NAT_OA || this->type == PLV1_NAT_OA_DRAFT_00_03) &&
  147. this->id_type != ID_IPV4_ADDR && this->id_type != ID_IPV6_ADDR)
  148. {
  149. DBG1(DBG_ENC, "invalid ID type %N for %N payload", id_type_names,
  150. this->id_type, payload_type_short_names, this->type);
  151. return FAILED;
  152. }
  153. switch (this->id_type)
  154. {
  155. case ID_IPV4_ADDR_RANGE:
  156. case ID_IPV4_ADDR_SUBNET:
  157. bad_length = this->id_data.len != 8;
  158. break;
  159. case ID_IPV6_ADDR_RANGE:
  160. case ID_IPV6_ADDR_SUBNET:
  161. bad_length = this->id_data.len != 32;
  162. break;
  163. }
  164. if (bad_length)
  165. {
  166. DBG1(DBG_ENC, "invalid %N length (%d bytes)",
  167. id_type_names, this->id_type, this->id_data.len);
  168. return FAILED;
  169. }
  170. return SUCCESS;
  171. }
  172. METHOD(payload_t, get_encoding_rules, int,
  173. private_id_payload_t *this, encoding_rule_t **rules)
  174. {
  175. if (this->type == PLV1_ID ||
  176. this->type == PLV1_NAT_OA || this->type == PLV1_NAT_OA_DRAFT_00_03)
  177. {
  178. *rules = encodings_v1;
  179. return countof(encodings_v1);
  180. }
  181. *rules = encodings_v2;
  182. return countof(encodings_v2);
  183. }
  184. METHOD(payload_t, get_header_length, int,
  185. private_id_payload_t *this)
  186. {
  187. return 8;
  188. }
  189. METHOD(payload_t, get_type, payload_type_t,
  190. private_id_payload_t *this)
  191. {
  192. return this->type;
  193. }
  194. METHOD(payload_t, get_next_type, payload_type_t,
  195. private_id_payload_t *this)
  196. {
  197. return this->next_payload;
  198. }
  199. METHOD(payload_t, set_next_type, void,
  200. private_id_payload_t *this, payload_type_t type)
  201. {
  202. this->next_payload = type;
  203. }
  204. METHOD(payload_t, get_length, size_t,
  205. private_id_payload_t *this)
  206. {
  207. return this->payload_length;
  208. }
  209. METHOD(id_payload_t, get_identification, identification_t*,
  210. private_id_payload_t *this)
  211. {
  212. return identification_create_from_encoding(this->id_type, this->id_data);
  213. }
  214. /**
  215. * Create a traffic selector from an range ID
  216. */
  217. static traffic_selector_t *get_ts_from_range(private_id_payload_t *this,
  218. ts_type_t type)
  219. {
  220. return traffic_selector_create_from_bytes(this->protocol_id, type,
  221. chunk_create(this->id_data.ptr, this->id_data.len / 2), this->port,
  222. chunk_skip(this->id_data, this->id_data.len / 2), this->port ?: 65535);
  223. }
  224. /**
  225. * Create a traffic selector from an subnet ID
  226. */
  227. static traffic_selector_t *get_ts_from_subnet(private_id_payload_t *this,
  228. ts_type_t type)
  229. {
  230. traffic_selector_t *ts;
  231. chunk_t net, netmask;
  232. int i;
  233. net = chunk_create(this->id_data.ptr, this->id_data.len / 2);
  234. netmask = chunk_clone(chunk_skip(this->id_data, this->id_data.len / 2));
  235. for (i = 0; i < net.len; i++)
  236. {
  237. netmask.ptr[i] = (netmask.ptr[i] ^ 0xFF) | net.ptr[i];
  238. }
  239. ts = traffic_selector_create_from_bytes(this->protocol_id, type,
  240. net, this->port, netmask, this->port ?: 65535);
  241. chunk_free(&netmask);
  242. return ts;
  243. }
  244. /**
  245. * Create a traffic selector from an IP ID
  246. */
  247. static traffic_selector_t *get_ts_from_ip(private_id_payload_t *this,
  248. ts_type_t type)
  249. {
  250. return traffic_selector_create_from_bytes(this->protocol_id, type,
  251. this->id_data, this->port, this->id_data, this->port ?: 65535);
  252. }
  253. METHOD(id_payload_t, get_ts, traffic_selector_t*,
  254. private_id_payload_t *this)
  255. {
  256. switch (this->id_type)
  257. {
  258. case ID_IPV4_ADDR_SUBNET:
  259. if (this->id_data.len == 8)
  260. {
  261. return get_ts_from_subnet(this, TS_IPV4_ADDR_RANGE);
  262. }
  263. break;
  264. case ID_IPV6_ADDR_SUBNET:
  265. if (this->id_data.len == 32)
  266. {
  267. return get_ts_from_subnet(this, TS_IPV6_ADDR_RANGE);
  268. }
  269. break;
  270. case ID_IPV4_ADDR_RANGE:
  271. if (this->id_data.len == 8)
  272. {
  273. return get_ts_from_range(this, TS_IPV4_ADDR_RANGE);
  274. }
  275. break;
  276. case ID_IPV6_ADDR_RANGE:
  277. if (this->id_data.len == 32)
  278. {
  279. return get_ts_from_range(this, TS_IPV6_ADDR_RANGE);
  280. }
  281. break;
  282. case ID_IPV4_ADDR:
  283. if (this->id_data.len == 4)
  284. {
  285. return get_ts_from_ip(this, TS_IPV4_ADDR_RANGE);
  286. }
  287. break;
  288. case ID_IPV6_ADDR:
  289. if (this->id_data.len == 16)
  290. {
  291. return get_ts_from_ip(this, TS_IPV6_ADDR_RANGE);
  292. }
  293. break;
  294. default:
  295. break;
  296. }
  297. return NULL;
  298. }
  299. METHOD(id_payload_t, get_encoded, chunk_t,
  300. private_id_payload_t *this)
  301. {
  302. uint16_t port = htons(this->port);
  303. return chunk_cat("cccc", chunk_from_thing(this->id_type),
  304. chunk_from_thing(this->protocol_id),
  305. chunk_from_thing(port), this->id_data);
  306. }
  307. METHOD2(payload_t, id_payload_t, destroy, void,
  308. private_id_payload_t *this)
  309. {
  310. free(this->id_data.ptr);
  311. free(this);
  312. }
  313. /*
  314. * Described in header.
  315. */
  316. id_payload_t *id_payload_create(payload_type_t type)
  317. {
  318. private_id_payload_t *this;
  319. INIT(this,
  320. .public = {
  321. .payload_interface = {
  322. .verify = _verify,
  323. .get_encoding_rules = _get_encoding_rules,
  324. .get_header_length = _get_header_length,
  325. .get_length = _get_length,
  326. .get_next_type = _get_next_type,
  327. .set_next_type = _set_next_type,
  328. .get_type = _get_type,
  329. .destroy = _destroy,
  330. },
  331. .get_identification = _get_identification,
  332. .get_encoded = _get_encoded,
  333. .get_ts = _get_ts,
  334. .destroy = _destroy,
  335. },
  336. .next_payload = PL_NONE,
  337. .payload_length = get_header_length(this),
  338. .type = type,
  339. );
  340. return &this->public;
  341. }
  342. /*
  343. * Described in header.
  344. */
  345. id_payload_t *id_payload_create_from_identification(payload_type_t type,
  346. identification_t *id)
  347. {
  348. private_id_payload_t *this;
  349. this = (private_id_payload_t*)id_payload_create(type);
  350. this->id_data = chunk_clone(id->get_encoding(id));
  351. this->id_type = id->get_type(id);
  352. this->payload_length += this->id_data.len;
  353. return &this->public;
  354. }
  355. /*
  356. * Described in header.
  357. */
  358. id_payload_t *id_payload_create_from_ts(traffic_selector_t *ts)
  359. {
  360. private_id_payload_t *this;
  361. uint8_t mask;
  362. host_t *net;
  363. this = (private_id_payload_t*)id_payload_create(PLV1_ID);
  364. if (ts->is_host(ts, NULL))
  365. {
  366. if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
  367. {
  368. this->id_type = ID_IPV4_ADDR;
  369. }
  370. else
  371. {
  372. this->id_type = ID_IPV6_ADDR;
  373. }
  374. this->id_data = chunk_clone(ts->get_from_address(ts));
  375. }
  376. else if (ts->to_subnet(ts, &net, &mask))
  377. {
  378. uint8_t netmask[16], len, byte;
  379. if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
  380. {
  381. this->id_type = ID_IPV4_ADDR_SUBNET;
  382. len = 4;
  383. }
  384. else
  385. {
  386. this->id_type = ID_IPV6_ADDR_SUBNET;
  387. len = 16;
  388. }
  389. memset(netmask, 0, sizeof(netmask));
  390. for (byte = 0; byte < sizeof(netmask); byte++)
  391. {
  392. if (mask < 8)
  393. {
  394. netmask[byte] = 0xFF << (8 - mask);
  395. break;
  396. }
  397. netmask[byte] = 0xFF;
  398. mask -= 8;
  399. }
  400. this->id_data = chunk_cat("cc", net->get_address(net),
  401. chunk_create(netmask, len));
  402. net->destroy(net);
  403. }
  404. else
  405. {
  406. if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
  407. {
  408. this->id_type = ID_IPV4_ADDR_RANGE;
  409. }
  410. else
  411. {
  412. this->id_type = ID_IPV6_ADDR_RANGE;
  413. }
  414. this->id_data = chunk_cat("cc",
  415. ts->get_from_address(ts), ts->get_to_address(ts));
  416. net->destroy(net);
  417. }
  418. this->port = ts->get_from_port(ts);
  419. this->protocol_id = ts->get_protocol(ts);
  420. this->payload_length += this->id_data.len;
  421. return &this->public;
  422. }