diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:35:38 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:35:38 +0000 |
commit | 7c52c3f35cdbdff58443b994f2f33d13b4d81f57 (patch) | |
tree | e54a27979ea72ec41702bec2984c2eadac3b8862 /src/charon/sa/ike_sa.c | |
parent | 4ef45ba0404dac3773e83af995a5ec584b23d633 (diff) | |
download | vyos-strongswan-7c52c3f35cdbdff58443b994f2f33d13b4d81f57.tar.gz vyos-strongswan-7c52c3f35cdbdff58443b994f2f33d13b4d81f57.zip |
Updated to new upstream version.
Diffstat (limited to 'src/charon/sa/ike_sa.c')
-rw-r--r-- | src/charon/sa/ike_sa.c | 559 |
1 files changed, 108 insertions, 451 deletions
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index bebd74160..6b7fa3582 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2006-2008 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger - * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -14,8 +14,6 @@ * 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. - * - * $Id: ike_sa.c 4945 2009-03-16 14:23:36Z martin $ */ #include <sys/time.h> @@ -57,10 +55,6 @@ #include <processing/jobs/initiate_mediation_job.h> #endif -#ifndef RESOLV_CONF -#define RESOLV_CONF "/etc/resolv.conf" -#endif - ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING, "CREATED", "CONNECTING", @@ -72,17 +66,18 @@ ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING, ); typedef struct private_ike_sa_t private_ike_sa_t; +typedef struct attribute_entry_t attribute_entry_t; /** * Private data of an ike_sa_t object. */ struct private_ike_sa_t { - + /** * Public members */ ike_sa_t public; - + /** * Identifier for the current IKE_SA. */ @@ -96,7 +91,7 @@ struct private_ike_sa_t { /** * Current state of the IKE_SA */ - ike_sa_state_t state; + ike_sa_state_t state; /** * IKE configuration used to set up this IKE_SA @@ -109,14 +104,14 @@ struct private_ike_sa_t { peer_cfg_t *peer_cfg; /** - * associated authentication/authorization info for local peer + * currently used authentication ruleset, local (as auth_cfg_t) */ - auth_info_t *my_auth; + auth_cfg_t *my_auth; /** - * associated authentication/authorization info for remote peer + * currently used authentication constraints, remote (as auth_cfg_t) */ - auth_info_t *other_auth; + auth_cfg_t *other_auth; /** * Selected IKE proposal @@ -179,7 +174,7 @@ struct private_ike_sa_t { * set of condition flags currently enabled for this IKE_SA */ ike_condition_t conditions; - + /** * Linked List containing the child sa's of the current IKE_SA. */ @@ -201,9 +196,9 @@ struct private_ike_sa_t { host_t *other_virtual_ip; /** - * List of DNS servers installed by us + * List of configuration attributes (attribute_entry_t) */ - linked_list_t *dns_servers; + linked_list_t *attributes; /** * list of peers additional addresses, transmitted via MOBIKE @@ -219,7 +214,7 @@ struct private_ike_sa_t { * number pending UPDATE_SA_ADDRESS (MOBIKE) */ u_int32_t pending_updates; - + /** * NAT keep alive interval */ @@ -234,12 +229,12 @@ struct private_ike_sa_t { * how many times we have retried so far (keyingtries) */ u_int32_t keyingtry; - + /** * local host address to be used for IKE, set via MIGRATE kernel message */ host_t *local_host; - + /** * remote host address to be used for IKE, set via MIGRATE kernel message */ @@ -247,6 +242,18 @@ struct private_ike_sa_t { }; /** + * Entry to maintain install configuration attributes during IKE_SA lifetime + */ +struct attribute_entry_t { + /** handler used to install this attribute */ + attribute_handler_t *handler; + /** attribute type */ + configuration_attribute_type_t type; + /** attribute data */ + chunk_t data; +}; + +/** * get the time of the latest traffic processed by the kernel */ static time_t get_use_time(private_ike_sa_t* this, bool inbound) @@ -355,40 +362,23 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg) DESTROY_IF(this->peer_cfg); peer_cfg->get_ref(peer_cfg); this->peer_cfg = peer_cfg; - + if (this->ike_cfg == NULL) { this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); this->ike_cfg->get_ref(this->ike_cfg); } - /* apply IDs if they are not already set */ - if (this->my_id->contains_wildcards(this->my_id)) - { - DESTROY_IF(this->my_id); - this->my_id = this->peer_cfg->get_my_id(this->peer_cfg); - this->my_id = this->my_id->clone(this->my_id); - } - if (this->other_id->contains_wildcards(this->other_id)) - { - DESTROY_IF(this->other_id); - this->other_id = this->peer_cfg->get_other_id(this->peer_cfg); - this->other_id = this->other_id->clone(this->other_id); - } -} - -/** - * Implementation of ike_sa_t.get_my_auth. - */ -static auth_info_t* get_my_auth(private_ike_sa_t *this) -{ - return this->my_auth; } /** - * Implementation of ike_sa_t.get_other_auth. + * Implementation of ike_sa_t.get_auth_cfg */ -static auth_info_t* get_other_auth(private_ike_sa_t *this) +static auth_cfg_t* get_auth_cfg(private_ike_sa_t *this, bool local) { + if (local) + { + return this->my_auth; + } return this->other_auth; } @@ -460,7 +450,7 @@ static void send_keepalive(private_ike_sa_t *this) } job = send_keepalive_job_create(this->ike_sa_id); charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, - (this->keepalive_interval - diff) * 1000); + this->keepalive_interval - diff); } /** @@ -559,7 +549,7 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition, */ static status_t send_dpd(private_ike_sa_t *this) { - send_dpd_job_t *job; + job_t *job; time_t diff, delay; delay = this->peer_cfg->get_dpd(this->peer_cfg); @@ -608,9 +598,8 @@ static status_t send_dpd(private_ike_sa_t *this) } } /* recheck in "interval" seconds */ - job = send_dpd_job_create(this->ike_sa_id); - charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, - (delay - diff) * 1000); + job = (job_t*)send_dpd_job_create(this->ike_sa_id); + charon->scheduler->schedule_job(charon->scheduler, job, delay - diff); return SUCCESS; } @@ -653,8 +642,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state) { this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED]; job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE); - charon->scheduler->schedule_job(charon->scheduler, - job, t * 1000); + charon->scheduler->schedule_job(charon->scheduler, job, t); DBG1(DBG_IKE, "scheduling rekeying in %ds", t); } t = this->peer_cfg->get_reauth_time(this->peer_cfg); @@ -663,8 +651,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state) { this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED]; job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE); - charon->scheduler->schedule_job(charon->scheduler, - job, t * 1000); + charon->scheduler->schedule_job(charon->scheduler, job, t); DBG1(DBG_IKE, "scheduling reauthentication in %ds", t); } t = this->peer_cfg->get_over_time(this->peer_cfg); @@ -686,8 +673,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state) this->stats[STAT_DELETE] += t; t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED]; job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE); - charon->scheduler->schedule_job(charon->scheduler, job, - t * 1000); + charon->scheduler->schedule_job(charon->scheduler, job, t); DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t); } @@ -1117,9 +1103,11 @@ static void resolve_hosts(private_ike_sa_t *this) } /** - * Initiates a CHILD_SA using the appropriate reqid + * Implementation of ike_sa_t.initiate */ -static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid) +static status_t initiate(private_ike_sa_t *this, + child_cfg_t *child_cfg, u_int32_t reqid, + traffic_selector_t *tsi, traffic_selector_t *tsr) { task_t *task; @@ -1181,7 +1169,7 @@ static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_c #endif /* ME */ { /* normal IKE_SA with CHILD_SA */ - task = (task_t*)child_create_create(&this->public, child_cfg); + task = (task_t*)child_create_create(&this->public, child_cfg, tsi, tsr); child_cfg->destroy(child_cfg); if (reqid) { @@ -1205,176 +1193,6 @@ static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_c } /** - * Implementation of ike_sa_t.initiate. - */ -static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg) -{ - return initiate_with_reqid(this, child_cfg, 0); -} - -/** - * Implementation of ike_sa_t.acquire. - */ -static status_t acquire(private_ike_sa_t *this, u_int32_t reqid) -{ - child_cfg_t *child_cfg; - iterator_t *iterator; - child_sa_t *current, *child_sa = NULL; - - switch (this->state) - { - case IKE_DELETING: - DBG1(DBG_IKE, "acquiring CHILD_SA {reqid %d} failed: " - "IKE_SA is deleting", reqid); - return FAILED; - case IKE_PASSIVE: - /* do not process acquires if passive */ - return FAILED; - default: - break; - } - - /* find CHILD_SA */ - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (current->get_reqid(current) == reqid) - { - child_sa = current; - break; - } - } - iterator->destroy(iterator); - if (!child_sa) - { - DBG1(DBG_IKE, "acquiring CHILD_SA {reqid %d} failed: " - "CHILD_SA not found", reqid); - return FAILED; - } - - child_cfg = child_sa->get_config(child_sa); - child_cfg->get_ref(child_cfg); - - return initiate_with_reqid(this, child_cfg, reqid); -} - -/** - * Implementation of ike_sa_t.route. - */ -static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg) -{ - child_sa_t *child_sa; - iterator_t *iterator; - linked_list_t *my_ts, *other_ts; - host_t *me, *other; - status_t status; - - /* check if not already routed*/ - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) - { - if (child_sa->get_state(child_sa) == CHILD_ROUTED && - streq(child_sa->get_name(child_sa), child_cfg->get_name(child_cfg))) - { - iterator->destroy(iterator); - DBG1(DBG_IKE, "routing CHILD_SA failed: already routed"); - return FAILED; - } - } - iterator->destroy(iterator); - - switch (this->state) - { - case IKE_DELETING: - case IKE_REKEYING: - DBG1(DBG_IKE, "routing CHILD_SA failed: IKE_SA is %N", - ike_sa_state_names, this->state); - return FAILED; - case IKE_CREATED: - case IKE_CONNECTING: - case IKE_ESTABLISHED: - case IKE_PASSIVE: - default: - break; - } - - resolve_hosts(this); - - /* install kernel policies */ - child_sa = child_sa_create(this->my_host, this->other_host, - child_cfg, 0, FALSE); - me = this->my_host; - if (this->my_virtual_ip) - { - me = this->my_virtual_ip; - } - other = this->other_host; - if (this->other_virtual_ip) - { - other = this->other_virtual_ip; - } - - my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me); - other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other); - - child_sa->set_mode(child_sa, child_cfg->get_mode(child_cfg)); - status = child_sa->add_policies(child_sa, my_ts, other_ts); - - my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); - other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); - if (status == SUCCESS) - { - this->child_sas->insert_last(this->child_sas, child_sa); - DBG1(DBG_IKE, "CHILD_SA routed"); - } - else - { - child_sa->destroy(child_sa); - DBG1(DBG_IKE, "routing CHILD_SA failed"); - } - return status; -} - -/** - * Implementation of ike_sa_t.unroute. - */ -static status_t unroute(private_ike_sa_t *this, u_int32_t reqid) -{ - iterator_t *iterator; - child_sa_t *child_sa; - bool found = FALSE; - - /* find CHILD_SA in ROUTED state */ - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) - { - if (child_sa->get_state(child_sa) == CHILD_ROUTED && - child_sa->get_reqid(child_sa) == reqid) - { - iterator->remove(iterator); - DBG1(DBG_IKE, "CHILD_SA unrouted"); - child_sa->destroy(child_sa); - found = TRUE; - break; - } - } - iterator->destroy(iterator); - - if (!found) - { - DBG1(DBG_IKE, "unrouting CHILD_SA failed: reqid %d not found", reqid); - return FAILED; - } - /* if we are not established, and we have no more routed childs, remove whole SA */ - if (this->state == IKE_CREATED && - this->child_sas->get_count(this->child_sas) == 0) - { - return DESTROY_ME; - } - return SUCCESS; -} - -/** * Implementation of ike_sa_t.process_message. */ static status_t process_message(private_ike_sa_t *this, message_t *message) @@ -1448,14 +1266,10 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) else { host_t *me, *other; - private_ike_sa_t *new; - iterator_t *iterator; - child_sa_t *child; - bool has_routed = FALSE; me = message->get_destination(message); other = message->get_source(message); - + /* if this IKE_SA is virgin, we check for a config */ if (this->ike_cfg == NULL) { @@ -1485,59 +1299,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) update_hosts(this, me, other); } } - status = this->task_manager->process_message(this->task_manager, message); - if (status != DESTROY_ME) - { - if (message->get_exchange_type(message) == IKE_AUTH && - this->state == IKE_ESTABLISHED) - { - /* purge auth items if SA is up, as they contain certs - * and other memory wasting elements */ - this->my_auth->purge(this->my_auth); - this->other_auth->purge(this->other_auth); - } - return status; - } - /* if IKE_SA gets closed for any reasons, reroute routed children */ - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child)) - { - if (child->get_state(child) == CHILD_ROUTED) - { - has_routed = TRUE; - break; - } - } - iterator->destroy(iterator); - if (!has_routed) - { - return status; - } - /* move routed children to a new IKE_SA, apply connection info */ - new = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new( - charon->ike_sa_manager, TRUE); - set_peer_cfg(new, this->peer_cfg); - new->other_host->destroy(new->other_host); - new->other_host = this->other_host->clone(this->other_host); - if (!has_condition(this, COND_NAT_THERE)) - { - new->other_host->set_port(new->other_host, IKEV2_UDP_PORT); - } - if (this->my_virtual_ip) - { - set_virtual_ip(new, TRUE, this->my_virtual_ip); - } - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child)) - { - if (child->get_state(child) == CHILD_ROUTED) - { - route(new, child->get_config(child)); - } - } - iterator->destroy(iterator); - charon->ike_sa_manager->checkin(charon->ike_sa_manager, &new->public); - return status; + return this->task_manager->process_message(this->task_manager, message); } } @@ -1846,7 +1608,7 @@ static status_t reestablish(private_ike_sa_t *this) #ifdef ME if (this->peer_cfg->is_mediation(this->peer_cfg)) { - status = new->initiate(new, NULL); + status = new->initiate(new, NULL, 0, NULL, NULL); } else #endif /* ME */ @@ -1869,10 +1631,11 @@ static status_t reestablish(private_ike_sa_t *this) DBG1(DBG_IKE, "restarting CHILD_SA %s", child_cfg->get_name(child_cfg)); child_cfg->get_ref(child_cfg); - status = new->initiate(new, child_cfg); + status = new->initiate(new, child_cfg, 0, NULL, NULL); break; case ACTION_ROUTE: - status = new->route(new, child_cfg); + charon->traps->install(charon->traps, + this->peer_cfg, child_cfg); break; default: continue; @@ -1888,13 +1651,15 @@ static status_t reestablish(private_ike_sa_t *this) if (status == DESTROY_ME) { charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new); - return FAILED; + status = FAILED; } else { charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); - return SUCCESS; + status = SUCCESS; } + charon->bus->set_sa(charon->bus, &this->public); + return status; } /** @@ -1960,8 +1725,8 @@ static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime) DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication" " in %ds", lifetime, lifetime - reduction); charon->scheduler->schedule_job(charon->scheduler, - (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), - (lifetime - reduction) * 1000); + (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), + lifetime - reduction); } else { @@ -2030,12 +1795,34 @@ static status_t roam(private_ike_sa_t *this, bool address) } /** + * Implementation of ike_sa_t.add_configuration_attribute + */ +static void add_configuration_attribute(private_ike_sa_t *this, + configuration_attribute_type_t type, chunk_t data) +{ + attribute_entry_t *entry; + attribute_handler_t *handler; + + handler = charon->attributes->handle(charon->attributes, + &this->public, type, data); + if (handler) + { + entry = malloc_thing(attribute_entry_t); + entry->handler = handler; + entry->type = type; + entry->data = chunk_clone(data); + + this->attributes->insert_last(this->attributes, entry); + } +} + +/** * Implementation of ike_sa_t.inherit. */ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other) { child_sa_t *child_sa; - host_t *ip; + attribute_entry_t *entry; /* apply hosts and ids */ this->my_host->destroy(this->my_host); @@ -2059,11 +1846,11 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other) other->other_virtual_ip = NULL; } - /* ... and DNS servers */ - while (other->dns_servers->remove_last(other->dns_servers, - (void**)&ip) == SUCCESS) + /* ... and configuration attributes */ + while (other->attributes->remove_last(other->attributes, + (void**)&entry) == SUCCESS) { - this->dns_servers->insert_first(this->dns_servers, ip); + this->attributes->insert_first(this->attributes, entry); } /* inherit all conditions */ @@ -2107,158 +1894,36 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other) DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, " "lifetime reduced to %ds", reauth, delete); charon->scheduler->schedule_job(charon->scheduler, - (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), - reauth * 1000); + (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth); charon->scheduler->schedule_job(charon->scheduler, - (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), - delete * 1000); + (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete); } /* we have to initate here, there may be new tasks to handle */ return this->task_manager->initiate(this->task_manager); } /** - * Implementation of ike_sa_t.remove_dns_server - */ -static void remove_dns_servers(private_ike_sa_t *this) -{ - FILE *file; - struct stat stats; - chunk_t contents, line, orig_line, token; - char string[INET6_ADDRSTRLEN]; - host_t *ip; - iterator_t *iterator; - - if (this->dns_servers->get_count(this->dns_servers) == 0) - { - /* don't touch anything if we have no nameservers installed */ - return; - } - - file = fopen(RESOLV_CONF, "r"); - if (file == NULL || stat(RESOLV_CONF, &stats) != 0) - { - DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s", - RESOLV_CONF, strerror(errno)); - return; - } - - contents = chunk_alloca((size_t)stats.st_size); - - if (fread(contents.ptr, 1, contents.len, file) != contents.len) - { - DBG1(DBG_IKE, "unable to read DNS configuration file: %s", strerror(errno)); - fclose(file); - return; - } - - fclose(file); - file = fopen(RESOLV_CONF, "w"); - if (file == NULL) - { - DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s", - RESOLV_CONF, strerror(errno)); - return; - } - - iterator = this->dns_servers->create_iterator(this->dns_servers, TRUE); - while (fetchline(&contents, &line)) - { - bool found = FALSE; - orig_line = line; - if (extract_token(&token, ' ', &line) && - strncasecmp(token.ptr, "nameserver", token.len) == 0) - { - if (!extract_token(&token, ' ', &line)) - { - token = line; - } - iterator->reset(iterator); - while (iterator->iterate(iterator, (void**)&ip)) - { - snprintf(string, sizeof(string), "%H", ip); - if (strlen(string) == token.len && - strncmp(token.ptr, string, token.len) == 0) - { - iterator->remove(iterator); - ip->destroy(ip); - found = TRUE; - break; - } - } - } - - if (!found) - { - /* write line untouched back to file */ - ignore_result(fwrite(orig_line.ptr, orig_line.len, 1, file)); - fprintf(file, "\n"); - } - } - iterator->destroy(iterator); - fclose(file); -} - -/** - * Implementation of ike_sa_t.add_dns_server - */ -static void add_dns_server(private_ike_sa_t *this, host_t *dns) -{ - FILE *file; - struct stat stats; - chunk_t contents; - - DBG1(DBG_IKE, "installing DNS server %H", dns); - - file = fopen(RESOLV_CONF, "a+"); - if (file == NULL || stat(RESOLV_CONF, &stats) != 0) - { - DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s", - RESOLV_CONF, strerror(errno)); - return; - } - - contents = chunk_alloca(stats.st_size); - - if (fread(contents.ptr, 1, contents.len, file) != contents.len) - { - DBG1(DBG_IKE, "unable to read DNS configuration file: %s", strerror(errno)); - fclose(file); - return; - } - - fclose(file); - file = fopen(RESOLV_CONF, "w"); - if (file == NULL) - { - DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s", - RESOLV_CONF, strerror(errno)); - return; - } - - if (fprintf(file, "nameserver %H # added by strongSwan, assigned by %D\n", - dns, this->other_id) < 0) - { - DBG1(DBG_IKE, "unable to write DNS configuration: %s", strerror(errno)); - } - else - { - this->dns_servers->insert_last(this->dns_servers, dns->clone(dns)); - } - ignore_result(fwrite(contents.ptr, contents.len, 1, file)); - - fclose(file); -} - -/** * Implementation of ike_sa_t.destroy. */ static void destroy(private_ike_sa_t *this) { + attribute_entry_t *entry; + charon->bus->set_sa(charon->bus, &this->public); set_state(this, IKE_DESTROYING); + /* remove attributes first, as we pass the IKE_SA to the handler */ + while (this->attributes->remove_last(this->attributes, + (void**)&entry) == SUCCESS) + { + charon->attributes->release(charon->attributes, entry->handler, + &this->public, entry->type, entry->data); + free(entry->data.ptr); + free(entry); + } + this->attributes->destroy(this->attributes); + this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy)); /* unset SA after here to avoid usage by the listeners */ @@ -2283,10 +1948,6 @@ static void destroy(private_ike_sa_t *this) } this->other_virtual_ip->destroy(this->other_virtual_ip); } - - remove_dns_servers(this); - this->dns_servers->destroy_offset(this->dns_servers, - offsetof(host_t, destroy)); this->additional_addresses->destroy_offset(this->additional_addresses, offsetof(host_t, destroy)); #ifdef ME @@ -2309,9 +1970,9 @@ static void destroy(private_ike_sa_t *this) DESTROY_IF(this->ike_cfg); DESTROY_IF(this->peer_cfg); - DESTROY_IF(this->my_auth); - DESTROY_IF(this->other_auth); DESTROY_IF(this->proposal); + this->my_auth->destroy(this->my_auth); + this->other_auth->destroy(this->other_auth); this->ike_sa_id->destroy(this->ike_sa_id); free(this); @@ -2331,16 +1992,12 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->public.get_name = (char* (*)(ike_sa_t*))get_name; this->public.get_statistic = (u_int32_t(*)(ike_sa_t*, statistic_t kind))get_statistic; this->public.process_message = (status_t (*)(ike_sa_t*, message_t*)) process_message; - this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*)) initiate; - this->public.route = (status_t (*)(ike_sa_t*,child_cfg_t*)) route; - this->public.unroute = (status_t (*)(ike_sa_t*,u_int32_t)) unroute; - this->public.acquire = (status_t (*)(ike_sa_t*,u_int32_t)) acquire; + this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*,u_int32_t,traffic_selector_t*,traffic_selector_t*)) initiate; this->public.get_ike_cfg = (ike_cfg_t* (*)(ike_sa_t*))get_ike_cfg; this->public.set_ike_cfg = (void (*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg; this->public.get_peer_cfg = (peer_cfg_t* (*)(ike_sa_t*))get_peer_cfg; this->public.set_peer_cfg = (void (*)(ike_sa_t*,peer_cfg_t*))set_peer_cfg; - this->public.get_my_auth = (auth_info_t*(*)(ike_sa_t*))get_my_auth; - this->public.get_other_auth = (auth_info_t*(*)(ike_sa_t*))get_other_auth; + this->public.get_auth_cfg = (auth_cfg_t*(*)(ike_sa_t*, bool local))get_auth_cfg; this->public.get_proposal = (proposal_t*(*)(ike_sa_t*))get_proposal; this->public.set_proposal = (void(*)(ike_sa_t*, proposal_t *proposal))set_proposal; this->public.get_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id; @@ -2388,7 +2045,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->public.get_unique_id = (u_int32_t (*)(ike_sa_t*))get_unique_id; this->public.set_virtual_ip = (void (*)(ike_sa_t*,bool,host_t*))set_virtual_ip; this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip; - this->public.add_dns_server = (void (*)(ike_sa_t*,host_t*))add_dns_server; + this->public.add_configuration_attribute = (void(*)(ike_sa_t*, configuration_attribute_type_t type, chunk_t data))add_configuration_attribute; this->public.set_kmaddress = (void (*)(ike_sa_t*,host_t*,host_t*))set_kmaddress; #ifdef ME this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server; @@ -2421,15 +2078,15 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->stats[STAT_INBOUND] = this->stats[STAT_OUTBOUND] = time(NULL); this->ike_cfg = NULL; this->peer_cfg = NULL; - this->my_auth = auth_info_create(); - this->other_auth = auth_info_create(); + this->my_auth = auth_cfg_create(); + this->other_auth = auth_cfg_create(); this->proposal = NULL; this->task_manager = task_manager_create(&this->public); this->unique_id = ++unique_id; this->my_virtual_ip = NULL; this->other_virtual_ip = NULL; - this->dns_servers = linked_list_create(); this->additional_addresses = linked_list_create(); + this->attributes = linked_list_create(); this->nat_detection_dest = chunk_empty; this->pending_updates = 0; this->keyingtry = 0; |