Return to notify_payload.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
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: }