pfkeyv2_parsemessage.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. /* $OpenBSD: pfkeyv2_parsemessage.c,v 1.49 2015/04/14 12:22:15 mikeb Exp $ */
  2. /*
  3. * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
  4. *
  5. * NRL grants permission for redistribution and use in source and binary
  6. * forms, with or without modification, of the software and documentation
  7. * created at NRL provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. All advertising materials mentioning features or use of this software
  15. * must display the following acknowledgements:
  16. * This product includes software developed by the University of
  17. * California, Berkeley and its contributors.
  18. * This product includes software developed at the Information
  19. * Technology Division, US Naval Research Laboratory.
  20. * 4. Neither the name of the NRL nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
  25. * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  26. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  27. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
  28. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  31. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. * The views and conclusions contained in the software and documentation
  37. * are those of the authors and should not be interpreted as representing
  38. * official policies, either expressed or implied, of the US Naval
  39. * Research Laboratory (NRL).
  40. */
  41. /*
  42. * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
  43. *
  44. * Redistribution and use in source and binary forms, with or without
  45. * modification, are permitted provided that the following conditions
  46. * are met:
  47. * 1. Redistributions of source code must retain the above copyright
  48. * notice, this list of conditions and the following disclaimer.
  49. * 2. Redistributions in binary form must reproduce the above copyright
  50. * notice, this list of conditions and the following disclaimer in the
  51. * documentation and/or other materials provided with the distribution.
  52. * 3. Neither the name of the author nor the names of any contributors
  53. * may be used to endorse or promote products derived from this software
  54. * without specific prior written permission.
  55. *
  56. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  57. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  58. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  59. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  60. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  61. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  62. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  63. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  64. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  65. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  66. * SUCH DAMAGE.
  67. */
  68. #include "pf.h"
  69. #include <sys/param.h>
  70. #include <sys/systm.h>
  71. #include <sys/socket.h>
  72. #include <sys/mbuf.h>
  73. #include <sys/proc.h>
  74. #include <netinet/ip_ipsp.h>
  75. #include <netinet/ip_var.h>
  76. #include <net/pfkeyv2.h>
  77. #if NPF > 0
  78. #include <net/if.h>
  79. #include <net/pfvar.h>
  80. #endif
  81. #ifdef ENCDEBUG
  82. #define DPRINTF(x) if (encdebug) printf x
  83. #else
  84. #define DPRINTF(x)
  85. #endif
  86. #define BITMAP_SA (1LL << SADB_EXT_SA)
  87. #define BITMAP_LIFETIME_CURRENT (1LL << SADB_EXT_LIFETIME_CURRENT)
  88. #define BITMAP_LIFETIME_HARD (1LL << SADB_EXT_LIFETIME_HARD)
  89. #define BITMAP_LIFETIME_SOFT (1LL << SADB_EXT_LIFETIME_SOFT)
  90. #define BITMAP_ADDRESS_SRC (1LL << SADB_EXT_ADDRESS_SRC)
  91. #define BITMAP_ADDRESS_DST (1LL << SADB_EXT_ADDRESS_DST)
  92. #define BITMAP_KEY_AUTH (1LL << SADB_EXT_KEY_AUTH)
  93. #define BITMAP_KEY_ENCRYPT (1LL << SADB_EXT_KEY_ENCRYPT)
  94. #define BITMAP_IDENTITY_SRC (1LL << SADB_EXT_IDENTITY_SRC)
  95. #define BITMAP_IDENTITY_DST (1LL << SADB_EXT_IDENTITY_DST)
  96. #define BITMAP_SENSITIVITY (1LL << SADB_EXT_SENSITIVITY)
  97. #define BITMAP_PROPOSAL (1LL << SADB_EXT_PROPOSAL)
  98. #define BITMAP_SUPPORTED_AUTH (1LL << SADB_EXT_SUPPORTED_AUTH)
  99. #define BITMAP_SUPPORTED_ENCRYPT (1LL << SADB_EXT_SUPPORTED_ENCRYPT)
  100. #define BITMAP_SPIRANGE (1LL << SADB_EXT_SPIRANGE)
  101. #define BITMAP_LIFETIME (BITMAP_LIFETIME_CURRENT | BITMAP_LIFETIME_HARD | BITMAP_LIFETIME_SOFT)
  102. #define BITMAP_ADDRESS (BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST)
  103. #define BITMAP_KEY (BITMAP_KEY_AUTH | BITMAP_KEY_ENCRYPT)
  104. #define BITMAP_IDENTITY (BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST)
  105. #define BITMAP_MSG 1
  106. #define BITMAP_X_SRC_MASK (1LL << SADB_X_EXT_SRC_MASK)
  107. #define BITMAP_X_DST_MASK (1LL << SADB_X_EXT_DST_MASK)
  108. #define BITMAP_X_PROTOCOL (1LL << SADB_X_EXT_PROTOCOL)
  109. #define BITMAP_X_SRC_FLOW (1LL << SADB_X_EXT_SRC_FLOW)
  110. #define BITMAP_X_DST_FLOW (1LL << SADB_X_EXT_DST_FLOW)
  111. #define BITMAP_X_FLOW_TYPE (1LL << SADB_X_EXT_FLOW_TYPE)
  112. #define BITMAP_X_SA2 (1LL << SADB_X_EXT_SA2)
  113. #define BITMAP_X_DST2 (1LL << SADB_X_EXT_DST2)
  114. #define BITMAP_X_POLICY (1LL << SADB_X_EXT_POLICY)
  115. #define BITMAP_X_FLOW (BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE)
  116. #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP)
  117. #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP)
  118. #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE)
  119. #define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG)
  120. #define BITMAP_X_TAP (1LL << SADB_X_EXT_TAP)
  121. uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
  122. {
  123. /* RESERVED */
  124. ~0,
  125. /* GETSPI */
  126. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
  127. /* UPDATE */
  128. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
  129. /* ADD */
  130. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP,
  131. /* DELETE */
  132. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  133. /* GET */
  134. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  135. /* ACQUIRE */
  136. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL,
  137. /* REGISTER */
  138. 0,
  139. /* EXPIRE */
  140. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  141. /* FLUSH */
  142. 0,
  143. /* DUMP */
  144. 0,
  145. /* X_PROMISC */
  146. 0,
  147. /* X_ADDFLOW */
  148. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_FLOW,
  149. /* X_DELFLOW */
  150. BITMAP_X_FLOW,
  151. /* X_GRPSPIS */
  152. BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
  153. /* X_ASKPOLICY */
  154. BITMAP_X_POLICY,
  155. };
  156. uint64_t sadb_exts_required_in[SADB_MAX+1] =
  157. {
  158. /* RESERVED */
  159. 0,
  160. /* GETSPI */
  161. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
  162. /* UPDATE */
  163. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  164. /* ADD */
  165. BITMAP_SA | BITMAP_ADDRESS_DST,
  166. /* DELETE */
  167. BITMAP_SA | BITMAP_ADDRESS_DST,
  168. /* GET */
  169. BITMAP_SA | BITMAP_ADDRESS_DST,
  170. /* ACQUIRE */
  171. 0,
  172. /* REGISTER */
  173. 0,
  174. /* EXPIRE */
  175. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  176. /* FLUSH */
  177. 0,
  178. /* DUMP */
  179. 0,
  180. /* X_PROMISC */
  181. 0,
  182. /* X_ADDFLOW */
  183. BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
  184. /* X_DELFLOW */
  185. BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
  186. /* X_GRPSPIS */
  187. BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
  188. /* X_ASKPOLICY */
  189. BITMAP_X_POLICY,
  190. };
  191. uint64_t sadb_exts_allowed_out[SADB_MAX+1] =
  192. {
  193. /* RESERVED */
  194. ~0,
  195. /* GETSPI */
  196. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  197. /* UPDATE */
  198. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
  199. /* ADD */
  200. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
  201. /* DELETE */
  202. BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
  203. /* GET */
  204. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP,
  205. /* ACQUIRE */
  206. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL,
  207. /* REGISTER */
  208. BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
  209. /* EXPIRE */
  210. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS,
  211. /* FLUSH */
  212. 0,
  213. /* DUMP */
  214. BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY,
  215. /* X_PROMISC */
  216. 0,
  217. /* X_ADDFLOW */
  218. BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST,
  219. /* X_DELFLOW */
  220. BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
  221. /* X_GRPSPIS */
  222. BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
  223. /* X_ASKPOLICY */
  224. BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY,
  225. };
  226. uint64_t sadb_exts_required_out[SADB_MAX+1] =
  227. {
  228. /* RESERVED */
  229. 0,
  230. /* GETSPI */
  231. BITMAP_SA | BITMAP_ADDRESS_DST,
  232. /* UPDATE */
  233. BITMAP_SA | BITMAP_ADDRESS_DST,
  234. /* ADD */
  235. BITMAP_SA | BITMAP_ADDRESS_DST,
  236. /* DELETE */
  237. BITMAP_SA | BITMAP_ADDRESS_DST,
  238. /* GET */
  239. BITMAP_SA | BITMAP_LIFETIME_CURRENT | BITMAP_ADDRESS_DST,
  240. /* ACQUIRE */
  241. 0,
  242. /* REGISTER */
  243. BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
  244. /* EXPIRE */
  245. BITMAP_SA | BITMAP_ADDRESS_DST,
  246. /* FLUSH */
  247. 0,
  248. /* DUMP */
  249. 0,
  250. /* X_PROMISC */
  251. 0,
  252. /* X_ADDFLOW */
  253. BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
  254. /* X_DELFLOW */
  255. BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
  256. /* X_GRPSPIS */
  257. BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
  258. /* X_REPPOLICY */
  259. BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE,
  260. };
  261. int pfkeyv2_parsemessage(void *, int, void **);
  262. #define RETURN_EINVAL(line) goto einval;
  263. int
  264. pfkeyv2_parsemessage(void *p, int len, void **headers)
  265. {
  266. struct sadb_ext *sadb_ext;
  267. int i, left = len;
  268. uint64_t allow, seen = 1;
  269. struct sadb_msg *sadb_msg = (struct sadb_msg *) p;
  270. bzero(headers, (SADB_EXT_MAX + 1) * sizeof(void *));
  271. if (left < sizeof(struct sadb_msg)) {
  272. DPRINTF(("pfkeyv2_parsemessage: message too short\n"));
  273. return (EINVAL);
  274. }
  275. headers[0] = p;
  276. if (sadb_msg->sadb_msg_len * sizeof(uint64_t) != left) {
  277. DPRINTF(("pfkeyv2_parsemessage: length not a multiple of 64\n"));
  278. return (EINVAL);
  279. }
  280. p += sizeof(struct sadb_msg);
  281. left -= sizeof(struct sadb_msg);
  282. if (sadb_msg->sadb_msg_reserved) {
  283. DPRINTF(("pfkeyv2_parsemessage: message header reserved "
  284. "field set\n"));
  285. return (EINVAL);
  286. }
  287. if (sadb_msg->sadb_msg_type > SADB_MAX) {
  288. DPRINTF(("pfkeyv2_parsemessage: message type > %d\n",
  289. SADB_MAX));
  290. return (EINVAL);
  291. }
  292. if (!sadb_msg->sadb_msg_type) {
  293. DPRINTF(("pfkeyv2_parsemessage: message type unset\n"));
  294. return (EINVAL);
  295. }
  296. if (sadb_msg->sadb_msg_pid != curproc->p_p->ps_pid) {
  297. DPRINTF(("pfkeyv2_parsemessage: bad PID value\n"));
  298. return (EINVAL);
  299. }
  300. if (sadb_msg->sadb_msg_errno) {
  301. if (left) {
  302. DPRINTF(("pfkeyv2_parsemessage: too-large error message\n"));
  303. return (EINVAL);
  304. }
  305. return (0);
  306. }
  307. if (sadb_msg->sadb_msg_type == SADB_X_PROMISC) {
  308. DPRINTF(("pfkeyv2_parsemessage: message type promiscuous\n"));
  309. return (0);
  310. }
  311. allow = sadb_exts_allowed_in[sadb_msg->sadb_msg_type];
  312. while (left > 0) {
  313. sadb_ext = (struct sadb_ext *)p;
  314. if (left < sizeof(struct sadb_ext)) {
  315. DPRINTF(("pfkeyv2_parsemessage: extension header too "
  316. "short\n"));
  317. return (EINVAL);
  318. }
  319. i = sadb_ext->sadb_ext_len * sizeof(uint64_t);
  320. if (left < i) {
  321. DPRINTF(("pfkeyv2_parsemessage: extension header "
  322. "exceeds message length\n"));
  323. return (EINVAL);
  324. }
  325. if (sadb_ext->sadb_ext_type > SADB_EXT_MAX) {
  326. DPRINTF(("pfkeyv2_parsemessage: unknown extension "
  327. "header %d\n", sadb_ext->sadb_ext_type));
  328. return (EINVAL);
  329. }
  330. if (!sadb_ext->sadb_ext_type) {
  331. DPRINTF(("pfkeyv2_parsemessage: unset extension "
  332. "header\n"));
  333. return (EINVAL);
  334. }
  335. if (!(allow & (1LL << sadb_ext->sadb_ext_type))) {
  336. DPRINTF(("pfkeyv2_parsemessage: extension header %d "
  337. "not permitted on message type %d\n",
  338. sadb_ext->sadb_ext_type, sadb_msg->sadb_msg_type));
  339. return (EINVAL);
  340. }
  341. if (headers[sadb_ext->sadb_ext_type]) {
  342. DPRINTF(("pfkeyv2_parsemessage: duplicate extension "
  343. "header %d\n", sadb_ext->sadb_ext_type));
  344. return (EINVAL);
  345. }
  346. seen |= (1LL << sadb_ext->sadb_ext_type);
  347. switch (sadb_ext->sadb_ext_type) {
  348. case SADB_EXT_SA:
  349. case SADB_X_EXT_SA2:
  350. {
  351. struct sadb_sa *sadb_sa = (struct sadb_sa *)p;
  352. if (i != sizeof(struct sadb_sa)) {
  353. DPRINTF(("pfkeyv2_parsemessage: bad header "
  354. "length for SA extension header %d\n",
  355. sadb_ext->sadb_ext_type));
  356. return (EINVAL);
  357. }
  358. if (sadb_sa->sadb_sa_state > SADB_SASTATE_MAX) {
  359. DPRINTF(("pfkeyv2_parsemessage: unknown SA "
  360. "state %d in SA extension header %d\n",
  361. sadb_sa->sadb_sa_state,
  362. sadb_ext->sadb_ext_type));
  363. return (EINVAL);
  364. }
  365. if (sadb_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
  366. DPRINTF(("pfkeyv2_parsemessage: cannot set SA "
  367. "state to dead, SA extension header %d\n",
  368. sadb_ext->sadb_ext_type));
  369. return (EINVAL);
  370. }
  371. if (sadb_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
  372. DPRINTF(("pfkeyv2_parsemessage: unknown "
  373. "encryption algorithm %d in SA extension "
  374. "header %d\n", sadb_sa->sadb_sa_encrypt,
  375. sadb_ext->sadb_ext_type));
  376. return (EINVAL);
  377. }
  378. if (sadb_sa->sadb_sa_auth > SADB_AALG_MAX) {
  379. DPRINTF(("pfkeyv2_parsemessage: unknown "
  380. "authentication algorithm %d in SA "
  381. "extension header %d\n",
  382. sadb_sa->sadb_sa_auth,
  383. sadb_ext->sadb_ext_type));
  384. return (EINVAL);
  385. }
  386. if (sadb_sa->sadb_sa_replay > 64) {
  387. DPRINTF(("pfkeyv2_parsemessage: unsupported "
  388. "replay window size %d in SA extension "
  389. "header %d\n", sadb_sa->sadb_sa_replay,
  390. sadb_ext->sadb_ext_type));
  391. return (EINVAL);
  392. }
  393. }
  394. break;
  395. case SADB_X_EXT_PROTOCOL:
  396. case SADB_X_EXT_FLOW_TYPE:
  397. if (i != sizeof(struct sadb_protocol)) {
  398. DPRINTF(("pfkeyv2_parsemessage: bad "
  399. "PROTOCOL/FLOW header length in extension "
  400. "header %d\n", sadb_ext->sadb_ext_type));
  401. return (EINVAL);
  402. }
  403. break;
  404. case SADB_X_EXT_POLICY:
  405. if (i != sizeof(struct sadb_x_policy)) {
  406. DPRINTF(("pfkeyv2_parsemessage: bad POLICY "
  407. "header length\n"));
  408. return (EINVAL);
  409. }
  410. break;
  411. case SADB_EXT_LIFETIME_CURRENT:
  412. case SADB_EXT_LIFETIME_HARD:
  413. case SADB_EXT_LIFETIME_SOFT:
  414. case SADB_X_EXT_LIFETIME_LASTUSE:
  415. if (i != sizeof(struct sadb_lifetime)) {
  416. DPRINTF(("pfkeyv2_parsemessage: bad header "
  417. "length for LIFETIME extension header "
  418. "%d\n", sadb_ext->sadb_ext_type));
  419. return (EINVAL);
  420. }
  421. break;
  422. case SADB_EXT_ADDRESS_SRC:
  423. case SADB_EXT_ADDRESS_DST:
  424. case SADB_X_EXT_SRC_MASK:
  425. case SADB_X_EXT_DST_MASK:
  426. case SADB_X_EXT_SRC_FLOW:
  427. case SADB_X_EXT_DST_FLOW:
  428. case SADB_X_EXT_DST2:
  429. {
  430. struct sadb_address *sadb_address =
  431. (struct sadb_address *)p;
  432. struct sockaddr *sa = (struct sockaddr *)(p +
  433. sizeof(struct sadb_address));
  434. if (i < sizeof(struct sadb_address) +
  435. sizeof(struct sockaddr)) {
  436. DPRINTF(("pfkeyv2_parsemessage: bad ADDRESS "
  437. "extension header %d length\n",
  438. sadb_ext->sadb_ext_type));
  439. return (EINVAL);
  440. }
  441. if (sadb_address->sadb_address_reserved) {
  442. DPRINTF(("pfkeyv2_parsemessage: ADDRESS "
  443. "extension header %d reserved field set\n",
  444. sadb_ext->sadb_ext_type));
  445. return (EINVAL);
  446. }
  447. if (sa->sa_len &&
  448. (i != sizeof(struct sadb_address) +
  449. PADUP(sa->sa_len))) {
  450. DPRINTF(("pfkeyv2_parsemessage: bad sockaddr "
  451. "length field in ADDRESS extension "
  452. "header %d\n", sadb_ext->sadb_ext_type));
  453. return (EINVAL);
  454. }
  455. switch (sa->sa_family) {
  456. case AF_INET:
  457. if (sizeof(struct sadb_address) +
  458. PADUP(sizeof(struct sockaddr_in)) != i) {
  459. DPRINTF(("pfkeyv2_parsemessage: "
  460. "invalid ADDRESS extension header "
  461. "%d length\n",
  462. sadb_ext->sadb_ext_type));
  463. return (EINVAL);
  464. }
  465. if (sa->sa_len != sizeof(struct sockaddr_in)) {
  466. DPRINTF(("pfkeyv2_parsemessage: bad "
  467. "sockaddr_in length in ADDRESS "
  468. "extension header %d\n",
  469. sadb_ext->sadb_ext_type));
  470. return (EINVAL);
  471. }
  472. /* Only check the right pieces */
  473. switch (sadb_ext->sadb_ext_type)
  474. {
  475. case SADB_X_EXT_SRC_MASK:
  476. case SADB_X_EXT_DST_MASK:
  477. case SADB_X_EXT_SRC_FLOW:
  478. case SADB_X_EXT_DST_FLOW:
  479. break;
  480. default:
  481. if (((struct sockaddr_in *)sa)->sin_port) {
  482. DPRINTF(("pfkeyv2_parsemessage"
  483. ": port field set in "
  484. "sockaddr_in of ADDRESS "
  485. "extension header %d\n",
  486. sadb_ext->sadb_ext_type));
  487. return (EINVAL);
  488. }
  489. break;
  490. }
  491. {
  492. char zero[sizeof(((struct sockaddr_in *)sa)->sin_zero)];
  493. bzero(zero, sizeof(zero));
  494. if (bcmp(&((struct sockaddr_in *)sa)->sin_zero, zero, sizeof(zero))) {
  495. DPRINTF(("pfkeyv2_parsemessage"
  496. ": reserved sockaddr_in "
  497. "field non-zero'ed in "
  498. "ADDRESS extension header "
  499. "%d\n",
  500. sadb_ext->sadb_ext_type));
  501. return (EINVAL);
  502. }
  503. }
  504. break;
  505. #ifdef INET6
  506. case AF_INET6:
  507. if (i != sizeof(struct sadb_address) +
  508. PADUP(sizeof(struct sockaddr_in6))) {
  509. DPRINTF(("pfkeyv2_parsemessage: "
  510. "invalid sockaddr_in6 length in "
  511. "ADDRESS extension header %d\n",
  512. sadb_ext->sadb_ext_type));
  513. return (EINVAL);
  514. }
  515. if (sa->sa_len !=
  516. sizeof(struct sockaddr_in6)) {
  517. DPRINTF(("pfkeyv2_parsemessage: bad "
  518. "sockaddr_in6 length in ADDRESS "
  519. "extension header %d\n",
  520. sadb_ext->sadb_ext_type));
  521. return (EINVAL);
  522. }
  523. if (((struct sockaddr_in6 *)sa)->sin6_flowinfo) {
  524. DPRINTF(("pfkeyv2_parsemessage: "
  525. "flowinfo field set in "
  526. "sockaddr_in6 of ADDRESS "
  527. "extension header %d\n",
  528. sadb_ext->sadb_ext_type));
  529. return (EINVAL);
  530. }
  531. /* Only check the right pieces */
  532. switch (sadb_ext->sadb_ext_type)
  533. {
  534. case SADB_X_EXT_SRC_MASK:
  535. case SADB_X_EXT_DST_MASK:
  536. case SADB_X_EXT_SRC_FLOW:
  537. case SADB_X_EXT_DST_FLOW:
  538. break;
  539. default:
  540. if (((struct sockaddr_in6 *)sa)->sin6_port) {
  541. DPRINTF(("pfkeyv2_parsemessage"
  542. ": port field set in "
  543. "sockaddr_in6 of ADDRESS "
  544. "extension header %d\n",
  545. sadb_ext->sadb_ext_type));
  546. return (EINVAL);
  547. }
  548. break;
  549. }
  550. break;
  551. #endif /* INET6 */
  552. default:
  553. if (sadb_msg->sadb_msg_satype ==
  554. SADB_X_SATYPE_TCPSIGNATURE &&
  555. sa->sa_family == 0)
  556. break;
  557. DPRINTF(("pfkeyv2_parsemessage: unknown "
  558. "address family %d in ADDRESS extension "
  559. "header %d\n",
  560. sa->sa_family, sadb_ext->sadb_ext_type));
  561. return (EINVAL);
  562. }
  563. }
  564. break;
  565. case SADB_EXT_KEY_AUTH:
  566. case SADB_EXT_KEY_ENCRYPT:
  567. {
  568. struct sadb_key *sadb_key = (struct sadb_key *)p;
  569. if (i < sizeof(struct sadb_key)) {
  570. DPRINTF(("pfkeyv2_parsemessage: bad header "
  571. "length in KEY extension header %d\n",
  572. sadb_ext->sadb_ext_type));
  573. return (EINVAL);
  574. }
  575. if (!sadb_key->sadb_key_bits) {
  576. DPRINTF(("pfkeyv2_parsemessage: key length "
  577. "unset in KEY extension header %d\n",
  578. sadb_ext->sadb_ext_type));
  579. return (EINVAL);
  580. }
  581. if (((sadb_key->sadb_key_bits + 63) / 64) * sizeof(uint64_t) != i - sizeof(struct sadb_key)) {
  582. DPRINTF(("pfkeyv2_parsemessage: invalid key "
  583. "length in KEY extension header %d\n",
  584. sadb_ext->sadb_ext_type));
  585. return (EINVAL);
  586. }
  587. if (sadb_key->sadb_key_reserved) {
  588. DPRINTF(("pfkeyv2_parsemessage: reserved field"
  589. " set in KEY extension header %d\n",
  590. sadb_ext->sadb_ext_type));
  591. return (EINVAL);
  592. }
  593. }
  594. break;
  595. case SADB_EXT_IDENTITY_SRC:
  596. case SADB_EXT_IDENTITY_DST:
  597. {
  598. struct sadb_ident *sadb_ident = (struct sadb_ident *)p;
  599. if (i < sizeof(struct sadb_ident)) {
  600. DPRINTF(("pfkeyv2_parsemessage: bad header "
  601. "length of IDENTITY extension header %d\n",
  602. sadb_ext->sadb_ext_type));
  603. return (EINVAL);
  604. }
  605. if (sadb_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
  606. DPRINTF(("pfkeyv2_parsemessage: unknown "
  607. "identity type %d in IDENTITY extension "
  608. "header %d\n",
  609. sadb_ident->sadb_ident_type,
  610. sadb_ext->sadb_ext_type));
  611. return (EINVAL);
  612. }
  613. if (sadb_ident->sadb_ident_reserved) {
  614. DPRINTF(("pfkeyv2_parsemessage: reserved "
  615. "field set in IDENTITY extension header "
  616. "%d\n", sadb_ext->sadb_ext_type));
  617. return (EINVAL);
  618. }
  619. if (i > sizeof(struct sadb_ident)) {
  620. char *c =
  621. (char *)(p + sizeof(struct sadb_ident));
  622. int j;
  623. if (*(char *)(p + i - 1)) {
  624. DPRINTF(("pfkeyv2_parsemessage: non "
  625. "NUL-terminated identity in "
  626. "IDENTITY extension header %d\n",
  627. sadb_ext->sadb_ext_type));
  628. return (EINVAL);
  629. }
  630. j = PADUP(strlen(c) + 1) +
  631. sizeof(struct sadb_ident);
  632. if (i != j) {
  633. DPRINTF(("pfkeyv2_parsemessage: actual"
  634. " identity length does not match "
  635. "expected length in identity "
  636. "extension header %d\n",
  637. sadb_ext->sadb_ext_type));
  638. return (EINVAL);
  639. }
  640. }
  641. }
  642. break;
  643. case SADB_EXT_SENSITIVITY:
  644. {
  645. struct sadb_sens *sadb_sens = (struct sadb_sens *)p;
  646. if (i < sizeof(struct sadb_sens)) {
  647. DPRINTF(("pfkeyv2_parsemessage: bad header "
  648. "length for SENSITIVITY extension "
  649. "header\n"));
  650. return (EINVAL);
  651. }
  652. if (i != (sadb_sens->sadb_sens_sens_len +
  653. sadb_sens->sadb_sens_integ_len) *
  654. sizeof(uint64_t) +
  655. sizeof(struct sadb_sens)) {
  656. DPRINTF(("pfkeyv2_parsemessage: bad payload "
  657. "length for SENSITIVITY extension "
  658. "header\n"));
  659. return (EINVAL);
  660. }
  661. }
  662. break;
  663. case SADB_EXT_PROPOSAL:
  664. {
  665. struct sadb_prop *sadb_prop = (struct sadb_prop *)p;
  666. if (i < sizeof(struct sadb_prop)) {
  667. DPRINTF(("pfkeyv2_parsemessage: bad PROPOSAL "
  668. "header length\n"));
  669. return (EINVAL);
  670. }
  671. if (sadb_prop->sadb_prop_reserved) {
  672. DPRINTF(("pfkeyv2_parsemessage: reserved field"
  673. "set in PROPOSAL extension header\n"));
  674. return (EINVAL);
  675. }
  676. if ((i - sizeof(struct sadb_prop)) %
  677. sizeof(struct sadb_comb)) {
  678. DPRINTF(("pfkeyv2_parsemessage: bad proposal "
  679. "length\n"));
  680. return (EINVAL);
  681. }
  682. {
  683. struct sadb_comb *sadb_comb =
  684. (struct sadb_comb *)(p +
  685. sizeof(struct sadb_prop));
  686. int j;
  687. for (j = 0;
  688. j < (i - sizeof(struct sadb_prop))/
  689. sizeof(struct sadb_comb);
  690. j++) {
  691. if (sadb_comb->sadb_comb_auth >
  692. SADB_AALG_MAX) {
  693. DPRINTF(("pfkeyv2_parsemessage"
  694. ": unknown authentication "
  695. "algorithm %d in "
  696. "PROPOSAL\n",
  697. sadb_comb->sadb_comb_auth));
  698. return (EINVAL);
  699. }
  700. if (sadb_comb->sadb_comb_encrypt >
  701. SADB_EALG_MAX) {
  702. DPRINTF(("pfkeyv2_parsemessage"
  703. ": unknown encryption "
  704. "algorithm %d in "
  705. "PROPOSAL\n",
  706. sadb_comb->sadb_comb_encrypt));
  707. return (EINVAL);
  708. }
  709. if (sadb_comb->sadb_comb_reserved) {
  710. DPRINTF(("pfkeyv2_parsemessage"
  711. ": reserved field set in "
  712. "COMB header\n"));
  713. return (EINVAL);
  714. }
  715. }
  716. }
  717. }
  718. break;
  719. case SADB_EXT_SUPPORTED_AUTH:
  720. case SADB_EXT_SUPPORTED_ENCRYPT:
  721. case SADB_X_EXT_SUPPORTED_COMP:
  722. {
  723. struct sadb_supported *sadb_supported =
  724. (struct sadb_supported *)p;
  725. int j;
  726. if (i < sizeof(struct sadb_supported)) {
  727. DPRINTF(("pfkeyv2_parsemessage: bad header "
  728. "length for SUPPORTED extension header "
  729. "%d\n", sadb_ext->sadb_ext_type));
  730. return (EINVAL);
  731. }
  732. if (sadb_supported->sadb_supported_reserved) {
  733. DPRINTF(("pfkeyv2_parsemessage: reserved "
  734. "field set in SUPPORTED extension "
  735. "header %d\n", sadb_ext->sadb_ext_type));
  736. return (EINVAL);
  737. }
  738. {
  739. struct sadb_alg *sadb_alg =
  740. (struct sadb_alg *)(p +
  741. sizeof(struct sadb_supported));
  742. int max_alg;
  743. max_alg = sadb_ext->sadb_ext_type ==
  744. SADB_EXT_SUPPORTED_AUTH ?
  745. SADB_AALG_MAX : SADB_EXT_SUPPORTED_ENCRYPT ?
  746. SADB_EALG_MAX : SADB_X_CALG_MAX;
  747. for (j = 0;
  748. j < sadb_supported->sadb_supported_len - 1;
  749. j++) {
  750. if (sadb_alg->sadb_alg_id > max_alg) {
  751. DPRINTF(("pfkeyv2_parsemessage"
  752. ": unknown algorithm %d "
  753. "in SUPPORTED extension "
  754. "header %d\n",
  755. sadb_alg->sadb_alg_id,
  756. sadb_ext->sadb_ext_type));
  757. return (EINVAL);
  758. }
  759. if (sadb_alg->sadb_alg_reserved) {
  760. DPRINTF(("pfkeyv2_parsemessage"
  761. ": reserved field set in "
  762. "supported algorithms "
  763. "header inside SUPPORTED "
  764. "extension header %d\n",
  765. sadb_ext->sadb_ext_type));
  766. return (EINVAL);
  767. }
  768. sadb_alg++;
  769. }
  770. }
  771. }
  772. break;
  773. case SADB_EXT_SPIRANGE:
  774. {
  775. struct sadb_spirange *sadb_spirange =
  776. (struct sadb_spirange *)p;
  777. if (i != sizeof(struct sadb_spirange)) {
  778. DPRINTF(("pfkeyv2_parsemessage: bad header "
  779. "length of SPIRANGE extension header\n"));
  780. return (EINVAL);
  781. }
  782. if (sadb_spirange->sadb_spirange_min >
  783. sadb_spirange->sadb_spirange_max) {
  784. DPRINTF(("pfkeyv2_parsemessage: bad SPI "
  785. "range\n"));
  786. return (EINVAL);
  787. }
  788. }
  789. break;
  790. case SADB_X_EXT_UDPENCAP:
  791. if (i != sizeof(struct sadb_x_udpencap)) {
  792. DPRINTF(("pfkeyv2_parsemessage: bad UDPENCAP "
  793. "header length\n"));
  794. return (EINVAL);
  795. }
  796. break;
  797. #if NPF > 0
  798. case SADB_X_EXT_TAG:
  799. if (i < sizeof(struct sadb_x_tag)) {
  800. DPRINTF(("pfkeyv2_parsemessage: "
  801. "TAG extension header too small"));
  802. return (EINVAL);
  803. }
  804. if (i > (sizeof(struct sadb_x_tag) +
  805. PF_TAG_NAME_SIZE)) {
  806. DPRINTF(("pfkeyv2_parsemessage: "
  807. "TAG extension header too long"));
  808. return (EINVAL);
  809. }
  810. break;
  811. case SADB_X_EXT_TAP:
  812. if (i < sizeof(struct sadb_x_tap)) {
  813. DPRINTF(("pfkeyv2_parsemessage: "
  814. "TAP extension header too small"));
  815. return (EINVAL);
  816. }
  817. if (i > sizeof(struct sadb_x_tap)) {
  818. DPRINTF(("pfkeyv2_parsemessage: "
  819. "TAP extension header too long"));
  820. return (EINVAL);
  821. }
  822. break;
  823. #endif
  824. default:
  825. DPRINTF(("pfkeyv2_parsemessage: unknown extension "
  826. "header type %d\n",
  827. sadb_ext->sadb_ext_type));
  828. return (EINVAL);
  829. }
  830. headers[sadb_ext->sadb_ext_type] = p;
  831. p += i;
  832. left -= i;
  833. }
  834. if (left) {
  835. DPRINTF(("pfkeyv2_parsemessage: message too long\n"));
  836. return (EINVAL);
  837. }
  838. {
  839. uint64_t required;
  840. required = sadb_exts_required_in[sadb_msg->sadb_msg_type];
  841. if ((seen & required) != required) {
  842. DPRINTF(("pfkeyv2_parsemessage: required fields "
  843. "missing\n"));
  844. return (EINVAL);
  845. }
  846. }
  847. switch (((struct sadb_msg *)headers[0])->sadb_msg_type) {
  848. case SADB_UPDATE:
  849. if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
  850. SADB_SASTATE_MATURE) {
  851. DPRINTF(("pfkeyv2_parsemessage: updating non-mature "
  852. "SA prohibited\n"));
  853. return (EINVAL);
  854. }
  855. break;
  856. case SADB_ADD:
  857. if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
  858. SADB_SASTATE_MATURE) {
  859. DPRINTF(("pfkeyv2_parsemessage: adding non-mature "
  860. "SA prohibited\n"));
  861. return (EINVAL);
  862. }
  863. break;
  864. }
  865. return (0);
  866. }