diff options
Diffstat (limited to 'src/charon/encoding')
-rw-r--r-- | src/charon/encoding/message.c | 47 | ||||
-rw-r--r-- | src/charon/encoding/message.h | 13 | ||||
-rw-r--r-- | src/charon/encoding/payloads/endpoint_notify.c | 422 | ||||
-rw-r--r-- | src/charon/encoding/payloads/endpoint_notify.h | 185 | ||||
-rw-r--r-- | src/charon/encoding/payloads/id_payload.c | 44 | ||||
-rw-r--r-- | src/charon/encoding/payloads/id_payload.h | 36 | ||||
-rw-r--r-- | src/charon/encoding/payloads/ike_header.c | 22 | ||||
-rw-r--r-- | src/charon/encoding/payloads/ike_header.h | 11 | ||||
-rw-r--r-- | src/charon/encoding/payloads/notify_payload.c | 42 | ||||
-rw-r--r-- | src/charon/encoding/payloads/notify_payload.h | 16 | ||||
-rw-r--r-- | src/charon/encoding/payloads/payload.c | 21 | ||||
-rw-r--r-- | src/charon/encoding/payloads/payload.h | 23 | ||||
-rw-r--r-- | src/charon/encoding/payloads/sa_payload.c | 2 |
13 files changed, 800 insertions, 84 deletions
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c index 980ff12b5..3dfa64fb9 100644 --- a/src/charon/encoding/message.c +++ b/src/charon/encoding/message.c @@ -6,7 +6,8 @@ */ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2007 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -149,9 +150,15 @@ static payload_rule_t ike_auth_i_payload_rules[] = { {CERTIFICATE,0,1,TRUE,FALSE}, {CERTIFICATE_REQUEST,0,1,TRUE,FALSE}, {ID_RESPONDER,0,1,TRUE,FALSE}, +#ifdef P2P + {SECURITY_ASSOCIATION,0,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE}, +#else {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE}, {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE}, +#endif /* P2P */ {CONFIGURATION,0,1,TRUE,FALSE}, {VENDOR_ID,0,10,TRUE,FALSE}, }; @@ -222,6 +229,24 @@ static payload_rule_t create_child_sa_r_payload_rules[] = { {VENDOR_ID,0,10,TRUE,FALSE}, }; +#ifdef P2P +/** + * Message rule for P2P_CONNECT from initiator. + */ +static payload_rule_t p2p_connect_i_payload_rules[] = { + {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, + {ID_PEER,1,1,TRUE,FALSE}, + {VENDOR_ID,0,10,TRUE,FALSE} +}; + +/** + * Message rule for P2P_CONNECT from responder. + */ +static payload_rule_t p2p_connect_r_payload_rules[] = { + {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, + {VENDOR_ID,0,10,TRUE,FALSE} +}; +#endif /* P2P */ /** * Message rules, defines allowed payloads. @@ -235,6 +260,10 @@ static message_rule_t message_rules[] = { {INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules}, {CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules}, {CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules}, +#ifdef P2P + {P2P_CONNECT,TRUE,TRUE,(sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),p2p_connect_i_payload_rules}, + {P2P_CONNECT,FALSE,TRUE,(sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),p2p_connect_r_payload_rules}, +#endif /* P2P */ }; @@ -446,6 +475,14 @@ static exchange_type_t get_exchange_type (private_message_t *this) } /** + * Implementation of message_t.get_first_payload_type. + */ +static payload_type_t get_first_payload_type (private_message_t *this) +{ + return this->first_payload; +} + +/** * Implementation of message_t.set_request. */ static void set_request (private_message_t *this,bool request) @@ -672,6 +709,13 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si return SUCCESS; } + if (!crypter || !signer) + { + DBG2(DBG_ENC, "no crypter or signer specified, do not encrypt message"); + /* message contains no content to encrypt */ + return SUCCESS; + } + DBG2(DBG_ENC, "copy all payloads to a temporary list"); all_payloads = linked_list_create(); @@ -1255,6 +1299,7 @@ message_t *message_create_from_packet(packet_t *packet) this->public.get_ike_sa_id = (ike_sa_id_t*(*)(message_t*))get_ike_sa_id; this->public.set_exchange_type = (void(*)(message_t*, exchange_type_t))set_exchange_type; this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type; + this->public.get_first_payload_type = (payload_type_t(*)(message_t*))get_first_payload_type; this->public.set_request = (void(*)(message_t*, bool))set_request; this->public.get_request = (bool(*)(message_t*))get_request; this->public.add_payload = (void(*)(message_t*,payload_t*))add_payload; diff --git a/src/charon/encoding/message.h b/src/charon/encoding/message.h index 73c2e05c6..35b659f33 100644 --- a/src/charon/encoding/message.h +++ b/src/charon/encoding/message.h @@ -6,7 +6,8 @@ */ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2007 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -152,6 +153,14 @@ struct message_t { * @return exchange type of the message */ exchange_type_t (*get_exchange_type) (message_t *this); + + /** + * @brief Gets the payload type of the first payload. + * + * @param this message_t object + * @return payload type of the first payload + */ + payload_type_t (*get_first_payload_type) (message_t *this); /** * @brief Sets the request flag. @@ -319,7 +328,7 @@ struct message_t { iterator_t * (*get_payload_iterator) (message_t *this); /** - * @brief Find a payload of a spicific type. + * @brief Find a payload of a specific type. * * Returns the first occurance. * diff --git a/src/charon/encoding/payloads/endpoint_notify.c b/src/charon/encoding/payloads/endpoint_notify.c new file mode 100644 index 000000000..30f3ecd5f --- /dev/null +++ b/src/charon/encoding/payloads/endpoint_notify.c @@ -0,0 +1,422 @@ +/** + * @file endpoint_notify.c + * + * @brief Implementation of endpoint_notify_t. + * + */ + +/* + * Copyright (C) 2007 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "endpoint_notify.h" + +#include <math.h> + +#include <daemon.h> + +typedef struct private_endpoint_notify_t private_endpoint_notify_t; + +/** + * Private data of an notify_payload_t object. + * + */ +struct private_endpoint_notify_t { + /** + * Public endpoint_notify_t interface. + */ + endpoint_notify_t public; + + /** + * Priority + */ + u_int32_t priority; + + /** + * Family + */ + p2p_endpoint_family_t family; + + /** + * Endpoint type + */ + p2p_endpoint_type_t type; + + /** + * Endpoint + */ + host_t *endpoint; + + /** + * Base (used for server reflexive endpoints) + */ + host_t *base; +}; + +/* Notification data: + 1 2 3 + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Priority ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Family ! Type ! Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! IP Address (variable) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/** + * Helper functions to parse integer values + */ +static status_t parse_uint8(u_int8_t **cur, u_int8_t *top, u_int8_t *val) +{ + if (*cur + sizeof(u_int8_t) > top) + { + return FAILED; + } + *val = *(u_int8_t*)*cur; + *cur += sizeof(u_int8_t); + return SUCCESS; +} + +static status_t parse_uint16(u_int8_t **cur, u_int8_t *top, u_int16_t *val) +{ + if (*cur + sizeof(u_int16_t) > top) + { + return FAILED; + } + *val = ntohs(*(u_int16_t*)*cur); + *cur += sizeof(u_int16_t); + return SUCCESS; +} + +static status_t parse_uint32(u_int8_t **cur, u_int8_t *top, u_int32_t *val) +{ + if (*cur + sizeof(u_int32_t) > top) + { + return FAILED; + } + *val = ntohl(*(u_int32_t*)*cur); + *cur += sizeof(u_int32_t); + return SUCCESS; +} + +/** + * Parses the notification data of a P2P_ENDPOINT notify + */ +static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t data) +{ + u_int8_t family, type, addr_family; + u_int16_t port; + chunk_t addr; + u_int8_t *cur = data.ptr; + u_int8_t *top = data.ptr + data.len; + + DBG3(DBG_IKE, "p2p_endpoint_data %B", &data); + + if (parse_uint32(&cur, top, &this->priority) != SUCCESS) + { + DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid priority"); + return FAILED; + } + + if (parse_uint8(&cur, top, &family) != SUCCESS || family >= MAX_FAMILY) + { + DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid family"); + return FAILED; + } + + this->family = (p2p_endpoint_family_t)family; + + if (parse_uint8(&cur, top, &type) != SUCCESS || type >= MAX_TYPE) + { + DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid type"); + return FAILED; + } + + this->type = (p2p_endpoint_type_t)type; + + addr_family = AF_INET; + addr.len = 4; + + switch(this->family) + { + case NO_FAMILY: + this->endpoint = NULL; + break; + + case IPv6: + addr_family = AF_INET6; + addr.len = 16; + // fall-through + case IPv4: + if (parse_uint16(&cur, top, &port) != SUCCESS) + { + DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid port"); + return FAILED; + } + + if (cur + addr.len > top) + { + DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid IP address"); + return FAILED; + } + + addr.ptr = cur; + + this->endpoint = host_create_from_chunk(addr_family, addr, port); + break; + } + + return SUCCESS; +} + + +/** + * Generates the notification data of a P2P_ENDPOINT notify + */ +static chunk_t build_notification_data(private_endpoint_notify_t *this) +{ + chunk_t prio_chunk, family_chunk, type_chunk, port_chunk, addr_chunk; + chunk_t data; + u_int32_t prio; + u_int16_t port; + u_int8_t family, type; + + prio = htonl(this->priority); + prio_chunk = chunk_from_thing(prio); + family = this->family; + family_chunk = chunk_from_thing(family); + type = this->type; + type_chunk = chunk_from_thing(type); + + if (this->endpoint) + { + port = htons(this->endpoint->get_port(this->endpoint)); + addr_chunk = this->endpoint->get_address(this->endpoint); + } + else + { + port = 0; + addr_chunk = chunk_empty; + } + port_chunk = chunk_from_thing(port); + + // data = prio | family | type | port | addr + data = chunk_cat("ccccc", prio_chunk, family_chunk, type_chunk, + port_chunk, addr_chunk); + DBG3(DBG_IKE, "p2p_endpoint_data %B", &data); + + return data; +} + +/** + * Implementation of endpoint_notify_t.build_notify + */ +static notify_payload_t *build_notify(private_endpoint_notify_t *this) +{ + chunk_t data; + notify_payload_t *notify; + + notify = notify_payload_create(); + notify->set_notify_type(notify, P2P_ENDPOINT); + data = build_notification_data(this); + notify->set_notification_data(notify, data); + chunk_free(&data); + + return notify; +} + +/** + * Implementation of endpoint_notify_t.get_priority. + */ +static u_int32_t get_priority(private_endpoint_notify_t *this) +{ + return this->priority; +} + +/** + * Implementation of endpoint_notify_t.set_priority. + */ +static void set_priority(private_endpoint_notify_t *this, u_int32_t priority) +{ + return this->priority = priority; +} + +/** + * Implementation of endpoint_notify_t.get_type. + */ +static p2p_endpoint_type_t get_type(private_endpoint_notify_t *this) +{ + return this->type; +} + +/** + * Implementation of endpoint_notify_t.get_family. + */ +static p2p_endpoint_family_t get_family(private_endpoint_notify_t *this) +{ + return this->family; +} + +/** + * Implementation of endpoint_notify_t.get_host. + */ +static host_t *get_host(private_endpoint_notify_t *this) +{ + return this->endpoint; +} + +/** + * Implementation of endpoint_notify_t.get_base. + */ +static host_t *get_base(private_endpoint_notify_t *this) +{ + return (!this->base) ? this->endpoint : this->base; +} + +/** + * Implementation of endpoint_notify_t.clone. + */ +static endpoint_notify_t *_clone(private_endpoint_notify_t *this) +{ + private_endpoint_notify_t *clone = (private_endpoint_notify_t*)endpoint_notify_create(); + + clone->priority = this->priority; + clone->type = this->type; + clone->family = this->family; + if (this->endpoint) + { + clone->endpoint = this->endpoint->clone(this->endpoint); + } + + if (this->base) + { + clone->base = this->base->clone(this->base); + } + + return &clone->public; +} + +/** + * Implementation of endpoint_notify_t.destroy. + */ +static status_t destroy(private_endpoint_notify_t *this) +{ + DESTROY_IF(this->endpoint); + free(this); + return SUCCESS; +} + +/* + * Described in header + */ +endpoint_notify_t *endpoint_notify_create() +{ + private_endpoint_notify_t *this = malloc_thing(private_endpoint_notify_t); + + /* public functions */ + this->public.get_priority = (u_int32_t (*) (endpoint_notify_t *)) get_priority; + this->public.set_priority = (void (*) (endpoint_notify_t *, u_int32_t)) set_priority; + this->public.get_type = (p2p_endpoint_type_t (*) (endpoint_notify_t *)) get_type; + this->public.get_family = (p2p_endpoint_family_t (*) (endpoint_notify_t *)) get_family; + this->public.get_host = (host_t *(*) (endpoint_notify_t *)) get_host; + this->public.get_base = (host_t *(*) (endpoint_notify_t *)) get_base; + this->public.build_notify = (notify_payload_t *(*) (endpoint_notify_t *)) build_notify; + this->public.clone = (endpoint_notify_t *(*) (endpoint_notify_t *)) _clone; + this->public.destroy = (void (*) (endpoint_notify_t *)) destroy; + + /* set default values of the fields */ + this->priority = 0; + this->family = NO_FAMILY; + this->type = NO_TYPE; + this->endpoint = NULL; + this->base = NULL; + + return &this->public; +} + +/** + * Described in header + */ +endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base) +{ + private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create(); + + this->type = type; + + switch(type) + { + case HOST: + this->priority = pow(2, 16) * P2P_PRIO_HOST; + break; + case SERVER_REFLEXIVE: + this->priority = pow(2, 16) * P2P_PRIO_SERVER; + break; + case PEER_REFLEXIVE: + this->priority = pow(2, 16) * P2P_PRIO_PEER; + break; + case RELAYED: + this->priority = pow(2, 16) * P2P_PRIO_RELAY; + break; + } + + this->priority += 65535; + + if (!host) { + return &this->public; + } + + switch(host->get_family(host)) + { + case AF_INET: + this->family = IPv4; + break; + case AF_INET6: + this->family = IPv6; + break; + default: + // unsupported family type, we do not set the hsot (family is set to NO_FAMILY) + return &this->public; + } + + this->endpoint = host->clone(host); + + if (base) + { + this->base = base->clone(base); + } + + return &this->public; +} + +/** + * Described in header + */ +endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify) +{ + if (notify->get_notify_type(notify) != P2P_ENDPOINT) + { + return NULL; + } + + private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create(); + chunk_t data = notify->get_notification_data(notify); + if (parse_notification_data(this, data) != SUCCESS) + { + destroy(this); + return NULL; + } + return &this->public; +} diff --git a/src/charon/encoding/payloads/endpoint_notify.h b/src/charon/encoding/payloads/endpoint_notify.h new file mode 100644 index 000000000..272301d5b --- /dev/null +++ b/src/charon/encoding/payloads/endpoint_notify.h @@ -0,0 +1,185 @@ +/** + * @file endpoint_notify.h + * + * @brief Interface of endpoint_notify_t. + * + */ + +/* + * Copyright (C) 2007 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + + +#ifndef ENDPOINT_NOTIFY_H_ +#define ENDPOINT_NOTIFY_H_ + +#define P2P_PRIO_HOST 255 +#define P2P_PRIO_SERVER 100 +#define P2P_PRIO_PEER 120 +#define P2P_PRIO_RELAY 0 + +typedef enum p2p_endpoint_family_t p2p_endpoint_family_t; +typedef enum p2p_endpoint_type_t p2p_endpoint_type_t; +typedef struct endpoint_notify_t endpoint_notify_t; + +#include <encoding/payloads/notify_payload.h> + +enum p2p_endpoint_family_t { + + NO_FAMILY = 0, + + IPv4 = 1, + + IPv6 = 2, + + MAX_FAMILY = 3 + +}; + +enum p2p_endpoint_type_t { + + NO_TYPE = 0, + + HOST = 1, + + SERVER_REFLEXIVE = 2, + + PEER_REFLEXIVE = 3, + + RELAYED = 4, + + MAX_TYPE = 5 + +}; + +/** + * @brief Class representing a P2P_ENDPOINT notify. In fact it's not + * the notify per se, but the notification data of that notify that is + * handled with this class. + * + * @b Constructors: + * - endpoint_notify_create() + * - endpoint_notify_create_from_host() + * + * @ingroup payloads + */ +struct endpoint_notify_t { + /** + * @brief Returns the priority of this endpoint. + * + * @param this object + * @return priority + */ + u_int32_t (*get_priority) (endpoint_notify_t *this); + + /** + * @brief Sets the priority of this endpoint. + * + * @param this object + * @param priority priority + */ + void (*set_priority) (endpoint_notify_t *this, u_int32_t priority); + + /** + * @brief Returns the endpoint type of this endpoint. + * + * @param this object + * @return endpoint type + */ + p2p_endpoint_type_t (*get_type) (endpoint_notify_t *this); + + /** + * @brief Returns the endpoint family of this endpoint. + * + * @param this object + * @return endpoint family + */ + p2p_endpoint_family_t (*get_family) (endpoint_notify_t *this); + + /** + * @brief Returns the host of this endpoint. + * + * @param this object + * @return host + */ + host_t *(*get_host) (endpoint_notify_t *this); + + /** + * @brief Returns the base of this endpoint. + * + * If this is not a SERVER_REFLEXIVE endpoint, the returned host is the same + * as the one returned by get_host. + * + * @param this object + * @return host + */ + host_t *(*get_base) (endpoint_notify_t *this); + + /** + * @brief Generates a notification payload from this endpoint. + * + * @param this object + * @return built notify_payload_t + */ + notify_payload_t *(*build_notify) (endpoint_notify_t *this); + + /** + * @brief Clones an endpoint_notify_t object. + * + * @param this endpoint_notify_t object to clone + * @return cloned object + */ + endpoint_notify_t *(*clone) (endpoint_notify_t *this); + + /** + * @brief Destroys an endpoint_notify_t object. + * + * @param this endpoint_notify_t object to destroy + */ + void (*destroy) (endpoint_notify_t *this); +}; + +/** + * @brief Creates an empty endpoint_notify_t object. + * + * @return created endpoint_notify_t object + * + * @ingroup payloads + */ +endpoint_notify_t *endpoint_notify_create(void); + + +/** + * @brief Creates an endpoint_notify_t object from a host. + * + * @param type the endpoint type + * @param host host to base the notify on (gets cloned) + * @param base base of the endpoint, applies only to reflexive endpoints (gets cloned) + * @return created endpoint_notify_t object + * + * @ingroup payloads + */ +endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base); + +/** + * @brief Creates an endpoint_notify_t object from a notify payload. + * + * @param notify the notify payload + * @return - created endpoint_notify_t object + * - NULL if invalid payload + * @ingroup payloads + */ +endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify); + +#endif /*ENDPOINT_NOTIFY_H_*/ diff --git a/src/charon/encoding/payloads/id_payload.c b/src/charon/encoding/payloads/id_payload.c index 74c0ce870..eee5e92db 100644 --- a/src/charon/encoding/payloads/id_payload.c +++ b/src/charon/encoding/payloads/id_payload.c @@ -6,6 +6,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -41,14 +42,14 @@ struct private_id_payload_t { id_payload_t public; /** - * TRUE if this ID payload is of type IDi, FALSE for IDr. + * one of ID_INITIATOR, ID_RESPONDER */ - bool is_initiator; + payload_type_t payload_type; /** * Next payload type. */ - u_int8_t next_payload; + payload_type_t next_payload; /** * Critical flag. @@ -149,14 +150,7 @@ static void get_encoding_rules(private_id_payload_t *this, encoding_rule_t **rul */ static payload_type_t get_payload_type(private_id_payload_t *this) { - if (this->is_initiator) - { - return ID_INITIATOR; - } - else - { - return ID_RESPONDER; - } + return this->payload_type; } /** @@ -164,7 +158,7 @@ static payload_type_t get_payload_type(private_id_payload_t *this) */ static payload_type_t get_next_type(private_id_payload_t *this) { - return (this->next_payload); + return this->next_payload; } /** @@ -238,22 +232,6 @@ static chunk_t get_data_clone (private_id_payload_t *this) } /** - * Implementation of id_payload_t.get_initiator. - */ -static bool get_initiator (private_id_payload_t *this) -{ - return (this->is_initiator); -} - -/** - * Implementation of id_payload_t.set_initiator. - */ -static void set_initiator (private_id_payload_t *this,bool is_initiator) -{ - this->is_initiator = is_initiator; -} - -/** * Implementation of id_payload_t.get_identification. */ static identification_t *get_identification (private_id_payload_t *this) @@ -276,7 +254,7 @@ static void destroy(private_id_payload_t *this) /* * Described in header. */ -id_payload_t *id_payload_create(bool is_initiator) +id_payload_t *id_payload_create(payload_type_t payload_type) { private_id_payload_t *this = malloc_thing(private_id_payload_t); @@ -297,8 +275,6 @@ id_payload_t *id_payload_create(bool is_initiator) this->public.get_data = (chunk_t (*) (id_payload_t *)) get_data; this->public.get_data_clone = (chunk_t (*) (id_payload_t *)) get_data_clone; - this->public.get_initiator = (bool (*) (id_payload_t *)) get_initiator; - this->public.set_initiator = (void (*) (id_payload_t *,bool)) set_initiator; this->public.get_identification = (identification_t * (*) (id_payload_t *this)) get_identification; /* private variables */ @@ -306,7 +282,7 @@ id_payload_t *id_payload_create(bool is_initiator) this->next_payload = NO_PAYLOAD; this->payload_length =ID_PAYLOAD_HEADER_LENGTH; this->id_data = chunk_empty; - this->is_initiator = is_initiator; + this->payload_type = payload_type; return (&(this->public)); } @@ -314,9 +290,9 @@ id_payload_t *id_payload_create(bool is_initiator) /* * Described in header. */ -id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification) +id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification) { - id_payload_t *this= id_payload_create(is_initiator); + id_payload_t *this= id_payload_create(payload_type); this->set_data(this,identification->get_encoding(identification)); this->set_id_type(this,identification->get_type(identification)); return this; diff --git a/src/charon/encoding/payloads/id_payload.h b/src/charon/encoding/payloads/id_payload.h index b67d85d2e..8e9322b4a 100644 --- a/src/charon/encoding/payloads/id_payload.h +++ b/src/charon/encoding/payloads/id_payload.h @@ -6,6 +6,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -112,28 +113,6 @@ struct id_payload_t { identification_t *(*get_identification) (id_payload_t *this); /** - * @brief Get the type of ID payload (IDi or IDr). - * - * @param this calling id_payload_t object - * @return - * - TRUE if this payload is of type IDi - * - FALSE if this payload is of type IDr - * - */ - bool (*get_initiator) (id_payload_t *this); - - /** - * @brief Set the type of ID payload (IDi or IDr). - * - * @param this calling id_payload_t object - * @param is_initiator - * - TRUE if this payload is of type IDi - * - FALSE if this payload is of type IDr - * - */ - void (*set_initiator) (id_payload_t *this,bool is_initiator); - - /** * @brief Destroys an id_payload_t object. * * @param this id_payload_t object to destroy @@ -144,28 +123,23 @@ struct id_payload_t { /** * @brief Creates an empty id_payload_t object. * - * @param is_initiator - * - TRUE if this payload is of type IDi - * - FALSE if this payload is of type IDr - * + * @param payload_type one of ID_INITIATOR, ID_RESPONDER * @return id_payload_t object * * @ingroup payloads */ -id_payload_t *id_payload_create(bool is_initiator); +id_payload_t *id_payload_create(payload_type_t payload_type); /** * @brief Creates an id_payload_t from an existing identification_t object. * - * @param is_initiator - * - TRUE if this payload is of type IDi - * - FALSE if this payload is of type IDr + * @param payload_type one of ID_INITIATOR, ID_RESPONDER * @param identification identification_t object * @return id_payload_t object * * @ingroup payloads */ -id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification); +id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification); diff --git a/src/charon/encoding/payloads/ike_header.c b/src/charon/encoding/payloads/ike_header.c index b1b4fbf87..7253e4f51 100644 --- a/src/charon/encoding/payloads/ike_header.c +++ b/src/charon/encoding/payloads/ike_header.c @@ -6,6 +6,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -109,7 +110,13 @@ ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFIN "IKE_AUTH", "CREATE_CHILD_SA", "INFORMATIONAL"); +#ifdef P2P +ENUM_NEXT(exchange_type_names, P2P_CONNECT, P2P_CONNECT, INFORMATIONAL, + "P2P_CONNECT"); +ENUM_END(exchange_type_names, P2P_CONNECT); +#else ENUM_END(exchange_type_names, INFORMATIONAL); +#endif /* P2P */ /** * Encoding rules to parse or generate a IKEv2-Header. @@ -172,12 +179,23 @@ encoding_rule_t ike_header_encodings[] = { */ static status_t verify(private_ike_header_t *this) { - if ((this->exchange_type < IKE_SA_INIT) || (this->exchange_type > INFORMATIONAL)) + if ((this->exchange_type < IKE_SA_INIT) || + ((this->exchange_type > INFORMATIONAL) +#ifdef P2P + && (this->exchange_type != P2P_CONNECT) +#endif /* P2P */ + )) { /* unsupported exchange type */ return FAILED; } - if (this->initiator_spi == 0) + + if (this->initiator_spi == 0 +#ifdef P2P + // we allow zero spi for INFORMATIONAL exchanges, to allow P2P connectivity checks + && this->exchange_type != INFORMATIONAL +#endif /* P2P */ + ) { /* initiator spi not set */ return FAILED; diff --git a/src/charon/encoding/payloads/ike_header.h b/src/charon/encoding/payloads/ike_header.h index 95c20f810..e80964482 100644 --- a/src/charon/encoding/payloads/ike_header.h +++ b/src/charon/encoding/payloads/ike_header.h @@ -6,6 +6,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -70,7 +71,7 @@ enum exchange_type_t{ /** * EXCHANGE_TYPE_UNDEFINED. In private space, since not a official message type. */ - EXCHANGE_TYPE_UNDEFINED = 240, + EXCHANGE_TYPE_UNDEFINED = 255, /** * IKE_SA_INIT. @@ -90,7 +91,13 @@ enum exchange_type_t{ /** * INFORMATIONAL. */ - INFORMATIONAL = 37 + INFORMATIONAL = 37, +#ifdef P2P + /** + * P2P_CONNECT + */ + P2P_CONNECT = 240 +#endif /* P2P */ }; /** diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c index e27d3c68f..74a6c3197 100644 --- a/src/charon/encoding/payloads/notify_payload.c +++ b/src/charon/encoding/payloads/notify_payload.c @@ -6,7 +6,8 @@ */ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2007 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -56,7 +57,13 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTH "INVALID_SELECTORS", "UNACCEPTABLE_ADDRESSES", "UNEXPECTED_NAT_DETECTED"); +#ifdef P2P +ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED, + "P2P_CONNECT_FAILED"); +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED, +#else ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED, +#endif /* P2P */ "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -79,7 +86,20 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETE "AUTH_LIFETIME"); ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME, "EAP_ONLY_AUTHENTICATION"); +#ifdef P2P +ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, + "USE_BEET_MODE"); +ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE, + "P2P_MEDIATION", + "P2P_ENDPOINT", + "P2P_CALLBACK", + "P2P_SESSIONID", + "P2P_SESSIONKEY", + "P2P_RESPONSE"); +ENUM_END(notify_type_names, P2P_RESPONSE); +#else ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION); +#endif /* P2P */ ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD, @@ -108,7 +128,13 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED "INVAL_SEL", "UNACCEPT_ADDR", "UNEXPECT_NAT"); +#ifdef P2P +ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED, + "P2P_CONN_FAIL"); +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED, +#else ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED, +#endif /* P2P */ "INIT_CONTACT", "SET_WINSIZE", "ADD_TS_POSS", @@ -131,7 +157,20 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NA "AUTH_LFT"); ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME, "EAP_ONLY"); +#ifdef P2P +ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, + "BEET_MODE"); +ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE, + "P2P_MED", + "P2P_EP", + "P2P_CB", + "P2P_SID", + "P2P_SKEY", + "P2P_R"); +ENUM_END(notify_type_short_names, P2P_RESPONSE); +#else ENUM_END(notify_type_short_names, EAP_ONLY_AUTHENTICATION); +#endif /* P2P */ typedef struct private_notify_payload_t private_notify_payload_t; @@ -303,6 +342,7 @@ static status_t verify(private_notify_payload_t *this) } break; } + // FIXME: check size of P2P-NAT-T payloads default: /* TODO: verify */ break; diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h index 231d0408d..4a9ad992b 100644 --- a/src/charon/encoding/payloads/notify_payload.h +++ b/src/charon/encoding/payloads/notify_payload.h @@ -6,7 +6,8 @@ */ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2007 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -67,6 +68,10 @@ enum notify_type_t { INVALID_SELECTORS = 39, UNACCEPTABLE_ADDRESSES = 40, UNEXPECTED_NAT_DETECTED = 41, +#ifdef P2P + /* P2P-NAT-T, private use */ + P2P_CONNECT_FAILED = 8192, +#endif /* P2P */ /* notify status messages */ INITIAL_CONTACT = 16384, SET_WINDOW_SIZE = 16385, @@ -94,6 +99,15 @@ enum notify_type_t { EAP_ONLY_AUTHENTICATION = 40960, /* BEET mode, not even a draft yet. private use */ USE_BEET_MODE = 40961, +#ifdef P2P + /* P2P-NAT-T, private use */ + P2P_MEDIATION = 40962, + P2P_ENDPOINT = 40963, + P2P_CALLBACK = 40964, + P2P_SESSIONID = 40965, + P2P_SESSIONKEY = 40966, + P2P_RESPONSE = 40967 +#endif /* P2P */ }; /** diff --git a/src/charon/encoding/payloads/payload.c b/src/charon/encoding/payloads/payload.c index 3bd4cdb13..2c51c60de 100644 --- a/src/charon/encoding/payloads/payload.c +++ b/src/charon/encoding/payloads/payload.c @@ -7,6 +7,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -63,7 +64,13 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N "ENCRYPTED", "CONFIGURATION", "EXTENSIBLE_AUTHENTICATION"); +#ifdef P2P +ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION, + "ID_PEER"); +ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER, +#else ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION, +#endif /* P2P */ "HEADER", "PROPOSAL_SUBSTRUCTURE", "TRANSFORM_SUBSTRUCTURE", @@ -93,7 +100,13 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT "E", "CP", "EAP"); +#ifdef P2P +ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION, + "IDp"); +ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER, +#else ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION, +#endif /* P2P */ "HDR", "PROP", "TRANS", @@ -123,9 +136,13 @@ payload_t *payload_create(payload_type_t type) case NONCE: return (payload_t*)nonce_payload_create(); case ID_INITIATOR: - return (payload_t*)id_payload_create(TRUE); + return (payload_t*)id_payload_create(ID_INITIATOR); case ID_RESPONDER: - return (payload_t*)id_payload_create(FALSE); + return (payload_t*)id_payload_create(ID_RESPONDER); +#ifdef P2P + case ID_PEER: + return (payload_t*)id_payload_create(ID_PEER); +#endif /* P2P */ case AUTHENTICATION: return (payload_t*)auth_payload_create(); case CERTIFICATE: diff --git a/src/charon/encoding/payloads/payload.h b/src/charon/encoding/payloads/payload.h index 9a8c2f482..ab902d755 100644 --- a/src/charon/encoding/payloads/payload.h +++ b/src/charon/encoding/payloads/payload.h @@ -6,6 +6,7 @@ */ /* + * Copyright (C) 2007 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -126,10 +127,18 @@ enum payload_type_t{ */ EXTENSIBLE_AUTHENTICATION = 48, +#ifdef P2P + /** + * Identification payload for peers in P2P-NAT-T has a value from + * the PRIVATE USE space. + */ + ID_PEER = 128, +#endif /* P2P */ + /** * Header has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle IKEv2-Header like a payload. */ HEADER = 140, @@ -137,7 +146,7 @@ enum payload_type_t{ /** * PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a proposal substructure like a payload. */ PROPOSAL_SUBSTRUCTURE = 141, @@ -145,7 +154,7 @@ enum payload_type_t{ /** * TRANSFORM_SUBSTRUCTURE has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a transform substructure like a payload. */ TRANSFORM_SUBSTRUCTURE = 142, @@ -153,7 +162,7 @@ enum payload_type_t{ /** * TRANSFORM_ATTRIBUTE has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a transform attribute like a payload. */ TRANSFORM_ATTRIBUTE = 143, @@ -161,7 +170,7 @@ enum payload_type_t{ /** * TRAFFIC_SELECTOR_SUBSTRUCTURE has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a transform selector like a payload. */ TRAFFIC_SELECTOR_SUBSTRUCTURE = 144, @@ -169,7 +178,7 @@ enum payload_type_t{ /** * CONFIGURATION_ATTRIBUTE has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a transform attribute like a payload. */ CONFIGURATION_ATTRIBUTE = 145, @@ -177,7 +186,7 @@ enum payload_type_t{ /** * A unknown payload has a value of PRIVATE USE space. * - * This payload type is not send over wire and just + * This payload type is not sent over wire and just * used internally to handle a unknown payload. */ UNKNOWN_PAYLOAD = 146, diff --git a/src/charon/encoding/payloads/sa_payload.c b/src/charon/encoding/payloads/sa_payload.c index e264b2123..304f1b64c 100644 --- a/src/charon/encoding/payloads/sa_payload.c +++ b/src/charon/encoding/payloads/sa_payload.c @@ -123,7 +123,7 @@ static status_t verify(private_sa_payload_t *this) { if (current_number != (expected_number + 1)) { - DBG1(DBG_ENC, "proposal number is %d, excepted %d or %d", + DBG1(DBG_ENC, "proposal number is %d, expected %d or %d", current_number, expected_number, expected_number + 1); status = FAILED; break; |