diff options
author | Martin Willi <martin@strongswan.org> | 2007-02-28 14:04:36 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-02-28 14:04:36 +0000 |
commit | c60c7694d2d8925c5d93ff33d132f561ad89e071 (patch) | |
tree | 9c7957b0749139c5e7c9b008c927e79d69f8e500 /src/charon/encoding | |
parent | a7a5e834e318d0582b6db979b63a5739c0a8244f (diff) | |
download | strongswan-c60c7694d2d8925c5d93ff33d132f561ad89e071.tar.bz2 strongswan-c60c7694d2d8925c5d93ff33d132f561ad89e071.tar.xz |
merged tasking branch into trunk
Diffstat (limited to 'src/charon/encoding')
-rw-r--r-- | src/charon/encoding/message.c | 58 | ||||
-rw-r--r-- | src/charon/encoding/message.h | 26 | ||||
-rw-r--r-- | src/charon/encoding/payloads/cert_payload.c | 2 | ||||
-rw-r--r-- | src/charon/encoding/payloads/certreq_payload.c | 3 | ||||
-rw-r--r-- | src/charon/encoding/payloads/configuration_attribute.c | 72 | ||||
-rw-r--r-- | src/charon/encoding/payloads/configuration_attribute.h | 6 | ||||
-rw-r--r-- | src/charon/encoding/payloads/cp_payload.c | 6 | ||||
-rw-r--r-- | src/charon/encoding/payloads/cp_payload.h | 14 | ||||
-rw-r--r-- | src/charon/encoding/payloads/notify_payload.c | 8 |
9 files changed, 157 insertions, 38 deletions
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c index fb37c996d..acc3abd1b 100644 --- a/src/charon/encoding/message.c +++ b/src/charon/encoding/message.c @@ -345,6 +345,7 @@ static status_t get_payload_rule(private_message_t *this, payload_type_t payload */ static void set_ike_sa_id (private_message_t *this,ike_sa_id_t *ike_sa_id) { + DESTROY_IF(this->ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id); } @@ -490,6 +491,29 @@ static void add_payload(private_message_t *this, payload_t *payload) } /** + * Implementation of message_t.add_notify. + */ +static void add_notify(private_message_t *this, bool flush, notify_type_t type, + chunk_t data) +{ + notify_payload_t *notify; + payload_t *payload; + + if (flush) + { + while (this->payloads->remove_last(this->payloads, + (void**)&payload) == SUCCESS) + { + payload->destroy(payload); + } + } + notify = notify_payload_create(); + notify->set_notify_type(notify, type); + notify->set_notification_data(notify, data); + add_payload(this, (payload_t*)notify); +} + +/** * Implementation of message_t.set_source. */ static void set_source(private_message_t *this, host_t *host) @@ -522,7 +546,7 @@ static host_t * get_destination(private_message_t *this) } /** - * Implementation of message_t.get_destination. + * Implementation of message_t.get_payload_iterator. */ static iterator_t *get_payload_iterator(private_message_t *this) { @@ -530,6 +554,27 @@ static iterator_t *get_payload_iterator(private_message_t *this) } /** + * Implementation of message_t.get_payload. + */ +static payload_t *get_payload(private_message_t *this, payload_type_t type) +{ + payload_t *current, *found = NULL; + iterator_t *iterator; + + iterator = this->payloads->create_iterator(this->payloads, TRUE); + while (iterator->iterate(iterator, (void**)¤t)) + { + if (current->get_type(current) == type) + { + found = current; + break; + } + } + iterator->destroy(iterator); + return found; +} + +/** * output handler in printf() */ static int print(FILE *stream, const struct printf_info *info, @@ -786,6 +831,10 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* */ static packet_t *get_packet (private_message_t *this) { + if (this->packet == NULL) + { + return NULL; + } return this->packet->clone(this->packet); } @@ -794,6 +843,10 @@ static packet_t *get_packet (private_message_t *this) */ static chunk_t get_packet_data (private_message_t *this) { + if (this->packet == NULL) + { + return chunk_empty; + } return chunk_clone(this->packet->get_data(this->packet)); } @@ -1147,7 +1200,6 @@ static status_t parse_body(private_message_t *this, crypter_t *crypter, signer_t status = verify(this); if (status != SUCCESS) { - DBG1(DBG_ENC, "verification of message failed"); return status; } @@ -1191,12 +1243,14 @@ message_t *message_create_from_packet(packet_t *packet) 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; + this->public.add_notify = (void(*)(message_t*,bool,notify_type_t,chunk_t))add_notify; this->public.generate = (status_t (*) (message_t *,crypter_t*,signer_t*,packet_t**)) generate; this->public.set_source = (void (*) (message_t*,host_t*)) set_source; this->public.get_source = (host_t * (*) (message_t*)) get_source; this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination; this->public.get_destination = (host_t * (*) (message_t*)) get_destination; this->public.get_payload_iterator = (iterator_t * (*) (message_t *)) get_payload_iterator; + this->public.get_payload = (payload_t * (*) (message_t *, payload_type_t)) get_payload; this->public.parse_header = (status_t (*) (message_t *)) parse_header; this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body; this->public.get_packet = (packet_t * (*) (message_t*)) get_packet; diff --git a/src/charon/encoding/message.h b/src/charon/encoding/message.h index dfb6d64af..73c2e05c6 100644 --- a/src/charon/encoding/message.h +++ b/src/charon/encoding/message.h @@ -184,6 +184,21 @@ struct message_t { void (*add_payload) (message_t *this, payload_t *payload); /** + * @brief Build a notify payload and add it to the message. + * + * This is a helper method to create notify messages or add + * notify payload to messages. The flush parameter specifies if existing + * payloads should get removed before appending the notify. + * + * @param this message_t object + * @param flush TRUE to remove existing payloads + * @param type type of the notify + * @param data a chunk of data to add to the notify, gets cloned + */ + void (*add_notify) (message_t *this, bool flush, notify_type_t type, + chunk_t data); + + /** * @brief Parses header of message. * * Begins parisng of a message created via message_create_from_packet(). @@ -304,6 +319,17 @@ struct message_t { iterator_t * (*get_payload_iterator) (message_t *this); /** + * @brief Find a payload of a spicific type. + * + * Returns the first occurance. + * + * @param this message_t object + * @param type type of the payload to find + * @return payload, or NULL if no such payload found + */ + payload_t* (*get_payload) (message_t *this, payload_type_t type); + + /** * @brief Returns a clone of the internal stored packet_t object. * * @param this message_t object diff --git a/src/charon/encoding/payloads/cert_payload.c b/src/charon/encoding/payloads/cert_payload.c index 2e690b45d..8f477ffd0 100644 --- a/src/charon/encoding/payloads/cert_payload.c +++ b/src/charon/encoding/payloads/cert_payload.c @@ -270,7 +270,7 @@ cert_payload_t *cert_payload_create() /* private variables */ this->critical = FALSE; this->next_payload = NO_PAYLOAD; - this->payload_length =CERT_PAYLOAD_HEADER_LENGTH; + this->payload_length = CERT_PAYLOAD_HEADER_LENGTH; this->cert_data = chunk_empty; return (&(this->public)); diff --git a/src/charon/encoding/payloads/certreq_payload.c b/src/charon/encoding/payloads/certreq_payload.c index 86f2e3524..fcddcf971 100644 --- a/src/charon/encoding/payloads/certreq_payload.c +++ b/src/charon/encoding/payloads/certreq_payload.c @@ -306,7 +306,10 @@ certreq_payload_t *certreq_payload_create_from_cacerts(void) int count = iterator->get_count(iterator); if (count == 0) + { + iterator->destroy(iterator); return NULL; + } this = certreq_payload_create(); keyids = chunk_alloc(count * HASH_SIZE_SHA1); diff --git a/src/charon/encoding/payloads/configuration_attribute.c b/src/charon/encoding/payloads/configuration_attribute.c index e7000e1b5..0aa82169f 100644 --- a/src/charon/encoding/payloads/configuration_attribute.c +++ b/src/charon/encoding/payloads/configuration_attribute.c @@ -27,6 +27,7 @@ #include <encoding/payloads/encodings.h> #include <library.h> +#include <daemon.h> typedef struct private_configuration_attribute_t private_configuration_attribute_t; @@ -50,7 +51,6 @@ struct private_configuration_attribute_t { * Length of the attribute. */ u_int16_t attribute_length; - /** * Attribute value as chunk. @@ -58,7 +58,7 @@ struct private_configuration_attribute_t { chunk_t attribute_value; }; -ENUM_BEGIN(configuration_attribute_type_name, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, +ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, "INTERNAL_IP4_ADDRESS", "INTERNAL_IP4_NETMASK", "INTERNAL_IP4_DNS", @@ -67,14 +67,14 @@ ENUM_BEGIN(configuration_attribute_type_name, INTERNAL_IP4_ADDRESS, INTERNAL_IP6 "INTERNAL_IP4_DHCP", "APPLICATION_VERSION", "INTERNAL_IP6_ADDRESS"); -ENUM_NEXT(configuration_attribute_type_name, INTERNAL_IP6_DNS, INTERNAL_IP6_SUBNET, INTERNAL_IP6_ADDRESS, +ENUM_NEXT(configuration_attribute_type_names, INTERNAL_IP6_DNS, INTERNAL_IP6_SUBNET, INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_DNS", "INTERNAL_IP6_NBNS", "INTERNAL_IP6_DHCP", "INTERNAL_IP4_SUBNET", "SUPPORTED_ATTRIBUTES", "INTERNAL_IP6_SUBNET"); -ENUM_END(configuration_attribute_type_name, INTERNAL_IP6_SUBNET); +ENUM_END(configuration_attribute_type_names, INTERNAL_IP6_SUBNET); /** * Encoding rules to parse or generate a configuration attribute. @@ -111,6 +111,14 @@ encoding_rule_t configuration_attribute_encodings[] = { */ static status_t verify(private_configuration_attribute_t *this) { + bool failed = FALSE; + + if (this->attribute_length != this->attribute_value.len) + { + DBG1(DBG_ENC, "invalid attribute length"); + return FAILED; + } + switch (this->attribute_type) { case INTERNAL_IP4_ADDRESS: @@ -119,27 +127,54 @@ static status_t verify(private_configuration_attribute_t *this) case INTERNAL_IP4_NBNS: case INTERNAL_ADDRESS_EXPIRY: case INTERNAL_IP4_DHCP: - case APPLICATION_VERSION: + if (this->attribute_length != 0 && this->attribute_length != 4) + { + failed = TRUE; + } + break; + case INTERNAL_IP4_SUBNET: + if (this->attribute_length != 0 && this->attribute_length != 8) + { + failed = TRUE; + } + break; case INTERNAL_IP6_ADDRESS: + case INTERNAL_IP6_SUBNET: + if (this->attribute_length != 0 && this->attribute_length != 17) + { + failed = TRUE; + } + break; case INTERNAL_IP6_DNS: case INTERNAL_IP6_NBNS: case INTERNAL_IP6_DHCP: - case INTERNAL_IP4_SUBNET: + if (this->attribute_length != 0 && this->attribute_length != 16) + { + failed = TRUE; + } + break; case SUPPORTED_ATTRIBUTES: - case INTERNAL_IP6_SUBNET: - { - /* Attribute types are not checked in here */ + if (this->attribute_length % 2) + { + failed = TRUE; + } + break; + case APPLICATION_VERSION: + /* any length acceptable */ break; - } default: + DBG1(DBG_ENC, "unknown attribute type %N", + configuration_attribute_type_names, this->attribute_type); return FAILED; } - if (this->attribute_length != this->attribute_value.len) + if (failed) { + DBG1(DBG_ENC, "invalid attribute length %d for %N", + this->attribute_length, configuration_attribute_type_names, + this->attribute_type); return FAILED; } - return SUCCESS; } @@ -208,9 +243,8 @@ static chunk_t get_value (private_configuration_attribute_t *this) return this->attribute_value; } - /** - * Implementation of configuration_attribute_t.set_attribute_type. + * Implementation of configuration_attribute_t.set_type. */ static void set_attribute_type (private_configuration_attribute_t *this, u_int16_t type) { @@ -218,7 +252,7 @@ static void set_attribute_type (private_configuration_attribute_t *this, u_int16 } /** - * Implementation of configuration_attribute_t.get_attribute_type. + * Implementation of configuration_attribute_t.get_type. */ static u_int16_t get_attribute_type (private_configuration_attribute_t *this) { @@ -226,7 +260,7 @@ static u_int16_t get_attribute_type (private_configuration_attribute_t *this) } /** - * Implementation of configuration_attribute_t.get_attribute_length. + * Implementation of configuration_attribute_t.get_length. */ static u_int16_t get_attribute_length (private_configuration_attribute_t *this) { @@ -265,9 +299,9 @@ configuration_attribute_t *configuration_attribute_create() /* public functions */ this->public.set_value = (void (*) (configuration_attribute_t *,chunk_t)) set_value; this->public.get_value = (chunk_t (*) (configuration_attribute_t *)) get_value; - this->public.set_attribute_type = (void (*) (configuration_attribute_t *,u_int16_t type)) set_attribute_type; - this->public.get_attribute_type = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_type; - this->public.get_attribute_length = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_length; + this->public.set_type = (void (*) (configuration_attribute_t *,u_int16_t type)) set_attribute_type; + this->public.get_type = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_type; + this->public.get_length = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_length; this->public.destroy = (void (*) (configuration_attribute_t *)) destroy; /* set default values of the fields */ diff --git a/src/charon/encoding/payloads/configuration_attribute.h b/src/charon/encoding/payloads/configuration_attribute.h index 5a11d0a35..5c4f65b14 100644 --- a/src/charon/encoding/payloads/configuration_attribute.h +++ b/src/charon/encoding/payloads/configuration_attribute.h @@ -109,7 +109,7 @@ struct configuration_attribute_t { * @param this calling configuration_attribute_t object * @param type type to set (most significant bit is set to zero) */ - void (*set_attribute_type) (configuration_attribute_t *this, u_int16_t type); + void (*set_type) (configuration_attribute_t *this, u_int16_t type); /** * @brief get the type of the attribute. @@ -117,7 +117,7 @@ struct configuration_attribute_t { * @param this calling configuration_attribute_t object * @return type of the value */ - u_int16_t (*get_attribute_type) (configuration_attribute_t *this); + u_int16_t (*get_type) (configuration_attribute_t *this); /** * @brief get the length of an attribute. @@ -125,7 +125,7 @@ struct configuration_attribute_t { * @param this calling configuration_attribute_t object * @return type of the value */ - u_int16_t (*get_attribute_length) (configuration_attribute_t *this); + u_int16_t (*get_length) (configuration_attribute_t *this); /** * @brief Destroys an configuration_attribute_t object. diff --git a/src/charon/encoding/payloads/cp_payload.c b/src/charon/encoding/payloads/cp_payload.c index bd16abc22..380ed9681 100644 --- a/src/charon/encoding/payloads/cp_payload.c +++ b/src/charon/encoding/payloads/cp_payload.c @@ -204,9 +204,9 @@ static size_t get_length(private_cp_payload_t *this) /** * Implementation of cp_payload_t.create_configuration_attribute_iterator. */ -static iterator_t *create_configuration_attribute_iterator (private_cp_payload_t *this,bool forward) +static iterator_t *create_attribute_iterator (private_cp_payload_t *this) { - return this->attributes->create_iterator(this->attributes,forward); + return this->attributes->create_iterator(this->attributes, TRUE); } /** @@ -261,7 +261,7 @@ cp_payload_t *cp_payload_create() this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; /* public functions */ - this->public.create_configuration_attribute_iterator = (iterator_t* (*) (cp_payload_t *,bool)) create_configuration_attribute_iterator; + this->public.create_attribute_iterator = (iterator_t* (*) (cp_payload_t *)) create_attribute_iterator; this->public.add_configuration_attribute = (void (*) (cp_payload_t *,configuration_attribute_t *)) add_configuration_attribute; this->public.set_config_type = (void (*) (cp_payload_t *, config_type_t)) set_config_type; this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type; diff --git a/src/charon/encoding/payloads/cp_payload.h b/src/charon/encoding/payloads/cp_payload.h index af36b48a3..27ff41005 100644 --- a/src/charon/encoding/payloads/cp_payload.h +++ b/src/charon/encoding/payloads/cp_payload.h @@ -77,23 +77,19 @@ struct cp_payload_t { /** * @brief Creates an iterator of stored configuration_attribute_t objects. * - * @warning The created iterator has to get destroyed by the caller! - * - * @warning When deleting an attribute using this iterator, - * the length of this configuration_attribute_t has to be refreshed - * by calling get_length()! + * When deleting an attribute using this iterator, the length of this + * configuration_attribute_t has to be refreshed by calling get_length()! * * @param this calling cp_payload_t object - * @param[in] forward iterator direction (TRUE: front to end) * @return created iterator_t object */ - iterator_t *(*create_configuration_attribute_iterator) (cp_payload_t *this, bool forward); + iterator_t *(*create_attribute_iterator) (cp_payload_t *this); /** * @brief Adds a configuration_attribute_t object to this object. * - * @warning The added configuration_attribute_t object is - * getting destroyed in destroy function of cp_payload_t. + * The added configuration_attribute_t object is getting destroyed in + * destroy function of cp_payload_t. * * @param this calling cp_payload_t object * @param attribute configuration_attribute_t object to add diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c index 38ee0946d..a04901a90 100644 --- a/src/charon/encoding/payloads/notify_payload.c +++ b/src/charon/encoding/payloads/notify_payload.c @@ -209,6 +209,9 @@ static status_t verify(private_notify_payload_t *this) diffie_hellman_group_t dh_group; if (this->notification_data.len != 2) { + DBG1(DBG_ENC, "invalid notify data length for %N (%d)", + notify_type_names, this->notify_type, + this->notification_data.len); return FAILED; } dh_group = ntohs(*((u_int16_t*)this->notification_data.ptr)); @@ -403,7 +406,10 @@ static chunk_t get_notification_data(private_notify_payload_t *this) static status_t set_notification_data(private_notify_payload_t *this, chunk_t notification_data) { chunk_free(&this->notification_data); - this->notification_data = chunk_clone(notification_data); + if (notification_data.len > 0) + { + this->notification_data = chunk_clone(notification_data); + } compute_length(this); return SUCCESS; } |