Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/tasks/child_create.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2019 Tobias Brunner
                      3:  * Copyright (C) 2005-2008 Martin Willi
                      4:  * Copyright (C) 2005 Jan Hutter
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "child_create.h"
                     19: 
                     20: #include <daemon.h>
                     21: #include <sa/ikev2/keymat_v2.h>
                     22: #include <crypto/diffie_hellman.h>
                     23: #include <credentials/certificates/x509.h>
                     24: #include <encoding/payloads/sa_payload.h>
                     25: #include <encoding/payloads/ke_payload.h>
                     26: #include <encoding/payloads/ts_payload.h>
                     27: #include <encoding/payloads/nonce_payload.h>
                     28: #include <encoding/payloads/notify_payload.h>
                     29: #include <encoding/payloads/delete_payload.h>
                     30: #include <processing/jobs/delete_ike_sa_job.h>
                     31: #include <processing/jobs/inactivity_job.h>
                     32: #include <processing/jobs/initiate_tasks_job.h>
                     33: 
                     34: typedef struct private_child_create_t private_child_create_t;
                     35: 
                     36: /**
                     37:  * Private members of a child_create_t task.
                     38:  */
                     39: struct private_child_create_t {
                     40: 
                     41:        /**
                     42:         * Public methods and task_t interface.
                     43:         */
                     44:        child_create_t public;
                     45: 
                     46:        /**
                     47:         * Assigned IKE_SA.
                     48:         */
                     49:        ike_sa_t *ike_sa;
                     50: 
                     51:        /**
                     52:         * Are we the initiator?
                     53:         */
                     54:        bool initiator;
                     55: 
                     56:        /**
                     57:         * nonce chosen by us
                     58:         */
                     59:        chunk_t my_nonce;
                     60: 
                     61:        /**
                     62:         * nonce chosen by peer
                     63:         */
                     64:        chunk_t other_nonce;
                     65: 
                     66:        /**
                     67:         * nonce generator
                     68:         */
                     69:        nonce_gen_t *nonceg;
                     70: 
                     71:        /**
                     72:         * config to create the CHILD_SA from
                     73:         */
                     74:        child_cfg_t *config;
                     75: 
                     76:        /**
                     77:         * list of proposal candidates
                     78:         */
                     79:        linked_list_t *proposals;
                     80: 
                     81:        /**
                     82:         * selected proposal to use for CHILD_SA
                     83:         */
                     84:        proposal_t *proposal;
                     85: 
                     86:        /**
                     87:         * traffic selectors for initiators side
                     88:         */
                     89:        linked_list_t *tsi;
                     90: 
                     91:        /**
                     92:         * traffic selectors for responders side
                     93:         */
                     94:        linked_list_t *tsr;
                     95: 
                     96:        /**
                     97:         * source of triggering packet
                     98:         */
                     99:        traffic_selector_t *packet_tsi;
                    100: 
                    101:        /**
                    102:         * destination of triggering packet
                    103:         */
                    104:        traffic_selector_t *packet_tsr;
                    105: 
                    106:        /**
                    107:         * optional diffie hellman exchange
                    108:         */
                    109:        diffie_hellman_t *dh;
                    110: 
                    111:        /**
                    112:         * Applying DH public value failed?
                    113:         */
                    114:        bool dh_failed;
                    115: 
                    116:        /**
                    117:         * group used for DH exchange
                    118:         */
                    119:        diffie_hellman_group_t dh_group;
                    120: 
                    121:        /**
                    122:         * IKE_SAs keymat
                    123:         */
                    124:        keymat_v2_t *keymat;
                    125: 
                    126:        /**
                    127:         * mode the new CHILD_SA uses (transport/tunnel/beet)
                    128:         */
                    129:        ipsec_mode_t mode;
                    130: 
                    131:        /**
                    132:         * peer accepts TFC padding for this SA
                    133:         */
                    134:        bool tfcv3;
                    135: 
                    136:        /**
                    137:         * IPComp transform to use
                    138:         */
                    139:        ipcomp_transform_t ipcomp;
                    140: 
                    141:        /**
                    142:         * IPComp transform proposed or accepted by the other peer
                    143:         */
                    144:        ipcomp_transform_t ipcomp_received;
                    145: 
                    146:        /**
                    147:         * IPsec protocol
                    148:         */
                    149:        protocol_id_t proto;
                    150: 
                    151:        /**
                    152:         * Own allocated SPI
                    153:         */
                    154:        uint32_t my_spi;
                    155: 
                    156:        /**
                    157:         * SPI received in proposal
                    158:         */
                    159:        uint32_t other_spi;
                    160: 
                    161:        /**
                    162:         * Own allocated Compression Parameter Index (CPI)
                    163:         */
                    164:        uint16_t my_cpi;
                    165: 
                    166:        /**
                    167:         * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
                    168:         */
                    169:        uint16_t other_cpi;
                    170: 
                    171:        /**
                    172:         * Data collected to create the CHILD_SA
                    173:         */
                    174:        child_sa_create_t child;
                    175: 
                    176:        /**
                    177:         * CHILD_SA which gets established
                    178:         */
                    179:        child_sa_t *child_sa;
                    180: 
                    181:        /**
                    182:         * successfully established the CHILD?
                    183:         */
                    184:        bool established;
                    185: 
                    186:        /**
                    187:         * whether the CHILD_SA rekeys an existing one
                    188:         */
                    189:        bool rekey;
                    190: 
                    191:        /**
                    192:         * whether we are retrying with another DH group
                    193:         */
                    194:        bool retry;
                    195: };
                    196: 
                    197: /**
                    198:  * Schedule a retry if creating the CHILD_SA temporary failed
                    199:  */
                    200: static void schedule_delayed_retry(private_child_create_t *this)
                    201: {
                    202:        child_create_t *task;
                    203:        uint32_t retry;
                    204: 
                    205:        retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
                    206: 
                    207:        task = child_create_create(this->ike_sa,
                    208:                                                           this->config->get_ref(this->config), FALSE,
                    209:                                                           this->packet_tsi, this->packet_tsr);
                    210:        task->use_reqid(task, this->child.reqid);
                    211:        task->use_marks(task, this->child.mark_in, this->child.mark_out);
                    212:        task->use_if_ids(task, this->child.if_id_in, this->child.if_id_out);
                    213: 
                    214:        DBG1(DBG_IKE, "creating CHILD_SA failed, trying again in %d seconds",
                    215:                 retry);
                    216:        this->ike_sa->queue_task_delayed(this->ike_sa, (task_t*)task, retry);
                    217: }
                    218: 
                    219: /**
                    220:  * get the nonce from a message
                    221:  */
                    222: static status_t get_nonce(message_t *message, chunk_t *nonce)
                    223: {
                    224:        nonce_payload_t *payload;
                    225: 
                    226:        payload = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
                    227:        if (payload == NULL)
                    228:        {
                    229:                return FAILED;
                    230:        }
                    231:        *nonce = payload->get_nonce(payload);
                    232:        return NEED_MORE;
                    233: }
                    234: 
                    235: /**
                    236:  * generate a new nonce to include in a CREATE_CHILD_SA message
                    237:  */
                    238: static bool generate_nonce(private_child_create_t *this)
                    239: {
                    240:        this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
                    241:        if (!this->nonceg)
                    242:        {
                    243:                DBG1(DBG_IKE, "no nonce generator found to create nonce");
                    244:                return FALSE;
                    245:        }
                    246:        if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
                    247:                                                                          &this->my_nonce))
                    248:        {
                    249:                DBG1(DBG_IKE, "nonce allocation failed");
                    250:                return FALSE;
                    251:        }
                    252:        return TRUE;
                    253: }
                    254: 
                    255: /**
                    256:  * Check a list of traffic selectors if any selector belongs to host
                    257:  */
                    258: static bool ts_list_is_host(linked_list_t *list, host_t *host)
                    259: {
                    260:        traffic_selector_t *ts;
                    261:        bool is_host = TRUE;
                    262:        enumerator_t *enumerator = list->create_enumerator(list);
                    263: 
                    264:        while (is_host && enumerator->enumerate(enumerator, (void**)&ts))
                    265:        {
                    266:                is_host = is_host && ts->is_host(ts, host);
                    267:        }
                    268:        enumerator->destroy(enumerator);
                    269:        return is_host;
                    270: }
                    271: 
                    272: /**
                    273:  * Allocate local SPI
                    274:  */
                    275: static bool allocate_spi(private_child_create_t *this)
                    276: {
                    277:        proposal_t *proposal;
                    278: 
                    279:        if (this->initiator)
                    280:        {
                    281:                this->proto = PROTO_ESP;
                    282:                /* we just get a SPI for the first protocol. TODO: If we ever support
                    283:                 * proposal lists with mixed protocols, we'd need multiple SPIs */
                    284:                if (this->proposals->get_first(this->proposals,
                    285:                                                                           (void**)&proposal) == SUCCESS)
                    286:                {
                    287:                        this->proto = proposal->get_protocol(proposal);
                    288:                }
                    289:        }
                    290:        else
                    291:        {
                    292:                this->proto = this->proposal->get_protocol(this->proposal);
                    293:        }
                    294:        this->my_spi = this->child_sa->alloc_spi(this->child_sa, this->proto);
                    295:        return this->my_spi != 0;
                    296: }
                    297: 
                    298: /**
                    299:  * Update the proposals with the allocated SPIs as initiator and check the DH
                    300:  * group and promote it if necessary
                    301:  */
                    302: static bool update_and_check_proposals(private_child_create_t *this)
                    303: {
                    304:        enumerator_t *enumerator;
                    305:        proposal_t *proposal;
                    306:        linked_list_t *other_dh_groups;
                    307:        bool found = FALSE;
                    308: 
                    309:        other_dh_groups = linked_list_create();
                    310:        enumerator = this->proposals->create_enumerator(this->proposals);
                    311:        while (enumerator->enumerate(enumerator, &proposal))
                    312:        {
                    313:                proposal->set_spi(proposal, this->my_spi);
                    314: 
                    315:                /* move the selected DH group to the front, if any */
                    316:                if (this->dh_group != MODP_NONE)
                    317:                {       /* proposals that don't contain the selected group are
                    318:                         * moved to the back */
                    319:                        if (!proposal->promote_dh_group(proposal, this->dh_group))
                    320:                        {
                    321:                                this->proposals->remove_at(this->proposals, enumerator);
                    322:                                other_dh_groups->insert_last(other_dh_groups, proposal);
                    323:                        }
                    324:                        else
                    325:                        {
                    326:                                found = TRUE;
                    327:                        }
                    328:                }
                    329:        }
                    330:        enumerator->destroy(enumerator);
                    331:        enumerator = other_dh_groups->create_enumerator(other_dh_groups);
                    332:        while (enumerator->enumerate(enumerator, (void**)&proposal))
                    333:        {       /* no need to remove from the list as we destroy it anyway*/
                    334:                this->proposals->insert_last(this->proposals, proposal);
                    335:        }
                    336:        enumerator->destroy(enumerator);
                    337:        other_dh_groups->destroy(other_dh_groups);
                    338: 
                    339:        return this->dh_group == MODP_NONE || found;
                    340: }
                    341: 
                    342: /**
                    343:  * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
                    344:  */
                    345: static void schedule_inactivity_timeout(private_child_create_t *this)
                    346: {
                    347:        uint32_t timeout, id;
                    348:        bool close_ike;
                    349: 
                    350:        timeout = this->config->get_inactivity(this->config);
                    351:        if (timeout)
                    352:        {
                    353:                close_ike = lib->settings->get_bool(lib->settings,
                    354:                                                                        "%s.inactivity_close_ike", FALSE, lib->ns);
                    355:                id = this->child_sa->get_unique_id(this->child_sa);
                    356:                lib->scheduler->schedule_job(lib->scheduler, (job_t*)
                    357:                                                inactivity_job_create(id, timeout, close_ike), timeout);
                    358:        }
                    359: }
                    360: 
                    361: /**
                    362:  * Check if we have a an address pool configured
                    363:  */
                    364: static bool have_pool(ike_sa_t *ike_sa)
                    365: {
                    366:        enumerator_t *enumerator;
                    367:        peer_cfg_t *peer_cfg;
                    368:        char *pool;
                    369:        bool found = FALSE;
                    370: 
                    371:        peer_cfg = ike_sa->get_peer_cfg(ike_sa);
                    372:        if (peer_cfg)
                    373:        {
                    374:                enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
                    375:                if (enumerator->enumerate(enumerator, &pool))
                    376:                {
                    377:                        found = TRUE;
                    378:                }
                    379:                enumerator->destroy(enumerator);
                    380:        }
                    381:        return found;
                    382: }
                    383: 
                    384: /**
                    385:  * Get hosts to use for dynamic traffic selectors
                    386:  */
                    387: static linked_list_t *get_dynamic_hosts(ike_sa_t *ike_sa, bool local)
                    388: {
                    389:        enumerator_t *enumerator;
                    390:        linked_list_t *list;
                    391:        host_t *host;
                    392: 
                    393:        list = linked_list_create();
                    394:        enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
                    395:        while (enumerator->enumerate(enumerator, &host))
                    396:        {
                    397:                list->insert_last(list, host);
                    398:        }
                    399:        enumerator->destroy(enumerator);
                    400: 
                    401:        if (list->get_count(list) == 0)
                    402:        {       /* no virtual IPs assigned */
                    403:                if (local)
                    404:                {
                    405:                        host = ike_sa->get_my_host(ike_sa);
                    406:                        list->insert_last(list, host);
                    407:                }
                    408:                else if (!have_pool(ike_sa))
                    409:                {       /* use host only if we don't have a pool configured */
                    410:                        host = ike_sa->get_other_host(ike_sa);
                    411:                        list->insert_last(list, host);
                    412:                }
                    413:        }
                    414:        return list;
                    415: }
                    416: 
                    417: /**
                    418:  * Substitute any host address with NATed address in traffic selector
                    419:  */
                    420: static linked_list_t* get_transport_nat_ts(private_child_create_t *this,
                    421:                                                                                   bool local, linked_list_t *in)
                    422: {
                    423:        enumerator_t *enumerator;
                    424:        linked_list_t *out;
                    425:        traffic_selector_t *ts;
                    426:        host_t *ike, *first = NULL;
                    427:        uint8_t mask;
                    428: 
                    429:        if (local)
                    430:        {
                    431:                ike = this->ike_sa->get_my_host(this->ike_sa);
                    432:        }
                    433:        else
                    434:        {
                    435:                ike = this->ike_sa->get_other_host(this->ike_sa);
                    436:        }
                    437: 
                    438:        out = linked_list_create();
                    439: 
                    440:        enumerator = in->create_enumerator(in);
                    441:        while (enumerator->enumerate(enumerator, &ts))
                    442:        {
                    443:                /* require that all selectors match the first "host" selector */
                    444:                if (ts->is_host(ts, first))
                    445:                {
                    446:                        if (!first)
                    447:                        {
                    448:                                ts->to_subnet(ts, &first, &mask);
                    449:                        }
                    450:                        ts = ts->clone(ts);
                    451:                        ts->set_address(ts, ike);
                    452:                        out->insert_last(out, ts);
                    453:                }
                    454:        }
                    455:        enumerator->destroy(enumerator);
                    456:        DESTROY_IF(first);
                    457: 
                    458:        return out;
                    459: }
                    460: 
                    461: /**
                    462:  * Narrow received traffic selectors with configuration
                    463:  */
                    464: static linked_list_t* narrow_ts(private_child_create_t *this, bool local,
                    465:                                                                linked_list_t *in)
                    466: {
                    467:        linked_list_t *hosts, *nat, *ts;
                    468:        ike_condition_t cond;
                    469: 
                    470:        cond = local ? COND_NAT_HERE : COND_NAT_THERE;
                    471:        hosts = get_dynamic_hosts(this->ike_sa, local);
                    472: 
                    473:        if (this->mode == MODE_TRANSPORT &&
                    474:                this->ike_sa->has_condition(this->ike_sa, cond))
                    475:        {
                    476:                nat = get_transport_nat_ts(this, local, in);
                    477:                ts = this->config->get_traffic_selectors(this->config, local, nat,
                    478:                                                                                                 hosts, TRUE);
                    479:                nat->destroy_offset(nat, offsetof(traffic_selector_t, destroy));
                    480:        }
                    481:        else
                    482:        {
                    483:                ts = this->config->get_traffic_selectors(this->config, local, in,
                    484:                                                                                                 hosts, TRUE);
                    485:        }
                    486: 
                    487:        hosts->destroy(hosts);
                    488: 
                    489:        return ts;
                    490: }
                    491: 
                    492: /**
                    493:  * Check if requested mode is acceptable
                    494:  */
                    495: static bool check_mode(private_child_create_t *this, host_t *i, host_t *r)
                    496: {
                    497:        switch (this->mode)
                    498:        {
                    499:                case MODE_TRANSPORT:
                    500:                        if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
                    501:                                   (!ts_list_is_host(this->tsi, i) ||
                    502:                                        !ts_list_is_host(this->tsr, r))
                    503:                           )
                    504:                        {
                    505:                                DBG1(DBG_IKE, "not using transport mode, not host-to-host");
                    506:                                return FALSE;
                    507:                        }
                    508:                        if (this->config->get_mode(this->config) != MODE_TRANSPORT)
                    509:                        {
                    510:                                return FALSE;
                    511:                        }
                    512:                        break;
                    513:                case MODE_BEET:
                    514:                        if (!ts_list_is_host(this->tsi, NULL) ||
                    515:                                !ts_list_is_host(this->tsr, NULL))
                    516:                        {
                    517:                                DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
                    518:                                return FALSE;
                    519:                        }
                    520:                        if (this->config->get_mode(this->config) != MODE_BEET)
                    521:                        {
                    522:                                return FALSE;
                    523:                        }
                    524:                        break;
                    525:                default:
                    526:                        break;
                    527:        }
                    528:        return TRUE;
                    529: }
                    530: 
                    531: /**
                    532:  * Install a CHILD_SA for usage, return value:
                    533:  * - FAILED: no acceptable proposal
                    534:  * - INVALID_ARG: diffie hellman group unacceptable
                    535:  * - NOT_FOUND: TS unacceptable
                    536:  */
                    537: static status_t select_and_install(private_child_create_t *this,
                    538:                                                                   bool no_dh, bool ike_auth)
                    539: {
                    540:        status_t status, status_i, status_o;
                    541:        child_sa_outbound_state_t out_state;
                    542:        chunk_t nonce_i, nonce_r;
                    543:        chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
                    544:        chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
                    545:        linked_list_t *my_ts, *other_ts;
                    546:        host_t *me, *other;
                    547:        proposal_selection_flag_t flags = 0;
                    548: 
                    549:        if (this->proposals == NULL)
                    550:        {
                    551:                DBG1(DBG_IKE, "SA payload missing in message");
                    552:                return FAILED;
                    553:        }
                    554:        if (this->tsi == NULL || this->tsr == NULL)
                    555:        {
                    556:                DBG1(DBG_IKE, "TS payloads missing in message");
                    557:                return NOT_FOUND;
                    558:        }
                    559: 
                    560:        me = this->ike_sa->get_my_host(this->ike_sa);
                    561:        other = this->ike_sa->get_other_host(this->ike_sa);
                    562: 
                    563:        if (no_dh)
                    564:        {
                    565:                flags |= PROPOSAL_SKIP_DH;
                    566:        }
                    567:        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) &&
                    568:                !lib->settings->get_bool(lib->settings, "%s.accept_private_algs",
                    569:                                                                 FALSE, lib->ns))
                    570:        {
                    571:                flags |= PROPOSAL_SKIP_PRIVATE;
                    572:        }
                    573:        if (!lib->settings->get_bool(lib->settings,
                    574:                                                        "%s.prefer_configured_proposals", TRUE, lib->ns))
                    575:        {
                    576:                flags |= PROPOSAL_PREFER_SUPPLIED;
                    577:        }
                    578:        this->proposal = this->config->select_proposal(this->config,
                    579:                                                                                                   this->proposals, flags);
                    580:        if (this->proposal == NULL)
                    581:        {
                    582:                DBG1(DBG_IKE, "no acceptable proposal found");
                    583:                charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD,
                    584:                                                   this->proposals);
                    585:                return FAILED;
                    586:        }
                    587:        this->other_spi = this->proposal->get_spi(this->proposal);
                    588: 
                    589:        if (!this->initiator)
                    590:        {
                    591:                if (!allocate_spi(this))
                    592:                {
                    593:                        /* responder has no SPI allocated yet */
                    594:                        DBG1(DBG_IKE, "allocating SPI failed");
                    595:                        return FAILED;
                    596:                }
                    597:                this->proposal->set_spi(this->proposal, this->my_spi);
                    598:        }
                    599:        this->child_sa->set_proposal(this->child_sa, this->proposal);
                    600: 
                    601:        if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
                    602:        {
                    603:                uint16_t group;
                    604: 
                    605:                if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
                    606:                                                                                  &group, NULL))
                    607:                {
                    608:                        DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N",
                    609:                                 diffie_hellman_group_names, this->dh_group,
                    610:                                 diffie_hellman_group_names, group);
                    611:                        this->dh_group = group;
                    612:                        return INVALID_ARG;
                    613:                }
                    614:                /* the selected proposal does not use a DH group */
                    615:                DBG1(DBG_IKE, "ignoring KE exchange, agreed on a non-PFS proposal");
                    616:                DESTROY_IF(this->dh);
                    617:                this->dh = NULL;
                    618:                this->dh_group = MODP_NONE;
                    619:        }
                    620: 
                    621:        if (this->initiator)
                    622:        {
                    623:                nonce_i = this->my_nonce;
                    624:                nonce_r = this->other_nonce;
                    625:                my_ts = narrow_ts(this, TRUE, this->tsi);
                    626:                other_ts = narrow_ts(this, FALSE, this->tsr);
                    627:        }
                    628:        else
                    629:        {
                    630:                nonce_r = this->my_nonce;
                    631:                nonce_i = this->other_nonce;
                    632:                my_ts = narrow_ts(this, TRUE, this->tsr);
                    633:                other_ts = narrow_ts(this, FALSE, this->tsi);
                    634:        }
                    635: 
                    636:        if (this->initiator)
                    637:        {
                    638:                if (ike_auth)
                    639:                {
                    640:                        charon->bus->narrow(charon->bus, this->child_sa,
                    641:                                                                NARROW_INITIATOR_POST_NOAUTH, my_ts, other_ts);
                    642:                }
                    643:                else
                    644:                {
                    645:                        charon->bus->narrow(charon->bus, this->child_sa,
                    646:                                                                NARROW_INITIATOR_POST_AUTH, my_ts, other_ts);
                    647:                }
                    648:        }
                    649:        else
                    650:        {
                    651:                charon->bus->narrow(charon->bus, this->child_sa,
                    652:                                                        NARROW_RESPONDER, my_ts, other_ts);
                    653:        }
                    654: 
                    655:        if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
                    656:        {
                    657:                charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
                    658:                my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
                    659:                other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
                    660:                DBG1(DBG_IKE, "no acceptable traffic selectors found");
                    661:                return NOT_FOUND;
                    662:        }
                    663: 
                    664:        this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
                    665:        this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
                    666:        if (this->initiator)
                    667:        {
                    668:                this->tsi = my_ts;
                    669:                this->tsr = other_ts;
                    670: 
                    671:                if (!check_mode(this, me, other))
                    672:                {
                    673:                        DBG1(DBG_IKE, "%N mode requested by responder is unacceptable",
                    674:                                 ipsec_mode_names, this->mode);
                    675:                        return FAILED;
                    676:                }
                    677:        }
                    678:        else
                    679:        {
                    680:                this->tsr = my_ts;
                    681:                this->tsi = other_ts;
                    682: 
                    683:                if (!check_mode(this, other, me))
                    684:                {
                    685:                        this->mode = MODE_TUNNEL;
                    686:                }
                    687:        }
                    688: 
                    689:        if (!this->initiator)
                    690:        {
                    691:                /* use a copy of the traffic selectors, as the POST hook should not
                    692:                 * change payloads */
                    693:                my_ts = this->tsr->clone_offset(this->tsr,
                    694:                                                                                offsetof(traffic_selector_t, clone));
                    695:                other_ts = this->tsi->clone_offset(this->tsi,
                    696:                                                                                offsetof(traffic_selector_t, clone));
                    697:                charon->bus->narrow(charon->bus, this->child_sa,
                    698:                                                        NARROW_RESPONDER_POST, my_ts, other_ts);
                    699: 
                    700:                if (my_ts->get_count(my_ts) == 0 ||     other_ts->get_count(other_ts) == 0)
                    701:                {
                    702:                        my_ts->destroy_offset(my_ts,
                    703:                                                                  offsetof(traffic_selector_t, destroy));
                    704:                        other_ts->destroy_offset(other_ts,
                    705:                                                                  offsetof(traffic_selector_t, destroy));
                    706:                        return NOT_FOUND;
                    707:                }
                    708:        }
                    709: 
                    710:        this->child_sa->set_policies(this->child_sa, my_ts, other_ts);
                    711:        if (!this->initiator)
                    712:        {
                    713:                my_ts->destroy_offset(my_ts,
                    714:                                                          offsetof(traffic_selector_t, destroy));
                    715:                other_ts->destroy_offset(other_ts,
                    716:                                                          offsetof(traffic_selector_t, destroy));
                    717:        }
                    718: 
                    719:        this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
                    720:        this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
                    721:        this->child_sa->set_mode(this->child_sa, this->mode);
                    722:        this->child_sa->set_protocol(this->child_sa,
                    723:                                                                 this->proposal->get_protocol(this->proposal));
                    724: 
                    725:        if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
                    726:        {
                    727:                this->my_cpi = this->other_cpi = 0;
                    728:                this->ipcomp = IPCOMP_NONE;
                    729:        }
                    730:        status_i = status_o = FAILED;
                    731:        if (this->keymat->derive_child_keys(this->keymat, this->proposal,
                    732:                        this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
                    733:        {
                    734:                if (this->initiator)
                    735:                {
                    736:                        status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
                    737:                                                        this->my_spi, this->my_cpi, this->initiator,
                    738:                                                        TRUE, this->tfcv3);
                    739:                }
                    740:                else
                    741:                {
                    742:                        status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
                    743:                                                        this->my_spi, this->my_cpi, this->initiator,
                    744:                                                        TRUE, this->tfcv3);
                    745:                }
                    746:                if (this->rekey)
                    747:                {       /* during rekeyings we install the outbound SA and/or policies
                    748:                         * separately: as responder when we receive the delete for the old
                    749:                         * SA, as initiator pretty much immediately in the ike-rekey task,
                    750:                         * unless there was a rekey collision that we lost */
                    751:                        if (this->initiator)
                    752:                        {
                    753:                                status_o = this->child_sa->register_outbound(this->child_sa,
                    754:                                                        encr_i, integ_i, this->other_spi, this->other_cpi,
                    755:                                                        this->tfcv3);
                    756:                        }
                    757:                        else
                    758:                        {
                    759:                                status_o = this->child_sa->register_outbound(this->child_sa,
                    760:                                                        encr_r, integ_r, this->other_spi, this->other_cpi,
                    761:                                                        this->tfcv3);
                    762:                        }
                    763:                }
                    764:                else if (this->initiator)
                    765:                {
                    766:                        status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
                    767:                                                        this->other_spi, this->other_cpi, this->initiator,
                    768:                                                        FALSE, this->tfcv3);
                    769:                }
                    770:                else
                    771:                {
                    772:                        status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
                    773:                                                        this->other_spi, this->other_cpi, this->initiator,
                    774:                                                        FALSE, this->tfcv3);
                    775:                }
                    776:        }
                    777: 
                    778:        if (status_i != SUCCESS || status_o != SUCCESS)
                    779:        {
                    780:                DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
                    781:                        (status_i != SUCCESS) ? "inbound " : "",
                    782:                        (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
                    783:                        (status_o != SUCCESS) ? "outbound " : "");
                    784:                charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
                    785:                                                   this->child_sa);
                    786:                status = FAILED;
                    787:        }
                    788:        else
                    789:        {
                    790:                status = this->child_sa->install_policies(this->child_sa);
                    791: 
                    792:                if (status != SUCCESS)
                    793:                {
                    794:                        DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
                    795:                        charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED,
                    796:                                                           this->child_sa);
                    797:                        status = NOT_FOUND;
                    798:                }
                    799:                else
                    800:                {
                    801:                        charon->bus->child_derived_keys(charon->bus, this->child_sa,
                    802:                                                                                        this->initiator, encr_i, encr_r,
                    803:                                                                                        integ_i, integ_r);
                    804:                }
                    805:        }
                    806:        chunk_clear(&integ_i);
                    807:        chunk_clear(&integ_r);
                    808:        chunk_clear(&encr_i);
                    809:        chunk_clear(&encr_r);
                    810: 
                    811:        if (status != SUCCESS)
                    812:        {
                    813:                return status;
                    814:        }
                    815: 
                    816:        charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
                    817:                                                        this->dh, nonce_i, nonce_r);
                    818: 
                    819:        my_ts = linked_list_create_from_enumerator(
                    820:                                this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
                    821:        other_ts = linked_list_create_from_enumerator(
                    822:                                this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
                    823:        out_state = this->child_sa->get_outbound_state(this->child_sa);
                    824: 
                    825:        DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
                    826:                 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
                    827:                 (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
                    828:                 this->child_sa->get_name(this->child_sa),
                    829:                 this->child_sa->get_unique_id(this->child_sa),
                    830:                 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
                    831:                 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
                    832:                 my_ts, other_ts);
                    833: 
                    834:        my_ts->destroy(my_ts);
                    835:        other_ts->destroy(other_ts);
                    836: 
                    837:        this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
                    838:        this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
                    839:        this->established = TRUE;
                    840: 
                    841:        schedule_inactivity_timeout(this);
                    842:        return SUCCESS;
                    843: }
                    844: 
                    845: /**
                    846:  * build the payloads for the message
                    847:  */
                    848: static bool build_payloads(private_child_create_t *this, message_t *message)
                    849: {
                    850:        sa_payload_t *sa_payload;
                    851:        nonce_payload_t *nonce_payload;
                    852:        ke_payload_t *ke_payload;
                    853:        ts_payload_t *ts_payload;
                    854:        kernel_feature_t features;
                    855: 
                    856:        /* add SA payload */
                    857:        if (this->initiator)
                    858:        {
                    859:                sa_payload = sa_payload_create_from_proposals_v2(this->proposals);
                    860:        }
                    861:        else
                    862:        {
                    863:                sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
                    864:        }
                    865:        message->add_payload(message, (payload_t*)sa_payload);
                    866: 
                    867:        /* add nonce payload if not in IKE_AUTH */
                    868:        if (message->get_exchange_type(message) == CREATE_CHILD_SA)
                    869:        {
                    870:                nonce_payload = nonce_payload_create(PLV2_NONCE);
                    871:                nonce_payload->set_nonce(nonce_payload, this->my_nonce);
                    872:                message->add_payload(message, (payload_t*)nonce_payload);
                    873:        }
                    874: 
                    875:        /* diffie hellman exchange, if PFS enabled */
                    876:        if (this->dh)
                    877:        {
                    878:                ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
                    879:                                                                                                                   this->dh);
                    880:                if (!ke_payload)
                    881:                {
                    882:                        DBG1(DBG_IKE, "creating KE payload failed");
                    883:                        return FALSE;
                    884:                }
                    885:                message->add_payload(message, (payload_t*)ke_payload);
                    886:        }
                    887: 
                    888:        /* add TSi/TSr payloads */
                    889:        ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
                    890:        message->add_payload(message, (payload_t*)ts_payload);
                    891:        ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
                    892:        message->add_payload(message, (payload_t*)ts_payload);
                    893: 
                    894:        /* add a notify if we are not in tunnel mode */
                    895:        switch (this->mode)
                    896:        {
                    897:                case MODE_TRANSPORT:
                    898:                        message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
                    899:                        break;
                    900:                case MODE_BEET:
                    901:                        message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
                    902:                        break;
                    903:                default:
                    904:                        break;
                    905:        }
                    906: 
                    907:        features = charon->kernel->get_features(charon->kernel);
                    908:        if (!(features & KERNEL_ESP_V3_TFC))
                    909:        {
                    910:                message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
                    911:                                                        chunk_empty);
                    912:        }
                    913:        return TRUE;
                    914: }
                    915: 
                    916: /**
                    917:  * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
                    918:  */
                    919: static void add_ipcomp_notify(private_child_create_t *this,
                    920:                                                                  message_t *message, uint8_t ipcomp)
                    921: {
                    922:        this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
                    923:        if (this->my_cpi)
                    924:        {
                    925:                this->ipcomp = ipcomp;
                    926:                message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
                    927:                                                        chunk_cata("cc", chunk_from_thing(this->my_cpi),
                    928:                                                                           chunk_from_thing(ipcomp)));
                    929:        }
                    930:        else
                    931:        {
                    932:                DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
                    933:        }
                    934: }
                    935: 
                    936: /**
                    937:  * handle a received notify payload
                    938:  */
                    939: static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
                    940: {
                    941:        switch (notify->get_notify_type(notify))
                    942:        {
                    943:                case USE_TRANSPORT_MODE:
                    944:                        this->mode = MODE_TRANSPORT;
                    945:                        break;
                    946:                case USE_BEET_MODE:
                    947:                        if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
                    948:                        {       /* handle private use notify only if we know its meaning */
                    949:                                this->mode = MODE_BEET;
                    950:                        }
                    951:                        else
                    952:                        {
                    953:                                DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
                    954:                                         "mode, but peer implementation unknown, skipped");
                    955:                        }
                    956:                        break;
                    957:                case IPCOMP_SUPPORTED:
                    958:                {
                    959:                        ipcomp_transform_t ipcomp;
                    960:                        uint16_t cpi;
                    961:                        chunk_t data;
                    962: 
                    963:                        data = notify->get_notification_data(notify);
                    964:                        cpi = *(uint16_t*)data.ptr;
                    965:                        ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
                    966:                        switch (ipcomp)
                    967:                        {
                    968:                                case IPCOMP_DEFLATE:
                    969:                                        this->other_cpi = cpi;
                    970:                                        this->ipcomp_received = ipcomp;
                    971:                                        break;
                    972:                                case IPCOMP_LZS:
                    973:                                case IPCOMP_LZJH:
                    974:                                default:
                    975:                                        DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
                    976:                                                 "transform ID we don't support %N",
                    977:                                                 ipcomp_transform_names, ipcomp);
                    978:                                        break;
                    979:                        }
                    980:                        break;
                    981:                }
                    982:                case ESP_TFC_PADDING_NOT_SUPPORTED:
                    983:                        DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
                    984:                                 notify_type_names, notify->get_notify_type(notify));
                    985:                        this->tfcv3 = FALSE;
                    986:                        break;
                    987:                default:
                    988:                        break;
                    989:        }
                    990: }
                    991: 
                    992: /**
                    993:  * Read payloads from message
                    994:  */
                    995: static void process_payloads(private_child_create_t *this, message_t *message)
                    996: {
                    997:        enumerator_t *enumerator;
                    998:        payload_t *payload;
                    999:        sa_payload_t *sa_payload;
                   1000:        ke_payload_t *ke_payload;
                   1001:        ts_payload_t *ts_payload;
                   1002: 
                   1003:        /* defaults to TUNNEL mode */
                   1004:        this->mode = MODE_TUNNEL;
                   1005: 
                   1006:        enumerator = message->create_payload_enumerator(message);
                   1007:        while (enumerator->enumerate(enumerator, &payload))
                   1008:        {
                   1009:                switch (payload->get_type(payload))
                   1010:                {
                   1011:                        case PLV2_SECURITY_ASSOCIATION:
                   1012:                                sa_payload = (sa_payload_t*)payload;
                   1013:                                this->proposals = sa_payload->get_proposals(sa_payload);
                   1014:                                break;
                   1015:                        case PLV2_KEY_EXCHANGE:
                   1016:                                ke_payload = (ke_payload_t*)payload;
                   1017:                                if (!this->initiator)
                   1018:                                {
                   1019:                                        this->dh_group = ke_payload->get_dh_group_number(ke_payload);
                   1020:                                        this->dh = this->keymat->keymat.create_dh(
                   1021:                                                                                &this->keymat->keymat, this->dh_group);
                   1022:                                }
                   1023:                                else if (this->dh)
                   1024:                                {
                   1025:                                        this->dh_failed = this->dh->get_dh_group(this->dh) !=
                   1026:                                                                        ke_payload->get_dh_group_number(ke_payload);
                   1027:                                }
                   1028:                                if (this->dh && !this->dh_failed)
                   1029:                                {
                   1030:                                        this->dh_failed = !this->dh->set_other_public_value(this->dh,
                   1031:                                                                ke_payload->get_key_exchange_data(ke_payload));
                   1032:                                }
                   1033:                                break;
                   1034:                        case PLV2_TS_INITIATOR:
                   1035:                                ts_payload = (ts_payload_t*)payload;
                   1036:                                this->tsi = ts_payload->get_traffic_selectors(ts_payload);
                   1037:                                break;
                   1038:                        case PLV2_TS_RESPONDER:
                   1039:                                ts_payload = (ts_payload_t*)payload;
                   1040:                                this->tsr = ts_payload->get_traffic_selectors(ts_payload);
                   1041:                                break;
                   1042:                        case PLV2_NOTIFY:
                   1043:                                handle_notify(this, (notify_payload_t*)payload);
                   1044:                                break;
                   1045:                        default:
                   1046:                                break;
                   1047:                }
                   1048:        }
                   1049:        enumerator->destroy(enumerator);
                   1050: }
                   1051: 
                   1052: /**
                   1053:  * Check if we should defer the creation of this CHILD_SA until after the
                   1054:  * IKE_SA has been established childless.
                   1055:  */
                   1056: static status_t defer_child_sa(private_child_create_t *this)
                   1057: {
                   1058:        ike_cfg_t *ike_cfg;
                   1059: 
                   1060:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                   1061: 
                   1062:        if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_CHILDLESS))
                   1063:        {
                   1064:                if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
                   1065:                {
                   1066:                        return NEED_MORE;
                   1067:                }
                   1068:        }
                   1069:        else if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
                   1070:        {
                   1071:                DBG1(DBG_IKE, "peer does not support childless IKE_SA initiation");
                   1072:                return DESTROY_ME;
                   1073:        }
                   1074:        return NOT_SUPPORTED;
                   1075: }
                   1076: 
                   1077: METHOD(task_t, build_i, status_t,
                   1078:        private_child_create_t *this, message_t *message)
                   1079: {
                   1080:        enumerator_t *enumerator;
                   1081:        host_t *vip;
                   1082:        peer_cfg_t *peer_cfg;
                   1083:        linked_list_t *list;
                   1084: 
                   1085:        switch (message->get_exchange_type(message))
                   1086:        {
                   1087:                case IKE_SA_INIT:
                   1088:                        return get_nonce(message, &this->my_nonce);
                   1089:                case CREATE_CHILD_SA:
                   1090:                        if (!generate_nonce(this))
                   1091:                        {
                   1092:                                message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
                   1093:                                                                        chunk_empty);
                   1094:                                return SUCCESS;
                   1095:                        }
                   1096:                        if (!this->retry && this->dh_group == MODP_NONE)
                   1097:                        {       /* during a rekeying the group might already be set */
                   1098:                                this->dh_group = this->config->get_dh_group(this->config);
                   1099:                        }
                   1100:                        break;
                   1101:                case IKE_AUTH:
                   1102:                        if (message->get_message_id(message) != 1)
                   1103:                        {
                   1104:                                /* send only in the first request, not in subsequent rounds */
                   1105:                                return NEED_MORE;
                   1106:                        }
                   1107:                        switch (defer_child_sa(this))
                   1108:                        {
                   1109:                                case DESTROY_ME:
                   1110:                                        /* config mismatch */
                   1111:                                        return DESTROY_ME;
                   1112:                                case NEED_MORE:
                   1113:                                        /* defer until after IKE_SA has been established */
                   1114:                                        chunk_free(&this->my_nonce);
                   1115:                                        return NEED_MORE;
                   1116:                                default:
                   1117:                                        /* just continue to establish the CHILD_SA */
                   1118:                                        break;
                   1119:                        }
                   1120:                        break;
                   1121:                default:
                   1122:                        break;
                   1123:        }
                   1124: 
                   1125:        /* check if we want a virtual IP, but don't have one */
                   1126:        list = linked_list_create();
                   1127:        peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                   1128:        if (!this->rekey)
                   1129:        {
                   1130:                enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
                   1131:                while (enumerator->enumerate(enumerator, &vip))
                   1132:                {
                   1133:                        /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
                   1134:                        vip = host_create_any(vip->get_family(vip));
                   1135:                        list->insert_last(list, vip);
                   1136:                }
                   1137:                enumerator->destroy(enumerator);
                   1138:        }
                   1139:        if (list->get_count(list))
                   1140:        {
                   1141:                this->tsi = this->config->get_traffic_selectors(this->config,
                   1142:                                                                                                                TRUE, NULL, list, TRUE);
                   1143:                list->destroy_offset(list, offsetof(host_t, destroy));
                   1144:        }
                   1145:        else
                   1146:        {       /* no virtual IPs configured */
                   1147:                list->destroy(list);
                   1148:                list = get_dynamic_hosts(this->ike_sa, TRUE);
                   1149:                this->tsi = this->config->get_traffic_selectors(this->config,
                   1150:                                                                                                                TRUE, NULL, list, TRUE);
                   1151:                list->destroy(list);
                   1152:        }
                   1153:        list = get_dynamic_hosts(this->ike_sa, FALSE);
                   1154:        this->tsr = this->config->get_traffic_selectors(this->config,
                   1155:                                                                                                        FALSE, NULL, list, TRUE);
                   1156:        list->destroy(list);
                   1157: 
                   1158:        if (this->packet_tsi)
                   1159:        {
                   1160:                this->tsi->insert_first(this->tsi,
                   1161:                                                                this->packet_tsi->clone(this->packet_tsi));
                   1162:        }
                   1163:        if (this->packet_tsr)
                   1164:        {
                   1165:                this->tsr->insert_first(this->tsr,
                   1166:                                                                this->packet_tsr->clone(this->packet_tsr));
                   1167:        }
                   1168:        this->proposals = this->config->get_proposals(this->config,
                   1169:                                                                                                  this->dh_group == MODP_NONE);
                   1170:        this->mode = this->config->get_mode(this->config);
                   1171: 
                   1172:        this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE);
                   1173:        this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa, FALSE);
                   1174:        this->child.encap = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY);
                   1175:        this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
                   1176:                                                                         this->ike_sa->get_other_host(this->ike_sa),
                   1177:                                                                         this->config, &this->child);
                   1178: 
                   1179:        if (this->child.reqid)
                   1180:        {
                   1181:                DBG0(DBG_IKE, "establishing CHILD_SA %s{%d} reqid %d",
                   1182:                         this->child_sa->get_name(this->child_sa),
                   1183:                         this->child_sa->get_unique_id(this->child_sa), this->child.reqid);
                   1184:        }
                   1185:        else
                   1186:        {
                   1187:                DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
                   1188:                         this->child_sa->get_name(this->child_sa),
                   1189:                         this->child_sa->get_unique_id(this->child_sa));
                   1190:        }
                   1191: 
                   1192:        if (!allocate_spi(this))
                   1193:        {
                   1194:                DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
                   1195:                return FAILED;
                   1196:        }
                   1197: 
                   1198:        if (!update_and_check_proposals(this))
                   1199:        {
                   1200:                DBG1(DBG_IKE, "requested DH group %N not contained in any of our "
                   1201:                         "proposals",
                   1202:                         diffie_hellman_group_names, this->dh_group);
                   1203:                return FAILED;
                   1204:        }
                   1205: 
                   1206:        if (this->dh_group != MODP_NONE)
                   1207:        {
                   1208:                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                   1209:                                                                                                  this->dh_group);
                   1210:        }
                   1211: 
                   1212:        if (this->config->has_option(this->config, OPT_IPCOMP))
                   1213:        {
                   1214:                /* IPCOMP_DEFLATE is the only transform we support at the moment */
                   1215:                add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
                   1216:        }
                   1217: 
                   1218:        if (message->get_exchange_type(message) == IKE_AUTH)
                   1219:        {
                   1220:                charon->bus->narrow(charon->bus, this->child_sa,
                   1221:                                                        NARROW_INITIATOR_PRE_NOAUTH, this->tsi, this->tsr);
                   1222:        }
                   1223:        else
                   1224:        {
                   1225:                charon->bus->narrow(charon->bus, this->child_sa,
                   1226:                                                        NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
                   1227:        }
                   1228: 
                   1229:        if (!build_payloads(this, message))
                   1230:        {
                   1231:                return FAILED;
                   1232:        }
                   1233: 
                   1234:        this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
                   1235:        this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
                   1236:        this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
                   1237:        this->tsi = NULL;
                   1238:        this->tsr = NULL;
                   1239:        this->proposals = NULL;
                   1240: 
                   1241:        return NEED_MORE;
                   1242: }
                   1243: 
                   1244: METHOD(task_t, process_r, status_t,
                   1245:        private_child_create_t *this, message_t *message)
                   1246: {
                   1247:        switch (message->get_exchange_type(message))
                   1248:        {
                   1249:                case IKE_SA_INIT:
                   1250:                        return get_nonce(message, &this->other_nonce);
                   1251:                case CREATE_CHILD_SA:
                   1252:                        get_nonce(message, &this->other_nonce);
                   1253:                        break;
                   1254:                case IKE_AUTH:
                   1255:                        if (message->get_message_id(message) != 1)
                   1256:                        {
                   1257:                                /* only handle first AUTH payload, not additional rounds */
                   1258:                                return NEED_MORE;
                   1259:                        }
                   1260:                default:
                   1261:                        break;
                   1262:        }
                   1263: 
                   1264:        process_payloads(this, message);
                   1265: 
                   1266:        return NEED_MORE;
                   1267: }
                   1268: 
                   1269: /**
                   1270:  * handle CHILD_SA setup failure
                   1271:  */
                   1272: static void handle_child_sa_failure(private_child_create_t *this,
                   1273:                                                                        message_t *message)
                   1274: {
                   1275:        bool is_first;
                   1276: 
                   1277:        is_first = message->get_exchange_type(message) == IKE_AUTH;
                   1278:        if (is_first &&
                   1279:                lib->settings->get_bool(lib->settings,
                   1280:                                                                "%s.close_ike_on_child_failure", FALSE, lib->ns))
                   1281:        {
                   1282:                /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
                   1283:                 * first */
                   1284:                DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
                   1285:                lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
                   1286:                        delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
                   1287:                        100);
                   1288:        }
                   1289:        else
                   1290:        {
                   1291:                DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
                   1292:                charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
                   1293:                                                   is_first);
                   1294:        }
                   1295: }
                   1296: 
                   1297: /**
                   1298:  * Substitute transport mode NAT selectors, if applicable
                   1299:  */
                   1300: static linked_list_t* get_ts_if_nat_transport(private_child_create_t *this,
                   1301:                                                                                          bool local, linked_list_t *in)
                   1302: {
                   1303:        linked_list_t *out = NULL;
                   1304:        ike_condition_t cond;
                   1305: 
                   1306:        if (this->mode == MODE_TRANSPORT)
                   1307:        {
                   1308:                cond = local ? COND_NAT_HERE : COND_NAT_THERE;
                   1309:                if (this->ike_sa->has_condition(this->ike_sa, cond))
                   1310:                {
                   1311:                        out = get_transport_nat_ts(this, local, in);
                   1312:                        if (out->get_count(out) == 0)
                   1313:                        {
                   1314:                                out->destroy(out);
                   1315:                                out = NULL;
                   1316:                        }
                   1317:                }
                   1318:        }
                   1319:        return out;
                   1320: }
                   1321: 
                   1322: /**
                   1323:  * Select a matching CHILD config as responder
                   1324:  */
                   1325: static child_cfg_t* select_child_cfg(private_child_create_t *this)
                   1326: {
                   1327:        peer_cfg_t *peer_cfg;
                   1328:        child_cfg_t *child_cfg = NULL;;
                   1329: 
                   1330:        peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                   1331:        if (peer_cfg && this->tsi && this->tsr)
                   1332:        {
                   1333:                linked_list_t *listr, *listi, *tsr, *tsi;
                   1334: 
                   1335:                tsr = get_ts_if_nat_transport(this, TRUE, this->tsr);
                   1336:                tsi = get_ts_if_nat_transport(this, FALSE, this->tsi);
                   1337: 
                   1338:                listr = get_dynamic_hosts(this->ike_sa, TRUE);
                   1339:                listi = get_dynamic_hosts(this->ike_sa, FALSE);
                   1340:                child_cfg = peer_cfg->select_child_cfg(peer_cfg,
                   1341:                                                                                        tsr ?: this->tsr, tsi ?: this->tsi,
                   1342:                                                                                        listr, listi);
                   1343:                if ((tsi || tsr) && child_cfg &&
                   1344:                        child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
                   1345:                {
                   1346:                        /* found a CHILD config, but it doesn't use transport mode */
                   1347:                        child_cfg->destroy(child_cfg);
                   1348:                        child_cfg = NULL;
                   1349:                }
                   1350:                if (!child_cfg && (tsi || tsr))
                   1351:                {
                   1352:                        /* no match for the substituted NAT selectors, try it without */
                   1353:                        child_cfg = peer_cfg->select_child_cfg(peer_cfg,
                   1354:                                                                                        this->tsr, this->tsi, listr, listi);
                   1355:                }
                   1356:                listr->destroy(listr);
                   1357:                listi->destroy(listi);
                   1358:                DESTROY_OFFSET_IF(tsi, offsetof(traffic_selector_t, destroy));
                   1359:                DESTROY_OFFSET_IF(tsr, offsetof(traffic_selector_t, destroy));
                   1360:        }
                   1361: 
                   1362:        return child_cfg;
                   1363: }
                   1364: 
                   1365: /**
                   1366:  * Check how to handle a possibly childless IKE_SA
                   1367:  */
                   1368: static status_t handle_childless(private_child_create_t *this)
                   1369: {
                   1370:        ike_cfg_t *ike_cfg;
                   1371: 
                   1372:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                   1373: 
                   1374:        if (!this->proposals && !this->tsi && !this->tsr)
                   1375:        {
                   1376:                /* looks like a childless IKE_SA, check if we allow it */
                   1377:                if (ike_cfg->childless(ike_cfg) == CHILDLESS_NEVER)
                   1378:                {
                   1379:                        /* we don't allow childless initiation */
                   1380:                        DBG1(DBG_IKE, "peer tried to initiate a childless IKE_SA");
                   1381:                        return INVALID_STATE;
                   1382:                }
                   1383:                return SUCCESS;
                   1384:        }
                   1385: 
                   1386:        /* the peer apparently wants to create a regular IKE_SA */
                   1387:        if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
                   1388:        {
                   1389:                /* reject it if we only allow childless initiation */
                   1390:                DBG1(DBG_IKE, "peer did not initiate a childless IKE_SA");
                   1391:                return INVALID_STATE;
                   1392:        }
                   1393:        return NOT_SUPPORTED;
                   1394: }
                   1395: 
                   1396: METHOD(task_t, build_r, status_t,
                   1397:        private_child_create_t *this, message_t *message)
                   1398: {
                   1399:        payload_t *payload;
                   1400:        enumerator_t *enumerator;
                   1401:        bool no_dh = TRUE, ike_auth = FALSE;
                   1402: 
                   1403:        switch (message->get_exchange_type(message))
                   1404:        {
                   1405:                case IKE_SA_INIT:
                   1406:                        return get_nonce(message, &this->my_nonce);
                   1407:                case CREATE_CHILD_SA:
                   1408:                        if (!generate_nonce(this))
                   1409:                        {
                   1410:                                message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
                   1411:                                                                        chunk_empty);
                   1412:                                return SUCCESS;
                   1413:                        }
                   1414:                        if (this->dh_failed)
                   1415:                        {
                   1416:                                DBG1(DBG_IKE, "applying DH public value failed");
                   1417:                                message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
                   1418:                                                                        chunk_empty);
                   1419:                                return SUCCESS;
                   1420:                        }
                   1421:                        no_dh = FALSE;
                   1422:                        break;
                   1423:                case IKE_AUTH:
                   1424:                        if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
                   1425:                        {       /* wait until all authentication round completed */
                   1426:                                return NEED_MORE;
                   1427:                        }
                   1428:                        if (this->ike_sa->has_condition(this->ike_sa, COND_REDIRECTED))
                   1429:                        {       /* no CHILD_SA is created for redirected SAs */
                   1430:                                return SUCCESS;
                   1431:                        }
                   1432:                        switch (handle_childless(this))
                   1433:                        {
                   1434:                                case SUCCESS:
                   1435:                                        /* no CHILD_SA built */
                   1436:                                        return SUCCESS;
                   1437:                                case INVALID_STATE:
                   1438:                                        message->add_notify(message, FALSE, INVALID_SYNTAX,
                   1439:                                                                                chunk_empty);
                   1440:                                        return FAILED;
                   1441:                                default:
                   1442:                                        /* continue with regular initiation */
                   1443:                                        break;
                   1444:                        }
                   1445:                        ike_auth = TRUE;
                   1446:                default:
                   1447:                        break;
                   1448:        }
                   1449: 
                   1450:        if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
                   1451:        {
                   1452:                DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
                   1453:                message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
                   1454:                return SUCCESS;
                   1455:        }
                   1456:        if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
                   1457:        {
                   1458:                DBG1(DBG_IKE, "unable to create CHILD_SA while deleting IKE_SA");
                   1459:                message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
                   1460:                return SUCCESS;
                   1461:        }
                   1462: 
                   1463:        if (this->config == NULL)
                   1464:        {
                   1465:                this->config = select_child_cfg(this);
                   1466:        }
                   1467:        if (this->config == NULL)
                   1468:        {
                   1469:                DBG1(DBG_IKE, "traffic selectors %#R === %#R unacceptable",
                   1470:                         this->tsr, this->tsi);
                   1471:                charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
                   1472:                message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
                   1473:                handle_child_sa_failure(this, message);
                   1474:                return SUCCESS;
                   1475:        }
                   1476: 
                   1477:        /* check if ike_config_t included non-critical error notifies */
                   1478:        enumerator = message->create_payload_enumerator(message);
                   1479:        while (enumerator->enumerate(enumerator, &payload))
                   1480:        {
                   1481:                if (payload->get_type(payload) == PLV2_NOTIFY)
                   1482:                {
                   1483:                        notify_payload_t *notify = (notify_payload_t*)payload;
                   1484: 
                   1485:                        switch (notify->get_notify_type(notify))
                   1486:                        {
                   1487:                                case INTERNAL_ADDRESS_FAILURE:
                   1488:                                case FAILED_CP_REQUIRED:
                   1489:                                {
                   1490:                                        DBG1(DBG_IKE,"configuration payload negotiation "
                   1491:                                                 "failed, no CHILD_SA built");
                   1492:                                        enumerator->destroy(enumerator);
                   1493:                                        handle_child_sa_failure(this, message);
                   1494:                                        return SUCCESS;
                   1495:                                }
                   1496:                                default:
                   1497:                                        break;
                   1498:                        }
                   1499:                }
                   1500:        }
                   1501:        enumerator->destroy(enumerator);
                   1502: 
                   1503:        this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE);
                   1504:        this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa, FALSE);
                   1505:        this->child.encap = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY);
                   1506:        this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
                   1507:                                                                         this->ike_sa->get_other_host(this->ike_sa),
                   1508:                                                                         this->config, &this->child);
                   1509: 
                   1510:        if (this->ipcomp_received != IPCOMP_NONE)
                   1511:        {
                   1512:                if (this->config->has_option(this->config, OPT_IPCOMP))
                   1513:                {
                   1514:                        add_ipcomp_notify(this, message, this->ipcomp_received);
                   1515:                }
                   1516:                else
                   1517:                {
                   1518:                        DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
                   1519:                                 notify_type_names, IPCOMP_SUPPORTED);
                   1520:                }
                   1521:        }
                   1522: 
                   1523:        switch (select_and_install(this, no_dh, ike_auth))
                   1524:        {
                   1525:                case SUCCESS:
                   1526:                        break;
                   1527:                case NOT_FOUND:
                   1528:                        message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
                   1529:                        handle_child_sa_failure(this, message);
                   1530:                        return SUCCESS;
                   1531:                case INVALID_ARG:
                   1532:                {
                   1533:                        uint16_t group = htons(this->dh_group);
                   1534:                        message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
                   1535:                                                                chunk_from_thing(group));
                   1536:                        return SUCCESS;
                   1537:                }
                   1538:                case FAILED:
                   1539:                default:
                   1540:                        message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
                   1541:                        handle_child_sa_failure(this, message);
                   1542:                        return SUCCESS;
                   1543:        }
                   1544: 
                   1545:        if (!build_payloads(this, message))
                   1546:        {
                   1547:                message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
                   1548:                handle_child_sa_failure(this, message);
                   1549:                return SUCCESS;
                   1550:        }
                   1551: 
                   1552:        if (!this->rekey)
                   1553:        {       /* invoke the child_up() hook if we are not rekeying */
                   1554:                charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
                   1555:        }
                   1556:        return SUCCESS;
                   1557: }
                   1558: 
                   1559: /**
                   1560:  * Raise alerts for received notify errors
                   1561:  */
                   1562: static void raise_alerts(private_child_create_t *this, notify_type_t type)
                   1563: {
                   1564:        linked_list_t *list;
                   1565: 
                   1566:        switch (type)
                   1567:        {
                   1568:                case NO_PROPOSAL_CHOSEN:
                   1569:                        list = this->config->get_proposals(this->config, FALSE);
                   1570:                        charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD, list);
                   1571:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                   1572:                        break;
                   1573:                default:
                   1574:                        break;
                   1575:        }
                   1576: }
                   1577: 
                   1578: METHOD(task_t, build_i_delete, status_t,
                   1579:        private_child_create_t *this, message_t *message)
                   1580: {
                   1581:        message->set_exchange_type(message, INFORMATIONAL);
                   1582:        if (this->my_spi && this->proto)
                   1583:        {
                   1584:                delete_payload_t *del;
                   1585: 
                   1586:                del = delete_payload_create(PLV2_DELETE, this->proto);
                   1587:                del->add_spi(del, this->my_spi);
                   1588:                message->add_payload(message, (payload_t*)del);
                   1589: 
                   1590:                DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x",
                   1591:                         protocol_id_names, this->proto, ntohl(this->my_spi));
                   1592:        }
                   1593:        return NEED_MORE;
                   1594: }
                   1595: 
                   1596: /**
                   1597:  * Change task to delete the failed CHILD_SA as initiator
                   1598:  */
                   1599: static status_t delete_failed_sa(private_child_create_t *this)
                   1600: {
                   1601:        if (this->my_spi && this->proto)
                   1602:        {
                   1603:                this->public.task.build = _build_i_delete;
                   1604:                this->public.task.process = (void*)return_success;
                   1605:                return NEED_MORE;
                   1606:        }
                   1607:        return SUCCESS;
                   1608: }
                   1609: 
                   1610: METHOD(task_t, process_i, status_t,
                   1611:        private_child_create_t *this, message_t *message)
                   1612: {
                   1613:        enumerator_t *enumerator;
                   1614:        payload_t *payload;
                   1615:        bool no_dh = TRUE, ike_auth = FALSE;
                   1616: 
                   1617:        switch (message->get_exchange_type(message))
                   1618:        {
                   1619:                case IKE_SA_INIT:
                   1620:                        return get_nonce(message, &this->other_nonce);
                   1621:                case CREATE_CHILD_SA:
                   1622:                        get_nonce(message, &this->other_nonce);
                   1623:                        no_dh = FALSE;
                   1624:                        break;
                   1625:                case IKE_AUTH:
                   1626:                        if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
                   1627:                        {       /* wait until all authentication round completed */
                   1628:                                return NEED_MORE;
                   1629:                        }
                   1630:                        if (defer_child_sa(this) == NEED_MORE)
                   1631:                        {       /* defer until after IKE_SA has been established */
                   1632:                                chunk_free(&this->other_nonce);
                   1633:                                return NEED_MORE;
                   1634:                        }
                   1635:                        ike_auth = TRUE;
                   1636:                default:
                   1637:                        break;
                   1638:        }
                   1639: 
                   1640:        /* check for erroneous notifies */
                   1641:        enumerator = message->create_payload_enumerator(message);
                   1642:        while (enumerator->enumerate(enumerator, &payload))
                   1643:        {
                   1644:                if (payload->get_type(payload) == PLV2_NOTIFY)
                   1645:                {
                   1646:                        notify_payload_t *notify = (notify_payload_t*)payload;
                   1647:                        notify_type_t type = notify->get_notify_type(notify);
                   1648: 
                   1649:                        switch (type)
                   1650:                        {
                   1651:                                /* handle notify errors related to CHILD_SA only */
                   1652:                                case NO_PROPOSAL_CHOSEN:
                   1653:                                case SINGLE_PAIR_REQUIRED:
                   1654:                                case NO_ADDITIONAL_SAS:
                   1655:                                case INTERNAL_ADDRESS_FAILURE:
                   1656:                                case FAILED_CP_REQUIRED:
                   1657:                                case TS_UNACCEPTABLE:
                   1658:                                case INVALID_SELECTORS:
                   1659:                                {
                   1660:                                        DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
                   1661:                                                 notify_type_names, type);
                   1662:                                        enumerator->destroy(enumerator);
                   1663:                                        raise_alerts(this, type);
                   1664:                                        handle_child_sa_failure(this, message);
                   1665:                                        /* an error in CHILD_SA creation is not critical */
                   1666:                                        return SUCCESS;
                   1667:                                }
                   1668:                                case TEMPORARY_FAILURE:
                   1669:                                {
                   1670:                                        DBG1(DBG_IKE, "received %N notify, will retry later",
                   1671:                                                 notify_type_names, type);
                   1672:                                        enumerator->destroy(enumerator);
                   1673:                                        if (!this->rekey)
                   1674:                                        {       /* the rekey task will retry itself if necessary */
                   1675:                                                schedule_delayed_retry(this);
                   1676:                                        }
                   1677:                                        return SUCCESS;
                   1678:                                }
                   1679:                                case INVALID_KE_PAYLOAD:
                   1680:                                {
                   1681:                                        chunk_t data;
                   1682:                                        uint16_t group = MODP_NONE;
                   1683: 
                   1684:                                        data = notify->get_notification_data(notify);
                   1685:                                        if (data.len == sizeof(group))
                   1686:                                        {
                   1687:                                                memcpy(&group, data.ptr, data.len);
                   1688:                                                group = ntohs(group);
                   1689:                                        }
                   1690:                                        if (this->retry)
                   1691:                                        {
                   1692:                                                DBG1(DBG_IKE, "already retried with DH group %N, "
                   1693:                                                         "ignore requested %N", diffie_hellman_group_names,
                   1694:                                                         this->dh_group, diffie_hellman_group_names, group);
                   1695:                                                handle_child_sa_failure(this, message);
                   1696:                                                /* an error in CHILD_SA creation is not critical */
                   1697:                                                return SUCCESS;
                   1698:                                        }
                   1699:                                        DBG1(DBG_IKE, "peer didn't accept DH group %N, "
                   1700:                                                 "it requested %N", diffie_hellman_group_names,
                   1701:                                                 this->dh_group, diffie_hellman_group_names, group);
                   1702:                                        this->retry = TRUE;
                   1703:                                        this->dh_group = group;
                   1704:                                        this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
                   1705:                                        this->public.task.migrate(&this->public.task, this->ike_sa);
                   1706:                                        enumerator->destroy(enumerator);
                   1707:                                        return NEED_MORE;
                   1708:                                }
                   1709:                                default:
                   1710:                                {
                   1711:                                        if (message->get_exchange_type(message) == CREATE_CHILD_SA)
                   1712:                                        {       /* handle notifies if not handled in IKE_AUTH */
                   1713:                                                if (type <= 16383)
                   1714:                                                {
                   1715:                                                        DBG1(DBG_IKE, "received %N notify error",
                   1716:                                                                 notify_type_names, type);
                   1717:                                                        enumerator->destroy(enumerator);
                   1718:                                                        return SUCCESS;
                   1719:                                                }
                   1720:                                                DBG2(DBG_IKE, "received %N notify",
                   1721:                                                         notify_type_names, type);
                   1722:                                        }
                   1723:                                        break;
                   1724:                                }
                   1725:                        }
                   1726:                }
                   1727:        }
                   1728:        enumerator->destroy(enumerator);
                   1729: 
                   1730:        process_payloads(this, message);
                   1731: 
                   1732:        if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
                   1733:        {
                   1734:                DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
                   1735:                         " one, no CHILD_SA built");
                   1736:                handle_child_sa_failure(this, message);
                   1737:                return delete_failed_sa(this);
                   1738:        }
                   1739:        else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
                   1740:        {
                   1741:                DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
                   1742:                         "IPComp is disabled");
                   1743:                this->ipcomp = IPCOMP_NONE;
                   1744:        }
                   1745:        else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
                   1746:        {
                   1747:                DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
                   1748:                         "no CHILD_SA built");
                   1749:                handle_child_sa_failure(this, message);
                   1750:                return delete_failed_sa(this);
                   1751:        }
                   1752: 
                   1753:        if (this->dh_failed)
                   1754:        {
                   1755:                DBG1(DBG_IKE, "applying DH public value failed");
                   1756:                handle_child_sa_failure(this, message);
                   1757:                return delete_failed_sa(this);
                   1758:        }
                   1759: 
                   1760:        if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
                   1761:        {
                   1762:                if (!this->rekey)
                   1763:                {       /* invoke the child_up() hook if we are not rekeying */
                   1764:                        charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
                   1765:                }
                   1766:        }
                   1767:        else
                   1768:        {
                   1769:                handle_child_sa_failure(this, message);
                   1770:                return delete_failed_sa(this);
                   1771:        }
                   1772:        return SUCCESS;
                   1773: }
                   1774: 
                   1775: METHOD(child_create_t, use_reqid, void,
                   1776:        private_child_create_t *this, uint32_t reqid)
                   1777: {
                   1778:        this->child.reqid = reqid;
                   1779: }
                   1780: 
                   1781: METHOD(child_create_t, use_marks, void,
                   1782:        private_child_create_t *this, uint32_t in, uint32_t out)
                   1783: {
                   1784:        this->child.mark_in = in;
                   1785:        this->child.mark_out = out;
                   1786: }
                   1787: 
                   1788: METHOD(child_create_t, use_if_ids, void,
                   1789:        private_child_create_t *this, uint32_t in, uint32_t out)
                   1790: {
                   1791:        this->child.if_id_in = in;
                   1792:        this->child.if_id_out = out;
                   1793: }
                   1794: 
                   1795: METHOD(child_create_t, use_dh_group, void,
                   1796:        private_child_create_t *this, diffie_hellman_group_t dh_group)
                   1797: {
                   1798:        this->dh_group = dh_group;
                   1799: }
                   1800: 
                   1801: METHOD(child_create_t, get_child, child_sa_t*,
                   1802:        private_child_create_t *this)
                   1803: {
                   1804:        return this->child_sa;
                   1805: }
                   1806: 
                   1807: METHOD(child_create_t, set_config, void,
                   1808:        private_child_create_t *this, child_cfg_t *cfg)
                   1809: {
                   1810:        DESTROY_IF(this->config);
                   1811:        this->config = cfg;
                   1812: }
                   1813: 
                   1814: METHOD(child_create_t, get_lower_nonce, chunk_t,
                   1815:        private_child_create_t *this)
                   1816: {
                   1817:        if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
                   1818:                           min(this->my_nonce.len, this->other_nonce.len)) < 0)
                   1819:        {
                   1820:                return this->my_nonce;
                   1821:        }
                   1822:        else
                   1823:        {
                   1824:                return this->other_nonce;
                   1825:        }
                   1826: }
                   1827: 
                   1828: METHOD(task_t, get_type, task_type_t,
                   1829:        private_child_create_t *this)
                   1830: {
                   1831:        return TASK_CHILD_CREATE;
                   1832: }
                   1833: 
                   1834: METHOD(task_t, migrate, void,
                   1835:        private_child_create_t *this, ike_sa_t *ike_sa)
                   1836: {
                   1837:        chunk_free(&this->my_nonce);
                   1838:        chunk_free(&this->other_nonce);
                   1839:        if (this->tsr)
                   1840:        {
                   1841:                this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
                   1842:        }
                   1843:        if (this->tsi)
                   1844:        {
                   1845:                this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
                   1846:        }
                   1847:        DESTROY_IF(this->child_sa);
                   1848:        DESTROY_IF(this->proposal);
                   1849:        DESTROY_IF(this->nonceg);
                   1850:        DESTROY_IF(this->dh);
                   1851:        this->dh_failed = FALSE;
                   1852:        if (this->proposals)
                   1853:        {
                   1854:                this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
                   1855:        }
                   1856: 
                   1857:        this->ike_sa = ike_sa;
                   1858:        this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
                   1859:        this->proposal = NULL;
                   1860:        this->proposals = NULL;
                   1861:        this->tsi = NULL;
                   1862:        this->tsr = NULL;
                   1863:        this->dh = NULL;
                   1864:        this->nonceg = NULL;
                   1865:        this->child_sa = NULL;
                   1866:        this->mode = MODE_TUNNEL;
                   1867:        this->ipcomp = IPCOMP_NONE;
                   1868:        this->ipcomp_received = IPCOMP_NONE;
                   1869:        this->other_cpi = 0;
                   1870:        this->established = FALSE;
                   1871:        this->child = (child_sa_create_t){};
                   1872: }
                   1873: 
                   1874: METHOD(task_t, destroy, void,
                   1875:        private_child_create_t *this)
                   1876: {
                   1877:        chunk_free(&this->my_nonce);
                   1878:        chunk_free(&this->other_nonce);
                   1879:        if (this->tsr)
                   1880:        {
                   1881:                this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
                   1882:        }
                   1883:        if (this->tsi)
                   1884:        {
                   1885:                this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
                   1886:        }
                   1887:        if (!this->established)
                   1888:        {
                   1889:                DESTROY_IF(this->child_sa);
                   1890:        }
                   1891:        DESTROY_IF(this->packet_tsi);
                   1892:        DESTROY_IF(this->packet_tsr);
                   1893:        DESTROY_IF(this->proposal);
                   1894:        DESTROY_IF(this->dh);
                   1895:        if (this->proposals)
                   1896:        {
                   1897:                this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
                   1898:        }
                   1899:        DESTROY_IF(this->config);
                   1900:        DESTROY_IF(this->nonceg);
                   1901:        free(this);
                   1902: }
                   1903: 
                   1904: /*
                   1905:  * Described in header.
                   1906:  */
                   1907: child_create_t *child_create_create(ike_sa_t *ike_sa,
                   1908:                                                        child_cfg_t *config, bool rekey,
                   1909:                                                        traffic_selector_t *tsi, traffic_selector_t *tsr)
                   1910: {
                   1911:        private_child_create_t *this;
                   1912: 
                   1913:        INIT(this,
                   1914:                .public = {
                   1915:                        .get_child = _get_child,
                   1916:                        .set_config = _set_config,
                   1917:                        .get_lower_nonce = _get_lower_nonce,
                   1918:                        .use_reqid = _use_reqid,
                   1919:                        .use_marks = _use_marks,
                   1920:                        .use_if_ids = _use_if_ids,
                   1921:                        .use_dh_group = _use_dh_group,
                   1922:                        .task = {
                   1923:                                .get_type = _get_type,
                   1924:                                .migrate = _migrate,
                   1925:                                .destroy = _destroy,
                   1926:                        },
                   1927:                },
                   1928:                .ike_sa = ike_sa,
                   1929:                .config = config,
                   1930:                .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
                   1931:                .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
                   1932:                .dh_group = MODP_NONE,
                   1933:                .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
                   1934:                .mode = MODE_TUNNEL,
                   1935:                .tfcv3 = TRUE,
                   1936:                .ipcomp = IPCOMP_NONE,
                   1937:                .ipcomp_received = IPCOMP_NONE,
                   1938:                .rekey = rekey,
                   1939:                .retry = FALSE,
                   1940:        );
                   1941: 
                   1942:        if (config)
                   1943:        {
                   1944:                this->public.task.build = _build_i;
                   1945:                this->public.task.process = _process_i;
                   1946:                this->initiator = TRUE;
                   1947:        }
                   1948:        else
                   1949:        {
                   1950:                this->public.task.build = _build_r;
                   1951:                this->public.task.process = _process_r;
                   1952:                this->initiator = FALSE;
                   1953:        }
                   1954:        return &this->public;
                   1955: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>