diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c index b8790470a..4c26a943a 100644 --- a/src/charon/config/traffic_selector.c +++ b/src/charon/config/traffic_selector.c @@ -406,26 +406,15 @@ static bool equals(private_traffic_selector_t *this, private_traffic_selector_t */ static chunk_t get_from_address(private_traffic_selector_t *this) { - chunk_t from = chunk_empty; - switch (this->type) { case TS_IPV4_ADDR_RANGE: - { - from.len = sizeof(this->from4); - from.ptr = malloc(from.len); - memcpy(from.ptr, this->from4, from.len); - break; - } + return chunk_create(this->from, sizeof(this->from4)); case TS_IPV6_ADDR_RANGE: - { - from.len = sizeof(this->from6); - from.ptr = malloc(from.len); - memcpy(from.ptr, this->from6, from.len); - break; - } + return chunk_create(this->from, sizeof(this->from6)); + default: + return chunk_empty; } - return from; } /** @@ -433,26 +422,15 @@ static chunk_t get_from_address(private_traffic_selector_t *this) */ static chunk_t get_to_address(private_traffic_selector_t *this) { - chunk_t to = chunk_empty; - switch (this->type) { case TS_IPV4_ADDR_RANGE: - { - to.len = sizeof(this->to4); - to.ptr = malloc(to.len); - memcpy(to.ptr, this->to4, to.len); - break; - } + return chunk_create(this->to, sizeof(this->to4)); case TS_IPV6_ADDR_RANGE: - { - to.len = sizeof(this->to6); - to.ptr = malloc(to.len); - memcpy(to.ptr, this->to6, to.len); - break; - } + return chunk_create(this->to, sizeof(this->to6)); + default: + return chunk_empty; } - return to; } /** @@ -525,6 +503,14 @@ static bool is_host(private_traffic_selector_t *this, host_t *host) return FALSE; } +/** + * Implementation of traffic_selector_t.is_dynamic + */ +static bool is_dynamic(private_traffic_selector_t *this) +{ + return this->dynamic; +} + /** * Implements traffic_selector_t.set_address. */ @@ -869,6 +855,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type; this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol; this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host; + this->public.is_dynamic = (bool(*)(traffic_selector_t*))is_dynamic; this->public.is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in; this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes; this->public.set_address = (void(*)(traffic_selector_t*,host_t*))set_address; diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h index e3b8214d0..215398dd5 100644 --- a/src/charon/config/traffic_selector.h +++ b/src/charon/config/traffic_selector.h @@ -92,7 +92,7 @@ struct traffic_selector_t { /** * Get starting address of this ts as a chunk. * - * Chunk is in network order gets allocated. + * Chunk is in network and points to internal data. * * @return chunk containing the address */ @@ -101,7 +101,7 @@ struct traffic_selector_t { /** * Get ending address of this ts as a chunk. * - * Chunk is in network order gets allocated. + * Chunk is in network and points to internal data. * * @return chunk containing the address */ @@ -154,6 +154,13 @@ struct traffic_selector_t { */ bool (*is_host) (traffic_selector_t *this, host_t* host); + /** + * Check if a traffic selector has been created by create_dynamic(). + * + * @return TRUE if TS is dynamic + */ + bool (*is_dynamic)(traffic_selector_t *this); + /** * Update the address of a traffic selector. * diff --git a/src/charon/encoding/payloads/traffic_selector_substructure.c b/src/charon/encoding/payloads/traffic_selector_substructure.c index 58ca408d5..ba970d1cc 100644 --- a/src/charon/encoding/payloads/traffic_selector_substructure.c +++ b/src/charon/encoding/payloads/traffic_selector_substructure.c @@ -269,8 +269,8 @@ traffic_selector_substructure_t *traffic_selector_substructure_create_from_traff this->ip_protocol_id = traffic_selector->get_protocol(traffic_selector); this->start_port = traffic_selector->get_from_port(traffic_selector); this->end_port = traffic_selector->get_to_port(traffic_selector); - this->starting_address = traffic_selector->get_from_address(traffic_selector); - this->ending_address = traffic_selector->get_to_address(traffic_selector); + this->starting_address = chunk_clone(traffic_selector->get_from_address(traffic_selector)); + this->ending_address = chunk_clone(traffic_selector->get_to_address(traffic_selector)); compute_length(this); diff --git a/src/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c index b3ad72ab2..8f5dc54dd 100644 --- a/src/charon/plugins/sql/pool.c +++ b/src/charon/plugins/sql/pool.c @@ -35,14 +35,6 @@ database_t *db; */ host_t *start = NULL, *end = NULL; -/** - * create a host from a blob - */ -static host_t *host_create_from_blob(chunk_t blob) -{ - return host_create_from_chunk(blob.len == 4 ? AF_INET : AF_INET6, blob, 0); -} - /** * calculate the size of a pool using start and end address chunk */ @@ -132,8 +124,8 @@ static void status(void) found = TRUE; } - start = host_create_from_blob(start_chunk); - end = host_create_from_blob(end_chunk); + start = host_create_from_chunk(AF_UNSPEC, start_chunk, 0); + end = host_create_from_chunk(AF_UNSPEC, end_chunk, 0); size = get_pool_size(start_chunk, end_chunk); printf("%8s %15H %15H ", name, start, end); if (timeout) @@ -541,7 +533,7 @@ static void leases(char *filter, bool utc) printf("%-8s %-15s %-7s %-*s %-*s %s\n", "name", "address", "status", len, "start", len, "end", "identity"); } - address = host_create_from_blob(address_chunk); + address = host_create_from_chunk(AF_UNSPEC, address_chunk, 0); identity = identification_create_from_encoding(identity_type, identity_chunk); printf("%-8s %-15H ", name, address); diff --git a/src/charon/plugins/sql/sql_attribute.c b/src/charon/plugins/sql/sql_attribute.c index f1e206279..486a432ca 100644 --- a/src/charon/plugins/sql/sql_attribute.c +++ b/src/charon/plugins/sql/sql_attribute.c @@ -44,22 +44,6 @@ struct private_sql_attribute_t { bool history; }; -/** - * read a host_t address from the addresses table - */ -static host_t *host_from_chunk(chunk_t chunk) -{ - switch (chunk.len) - { - case 4: - return host_create_from_chunk(AF_INET, chunk, 0); - case 16: - return host_create_from_chunk(AF_INET6, chunk, 0); - default: - return NULL; - } -} - /** * lookup/insert an identity */ @@ -145,7 +129,7 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, "WHERE id = ? AND identity = ? AND released != 0", DB_UINT, now, DB_UINT, id, DB_UINT, identity) > 0) { - host = host_from_chunk(address); + host = host_create_from_chunk(AF_UNSPEC, address, 0); if (host) { DBG1(DBG_CFG, "acquired existing lease " @@ -177,7 +161,7 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, DB_UINT, now, DB_UINT, identity, DB_UINT, id, DB_UINT, now - timeout) > 0) { - host = host_from_chunk(address); + host = host_create_from_chunk(AF_UNSPEC, address, 0); if (host) { DBG1(DBG_CFG, "acquired new lease " diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 95c7735de..d615412db 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -497,6 +497,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, soft = this->config->get_lifetime(this->config, TRUE); hard = this->config->get_lifetime(this->config, FALSE); + status = charon->kernel_interface->add_sa(charon->kernel_interface, src, dst, spi, this->protocol, this->reqid, in ? soft : 0, hard, enc_alg, encr, int_alg, integ, @@ -617,7 +618,6 @@ static status_t add_policies(private_child_sa_t *this, this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN, this->my_spi, this->protocol, this->reqid, mode, this->ipcomp, this->my_cpi, routed); - if (mode == MODE_TUNNEL) { status |= charon->kernel_interface->add_policy(charon->kernel_interface, @@ -625,7 +625,7 @@ static status_t add_policies(private_child_sa_t *this, this->my_spi, this->protocol, this->reqid, mode, this->ipcomp, this->my_cpi, routed); } - + if (status != SUCCESS) { break; @@ -633,7 +633,7 @@ static status_t add_policies(private_child_sa_t *this, } enumerator->destroy(enumerator); } - + if (status == SUCCESS) { /* switch to routed state if no SAD entry set up */ @@ -681,7 +681,6 @@ static status_t update_hosts(private_child_sa_t *this, { return NOT_SUPPORTED; } - /* update his (responder) SA */ if (charon->kernel_interface->update_sa(charon->kernel_interface, this->other_spi, this->protocol, this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0, @@ -699,7 +698,7 @@ static status_t update_hosts(private_child_sa_t *this, { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; - + /* always use high priorities, as hosts getting updated are INSTALLED */ enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) @@ -714,7 +713,7 @@ static status_t update_hosts(private_child_sa_t *this, charon->kernel_interface->del_policy(charon->kernel_interface, other_ts, my_ts, POLICY_FWD, FALSE); } - + /* check whether we have to update a "dynamic" traffic selector */ if (!me->ip_equals(me, this->my_addr) && my_ts->is_host(my_ts, this->my_addr)) @@ -726,7 +725,7 @@ static status_t update_hosts(private_child_sa_t *this, { other_ts->set_address(other_ts, other); } - + /* we reinstall the virtual IP to handle interface roaming * correctly */ if (vip) @@ -734,7 +733,7 @@ static status_t update_hosts(private_child_sa_t *this, charon->kernel_interface->del_ip(charon->kernel_interface, vip); charon->kernel_interface->add_ip(charon->kernel_interface, vip, me); } - + /* reinstall updated policies */ charon->kernel_interface->add_policy(charon->kernel_interface, me, other, my_ts, other_ts, POLICY_OUT, this->other_spi, @@ -755,7 +754,7 @@ static status_t update_hosts(private_child_sa_t *this, enumerator->destroy(enumerator); } } - + /* apply hosts */ if (!this->config->use_proxy_mode(this->config) || this->mode != MODE_TRANSPORT) { @@ -854,7 +853,7 @@ static void destroy(private_child_sa_t *this) } enumerator->destroy(enumerator); } - + this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy)); this->my_addr->destroy(this->my_addr); @@ -981,4 +980,3 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, return &this->public; } - diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c index 8abeaa415..d30d057ed 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c @@ -42,7 +42,7 @@ struct modulus_entry_t { * Optimum length of exponent in bits. */ long opt_exponent_len; - + /* * Generator value. */ @@ -88,7 +88,7 @@ struct private_openssl_diffie_hellman_t { * Other public value */ BIGNUM *pub_key; - + /** * Shared secret */ diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index cfcb87373..8c79f718a 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -504,38 +504,56 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port) */ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) { - private_host_t *this = host_create_empty(); + private_host_t *this; + switch (family) + { + case AF_INET: + if (address.len < IPV4_LEN) + { + return NULL; + } + address.len = IPV4_LEN; + break; + case AF_INET6: + if (address.len < IPV6_LEN) + { + return NULL; + } + address.len = IPV6_LEN; + break; + case AF_UNSPEC: + switch (address.len) + { + case IPV4_LEN: + family = AF_INET; + break; + case IPV6_LEN: + family = AF_INET6; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + this = host_create_empty(); this->address.sa_family = family; switch (family) { case AF_INET: - { - if (address.len != IPV4_LEN) - { - break; - } - memcpy(&(this->address4.sin_addr.s_addr), address.ptr, IPV4_LEN); + memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len); this->address4.sin_port = htons(port); this->socklen = sizeof(struct sockaddr_in); - return &(this->public); - } + break; case AF_INET6: - { - if (address.len != IPV6_LEN) - { - break; - } - memcpy(&(this->address6.sin6_addr.s6_addr), address.ptr, IPV6_LEN); + memcpy(&this->address6.sin6_addr.s6_addr, address.ptr, address.len); this->address6.sin6_port = htons(port); this->socklen = sizeof(struct sockaddr_in6); - return &this->public; - } - default: break; } - free(this); - return NULL; + return &this->public; } /* diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h index 02bfed8a6..667cc6bcc 100644 --- a/src/libstrongswan/utils/host.h +++ b/src/libstrongswan/utils/host.h @@ -170,7 +170,9 @@ host_t *host_create_from_string(char *string, u_int16_t port); host_t *host_create_from_dns(char *string, int family, u_int16_t port); /** - * Constructor to create a host_t object from an address chunk + * Constructor to create a host_t object from an address chunk. + * + * If family is AF_UNSPEC, it is guessed using address.len. * * @param family Address family, such as AF_INET or AF_INET6 * @param address address as chunk_t in network order