Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/notify_payload.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2006-2018 Tobias Brunner
3: * Copyright (C) 2005-2010 Martin Willi
4: * Copyright (C) 2010 revosec AG
5: * Copyright (C) 2006 Daniel Roethlisberger
6: * Copyright (C) 2005 Jan Hutter
7: * HSR Hochschule fuer Technik Rapperswil
8: *
9: * This program is free software; you can redistribute it and/or modify it
10: * under the terms of the GNU General Public License as published by the
11: * Free Software Foundation; either version 2 of the License, or (at your
12: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13: *
14: * This program is distributed in the hope that it will be useful, but
15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17: * for more details.
18: */
19:
20: #include <stddef.h>
21:
22: #include "notify_payload.h"
23:
24: #include <daemon.h>
25: #include <encoding/payloads/encodings.h>
26: #include <crypto/hashers/hasher.h>
27:
28: ENUM_BEGIN(notify_type_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
29: "UNSUPPORTED_CRITICAL_PAYLOAD");
30: ENUM_NEXT(notify_type_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
31: "INVALID_IKE_SPI",
32: "INVALID_MAJOR_VERSION");
33: ENUM_NEXT(notify_type_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
34: "INVALID_SYNTAX");
35: ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
36: "INVALID_MESSAGE_ID");
37: ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
38: "INVALID_SPI");
39: ENUM_NEXT(notify_type_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
40: "ATTRIBUTES_NOT_SUPPORTED",
41: "NO_PROPOSAL_CHOSEN");
42: ENUM_NEXT(notify_type_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
43: "PAYLOAD_MALFORMED",
44: "INVALID_KE_PAYLOAD",
45: "INVALID_ID_INFORMATION",
46: "INVALID_CERT_ENCODING",
47: "INVALID_CERTIFICATE",
48: "CERT_TYPE_UNSUPPORTED",
49: "INVALID_CERT_AUTHORITY",
50: "INVALID_HASH_INFORMATION",
51: "AUTHENTICATION_FAILED");
52: ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
53: "SINGLE_PAIR_REQUIRED",
54: "NO_ADDITIONAL_SAS",
55: "INTERNAL_ADDRESS_FAILURE",
56: "FAILED_CP_REQUIRED",
57: "TS_UNACCEPTABLE",
58: "INVALID_SELECTORS",
59: "UNACCEPTABLE_ADDRESSES",
60: "UNEXPECTED_NAT_DETECTED",
61: "USE_ASSIGNED_HoA",
62: "TEMPORARY_FAILURE",
63: "CHILD_SA_NOT_FOUND");
64: ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
65: "ME_CONNECT_FAILED");
66: ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
67: "MS_NOTIFY_STATUS");
68: ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
69: "INITIAL_CONTACT",
70: "SET_WINDOW_SIZE",
71: "ADDITIONAL_TS_POSSIBLE",
72: "IPCOMP_SUPPORTED",
73: "NAT_DETECTION_SOURCE_IP",
74: "NAT_DETECTION_DESTINATION_IP",
75: "COOKIE",
76: "USE_TRANSPORT_MODE",
77: "HTTP_CERT_LOOKUP_SUPPORTED",
78: "REKEY_SA",
79: "ESP_TFC_PADDING_NOT_SUPPORTED",
80: "NON_FIRST_FRAGMENTS_ALSO",
81: "MOBIKE_SUPPORTED",
82: "ADDITIONAL_IP4_ADDRESS",
83: "ADDITIONAL_IP6_ADDRESS",
84: "NO_ADDITIONAL_ADDRESSES",
85: "UPDATE_SA_ADDRESSES",
86: "COOKIE2",
87: "NO_NATS_ALLOWED",
88: "AUTH_LIFETIME",
89: "MULTIPLE_AUTH_SUPPORTED",
90: "ANOTHER_AUTH_FOLLOWS",
91: "REDIRECT_SUPPORTED",
92: "REDIRECT",
93: "REDIRECTED_FROM",
94: "TICKET_LT_OPAQUE",
95: "TICKET_REQUEST",
96: "TICKET_ACK",
97: "TICKET_NACK",
98: "TICKET_OPAQUE",
99: "LINK_ID",
100: "USE_WESP_MODE",
101: "ROHC_SUPPORTED",
102: "EAP_ONLY_AUTHENTICATION",
103: "CHILDLESS_IKEV2_SUPPORTED",
104: "QUICK_CRASH_DETECTION",
105: "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
106: "IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED",
107: "IKEV2_MESSAGE_ID_SYNC",
108: "IPSEC_REPLAY_COUNTER_SYNC",
109: "SECURE PASSWORD_METHOD",
110: "PSK_PERSIST",
111: "PSK_CONFIRM",
112: "ERX_SUPPORTED",
113: "IFOM_CAPABILITY",
114: "SENDER_REQUEST_ID",
115: "FRAGMENTATION_SUPPORTED",
116: "SIGNATURE_HASH_ALGORITHMS");
117: ENUM_NEXT(notify_type_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
118: "USE_PPK",
119: "PPK_IDENTITY",
120: "NO_PPK_AUTH");
121: ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
122: "INITIAL_CONTACT");
123: ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
124: "DPD_R_U_THERE",
125: "DPD_R_U_THERE_ACK");
126: ENUM_NEXT(notify_type_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
127: "UNITY_LOAD_BALANCE");
128: ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
129: "USE_BEET_MODE");
130: ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
131: "ME_MEDIATION",
132: "ME_ENDPOINT",
133: "ME_CALLBACK",
134: "ME_CONNECTID",
135: "ME_CONNECTKEY",
136: "ME_CONNECTAUTH",
137: "ME_RESPONSE",
138: "RADIUS_ATTRIBUTE");
139: ENUM_END(notify_type_names, RADIUS_ATTRIBUTE);
140:
141:
142: ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
143: "CRIT");
144: ENUM_NEXT(notify_type_short_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
145: "INVAL_IKE_SPI",
146: "INVAL_MAJOR");
147: ENUM_NEXT(notify_type_short_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
148: "INVAL_SYN");
149: ENUM_NEXT(notify_type_short_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
150: "INVAL_MID");
151: ENUM_NEXT(notify_type_short_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
152: "INVAL_SPI");
153: ENUM_NEXT(notify_type_short_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
154: "ATTR_UNSUP",
155: "NO_PROP");
156: ENUM_NEXT(notify_type_short_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
157: "PLD_MAL",
158: "INVAL_KE",
159: "INVAL_ID",
160: "INVAL_CERTEN",
161: "INVAL_CERT",
162: "CERT_UNSUP",
163: "INVAL_CA",
164: "INVAL_HASH",
165: "AUTH_FAILED");
166: ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
167: "SINGLE_PAIR",
168: "NO_ADD_SAS",
169: "INT_ADDR_FAIL",
170: "FAIL_CP_REQ",
171: "TS_UNACCEPT",
172: "INVAL_SEL",
173: "UNACCEPT_ADDR",
174: "UNEXPECT_NAT",
175: "ASSIGNED_HoA",
176: "TEMP_FAIL",
177: "NO_CHILD_SA");
178: ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
179: "ME_CONN_FAIL");
180: ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
181: "MS_STATUS");
182: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
183: "INIT_CONTACT",
184: "SET_WINSIZE",
185: "ADD_TS_POSS",
186: "IPCOMP_SUP",
187: "NATD_S_IP",
188: "NATD_D_IP",
189: "COOKIE",
190: "USE_TRANSP",
191: "HTTP_CERT_LOOK",
192: "REKEY_SA",
193: "ESP_TFC_PAD_N",
194: "NON_FIRST_FRAG",
195: "MOBIKE_SUP",
196: "ADD_4_ADDR",
197: "ADD_6_ADDR",
198: "NO_ADD_ADDR",
199: "UPD_SA_ADDR",
200: "COOKIE2",
201: "NO_NATS",
202: "AUTH_LFT",
203: "MULT_AUTH",
204: "AUTH_FOLLOWS",
205: "REDIR_SUP",
206: "REDIR",
207: "REDIR_FROM",
208: "TKT_LT_OPAK",
209: "TKT_REQ",
210: "TKT_ACK",
211: "TKT_NACK",
212: "TKT_OPAK",
213: "LINK_ID",
214: "WESP_MODE",
215: "ROHC_SUP",
216: "EAP_ONLY",
217: "CHDLESS_SUP",
218: "CRASH_DET",
219: "MSG_ID_SYN_SUP",
220: "RPL_CTR_SYN_SUP",
221: "MSG_ID_SYN",
222: "RPL_CTR_SYN",
223: "SEC_PASSWD",
224: "PSK_PST",
225: "PSK_CFM",
226: "ERX_SUP",
227: "IFOM_CAP",
228: "SENDER_REQ_ID",
229: "FRAG_SUP",
230: "HASH_ALG");
231: ENUM_NEXT(notify_type_short_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
232: "USE_PPK",
233: "PPK_ID",
234: "NO_PPK");
235: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
236: "INITIAL_CONTACT");
237: ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
238: "DPD",
239: "DPD_ACK");
240: ENUM_NEXT(notify_type_short_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
241: "UNITY_LB");
242: ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
243: "BEET_MODE");
244: ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
245: "ME_MED",
246: "ME_EP",
247: "ME_CB",
248: "ME_CID",
249: "ME_CKEY",
250: "ME_CAUTH",
251: "ME_R",
252: "RADIUS");
253: ENUM_END(notify_type_short_names, RADIUS_ATTRIBUTE);
254:
255:
256: typedef struct private_notify_payload_t private_notify_payload_t;
257:
258: /**
259: * Private data of an notify_payload_t object.
260: */
261: struct private_notify_payload_t {
262:
263: /**
264: * Public notify_payload_t interface.
265: */
266: notify_payload_t public;
267:
268: /**
269: * Next payload type.
270: */
271: uint8_t next_payload;
272:
273: /**
274: * Critical flag.
275: */
276: bool critical;
277:
278: /**
279: * reserved bits
280: */
281: bool reserved[8];
282:
283: /**
284: * Length of this payload.
285: */
286: uint16_t payload_length;
287:
288: /**
289: * Domain of interpretation, IKEv1 only.
290: */
291: uint32_t doi;
292:
293: /**
294: * Protocol id.
295: */
296: uint8_t protocol_id;
297:
298: /**
299: * Spi size.
300: */
301: uint8_t spi_size;
302:
303: /**
304: * Notify message type.
305: */
306: uint16_t notify_type;
307:
308: /**
309: * Security parameter index (spi).
310: */
311: chunk_t spi;
312:
313: /**
314: * Notification data.
315: */
316: chunk_t notify_data;
317:
318: /**
319: * Type of payload, PLV2_NOTIFY or PLV1_NOTIFY
320: */
321: payload_type_t type;
322: };
323:
324: /**
325: * Encoding rules for an IKEv2 notification payload
326: */
327: static encoding_rule_t encodings_v2[] = {
328: /* 1 Byte next payload type, stored in the field next_payload */
329: { U_INT_8, offsetof(private_notify_payload_t, next_payload) },
330: /* the critical bit */
331: { FLAG, offsetof(private_notify_payload_t, critical) },
332: /* 7 Bit reserved bits, nowhere stored */
333: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[0]) },
334: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[1]) },
335: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[2]) },
336: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[3]) },
337: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[4]) },
338: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[5]) },
339: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[6]) },
340: /* Length of the whole payload*/
341: { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
342: /* Protocol ID as 8 bit field*/
343: { U_INT_8, offsetof(private_notify_payload_t, protocol_id) },
344: /* SPI Size as 8 bit field*/
345: { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) },
346: /* Notify message type as 16 bit field*/
347: { U_INT_16, offsetof(private_notify_payload_t, notify_type) },
348: /* SPI as variable length field*/
349: { SPI, offsetof(private_notify_payload_t, spi) },
350: /* Key Exchange Data is from variable size */
351: { CHUNK_DATA, offsetof(private_notify_payload_t, notify_data) },
352: };
353:
354: /*
355: 1 2 3
356: 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
357: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
358: ! Next Payload !C! RESERVED ! Payload Length !
359: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
360: ! Protocol ID ! SPI Size ! Notify Message Type !
361: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
362: ! !
363: ~ Security Parameter Index (SPI) ~
364: ! !
365: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
366: ! !
367: ~ Notification Data ~
368: ! !
369: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
370: */
371: /**
372: * Encoding rules for an IKEv1 notification payload
373: */
374: static encoding_rule_t encodings_v1[] = {
375: /* 1 Byte next payload type, stored in the field next_payload */
376: { U_INT_8, offsetof(private_notify_payload_t, next_payload) },
377: /* 8 reserved bits */
378: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[0]) },
379: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[1]) },
380: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[2]) },
381: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[3]) },
382: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[4]) },
383: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[5]) },
384: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[6]) },
385: { RESERVED_BIT, offsetof(private_notify_payload_t, reserved[7]) },
386: /* Length of the whole payload*/
387: { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
388: /* DOI as 32 bit field*/
389: { U_INT_32, offsetof(private_notify_payload_t, doi) },
390: /* Protocol ID as 8 bit field*/
391: { U_INT_8, offsetof(private_notify_payload_t, protocol_id) },
392: /* SPI Size as 8 bit field*/
393: { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) },
394: /* Notify message type as 16 bit field*/
395: { U_INT_16, offsetof(private_notify_payload_t, notify_type) },
396: /* SPI as variable length field*/
397: { SPI, offsetof(private_notify_payload_t, spi) },
398: /* Key Exchange Data is from variable size */
399: { CHUNK_DATA, offsetof(private_notify_payload_t, notify_data) },
400: };
401:
402: /*
403: 1 2 3
404: 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
405: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
406: ! Next Payload ! RESERVED ! Payload Length !
407: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
408: ! DOI !
409: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
410: ! Protocol ID ! SPI Size ! Notify Message Type !
411: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
412: ! !
413: ~ Security Parameter Index (SPI) ~
414: ! !
415: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416: ! !
417: ~ Notification Data ~
418: ! !
419: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
420: */
421:
422:
423: METHOD(payload_t, verify, status_t,
424: private_notify_payload_t *this)
425: {
426: bool bad_length = FALSE;
427:
428: switch (this->protocol_id)
429: {
430: case PROTO_NONE:
431: case PROTO_IKE:
432: case PROTO_AH:
433: case PROTO_ESP:
434: break;
435: default:
436: DBG1(DBG_ENC, "Unknown protocol (%d)", this->protocol_id);
437: return FAILED;
438: }
439:
440: switch (this->notify_type)
441: {
442: case INVALID_KE_PAYLOAD:
443: {
444: if (this->type == PLV2_NOTIFY && this->notify_data.len != 2)
445: {
446: bad_length = TRUE;
447: }
448: break;
449: }
450: case NAT_DETECTION_SOURCE_IP:
451: case NAT_DETECTION_DESTINATION_IP:
452: case ME_CONNECTAUTH:
453: {
454: if (this->notify_data.len != HASH_SIZE_SHA1)
455: {
456: bad_length = TRUE;
457: }
458: break;
459: }
460: case INVALID_SYNTAX:
461: case INVALID_MAJOR_VERSION:
462: case NO_PROPOSAL_CHOSEN:
463: {
464: if (this->type == PLV2_NOTIFY && this->notify_data.len != 0)
465: {
466: bad_length = TRUE;
467: }
468: break;
469: }
470: case COOKIE:
471: {
472: if (this->notify_data.len < 1 || this->notify_data.len > 64)
473: {
474: bad_length = TRUE;
475: }
476: break;
477: }
478: case ADDITIONAL_IP4_ADDRESS:
479: {
480: if (this->notify_data.len != 4)
481: {
482: bad_length = TRUE;
483: }
484: break;
485: }
486: case ADDITIONAL_IP6_ADDRESS:
487: {
488: if (this->notify_data.len != 16)
489: {
490: bad_length = TRUE;
491: }
492: break;
493: }
494: case SIGNATURE_HASH_ALGORITHMS:
495: {
496: if (this->notify_data.len % 2)
497: {
498: bad_length = TRUE;
499: }
500: break;
501: }
502: case AUTH_LIFETIME:
503: {
504: if (this->notify_data.len != 4)
505: {
506: bad_length = TRUE;
507: }
508: break;
509: }
510: case IPCOMP_SUPPORTED:
511: {
512: if (this->notify_data.len != 3)
513: {
514: bad_length = TRUE;
515: }
516: break;
517: }
518: case ME_ENDPOINT:
519: if (this->notify_data.len != 8 &&
520: this->notify_data.len != 12 &&
521: this->notify_data.len != 24)
522: {
523: bad_length = TRUE;
524: }
525: break;
526: case ME_CONNECTID:
527: if (this->notify_data.len < 4 ||
528: this->notify_data.len > 16)
529: {
530: bad_length = TRUE;
531: }
532: break;
533: case ME_CONNECTKEY:
534: if (this->notify_data.len < 16 ||
535: this->notify_data.len > 32)
536: {
537: bad_length = TRUE;
538: }
539: break;
540: case DPD_R_U_THERE:
541: case DPD_R_U_THERE_ACK:
542: if (this->notify_data.len != 4)
543: {
544: bad_length = TRUE;
545: }
546: break;
547: default:
548: /* TODO: verify */
549: break;
550: }
551: if (bad_length)
552: {
553: DBG1(DBG_ENC, "invalid notify data length for %N (%d)",
554: notify_type_names, this->notify_type,
555: this->notify_data.len);
556: return FAILED;
557: }
558: return SUCCESS;
559: }
560:
561: METHOD(payload_t, get_encoding_rules, int,
562: private_notify_payload_t *this, encoding_rule_t **rules)
563: {
564: if (this->type == PLV2_NOTIFY)
565: {
566: *rules = encodings_v2;
567: return countof(encodings_v2);
568: }
569: *rules = encodings_v1;
570: return countof(encodings_v1);
571: }
572:
573: METHOD(payload_t, get_header_length, int,
574: private_notify_payload_t *this)
575: {
576: if (this->type == PLV2_NOTIFY)
577: {
578: return 8 + this->spi_size;
579: }
580: return 12 + this->spi_size;
581: }
582:
583: METHOD(payload_t, get_type, payload_type_t,
584: private_notify_payload_t *this)
585: {
586: return this->type;
587: }
588:
589: METHOD(payload_t, get_next_type, payload_type_t,
590: private_notify_payload_t *this)
591: {
592: return this->next_payload;
593: }
594:
595: METHOD(payload_t, set_next_type, void,
596: private_notify_payload_t *this, payload_type_t type)
597: {
598: this->next_payload = type;
599: }
600:
601: /**
602: * recompute the payloads length.
603: */
604: static void compute_length(private_notify_payload_t *this)
605: {
606: this->payload_length = get_header_length(this) + this->notify_data.len;
607: }
608:
609: METHOD(payload_t, get_length, size_t,
610: private_notify_payload_t *this)
611: {
612: return this->payload_length;
613: }
614:
615: METHOD(notify_payload_t, get_protocol_id, uint8_t,
616: private_notify_payload_t *this)
617: {
618: return this->protocol_id;
619: }
620:
621: METHOD(notify_payload_t, set_protocol_id, void,
622: private_notify_payload_t *this, uint8_t protocol_id)
623: {
624: this->protocol_id = protocol_id;
625: }
626:
627: METHOD(notify_payload_t, get_notify_type, notify_type_t,
628: private_notify_payload_t *this)
629: {
630: return this->notify_type;
631: }
632:
633: METHOD(notify_payload_t, set_notify_type, void,
634: private_notify_payload_t *this, notify_type_t notify_type)
635: {
636: this->notify_type = notify_type;
637: }
638:
639: METHOD(notify_payload_t, get_spi, uint32_t,
640: private_notify_payload_t *this)
641: {
642: switch (this->protocol_id)
643: {
644: case PROTO_AH:
645: case PROTO_ESP:
646: if (this->spi.len == 4)
647: {
648: return *((uint32_t*)this->spi.ptr);
649: }
650: default:
651: break;
652: }
653: return 0;
654: }
655:
656: METHOD(notify_payload_t, set_spi, void,
657: private_notify_payload_t *this, uint32_t spi)
658: {
659: chunk_free(&this->spi);
660: switch (this->protocol_id)
661: {
662: case PROTO_AH:
663: case PROTO_ESP:
664: this->spi = chunk_alloc(4);
665: *((uint32_t*)this->spi.ptr) = spi;
666: break;
667: default:
668: break;
669: }
670: this->spi_size = this->spi.len;
671: compute_length(this);
672: }
673:
674: METHOD(notify_payload_t, get_spi_data, chunk_t,
675: private_notify_payload_t *this)
676: {
677: switch (this->protocol_id)
678: {
679: case PROTO_IKE:
680: if (this->spi.len == 16)
681: {
682: return this->spi;
683: }
684: default:
685: break;
686: }
687: return chunk_empty;
688: }
689:
690: METHOD(notify_payload_t, set_spi_data, void,
691: private_notify_payload_t *this, chunk_t spi)
692: {
693: chunk_free(&this->spi);
694: switch (this->protocol_id)
695: {
696: case PROTO_IKE:
697: this->spi = chunk_clone(spi);
698: default:
699: break;
700: }
701: this->spi_size = this->spi.len;
702: compute_length(this);
703: }
704:
705: METHOD(notify_payload_t, get_notification_data, chunk_t,
706: private_notify_payload_t *this)
707: {
708: return this->notify_data;
709: }
710:
711: METHOD(notify_payload_t, set_notification_data, void,
712: private_notify_payload_t *this, chunk_t data)
713: {
714: free(this->notify_data.ptr);
715: this->notify_data = chunk_clone(data);
716: compute_length(this);
717: }
718:
719: METHOD2(payload_t, notify_payload_t, destroy, void,
720: private_notify_payload_t *this)
721: {
722: free(this->notify_data.ptr);
723: free(this->spi.ptr);
724: free(this);
725: }
726:
727: /*
728: * Described in header
729: */
730: notify_payload_t *notify_payload_create(payload_type_t type)
731: {
732: private_notify_payload_t *this;
733:
734: INIT(this,
735: .public = {
736: .payload_interface = {
737: .verify = _verify,
738: .get_encoding_rules = _get_encoding_rules,
739: .get_header_length = _get_header_length,
740: .get_length = _get_length,
741: .get_next_type = _get_next_type,
742: .set_next_type = _set_next_type,
743: .get_type = _get_type,
744: .destroy = _destroy,
745: },
746: .get_protocol_id = _get_protocol_id,
747: .set_protocol_id = _set_protocol_id,
748: .get_notify_type = _get_notify_type,
749: .set_notify_type = _set_notify_type,
750: .get_spi = _get_spi,
751: .set_spi = _set_spi,
752: .get_spi_data = _get_spi_data,
753: .set_spi_data = _set_spi_data,
754: .get_notification_data = _get_notification_data,
755: .set_notification_data = _set_notification_data,
756: .destroy = _destroy,
757: },
758: .doi = IKEV1_DOI_IPSEC,
759: .next_payload = PL_NONE,
760: .type = type,
761: );
762: compute_length(this);
763: return &this->public;
764: }
765:
766: /*
767: * Described in header.
768: */
769: notify_payload_t *notify_payload_create_from_protocol_and_type(
770: payload_type_t type, protocol_id_t protocol, notify_type_t notify)
771: {
772: notify_payload_t *this = notify_payload_create(type);
773:
774: this->set_notify_type(this, notify);
775: this->set_protocol_id(this, protocol);
776:
777: return this;
778: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>