diff options
Diffstat (limited to 'src/charon/encoding/payloads')
-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 |
7 files changed, 75 insertions, 36 deletions
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; } |