Annotation of embedaddon/strongswan/src/libcharon/sa/ikev1/tasks/quick_mode.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012-2019 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Copyright (C) 2011 Martin Willi
                      6:  * Copyright (C) 2011 revosec AG
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: /*
                     20:  * Copyright (C) 2012 Volker RĂ¼melin
                     21:  *
                     22:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     23:  * of this software and associated documentation files (the "Software"), to deal
                     24:  * in the Software without restriction, including without limitation the rights
                     25:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     26:  * copies of the Software, and to permit persons to whom the Software is
                     27:  * furnished to do so, subject to the following conditions:
                     28:  *
                     29:  * The above copyright notice and this permission notice shall be included in
                     30:  * all copies or substantial portions of the Software.
                     31:  *
                     32:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     33:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     34:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     35:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     36:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     37:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     38:  * THE SOFTWARE.
                     39:  */
                     40: 
                     41: #include "quick_mode.h"
                     42: 
                     43: #include <string.h>
                     44: 
                     45: #include <daemon.h>
                     46: #include <sa/ikev1/keymat_v1.h>
                     47: #include <encoding/payloads/sa_payload.h>
                     48: #include <encoding/payloads/nonce_payload.h>
                     49: #include <encoding/payloads/ke_payload.h>
                     50: #include <encoding/payloads/id_payload.h>
                     51: #include <encoding/payloads/payload.h>
                     52: #include <sa/ikev1/tasks/informational.h>
                     53: #include <sa/ikev1/tasks/quick_delete.h>
                     54: #include <processing/jobs/inactivity_job.h>
                     55: 
                     56: typedef struct private_quick_mode_t private_quick_mode_t;
                     57: 
                     58: /**
                     59:  * Private members of a quick_mode_t task.
                     60:  */
                     61: struct private_quick_mode_t {
                     62: 
                     63:        /**
                     64:         * Public methods and task_t interface.
                     65:         */
                     66:        quick_mode_t public;
                     67: 
                     68:        /**
                     69:         * Assigned IKE_SA.
                     70:         */
                     71:        ike_sa_t *ike_sa;
                     72: 
                     73:        /**
                     74:         * TRUE if we are initiating quick mode
                     75:         */
                     76:        bool initiator;
                     77: 
                     78:        /**
                     79:         * Traffic selector of initiator
                     80:         */
                     81:        traffic_selector_t *tsi;
                     82: 
                     83:        /**
                     84:         * Traffic selector of responder
                     85:         */
                     86:        traffic_selector_t *tsr;
                     87: 
                     88:        /**
                     89:         * Initiators nonce
                     90:         */
                     91:        chunk_t nonce_i;
                     92: 
                     93:        /**
                     94:         * Responder nonce
                     95:         */
                     96:        chunk_t nonce_r;
                     97: 
                     98:        /**
                     99:         * Initiators ESP SPI
                    100:         */
                    101:        uint32_t spi_i;
                    102: 
                    103:        /**
                    104:         * Responder ESP SPI
                    105:         */
                    106:        uint32_t spi_r;
                    107: 
                    108:        /**
                    109:         * Initiators IPComp CPI
                    110:         */
                    111:        uint16_t cpi_i;
                    112: 
                    113:        /**
                    114:         * Responders IPComp CPI
                    115:         */
                    116:        uint16_t cpi_r;
                    117: 
                    118:        /**
                    119:         * selected CHILD_SA proposal
                    120:         */
                    121:        proposal_t *proposal;
                    122: 
                    123:        /**
                    124:         * Config of CHILD_SA to establish
                    125:         */
                    126:        child_cfg_t *config;
                    127: 
                    128:        /**
                    129:         * CHILD_SA we are about to establish
                    130:         */
                    131:        child_sa_t *child_sa;
                    132: 
                    133:        /**
                    134:         * IKEv1 keymat
                    135:         */
                    136:        keymat_v1_t *keymat;
                    137: 
                    138:        /**
                    139:         * DH exchange, when PFS is in use
                    140:         */
                    141:        diffie_hellman_t *dh;
                    142: 
                    143:        /**
                    144:         * Negotiated lifetime of new SA
                    145:         */
                    146:        uint32_t lifetime;
                    147: 
                    148:        /**
                    149:         * Negotiated lifebytes of new SA
                    150:         */
                    151:        uint64_t lifebytes;
                    152: 
                    153:        /**
                    154:         * Data collected to create the CHILD_SA
                    155:         */
                    156:        child_sa_create_t child;
                    157: 
                    158:        /**
                    159:         * SPI of SA we rekey
                    160:         */
                    161:        uint32_t rekey;
                    162: 
                    163:        /**
                    164:         * Delete old child after successful rekey
                    165:         */
                    166:        bool delete;
                    167: 
                    168:        /**
                    169:         * Negotiated mode, tunnel or transport
                    170:         */
                    171:        ipsec_mode_t mode;
                    172: 
                    173:        /*
                    174:         * SA protocol (ESP|AH) negotiated
                    175:         */
                    176:        protocol_id_t proto;
                    177: 
                    178:        /**
                    179:         * Message ID of handled quick mode exchange
                    180:         */
                    181:        uint32_t mid;
                    182: 
                    183:        /** states of quick mode */
                    184:        enum {
                    185:                QM_INIT,
                    186:                QM_NEGOTIATED,
                    187:        } state;
                    188: };
                    189: 
                    190: /**
                    191:  * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
                    192:  */
                    193: static void schedule_inactivity_timeout(private_quick_mode_t *this)
                    194: {
                    195:        uint32_t timeout;
                    196:        bool close_ike;
                    197: 
                    198:        timeout = this->config->get_inactivity(this->config);
                    199:        if (timeout)
                    200:        {
                    201:                close_ike = lib->settings->get_bool(lib->settings,
                    202:                                                                        "%s.inactivity_close_ike", FALSE, lib->ns);
                    203:                lib->scheduler->schedule_job(lib->scheduler, (job_t*)
                    204:                        inactivity_job_create(this->child_sa->get_unique_id(this->child_sa),
                    205:                                                                  timeout, close_ike), timeout);
                    206:        }
                    207: }
                    208: 
                    209: /**
                    210:  * Check if we have a an address pool configured
                    211:  */
                    212: static bool have_pool(ike_sa_t *ike_sa)
                    213: {
                    214:        enumerator_t *enumerator;
                    215:        peer_cfg_t *peer_cfg;
                    216:        char *pool;
                    217:        bool found = FALSE;
                    218: 
                    219:        peer_cfg = ike_sa->get_peer_cfg(ike_sa);
                    220:        if (peer_cfg)
                    221:        {
                    222:                enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
                    223:                if (enumerator->enumerate(enumerator, &pool))
                    224:                {
                    225:                        found = TRUE;
                    226:                }
                    227:                enumerator->destroy(enumerator);
                    228:        }
                    229:        return found;
                    230: }
                    231: 
                    232: /**
                    233:  * Get hosts to use for dynamic traffic selectors
                    234:  */
                    235: static linked_list_t *get_dynamic_hosts(ike_sa_t *ike_sa, bool local)
                    236: {
                    237:        enumerator_t *enumerator;
                    238:        linked_list_t *list;
                    239:        host_t *host;
                    240: 
                    241:        list = linked_list_create();
                    242:        enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
                    243:        while (enumerator->enumerate(enumerator, &host))
                    244:        {
                    245:                list->insert_last(list, host);
                    246:        }
                    247:        enumerator->destroy(enumerator);
                    248: 
                    249:        if (list->get_count(list) == 0)
                    250:        {       /* no virtual IPs assigned */
                    251:                if (local)
                    252:                {
                    253:                        host = ike_sa->get_my_host(ike_sa);
                    254:                        list->insert_last(list, host);
                    255:                }
                    256:                else if (!have_pool(ike_sa))
                    257:                {       /* use host only if we don't have a pool configured */
                    258:                        host = ike_sa->get_other_host(ike_sa);
                    259:                        list->insert_last(list, host);
                    260:                }
                    261:        }
                    262:        return list;
                    263: }
                    264: 
                    265: /**
                    266:  * Install negotiated CHILD_SA
                    267:  */
                    268: static bool install(private_quick_mode_t *this)
                    269: {
                    270:        status_t status, status_i, status_o;
                    271:        chunk_t encr_i, encr_r, integ_i, integ_r;
                    272:        linked_list_t *tsi, *tsr, *my_ts, *other_ts;
                    273:        child_sa_t *old = NULL;
                    274: 
                    275:        this->child_sa->set_proposal(this->child_sa, this->proposal);
                    276:        this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
                    277:        this->child_sa->set_mode(this->child_sa, this->mode);
                    278: 
                    279:        if (this->cpi_i && this->cpi_r)
                    280:        {       /* DEFLATE is the only transform we currently support */
                    281:                this->child_sa->set_ipcomp(this->child_sa, IPCOMP_DEFLATE);
                    282:        }
                    283:        else
                    284:        {
                    285:                this->cpi_i = this->cpi_r = 0;
                    286:        }
                    287: 
                    288:        this->child_sa->set_protocol(this->child_sa,
                    289:                                                                 this->proposal->get_protocol(this->proposal));
                    290: 
                    291:        status_i = status_o = FAILED;
                    292:        encr_i = encr_r = integ_i = integ_r = chunk_empty;
                    293:        tsi = linked_list_create_with_items(this->tsi->clone(this->tsi), NULL);
                    294:        tsr = linked_list_create_with_items(this->tsr->clone(this->tsr), NULL);
                    295:        if (this->initiator)
                    296:        {
                    297:                charon->bus->narrow(charon->bus, this->child_sa,
                    298:                                                        NARROW_INITIATOR_POST_AUTH, tsi, tsr);
                    299:        }
                    300:        else
                    301:        {
                    302:                charon->bus->narrow(charon->bus, this->child_sa,
                    303:                                                        NARROW_RESPONDER_POST, tsr, tsi);
                    304:        }
                    305:        if (tsi->get_count(tsi) == 0 || tsr->get_count(tsr) == 0)
                    306:        {
                    307:                tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                    308:                tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                    309:                DBG1(DBG_IKE, "no acceptable traffic selectors found");
                    310:                return FALSE;
                    311:        }
                    312: 
                    313:        if (this->initiator)
                    314:        {
                    315:                this->child_sa->set_policies(this->child_sa, tsi, tsr);
                    316:        }
                    317:        else
                    318:        {
                    319:                this->child_sa->set_policies(this->child_sa, tsr, tsi);
                    320:        }
                    321:        tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                    322:        tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                    323: 
                    324:        if (this->keymat->derive_child_keys(this->keymat, this->proposal, this->dh,
                    325:                                                this->spi_i, this->spi_r, this->nonce_i, this->nonce_r,
                    326:                                                &encr_i, &integ_i, &encr_r, &integ_r))
                    327:        {
                    328:                if (this->initiator)
                    329:                {
                    330:                        status_i = this->child_sa->install(this->child_sa,
                    331:                                                                        encr_r, integ_r, this->spi_i, this->cpi_i,
                    332:                                                                        this->initiator, TRUE, FALSE);
                    333:                        status_o = this->child_sa->install(this->child_sa,
                    334:                                                                        encr_i, integ_i, this->spi_r, this->cpi_r,
                    335:                                                                        this->initiator, FALSE, FALSE);
                    336:                }
                    337:                else
                    338:                {
                    339:                        status_i = this->child_sa->install(this->child_sa,
                    340:                                                                        encr_i, integ_i, this->spi_r, this->cpi_r,
                    341:                                                                        this->initiator, TRUE, FALSE);
                    342:                        status_o = this->child_sa->install(this->child_sa,
                    343:                                                                        encr_r, integ_r, this->spi_i, this->cpi_i,
                    344:                                                                        this->initiator, FALSE, FALSE);
                    345:                }
                    346:        }
                    347: 
                    348:        if (status_i != SUCCESS || status_o != SUCCESS)
                    349:        {
                    350:                DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
                    351:                        (status_i != SUCCESS) ? "inbound " : "",
                    352:                        (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
                    353:                        (status_o != SUCCESS) ? "outbound " : "");
                    354:                status = FAILED;
                    355:        }
                    356:        else
                    357:        {
                    358:                status = this->child_sa->install_policies(this->child_sa);
                    359: 
                    360:                if (status != SUCCESS)
                    361:                {
                    362:                        DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
                    363:                }
                    364:                else
                    365:                {
                    366:                        charon->bus->child_derived_keys(charon->bus, this->child_sa,
                    367:                                                                                        this->initiator, encr_i, encr_r,
                    368:                                                                                        integ_i, integ_r);
                    369:                }
                    370:        }
                    371:        chunk_clear(&integ_i);
                    372:        chunk_clear(&integ_r);
                    373:        chunk_clear(&encr_i);
                    374:        chunk_clear(&encr_r);
                    375: 
                    376:        if (status != SUCCESS)
                    377:        {
                    378:                return FALSE;
                    379:        }
                    380: 
                    381:        charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
                    382:                                                        this->dh, this->nonce_i, this->nonce_r);
                    383: 
                    384:        my_ts = linked_list_create_from_enumerator(
                    385:                                this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
                    386:        other_ts = linked_list_create_from_enumerator(
                    387:                                this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
                    388: 
                    389:        DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
                    390:                 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
                    391:                 this->child_sa->get_name(this->child_sa),
                    392:                 this->child_sa->get_unique_id(this->child_sa),
                    393:                 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
                    394:                 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
                    395: 
                    396:        my_ts->destroy(my_ts);
                    397:        other_ts->destroy(other_ts);
                    398: 
                    399:        this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
                    400:        this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
                    401: 
                    402:        if (this->rekey)
                    403:        {
                    404:                old = this->ike_sa->get_child_sa(this->ike_sa,
                    405:                                                                this->proposal->get_protocol(this->proposal),
                    406:                                                                this->rekey, TRUE);
                    407:        }
                    408:        if (old)
                    409:        {
                    410:                charon->bus->child_rekey(charon->bus, old, this->child_sa);
                    411:                /* rekeyed CHILD_SAs stay installed until they expire or are deleted
                    412:                 * by the other peer */
                    413:                old->set_state(old, CHILD_REKEYED);
                    414:                /* as initiator we delete the CHILD_SA if configured to do so */
                    415:                if (this->initiator && this->delete)
                    416:                {
                    417:                        this->ike_sa->queue_task(this->ike_sa,
                    418:                                (task_t*)quick_delete_create(this->ike_sa,
                    419:                                                                this->proposal->get_protocol(this->proposal),
                    420:                                                                this->rekey, TRUE, FALSE));
                    421:                }
                    422:        }
                    423:        else
                    424:        {
                    425:                charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
                    426:        }
                    427:        schedule_inactivity_timeout(this);
                    428:        this->child_sa = NULL;
                    429:        return TRUE;
                    430: }
                    431: 
                    432: /**
                    433:  * Generate and add NONCE
                    434:  */
                    435: static bool add_nonce(private_quick_mode_t *this, chunk_t *nonce,
                    436:                                          message_t *message)
                    437: {
                    438:        nonce_payload_t *nonce_payload;
                    439:        nonce_gen_t *nonceg;
                    440: 
                    441:        nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
                    442:        if (!nonceg)
                    443:        {
                    444:                DBG1(DBG_IKE, "no nonce generator found to create nonce");
                    445:                return FALSE;
                    446:        }
                    447:        if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, nonce))
                    448:        {
                    449:                DBG1(DBG_IKE, "nonce allocation failed");
                    450:                nonceg->destroy(nonceg);
                    451:                return FALSE;
                    452:        }
                    453:        nonceg->destroy(nonceg);
                    454: 
                    455:        nonce_payload = nonce_payload_create(PLV1_NONCE);
                    456:        nonce_payload->set_nonce(nonce_payload, *nonce);
                    457:        message->add_payload(message, &nonce_payload->payload_interface);
                    458: 
                    459:        return TRUE;
                    460: }
                    461: 
                    462: /**
                    463:  * Extract nonce from NONCE payload
                    464:  */
                    465: static bool get_nonce(private_quick_mode_t *this, chunk_t *nonce,
                    466:                                          message_t *message)
                    467: {
                    468:        nonce_payload_t *nonce_payload;
                    469: 
                    470:        nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
                    471:        if (!nonce_payload)
                    472:        {
                    473:                DBG1(DBG_IKE, "NONCE payload missing in message");
                    474:                return FALSE;
                    475:        }
                    476:        *nonce = nonce_payload->get_nonce(nonce_payload);
                    477: 
                    478:        return TRUE;
                    479: }
                    480: 
                    481: /**
                    482:  * Add KE payload to message
                    483:  */
                    484: static bool add_ke(private_quick_mode_t *this, message_t *message)
                    485: {
                    486:        ke_payload_t *ke_payload;
                    487: 
                    488:        ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
                    489:                                                                                                           this->dh);
                    490:        if (!ke_payload)
                    491:        {
                    492:                DBG1(DBG_IKE, "creating KE payload failed");
                    493:                return FALSE;
                    494:        }
                    495:        message->add_payload(message, &ke_payload->payload_interface);
                    496:        return TRUE;
                    497: }
                    498: 
                    499: /**
                    500:  * Get DH value from a KE payload
                    501:  */
                    502: static bool get_ke(private_quick_mode_t *this, message_t *message)
                    503: {
                    504:        ke_payload_t *ke_payload;
                    505: 
                    506:        ke_payload = (ke_payload_t*)message->get_payload(message, PLV1_KEY_EXCHANGE);
                    507:        if (!ke_payload)
                    508:        {
                    509:                DBG1(DBG_IKE, "KE payload missing");
                    510:                return FALSE;
                    511:        }
                    512:        if (!this->dh->set_other_public_value(this->dh,
                    513:                                                                ke_payload->get_key_exchange_data(ke_payload)))
                    514:        {
                    515:                DBG1(DBG_IKE, "unable to apply received KE value");
                    516:                return FALSE;
                    517:        }
                    518:        return TRUE;
                    519: }
                    520: 
                    521: /**
                    522:  * Select a traffic selector from configuration
                    523:  */
                    524: static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
                    525:                                                                         linked_list_t *supplied)
                    526: {
                    527:        traffic_selector_t *ts;
                    528:        linked_list_t *list, *hosts;
                    529: 
                    530:        hosts = get_dynamic_hosts(this->ike_sa, local);
                    531:        list = this->config->get_traffic_selectors(this->config,
                    532:                                                                                           local, supplied, hosts, TRUE);
                    533:        hosts->destroy(hosts);
                    534:        if (list->get_first(list, (void**)&ts) == SUCCESS)
                    535:        {
                    536:                ts = ts->clone(ts);
                    537:        }
                    538:        else
                    539:        {
                    540:                DBG1(DBG_IKE, "%s traffic selector missing in configuration",
                    541:                         local ? "local" : "remote");
                    542:                ts = NULL;
                    543:        }
                    544:        list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
                    545:        return ts;
                    546: }
                    547: 
                    548: /**
                    549:  * Add selected traffic selectors to message
                    550:  */
                    551: static void add_ts(private_quick_mode_t *this, message_t *message)
                    552: {
                    553:        id_payload_t *id_payload;
                    554: 
                    555:        id_payload = id_payload_create_from_ts(this->tsi);
                    556:        message->add_payload(message, &id_payload->payload_interface);
                    557:        id_payload = id_payload_create_from_ts(this->tsr);
                    558:        message->add_payload(message, &id_payload->payload_interface);
                    559: }
                    560: 
                    561: /**
                    562:  * Get traffic selectors from received message
                    563:  */
                    564: static bool get_ts(private_quick_mode_t *this, message_t *message)
                    565: {
                    566:        traffic_selector_t *tsi = NULL, *tsr = NULL;
                    567:        enumerator_t *enumerator;
                    568:        id_payload_t *id_payload;
                    569:        payload_t *payload;
                    570:        host_t *hsi, *hsr;
                    571:        bool first = TRUE;
                    572: 
                    573:        enumerator = message->create_payload_enumerator(message);
                    574:        while (enumerator->enumerate(enumerator, &payload))
                    575:        {
                    576:                if (payload->get_type(payload) == PLV1_ID)
                    577:                {
                    578:                        id_payload = (id_payload_t*)payload;
                    579: 
                    580:                        if (first)
                    581:                        {
                    582:                                tsi = id_payload->get_ts(id_payload);
                    583:                                first = FALSE;
                    584:                        }
                    585:                        else
                    586:                        {
                    587:                                tsr = id_payload->get_ts(id_payload);
                    588:                                break;
                    589:                        }
                    590:                }
                    591:        }
                    592:        enumerator->destroy(enumerator);
                    593: 
                    594:        /* create host2host selectors if ID payloads missing */
                    595:        if (this->initiator)
                    596:        {
                    597:                hsi = this->ike_sa->get_my_host(this->ike_sa);
                    598:                hsr = this->ike_sa->get_other_host(this->ike_sa);
                    599:        }
                    600:        else
                    601:        {
                    602:                hsr = this->ike_sa->get_my_host(this->ike_sa);
                    603:                hsi = this->ike_sa->get_other_host(this->ike_sa);
                    604:        }
                    605:        if (!tsi)
                    606:        {
                    607:                tsi = traffic_selector_create_from_subnet(hsi->clone(hsi),
                    608:                                        hsi->get_family(hsi) == AF_INET ? 32 : 128, 0, 0, 65535);
                    609:        }
                    610:        if (!tsr)
                    611:        {
                    612:                tsr = traffic_selector_create_from_subnet(hsr->clone(hsr),
                    613:                                        hsr->get_family(hsr) == AF_INET ? 32 : 128, 0, 0, 65535);
                    614:        }
                    615:        if (this->mode == MODE_TRANSPORT && this->child.encap &&
                    616:           (!tsi->is_host(tsi, hsi) || !tsr->is_host(tsr, hsr)))
                    617:        {       /* change TS in case of a NAT in transport mode */
                    618:                DBG2(DBG_IKE, "changing received traffic selectors %R=== %R due to NAT",
                    619:                         tsi, tsr);
                    620:                tsi->set_address(tsi, hsi);
                    621:                tsr->set_address(tsr, hsr);
                    622:        }
                    623: 
                    624:        if (this->initiator)
                    625:        {
                    626:                traffic_selector_t *tsisub, *tsrsub;
                    627: 
                    628:                /* check if peer selection is valid */
                    629:                tsisub = this->tsi->get_subset(this->tsi, tsi);
                    630:                tsrsub = this->tsr->get_subset(this->tsr, tsr);
                    631:                if (!tsisub || !tsrsub)
                    632:                {
                    633:                        DBG1(DBG_IKE, "peer selected invalid traffic selectors: "
                    634:                                 "%R for %R, %R for %R", tsi, this->tsi, tsr, this->tsr);
                    635:                        DESTROY_IF(tsisub);
                    636:                        DESTROY_IF(tsrsub);
                    637:                        tsi->destroy(tsi);
                    638:                        tsr->destroy(tsr);
                    639:                        return FALSE;
                    640:                }
                    641:                tsi->destroy(tsi);
                    642:                tsr->destroy(tsr);
                    643:                this->tsi->destroy(this->tsi);
                    644:                this->tsr->destroy(this->tsr);
                    645:                this->tsi = tsisub;
                    646:                this->tsr = tsrsub;
                    647:        }
                    648:        else
                    649:        {
                    650:                this->tsi = tsi;
                    651:                this->tsr = tsr;
                    652:        }
                    653:        return TRUE;
                    654: }
                    655: 
                    656: /**
                    657:  * Get encap
                    658:  */
                    659: static encap_t get_encap(ike_sa_t* ike_sa, bool udp)
                    660: {
                    661:        if (!udp)
                    662:        {
                    663:                return ENCAP_NONE;
                    664:        }
                    665:        if (ike_sa->supports_extension(ike_sa, EXT_NATT_DRAFT_02_03))
                    666:        {
                    667:                return ENCAP_UDP_DRAFT_00_03;
                    668:        }
                    669:        return ENCAP_UDP;
                    670: }
                    671: 
                    672: /**
                    673:  * Get NAT-OA payload type (RFC 3947 or RFC 3947 drafts).
                    674:  */
                    675: static payload_type_t get_nat_oa_payload_type(ike_sa_t *ike_sa)
                    676: {
                    677:        if (ike_sa->supports_extension(ike_sa, EXT_NATT_DRAFT_02_03))
                    678:        {
                    679:                return PLV1_NAT_OA_DRAFT_00_03;
                    680:        }
                    681:        return PLV1_NAT_OA;
                    682: }
                    683: 
                    684: /**
                    685:  * Add NAT-OA payloads
                    686:  */
                    687: static void add_nat_oa_payloads(private_quick_mode_t *this, message_t *message)
                    688: {
                    689:        identification_t *id;
                    690:        id_payload_t *nat_oa;
                    691:        host_t *init, *resp;
                    692:        payload_type_t nat_oa_payload_type;
                    693: 
                    694:        if (this->initiator)
                    695:        {
                    696:                init = message->get_source(message);
                    697:                resp = message->get_destination(message);
                    698:        }
                    699:        else
                    700:        {
                    701:                init = message->get_destination(message);
                    702:                resp = message->get_source(message);
                    703:        }
                    704: 
                    705:        nat_oa_payload_type = get_nat_oa_payload_type(this->ike_sa);
                    706: 
                    707:        /* first NAT-OA is the initiator's address */
                    708:        id = identification_create_from_sockaddr(init->get_sockaddr(init));
                    709:        nat_oa = id_payload_create_from_identification(nat_oa_payload_type, id);
                    710:        message->add_payload(message, (payload_t*)nat_oa);
                    711:        id->destroy(id);
                    712: 
                    713:        /* second NAT-OA is that of the responder */
                    714:        id = identification_create_from_sockaddr(resp->get_sockaddr(resp));
                    715:        nat_oa = id_payload_create_from_identification(nat_oa_payload_type, id);
                    716:        message->add_payload(message, (payload_t*)nat_oa);
                    717:        id->destroy(id);
                    718: }
                    719: 
                    720: /**
                    721:  * Look up lifetimes
                    722:  */
                    723: static void get_lifetimes(private_quick_mode_t *this)
                    724: {
                    725:        lifetime_cfg_t *lft;
                    726: 
                    727:        lft = this->config->get_lifetime(this->config, TRUE);
                    728:        if (lft->time.life)
                    729:        {
                    730:                this->lifetime = lft->time.life;
                    731:        }
                    732:        if (lft->bytes.life)
                    733:        {
                    734:                this->lifebytes = lft->bytes.life;
                    735:        }
                    736:        free(lft);
                    737: }
                    738: 
                    739: /**
                    740:  * Check and apply lifetimes
                    741:  */
                    742: static void apply_lifetimes(private_quick_mode_t *this, sa_payload_t *sa_payload)
                    743: {
                    744:        uint32_t lifetime;
                    745:        uint64_t lifebytes;
                    746: 
                    747:        lifetime = sa_payload->get_lifetime(sa_payload, this->proposal);
                    748:        lifebytes = sa_payload->get_lifebytes(sa_payload, this->proposal);
                    749:        if (this->lifetime != lifetime)
                    750:        {
                    751:                DBG1(DBG_IKE, "received %us lifetime, configured %us",
                    752:                         lifetime, this->lifetime);
                    753:                this->lifetime = lifetime;
                    754:        }
                    755:        if (this->lifebytes != lifebytes)
                    756:        {
                    757:                DBG1(DBG_IKE, "received %llu lifebytes, configured %llu",
                    758:                         lifebytes, this->lifebytes);
                    759:                this->lifebytes = lifebytes;
                    760:        }
                    761: }
                    762: 
                    763: /**
                    764:  * Set the task ready to build notify error message
                    765:  */
                    766: static status_t send_notify(private_quick_mode_t *this, notify_type_t type)
                    767: {
                    768:        notify_payload_t *notify;
                    769: 
                    770:        notify = notify_payload_create_from_protocol_and_type(PLV1_NOTIFY,
                    771:                                                                                                                  this->proto, type);
                    772:        notify->set_spi(notify, this->spi_i);
                    773: 
                    774:        this->ike_sa->queue_task(this->ike_sa,
                    775:                                                (task_t*)informational_create(this->ike_sa, notify));
                    776:        /* cancel all active/passive tasks in favour of informational */
                    777:        this->ike_sa->flush_queue(this->ike_sa,
                    778:                                        this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
                    779:        return ALREADY_DONE;
                    780: }
                    781: 
                    782: /**
                    783:  * Prepare a list of proposals from child_config containing only the specified
                    784:  * DH group, unless it is set to MODP_NONE.
                    785:  */
                    786: static linked_list_t *get_proposals(private_quick_mode_t *this,
                    787:                                                                        diffie_hellman_group_t group)
                    788: {
                    789:        linked_list_t *list;
                    790:        proposal_t *proposal;
                    791:        enumerator_t *enumerator;
                    792: 
                    793:        list = this->config->get_proposals(this->config, FALSE);
                    794:        enumerator = list->create_enumerator(list);
                    795:        while (enumerator->enumerate(enumerator, &proposal))
                    796:        {
                    797:                if (group != MODP_NONE)
                    798:                {
                    799:                        if (!proposal->has_dh_group(proposal, group))
                    800:                        {
                    801:                                list->remove_at(list, enumerator);
                    802:                                proposal->destroy(proposal);
                    803:                                continue;
                    804:                        }
                    805:                        proposal->promote_dh_group(proposal, group);
                    806:                }
                    807:                proposal->set_spi(proposal, this->spi_i);
                    808:        }
                    809:        enumerator->destroy(enumerator);
                    810: 
                    811:        return list;
                    812: }
                    813: 
                    814: METHOD(task_t, build_i, status_t,
                    815:        private_quick_mode_t *this, message_t *message)
                    816: {
                    817:        switch (this->state)
                    818:        {
                    819:                case QM_INIT:
                    820:                {
                    821:                        sa_payload_t *sa_payload;
                    822:                        linked_list_t *list, *tsi, *tsr;
                    823:                        proposal_t *proposal;
                    824:                        diffie_hellman_group_t group;
                    825:                        encap_t encap;
                    826: 
                    827:                        this->mode = this->config->get_mode(this->config);
                    828:                        this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa,
                    829:                                                                                                                           TRUE);
                    830:                        this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa,
                    831:                                                                                                                                FALSE);
                    832:                        this->child.encap = this->ike_sa->has_condition(this->ike_sa,
                    833:                                                                                                                        COND_NAT_ANY);
                    834:                        this->child_sa = child_sa_create(
                    835:                                                                        this->ike_sa->get_my_host(this->ike_sa),
                    836:                                                                        this->ike_sa->get_other_host(this->ike_sa),
                    837:                                                                        this->config, &this->child);
                    838: 
                    839:                        if (this->child.encap && this->mode == MODE_TRANSPORT)
                    840:                        {
                    841:                                /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
                    842:                                add_nat_oa_payloads(this, message);
                    843:                        }
                    844: 
                    845:                        if (this->config->has_option(this->config, OPT_IPCOMP))
                    846:                        {
                    847:                                this->cpi_i = this->child_sa->alloc_cpi(this->child_sa);
                    848:                                if (!this->cpi_i)
                    849:                                {
                    850:                                        DBG1(DBG_IKE, "unable to allocate a CPI from kernel, "
                    851:                                                 "IPComp disabled");
                    852:                                }
                    853:                        }
                    854: 
                    855:                        list = this->config->get_proposals(this->config, FALSE);
                    856:                        if (list->get_first(list, (void**)&proposal) == SUCCESS)
                    857:                        {
                    858:                                this->proto = proposal->get_protocol(proposal);
                    859:                        }
                    860:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                    861:                        this->spi_i = this->child_sa->alloc_spi(this->child_sa, this->proto);
                    862:                        if (!this->spi_i)
                    863:                        {
                    864:                                DBG1(DBG_IKE, "allocating SPI from kernel failed");
                    865:                                return FAILED;
                    866:                        }
                    867: 
                    868:                        group = this->config->get_dh_group(this->config);
                    869:                        if (group != MODP_NONE)
                    870:                        {
                    871:                                proposal_t *proposal;
                    872:                                uint16_t preferred_group;
                    873: 
                    874:                                proposal = this->ike_sa->get_proposal(this->ike_sa);
                    875:                                proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
                    876:                                                                                &preferred_group, NULL);
                    877:                                /* try the negotiated DH group from IKE_SA */
                    878:                                list = get_proposals(this, preferred_group);
                    879:                                if (list->get_count(list))
                    880:                                {
                    881:                                        group = preferred_group;
                    882:                                }
                    883:                                else
                    884:                                {
                    885:                                        /* fall back to the first configured DH group */
                    886:                                        list->destroy(list);
                    887:                                        list = get_proposals(this, group);
                    888:                                }
                    889: 
                    890:                                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                    891:                                                                                                                  group);
                    892:                                if (!this->dh)
                    893:                                {
                    894:                                        DBG1(DBG_IKE, "configured DH group %N not supported",
                    895:                                                 diffie_hellman_group_names, group);
                    896:                                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                    897:                                        return FAILED;
                    898:                                }
                    899:                        }
                    900:                        else
                    901:                        {
                    902:                                list = get_proposals(this, MODP_NONE);
                    903:                        }
                    904: 
                    905:                        get_lifetimes(this);
                    906:                        encap = get_encap(this->ike_sa, this->child.encap);
                    907:                        sa_payload = sa_payload_create_from_proposals_v1(list,
                    908:                                                                this->lifetime, this->lifebytes, AUTH_NONE,
                    909:                                                                this->mode, encap, this->cpi_i);
                    910:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                    911:                        message->add_payload(message, &sa_payload->payload_interface);
                    912: 
                    913:                        if (!add_nonce(this, &this->nonce_i, message))
                    914:                        {
                    915:                                return FAILED;
                    916:                        }
                    917:                        if (group != MODP_NONE)
                    918:                        {
                    919:                                if (!add_ke(this, message))
                    920:                                {
                    921:                                        return FAILED;
                    922:                                }
                    923:                        }
                    924:                        if (!this->tsi)
                    925:                        {
                    926:                                this->tsi = select_ts(this, TRUE, NULL);
                    927:                        }
                    928:                        if (!this->tsr)
                    929:                        {
                    930:                                this->tsr = select_ts(this, FALSE, NULL);
                    931:                        }
                    932:                        tsi = linked_list_create_with_items(this->tsi, NULL);
                    933:                        tsr = linked_list_create_with_items(this->tsr, NULL);
                    934:                        this->tsi = this->tsr = NULL;
                    935:                        charon->bus->narrow(charon->bus, this->child_sa,
                    936:                                                                NARROW_INITIATOR_PRE_AUTH, tsi, tsr);
                    937:                        tsi->remove_first(tsi, (void**)&this->tsi);
                    938:                        tsr->remove_first(tsr, (void**)&this->tsr);
                    939:                        tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                    940:                        tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                    941:                        if (!this->tsi || !this->tsr)
                    942:                        {
                    943:                                return FAILED;
                    944:                        }
                    945:                        add_ts(this, message);
                    946:                        return NEED_MORE;
                    947:                }
                    948:                case QM_NEGOTIATED:
                    949:                {
                    950:                        return SUCCESS;
                    951:                }
                    952:                default:
                    953:                        return FAILED;
                    954:        }
                    955: }
                    956: 
                    957: /**
                    958:  * Check for notify errors, return TRUE if error found
                    959:  */
                    960: static bool has_notify_errors(private_quick_mode_t *this, message_t *message)
                    961: {
                    962:        enumerator_t *enumerator;
                    963:        payload_t *payload;
                    964:        bool err = FALSE;
                    965: 
                    966:        enumerator = message->create_payload_enumerator(message);
                    967:        while (enumerator->enumerate(enumerator, &payload))
                    968:        {
                    969:                if (payload->get_type(payload) == PLV1_NOTIFY)
                    970:                {
                    971:                        notify_payload_t *notify;
                    972:                        notify_type_t type;
                    973: 
                    974:                        notify = (notify_payload_t*)payload;
                    975:                        type = notify->get_notify_type(notify);
                    976:                        if (type < 16384)
                    977:                        {
                    978: 
                    979:                                DBG1(DBG_IKE, "received %N error notify",
                    980:                                         notify_type_names, type);
                    981:                                err = TRUE;
                    982:                        }
                    983:                        else
                    984:                        {
                    985:                                DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
                    986:                        }
                    987:                }
                    988:        }
                    989:        enumerator->destroy(enumerator);
                    990: 
                    991:        return err;
                    992: }
                    993: 
                    994: /**
                    995:  * Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
                    996:  */
                    997: static void check_for_rekeyed_child(private_quick_mode_t *this, bool responder)
                    998: {
                    999:        enumerator_t *enumerator, *policies;
                   1000:        traffic_selector_t *local, *remote, *my_ts, *other_ts;
                   1001:        child_sa_t *child_sa;
                   1002:        proposal_t *proposal;
                   1003:        char *name;
                   1004: 
                   1005:        if (responder)
                   1006:        {
                   1007:                my_ts = this->tsr;
                   1008:                other_ts = this->tsi;
                   1009:        }
                   1010:        else
                   1011:        {
                   1012:                my_ts = this->tsi;
                   1013:                other_ts = this->tsr;
                   1014:        }
                   1015: 
                   1016:        name = this->config->get_name(this->config);
                   1017:        enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
                   1018:        while (!this->child.reqid && enumerator->enumerate(enumerator, &child_sa))
                   1019:        {
                   1020:                if (streq(child_sa->get_name(child_sa), name))
                   1021:                {
                   1022:                        proposal = child_sa->get_proposal(child_sa);
                   1023:                        switch (child_sa->get_state(child_sa))
                   1024:                        {
                   1025:                                case CHILD_INSTALLED:
                   1026:                                case CHILD_REKEYING:
                   1027:                                        policies = child_sa->create_policy_enumerator(child_sa);
                   1028:                                        if (policies->enumerate(policies, &local, &remote) &&
                   1029:                                                local->equals(local, my_ts) &&
                   1030:                                                remote->equals(remote, other_ts) &&
                   1031:                                                this->proposal->equals(this->proposal, proposal))
                   1032:                                        {
                   1033:                                                this->rekey = child_sa->get_spi(child_sa, TRUE);
                   1034:                                                this->child.reqid = child_sa->get_reqid(child_sa);
                   1035:                                                this->child.mark_in = child_sa->get_mark(child_sa,
                   1036:                                                                                                                                 TRUE).value;
                   1037:                                                this->child.mark_out = child_sa->get_mark(child_sa,
                   1038:                                                                                                                                  FALSE).value;
                   1039:                                                this->child.if_id_in = child_sa->get_if_id(child_sa,
                   1040:                                                                                                                                   TRUE);
                   1041:                                                this->child.if_id_out = child_sa->get_if_id(child_sa,
                   1042:                                                                                                                                        FALSE);
                   1043:                                                child_sa->set_state(child_sa, CHILD_REKEYING);
                   1044:                                                DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}",
                   1045:                                                         child_sa->get_name(child_sa),
                   1046:                                                         child_sa->get_unique_id(child_sa));
                   1047:                                        }
                   1048:                                        policies->destroy(policies);
                   1049:                                        break;
                   1050:                                case CHILD_REKEYED:
                   1051:                                default:
                   1052:                                        break;
                   1053:                        }
                   1054:                }
                   1055:        }
                   1056:        enumerator->destroy(enumerator);
                   1057: }
                   1058: 
                   1059: METHOD(task_t, process_r, status_t,
                   1060:        private_quick_mode_t *this, message_t *message)
                   1061: {
                   1062:        if (this->mid && this->mid != message->get_message_id(message))
                   1063:        {       /* not responsible for this quick mode exchange */
                   1064:                return INVALID_ARG;
                   1065:        }
                   1066: 
                   1067:        switch (this->state)
                   1068:        {
                   1069:                case QM_INIT:
                   1070:                {
                   1071:                        sa_payload_t *sa_payload;
                   1072:                        linked_list_t *tsi, *tsr, *hostsi, *hostsr, *list = NULL;
                   1073:                        peer_cfg_t *peer_cfg;
                   1074:                        uint16_t group;
                   1075:                        proposal_selection_flag_t flags = 0;
                   1076: 
                   1077:                        sa_payload = (sa_payload_t*)message->get_payload(message,
                   1078:                                                                                                        PLV1_SECURITY_ASSOCIATION);
                   1079:                        if (!sa_payload)
                   1080:                        {
                   1081:                                DBG1(DBG_IKE, "sa payload missing");
                   1082:                                return send_notify(this, INVALID_PAYLOAD_TYPE);
                   1083:                        }
                   1084: 
                   1085:                        this->mode = sa_payload->get_encap_mode(sa_payload,
                   1086:                                                                                                        &this->child.encap);
                   1087: 
                   1088:                        if (!get_ts(this, message))
                   1089:                        {
                   1090:                                return FAILED;
                   1091:                        }
                   1092:                        peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
                   1093:                        tsi = linked_list_create_with_items(this->tsi, NULL);
                   1094:                        tsr = linked_list_create_with_items(this->tsr, NULL);
                   1095:                        this->tsi = this->tsr = NULL;
                   1096:                        hostsi = get_dynamic_hosts(this->ike_sa, FALSE);
                   1097:                        hostsr = get_dynamic_hosts(this->ike_sa, TRUE);
                   1098:                        this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
                   1099:                                                                                                          hostsr, hostsi);
                   1100:                        hostsi->destroy(hostsi);
                   1101:                        hostsr->destroy(hostsr);
                   1102:                        if (this->config)
                   1103:                        {
                   1104:                                this->tsi = select_ts(this, FALSE, tsi);
                   1105:                                this->tsr = select_ts(this, TRUE, tsr);
                   1106:                        }
                   1107:                        if (!this->config || !this->tsi || !this->tsr ||
                   1108:                                this->mode != this->config->get_mode(this->config))
                   1109:                        {
                   1110:                                DBG1(DBG_IKE, "no matching CHILD_SA config found for "
                   1111:                                         "%#R === %#R", tsi, tsr);
                   1112:                                tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                   1113:                                tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                   1114:                                return send_notify(this, INVALID_ID_INFORMATION);
                   1115:                        }
                   1116:                        tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                   1117:                        tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                   1118: 
                   1119:                        if (this->config->has_option(this->config, OPT_IPCOMP))
                   1120:                        {
                   1121:                                list = sa_payload->get_ipcomp_proposals(sa_payload,
                   1122:                                                                                                                &this->cpi_i);
                   1123:                                if (!list->get_count(list))
                   1124:                                {
                   1125:                                        DBG1(DBG_IKE, "expected IPComp proposal but peer did "
                   1126:                                                 "not send one, IPComp disabled");
                   1127:                                        this->cpi_i = 0;
                   1128:                                }
                   1129:                        }
                   1130:                        if (!list || !list->get_count(list))
                   1131:                        {
                   1132:                                DESTROY_IF(list);
                   1133:                                list = sa_payload->get_proposals(sa_payload);
                   1134:                        }
                   1135:                        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN)
                   1136:                                && !lib->settings->get_bool(lib->settings,
                   1137:                                                                        "%s.accept_private_algs", FALSE, lib->ns))
                   1138:                        {
                   1139:                                flags |= PROPOSAL_SKIP_PRIVATE;
                   1140:                        }
                   1141:                        if (!lib->settings->get_bool(lib->settings,
                   1142:                                                        "%s.prefer_configured_proposals", TRUE, lib->ns))
                   1143:                        {
                   1144:                                flags |= PROPOSAL_PREFER_SUPPLIED;
                   1145:                        }
                   1146:                        this->proposal = this->config->select_proposal(this->config, list,
                   1147:                                                                                                                   flags);
                   1148:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                   1149: 
                   1150:                        if (!this->proposal)
                   1151:                        {
                   1152:                                DBG1(DBG_IKE, "no matching proposal found, sending %N",
                   1153:                                         notify_type_names, NO_PROPOSAL_CHOSEN);
                   1154:                                return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1155:                        }
                   1156:                        this->spi_i = this->proposal->get_spi(this->proposal);
                   1157: 
                   1158:                        get_lifetimes(this);
                   1159:                        apply_lifetimes(this, sa_payload);
                   1160: 
                   1161:                        if (!get_nonce(this, &this->nonce_i, message))
                   1162:                        {
                   1163:                                return send_notify(this, INVALID_PAYLOAD_TYPE);
                   1164:                        }
                   1165: 
                   1166:                        if (this->proposal->get_algorithm(this->proposal,
                   1167:                                                                                DIFFIE_HELLMAN_GROUP, &group, NULL))
                   1168:                        {
                   1169:                                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                   1170:                                                                                                                  group);
                   1171:                                if (!this->dh)
                   1172:                                {
                   1173:                                        DBG1(DBG_IKE, "negotiated DH group %N not supported",
                   1174:                                                 diffie_hellman_group_names, group);
                   1175:                                        return send_notify(this, INVALID_KEY_INFORMATION);
                   1176:                                }
                   1177:                                if (!get_ke(this, message))
                   1178:                                {
                   1179:                                        return send_notify(this, INVALID_PAYLOAD_TYPE);
                   1180:                                }
                   1181:                        }
                   1182: 
                   1183:                        check_for_rekeyed_child(this, TRUE);
                   1184:                        this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa,
                   1185:                                                                                                                           TRUE);
                   1186:                        this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa,
                   1187:                                                                                                                                FALSE);
                   1188:                        this->child_sa = child_sa_create(
                   1189:                                                                        this->ike_sa->get_my_host(this->ike_sa),
                   1190:                                                                        this->ike_sa->get_other_host(this->ike_sa),
                   1191:                                                                        this->config, &this->child);
                   1192: 
                   1193:                        tsi = linked_list_create_with_items(this->tsi, NULL);
                   1194:                        tsr = linked_list_create_with_items(this->tsr, NULL);
                   1195:                        this->tsi = this->tsr = NULL;
                   1196:                        charon->bus->narrow(charon->bus, this->child_sa,
                   1197:                                                                NARROW_RESPONDER, tsr, tsi);
                   1198:                        if (tsi->remove_first(tsi, (void**)&this->tsi) != SUCCESS ||
                   1199:                                tsr->remove_first(tsr, (void**)&this->tsr) != SUCCESS)
                   1200:                        {
                   1201:                                tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                   1202:                                tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                   1203:                                return send_notify(this, INVALID_ID_INFORMATION);
                   1204:                        }
                   1205:                        tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
                   1206:                        tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
                   1207: 
                   1208:                        return NEED_MORE;
                   1209:                }
                   1210:                case QM_NEGOTIATED:
                   1211:                {
                   1212:                        if (has_notify_errors(this, message))
                   1213:                        {
                   1214:                                return SUCCESS;
                   1215:                        }
                   1216:                        if (message->get_exchange_type(message) == INFORMATIONAL_V1)
                   1217:                        {
                   1218:                                if (message->get_payload(message, PLV1_DELETE))
                   1219:                                {
                   1220:                                        /* If the DELETE for a Quick Mode follows immediately
                   1221:                                         * after rekeying, we might receive it before the
                   1222:                                         * third completing Quick Mode message. Ignore it, as
                   1223:                                         * it gets handled by a separately queued delete task. */
                   1224:                                        return NEED_MORE;
                   1225:                                }
                   1226:                                return SUCCESS;
                   1227:                        }
                   1228:                        if (!this->rekey)
                   1229:                        {
                   1230:                                /* do another check in case SAs were created since we handled
                   1231:                                 * the QM request, this is consistent with the rekey check
                   1232:                                 * before installation on the initiator */
                   1233:                                check_for_rekeyed_child(this, TRUE);
                   1234:                                if (this->rekey)
                   1235:                                {
                   1236:                                        this->child_sa->destroy(this->child_sa);
                   1237:                                        this->child_sa = child_sa_create(
                   1238:                                                                        this->ike_sa->get_my_host(this->ike_sa),
                   1239:                                                                        this->ike_sa->get_other_host(this->ike_sa),
                   1240:                                                                        this->config, &this->child);
                   1241:                                }
                   1242:                        }
                   1243:                        if (!install(this))
                   1244:                        {
                   1245:                                ike_sa_t *ike_sa = this->ike_sa;
                   1246:                                task_t *task;
                   1247: 
                   1248:                                task = (task_t*)quick_delete_create(this->ike_sa,
                   1249:                                                                this->proposal->get_protocol(this->proposal),
                   1250:                                                                this->spi_i, TRUE, TRUE);
                   1251:                                /* flush_queue() destroys the current task */
                   1252:                                ike_sa->flush_queue(ike_sa, TASK_QUEUE_PASSIVE);
                   1253:                                ike_sa->queue_task(ike_sa, task);
                   1254:                                return ALREADY_DONE;
                   1255:                        }
                   1256:                        return SUCCESS;
                   1257:                }
                   1258:                default:
                   1259:                        return FAILED;
                   1260:        }
                   1261: }
                   1262: 
                   1263: METHOD(task_t, build_r, status_t,
                   1264:        private_quick_mode_t *this, message_t *message)
                   1265: {
                   1266:        if (this->mid && this->mid != message->get_message_id(message))
                   1267:        {       /* not responsible for this quick mode exchange */
                   1268:                return INVALID_ARG;
                   1269:        }
                   1270: 
                   1271:        switch (this->state)
                   1272:        {
                   1273:                case QM_INIT:
                   1274:                {
                   1275:                        sa_payload_t *sa_payload;
                   1276:                        encap_t encap;
                   1277: 
                   1278:                        this->proto = this->proposal->get_protocol(this->proposal);
                   1279:                        this->spi_r = this->child_sa->alloc_spi(this->child_sa, this->proto);
                   1280:                        if (!this->spi_r)
                   1281:                        {
                   1282:                                DBG1(DBG_IKE, "allocating SPI from kernel failed");
                   1283:                                return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1284:                        }
                   1285:                        this->proposal->set_spi(this->proposal, this->spi_r);
                   1286: 
                   1287:                        if (this->cpi_i)
                   1288:                        {
                   1289:                                this->cpi_r = this->child_sa->alloc_cpi(this->child_sa);
                   1290:                                if (!this->cpi_r)
                   1291:                                {
                   1292:                                        DBG1(DBG_IKE, "unable to allocate a CPI from "
                   1293:                                                 "kernel, IPComp disabled");
                   1294:                                        return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1295:                                }
                   1296:                        }
                   1297: 
                   1298:                        if (this->child.encap && this->mode == MODE_TRANSPORT)
                   1299:                        {
                   1300:                                /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
                   1301:                                add_nat_oa_payloads(this, message);
                   1302:                        }
                   1303: 
                   1304:                        encap = get_encap(this->ike_sa, this->child.encap);
                   1305:                        sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
                   1306:                                                                this->lifetime, this->lifebytes, AUTH_NONE,
                   1307:                                                                this->mode, encap, this->cpi_r);
                   1308:                        message->add_payload(message, &sa_payload->payload_interface);
                   1309: 
                   1310:                        if (!add_nonce(this, &this->nonce_r, message))
                   1311:                        {
                   1312:                                return FAILED;
                   1313:                        }
                   1314:                        if (this->dh)
                   1315:                        {
                   1316:                                if (!add_ke(this, message))
                   1317:                                {
                   1318:                                        return FAILED;
                   1319:                                }
                   1320:                        }
                   1321: 
                   1322:                        add_ts(this, message);
                   1323: 
                   1324:                        this->state = QM_NEGOTIATED;
                   1325:                        this->mid = message->get_message_id(message);
                   1326:                        return NEED_MORE;
                   1327:                }
                   1328:                case QM_NEGOTIATED:
                   1329:                        if (message->get_exchange_type(message) == INFORMATIONAL_V1)
                   1330:                        {
                   1331:                                /* skip INFORMATIONAL response if we received a INFORMATIONAL
                   1332:                                 * delete, see process_r() */
                   1333:                                return ALREADY_DONE;
                   1334:                        }
                   1335:                        /* fall */
                   1336:                default:
                   1337:                        return FAILED;
                   1338:        }
                   1339: }
                   1340: 
                   1341: METHOD(task_t, process_i, status_t,
                   1342:        private_quick_mode_t *this, message_t *message)
                   1343: {
                   1344:        switch (this->state)
                   1345:        {
                   1346:                case QM_INIT:
                   1347:                {
                   1348:                        sa_payload_t *sa_payload;
                   1349:                        linked_list_t *list = NULL;
                   1350:                        proposal_selection_flag_t flags = 0;
                   1351: 
                   1352:                        sa_payload = (sa_payload_t*)message->get_payload(message,
                   1353:                                                                                                        PLV1_SECURITY_ASSOCIATION);
                   1354:                        if (!sa_payload)
                   1355:                        {
                   1356:                                DBG1(DBG_IKE, "sa payload missing");
                   1357:                                return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1358:                        }
                   1359:                        if (this->cpi_i)
                   1360:                        {
                   1361:                                list = sa_payload->get_ipcomp_proposals(sa_payload,
                   1362:                                                                                                                &this->cpi_r);
                   1363:                                if (!list->get_count(list))
                   1364:                                {
                   1365:                                        DBG1(DBG_IKE, "peer did not accept our IPComp proposal, "
                   1366:                                                 "IPComp disabled");
                   1367:                                        this->cpi_i = 0;
                   1368:                                }
                   1369:                        }
                   1370:                        if (!list || !list->get_count(list))
                   1371:                        {
                   1372:                                DESTROY_IF(list);
                   1373:                                list = sa_payload->get_proposals(sa_payload);
                   1374:                        }
                   1375:                        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN)
                   1376:                                && !lib->settings->get_bool(lib->settings,
                   1377:                                                                        "%s.accept_private_algs", FALSE, lib->ns))
                   1378:                        {
                   1379:                                flags |= PROPOSAL_SKIP_PRIVATE;
                   1380:                        }
                   1381:                        this->proposal = this->config->select_proposal(this->config, list,
                   1382:                                                                                                                   flags);
                   1383:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                   1384:                        if (!this->proposal)
                   1385:                        {
                   1386:                                DBG1(DBG_IKE, "no matching proposal found");
                   1387:                                return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1388:                        }
                   1389:                        this->spi_r = this->proposal->get_spi(this->proposal);
                   1390: 
                   1391:                        apply_lifetimes(this, sa_payload);
                   1392: 
                   1393:                        if (!get_nonce(this, &this->nonce_r, message))
                   1394:                        {
                   1395:                                return send_notify(this, INVALID_PAYLOAD_TYPE);
                   1396:                        }
                   1397:                        if (this->dh && !get_ke(this, message))
                   1398:                        {
                   1399:                                return send_notify(this, INVALID_KEY_INFORMATION);
                   1400:                        }
                   1401:                        if (!get_ts(this, message))
                   1402:                        {
                   1403:                                return send_notify(this, INVALID_PAYLOAD_TYPE);
                   1404:                        }
                   1405:                        check_for_rekeyed_child(this, FALSE);
                   1406:                        if (!install(this))
                   1407:                        {
                   1408:                                return send_notify(this, NO_PROPOSAL_CHOSEN);
                   1409:                        }
                   1410:                        this->state = QM_NEGOTIATED;
                   1411:                        return NEED_MORE;
                   1412:                }
                   1413:                default:
                   1414:                        return FAILED;
                   1415:        }
                   1416: }
                   1417: 
                   1418: METHOD(task_t, get_type, task_type_t,
                   1419:        private_quick_mode_t *this)
                   1420: {
                   1421:        return TASK_QUICK_MODE;
                   1422: }
                   1423: 
                   1424: METHOD(quick_mode_t, get_mid, uint32_t,
                   1425:        private_quick_mode_t *this)
                   1426: {
                   1427:        return this->mid;
                   1428: }
                   1429: 
                   1430: METHOD(quick_mode_t, use_reqid, void,
                   1431:        private_quick_mode_t *this, uint32_t reqid)
                   1432: {
                   1433:        this->child.reqid = reqid;
                   1434: }
                   1435: 
                   1436: METHOD(quick_mode_t, use_marks, void,
                   1437:        private_quick_mode_t *this, uint32_t in, uint32_t out)
                   1438: {
                   1439:        this->child.mark_in = in;
                   1440:        this->child.mark_out = out;
                   1441: }
                   1442: 
                   1443: METHOD(quick_mode_t, use_if_ids, void,
                   1444:        private_quick_mode_t *this, uint32_t in, uint32_t out)
                   1445: {
                   1446:        this->child.if_id_in = in;
                   1447:        this->child.if_id_out = out;
                   1448: }
                   1449: 
                   1450: METHOD(quick_mode_t, rekey, void,
                   1451:        private_quick_mode_t *this, uint32_t spi)
                   1452: {
                   1453:        this->rekey = spi;
                   1454: }
                   1455: 
                   1456: METHOD(task_t, migrate, void,
                   1457:        private_quick_mode_t *this, ike_sa_t *ike_sa)
                   1458: {
                   1459:        chunk_free(&this->nonce_i);
                   1460:        chunk_free(&this->nonce_r);
                   1461:        DESTROY_IF(this->tsi);
                   1462:        DESTROY_IF(this->tsr);
                   1463:        DESTROY_IF(this->proposal);
                   1464:        DESTROY_IF(this->child_sa);
                   1465:        DESTROY_IF(this->dh);
                   1466: 
                   1467:        this->ike_sa = ike_sa;
                   1468:        this->keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
                   1469:        this->state = QM_INIT;
                   1470:        this->mid = 0;
                   1471:        this->tsi = NULL;
                   1472:        this->tsr = NULL;
                   1473:        this->proposal = NULL;
                   1474:        this->child_sa = NULL;
                   1475:        this->dh = NULL;
                   1476:        this->spi_i = 0;
                   1477:        this->spi_r = 0;
                   1478:        this->child = (child_sa_create_t){};
                   1479: 
                   1480:        if (!this->initiator)
                   1481:        {
                   1482:                DESTROY_IF(this->config);
                   1483:                this->config = NULL;
                   1484:        }
                   1485: }
                   1486: 
                   1487: METHOD(task_t, destroy, void,
                   1488:        private_quick_mode_t *this)
                   1489: {
                   1490:        chunk_free(&this->nonce_i);
                   1491:        chunk_free(&this->nonce_r);
                   1492:        DESTROY_IF(this->tsi);
                   1493:        DESTROY_IF(this->tsr);
                   1494:        DESTROY_IF(this->proposal);
                   1495:        DESTROY_IF(this->child_sa);
                   1496:        DESTROY_IF(this->config);
                   1497:        DESTROY_IF(this->dh);
                   1498:        free(this);
                   1499: }
                   1500: 
                   1501: /*
                   1502:  * Described in header.
                   1503:  */
                   1504: quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config,
                   1505:                                                        traffic_selector_t *tsi, traffic_selector_t *tsr)
                   1506: {
                   1507:        private_quick_mode_t *this;
                   1508: 
                   1509:        INIT(this,
                   1510:                .public = {
                   1511:                        .task = {
                   1512:                                .get_type = _get_type,
                   1513:                                .migrate = _migrate,
                   1514:                                .destroy = _destroy,
                   1515:                        },
                   1516:                        .get_mid = _get_mid,
                   1517:                        .use_reqid = _use_reqid,
                   1518:                        .use_marks = _use_marks,
                   1519:                        .use_if_ids = _use_if_ids,
                   1520:                        .rekey = _rekey,
                   1521:                },
                   1522:                .ike_sa = ike_sa,
                   1523:                .initiator = config != NULL,
                   1524:                .config = config,
                   1525:                .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
                   1526:                .state = QM_INIT,
                   1527:                .tsi = tsi ? tsi->clone(tsi) : NULL,
                   1528:                .tsr = tsr ? tsr->clone(tsr) : NULL,
                   1529:                .proto = PROTO_ESP,
                   1530:                .delete = lib->settings->get_bool(lib->settings,
                   1531:                                                                                  "%s.delete_rekeyed", FALSE, lib->ns),
                   1532:        );
                   1533: 
                   1534:        if (config)
                   1535:        {
                   1536:                this->public.task.build = _build_i;
                   1537:                this->public.task.process = _process_i;
                   1538:        }
                   1539:        else
                   1540:        {
                   1541:                this->public.task.build = _build_r;
                   1542:                this->public.task.process = _process_r;
                   1543:        }
                   1544: 
                   1545:        return &this->public;
                   1546: }

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