Annotation of embedaddon/strongswan/src/libcharon/plugins/sql/sql_config.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2006-2008 Martin Willi
        !             3:  * Copyright (C) 2010 Andreas Steffen
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
        !             6:  * This program is free software; you can redistribute it and/or modify it
        !             7:  * under the terms of the GNU General Public License as published by the
        !             8:  * Free Software Foundation; either version 2 of the License, or (at your
        !             9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            10:  *
        !            11:  * This program is distributed in the hope that it will be useful, but
        !            12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            14:  * for more details.
        !            15:  */
        !            16: 
        !            17: #include <string.h>
        !            18: 
        !            19: #include "sql_config.h"
        !            20: 
        !            21: #include <daemon.h>
        !            22: 
        !            23: typedef struct private_sql_config_t private_sql_config_t;
        !            24: 
        !            25: /**
        !            26:  * Private data of an sql_config_t object
        !            27:  */
        !            28: struct private_sql_config_t {
        !            29: 
        !            30:        /**
        !            31:         * Public part
        !            32:         */
        !            33:        sql_config_t public;
        !            34: 
        !            35:        /**
        !            36:         * database connection
        !            37:         */
        !            38:        database_t *db;
        !            39: };
        !            40: 
        !            41: /**
        !            42:  * Forward declaration
        !            43:  */
        !            44: static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
        !            45:                                                                  identification_t *me, identification_t *other);
        !            46: 
        !            47: /**
        !            48:  * Build a traffic selector from an SQL query
        !            49:  */
        !            50: static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
        !            51:                                                                                                  enumerator_t *e, bool *local)
        !            52: {
        !            53:        int type, protocol, start_port, end_port;
        !            54:        chunk_t start_addr, end_addr;
        !            55:        traffic_selector_t *ts;
        !            56:        enum {
        !            57:                TS_LOCAL = 0,
        !            58:                TS_REMOTE = 1,
        !            59:                TS_LOCAL_DYNAMIC = 2,
        !            60:                TS_REMOTE_DYNAMIC = 3,
        !            61:        } kind;
        !            62: 
        !            63:        while (e->enumerate(e, &kind, &type, &protocol,
        !            64:                                                &start_addr, &end_addr, &start_port, &end_port))
        !            65:        {
        !            66:                *local = FALSE;
        !            67:                switch (kind)
        !            68:                {
        !            69:                        case TS_LOCAL:
        !            70:                                *local = TRUE;
        !            71:                                /* FALL */
        !            72:                        case TS_REMOTE:
        !            73:                                ts = traffic_selector_create_from_bytes(protocol, type,
        !            74:                                                                start_addr, start_port, end_addr, end_port);
        !            75:                                break;
        !            76:                        case TS_LOCAL_DYNAMIC:
        !            77:                                *local = TRUE;
        !            78:                                /* FALL */
        !            79:                        case TS_REMOTE_DYNAMIC:
        !            80:                                ts = traffic_selector_create_dynamic(protocol,
        !            81:                                                                start_port, end_port);
        !            82:                                break;
        !            83:                        default:
        !            84:                                continue;
        !            85:                }
        !            86:                if (ts)
        !            87:                {
        !            88:                        return ts;
        !            89:                }
        !            90:        }
        !            91:        return NULL;
        !            92: }
        !            93: 
        !            94: /**
        !            95:  * Add traffic selectors to a child config
        !            96:  */
        !            97: static void add_traffic_selectors(private_sql_config_t *this,
        !            98:                                                                  child_cfg_t *child, int id)
        !            99: {
        !           100:        enumerator_t *e;
        !           101:        traffic_selector_t *ts;
        !           102:        bool local;
        !           103: 
        !           104:        e = this->db->query(this->db,
        !           105:                        "SELECT ct.kind, t.type, t.protocol, "
        !           106:                        "t.start_addr, t.end_addr, t.start_port, t.end_port "
        !           107:                        "FROM traffic_selectors AS t "
        !           108:                        "JOIN child_config_traffic_selector AS ct "
        !           109:                        "ON t.id = ct.traffic_selector WHERE ct.child_cfg = ?",
        !           110:                        DB_INT, id,
        !           111:                        DB_INT, DB_INT, DB_INT,
        !           112:                        DB_BLOB, DB_BLOB, DB_INT, DB_INT);
        !           113:        if (e)
        !           114:        {
        !           115:                while ((ts = build_traffic_selector(this, e, &local)))
        !           116:                {
        !           117:                        child->add_traffic_selector(child, local, ts);
        !           118:                }
        !           119:                e->destroy(e);
        !           120:        }
        !           121: }
        !           122: 
        !           123: /**
        !           124:  * Add ESP proposals to a child config
        !           125:  */
        !           126: static void add_esp_proposals(private_sql_config_t *this,
        !           127:                                                          child_cfg_t *child, int id)
        !           128: {
        !           129:        enumerator_t *e;
        !           130:        proposal_t *proposal;
        !           131:        char *prop;
        !           132:        bool use_default = TRUE;
        !           133: 
        !           134:        e = this->db->query(this->db,
        !           135:                        "SELECT p.proposal "
        !           136:                        "FROM proposals AS p JOIN child_config_proposal AS cp "
        !           137:                        "ON p.id = cp.prop WHERE cp.child_cfg = ? ORDER BY cp.prio",
        !           138:                        DB_INT, id, DB_TEXT);
        !           139:        if (e)
        !           140:        {
        !           141:                while (e->enumerate(e, &prop))
        !           142:                {
        !           143:                        proposal = proposal_create_from_string(PROTO_ESP, prop);
        !           144:                        if (!proposal)
        !           145:                        {
        !           146:                                DBG1(DBG_CFG, "could not create ESP proposal from '%s'", prop);
        !           147:                                break;
        !           148:                        }
        !           149:                        child->add_proposal(child, proposal);
        !           150:                        use_default = FALSE;
        !           151:                }
        !           152:                e->destroy(e);
        !           153:        }
        !           154:        if (use_default)
        !           155:        {
        !           156:                child->add_proposal(child, proposal_create_default(PROTO_ESP));
        !           157:                child->add_proposal(child, proposal_create_default_aead(PROTO_ESP));
        !           158:        }
        !           159: }
        !           160: 
        !           161: /**
        !           162:  * Build a child config from an SQL query
        !           163:  */
        !           164: static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
        !           165: {
        !           166:        int id, lifetime, rekeytime, jitter, hostaccess, mode, ipcomp, reqid;
        !           167:        int start, dpd, close;
        !           168:        char *name, *updown;
        !           169:        child_cfg_t *child_cfg;
        !           170: 
        !           171:        if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, &updown,
        !           172:                                                &hostaccess, &mode, &start, &dpd, &close, &ipcomp, &reqid))
        !           173:        {
        !           174:                child_cfg_create_t child = {
        !           175:                        .mode = mode,
        !           176:                        .reqid = reqid,
        !           177:                        .options = (ipcomp ? OPT_IPCOMP : 0) |
        !           178:                                           (hostaccess ? OPT_HOSTACCESS : 0),
        !           179:                        .lifetime = {
        !           180:                                .time = {
        !           181:                                        .life = lifetime, .rekey = rekeytime, .jitter = jitter
        !           182:                                },
        !           183:                        },
        !           184:                        .start_action = start,
        !           185:                        .dpd_action = dpd,
        !           186:                        .close_action = close,
        !           187:                        .updown = updown,
        !           188:                };
        !           189:                child_cfg = child_cfg_create(name, &child);
        !           190:                add_esp_proposals(this, child_cfg, id);
        !           191:                add_traffic_selectors(this, child_cfg, id);
        !           192:                return child_cfg;
        !           193:        }
        !           194:        return NULL;
        !           195: }
        !           196: 
        !           197: /**
        !           198:  * Add child configs to peer config
        !           199:  */
        !           200: static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
        !           201: {
        !           202:        enumerator_t *e;
        !           203:        child_cfg_t *child_cfg;
        !           204: 
        !           205:        e = this->db->query(this->db,
        !           206:                        "SELECT c.id, c.name, c.lifetime, c.rekeytime, c.jitter, c.updown, "
        !           207:                        "c.hostaccess, c.mode, c.start_action, c.dpd_action, "
        !           208:                        "c.close_action, c.ipcomp, c.reqid "
        !           209:                        "FROM child_configs AS c JOIN peer_config_child_config AS pc "
        !           210:                        "ON c.id = pc.child_cfg WHERE pc.peer_cfg = ?",
        !           211:                        DB_INT, id,
        !           212:                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_TEXT, DB_INT,
        !           213:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
        !           214:        if (e)
        !           215:        {
        !           216:                while ((child_cfg = build_child_cfg(this, e)))
        !           217:                {
        !           218:                        peer->add_child_cfg(peer, child_cfg);
        !           219:                }
        !           220:                e->destroy(e);
        !           221:        }
        !           222: }
        !           223: 
        !           224: /**
        !           225:  * Add IKE proposals to an IKE config
        !           226:  */
        !           227: static void add_ike_proposals(private_sql_config_t *this,
        !           228:                                                          ike_cfg_t *ike_cfg, int id)
        !           229: {
        !           230:        enumerator_t *e;
        !           231:        proposal_t *proposal;
        !           232:        char *prop;
        !           233:        bool use_default = TRUE;
        !           234: 
        !           235:        e = this->db->query(this->db,
        !           236:                        "SELECT p.proposal "
        !           237:                        "FROM proposals AS p "
        !           238:                        "JOIN ike_config_proposal AS ip ON p.id = ip.prop "
        !           239:                        "WHERE ip.ike_cfg = ? ORDER BY ip.prio",
        !           240:                        DB_INT, id, DB_TEXT);
        !           241:        if (e)
        !           242:        {
        !           243:                while (e->enumerate(e, &prop))
        !           244:                {
        !           245:                        proposal = proposal_create_from_string(PROTO_IKE, prop);
        !           246:                        if (!proposal)
        !           247:                        {
        !           248:                                DBG1(DBG_CFG, "could not create IKE proposal from '%s'", prop);
        !           249:                                break;
        !           250:                        }
        !           251:                        ike_cfg->add_proposal(ike_cfg, proposal);
        !           252:                        use_default = FALSE;
        !           253:                }
        !           254:                e->destroy(e);
        !           255:        }
        !           256:        if (use_default)
        !           257:        {
        !           258:                ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        !           259:                ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
        !           260:        }
        !           261: }
        !           262: 
        !           263: /**
        !           264:  * Build an IKE config from an SQL query
        !           265:  */
        !           266: static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
        !           267:                                                                host_t *my_host, host_t *other_host)
        !           268: {
        !           269:        int id, certreq, force_encap;
        !           270:        char *local, *remote;
        !           271: 
        !           272:        while (e->enumerate(e, &id, &certreq, &force_encap, &local, &remote))
        !           273:        {
        !           274:                ike_cfg_t *ike_cfg;
        !           275:                ike_cfg_create_t ike = {
        !           276:                        .version = IKEV2,
        !           277:                        .local = local,
        !           278:                        .local_port = charon->socket->get_port(charon->socket, FALSE),
        !           279:                        .remote = remote,
        !           280:                        .remote_port = IKEV2_UDP_PORT,
        !           281:                        .no_certreq = !certreq,
        !           282:                        .force_encap = force_encap,
        !           283:                        .fragmentation = FRAGMENTATION_YES,
        !           284:                };
        !           285: 
        !           286:                ike_cfg = ike_cfg_create(&ike);
        !           287:                add_ike_proposals(this, ike_cfg, id);
        !           288:                return ike_cfg;
        !           289:        }
        !           290:        return NULL;
        !           291: }
        !           292: 
        !           293: /**
        !           294:  * Query an IKE config by its id
        !           295:  */
        !           296: static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
        !           297: {
        !           298:        enumerator_t *e;
        !           299:        ike_cfg_t *ike_cfg = NULL;
        !           300: 
        !           301:        e = this->db->query(this->db,
        !           302:                        "SELECT c.id, c.certreq, c.force_encap, c.local, c.remote "
        !           303:                        "FROM ike_configs AS c WHERE c.id = ?",
        !           304:                        DB_INT, id,
        !           305:                        DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
        !           306:        if (e)
        !           307:        {
        !           308:                ike_cfg = build_ike_cfg(this, e, NULL, NULL);
        !           309:                e->destroy(e);
        !           310:        }
        !           311:        return ike_cfg;
        !           312: }
        !           313: 
        !           314: #ifdef ME
        !           315: /**
        !           316:  * Query a peer config by its id
        !           317:  */
        !           318: static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
        !           319: {
        !           320:        enumerator_t *e;
        !           321:        peer_cfg_t *peer_cfg = NULL;
        !           322: 
        !           323:        e = this->db->query(this->db,
        !           324:                        "SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
        !           325:                        "c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
        !           326:                        "c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
        !           327:                        "c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
        !           328:                        "c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
        !           329:                        "FROM peer_configs AS c "
        !           330:                        "JOIN identities AS l ON c.local_id = l.id "
        !           331:                        "JOIN identities AS r ON c.remote_id = r.id "
        !           332:                        "LEFT JOIN identities AS p ON c.peer_id = p.id "
        !           333:                        "WHERE c.id = ?",
        !           334:                        DB_INT, id,
        !           335:                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
        !           336:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           337:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           338:                        DB_INT, DB_TEXT, DB_TEXT,
        !           339:                        DB_INT, DB_INT, DB_INT, DB_BLOB);
        !           340:        if (e)
        !           341:        {
        !           342:                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
        !           343:                e->destroy(e);
        !           344:        }
        !           345:        return peer_cfg;
        !           346: }
        !           347: #endif /* ME */
        !           348: 
        !           349: /**
        !           350:  * Check if the two IDs match (the first one is optional)
        !           351:  */
        !           352: static inline bool id_matches(identification_t *id, identification_t *sql_id)
        !           353: {
        !           354:        return !id || id->matches(id, sql_id) || sql_id->matches(sql_id, id);
        !           355: }
        !           356: 
        !           357: /**
        !           358:  * Build a peer config from an SQL query
        !           359:  */
        !           360: static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
        !           361:                                                                  identification_t *me, identification_t *other)
        !           362: {
        !           363:        int id, ike_cfg, l_type, r_type,
        !           364:                cert_policy, uniqueid, auth_method, eap_type, eap_vendor, keyingtries,
        !           365:                rekeytime, reauthtime, jitter, overtime, mobike, dpd_delay,
        !           366:                mediation, mediated_by, p_type;
        !           367:        chunk_t l_data, r_data, p_data;
        !           368:        char *name, *virtual, *pool;
        !           369:        enumerator_t *enumerator;
        !           370: 
        !           371:        while (e->enumerate(e,
        !           372:                        &id, &name, &ike_cfg, &l_type, &l_data, &r_type, &r_data,
        !           373:                        &cert_policy, &uniqueid, &auth_method, &eap_type, &eap_vendor,
        !           374:                        &keyingtries, &rekeytime, &reauthtime, &jitter, &overtime, &mobike,
        !           375:                        &dpd_delay,     &virtual, &pool,
        !           376:                        &mediation, &mediated_by, &p_type, &p_data))
        !           377:        {
        !           378:                identification_t *local_id, *remote_id, *peer_id = NULL;
        !           379:                peer_cfg_t *peer_cfg, *mediated_cfg = NULL;
        !           380:                ike_cfg_t *ike;
        !           381:                host_t *vip = NULL;
        !           382:                auth_cfg_t *auth;
        !           383: 
        !           384:                local_id = identification_create_from_encoding(l_type, l_data);
        !           385:                remote_id = identification_create_from_encoding(r_type, r_data);
        !           386:                if (!id_matches(me, local_id) || !id_matches(other, remote_id))
        !           387:                {
        !           388:                        local_id->destroy(local_id);
        !           389:                        remote_id->destroy(remote_id);
        !           390:                        continue;
        !           391:                }
        !           392:                ike = get_ike_cfg_by_id(this, ike_cfg);
        !           393: 
        !           394: #ifdef ME
        !           395:                mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by)
        !           396:                                                                   : NULL;
        !           397:                if (p_type)
        !           398:                {
        !           399:                        peer_id = identification_create_from_encoding(p_type, p_data);
        !           400:                }
        !           401: #endif /* ME */
        !           402: 
        !           403:                if (virtual)
        !           404:                {
        !           405:                        vip = host_create_from_string(virtual, 0);
        !           406:                }
        !           407:                if (ike)
        !           408:                {
        !           409:                        peer_cfg_create_t peer = {
        !           410:                                .cert_policy = cert_policy,
        !           411:                                .unique = uniqueid,
        !           412:                                .keyingtries = keyingtries,
        !           413:                                .rekey_time = rekeytime,
        !           414:                                .reauth_time = reauthtime,
        !           415:                                .jitter_time = jitter,
        !           416:                                .over_time = overtime,
        !           417:                                .no_mobike = !mobike,
        !           418:                                .dpd = dpd_delay,
        !           419: #ifdef ME
        !           420:                                .mediation = mediation,
        !           421:                                .mediated_by = mediated_cfg ?
        !           422:                                                                        mediated_cfg->get_name(mediated_cfg) : NULL,
        !           423:                                .peer_id = peer_id,
        !           424: #endif /* ME */
        !           425:                        };
        !           426: 
        !           427:                        peer_cfg = peer_cfg_create(name, ike, &peer);
        !           428:                        if (vip)
        !           429:                        {
        !           430:                                peer_cfg->add_virtual_ip(peer_cfg, vip);
        !           431:                        }
        !           432:                        if (pool)
        !           433:                        {
        !           434:                                /* attr-sql used comma separated pools, but we now completely
        !           435:                                 * support multiple pools directly. Support old SQL configs: */
        !           436:                                enumerator = enumerator_create_token(pool, ",", " ");
        !           437:                                while (enumerator->enumerate(enumerator, &pool))
        !           438:                                {
        !           439:                                        peer_cfg->add_pool(peer_cfg, pool);
        !           440:                                }
        !           441:                                enumerator->destroy(enumerator);
        !           442:                        }
        !           443:                        auth = auth_cfg_create();
        !           444:                        auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
        !           445:                        auth->add(auth, AUTH_RULE_IDENTITY, local_id);
        !           446:                        peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
        !           447:                        auth = auth_cfg_create();
        !           448:                        auth->add(auth, AUTH_RULE_IDENTITY, remote_id);
        !           449:                        if (eap_type)
        !           450:                        {
        !           451:                                auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
        !           452:                                auth->add(auth, AUTH_RULE_EAP_TYPE, eap_type);
        !           453:                                if (eap_vendor)
        !           454:                                {
        !           455:                                        auth->add(auth, AUTH_RULE_EAP_VENDOR, eap_vendor);
        !           456:                                }
        !           457:                        }
        !           458:                        peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
        !           459:                        add_child_cfgs(this, peer_cfg, id);
        !           460:                        DESTROY_IF(mediated_cfg);
        !           461:                        return peer_cfg;
        !           462:                }
        !           463:                DESTROY_IF(ike);
        !           464:                DESTROY_IF(mediated_cfg);
        !           465:                DESTROY_IF(peer_id);
        !           466:                DESTROY_IF(local_id);
        !           467:                DESTROY_IF(remote_id);
        !           468:        }
        !           469:        return NULL;
        !           470: }
        !           471: 
        !           472: METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
        !           473:        private_sql_config_t *this, char *name)
        !           474: {
        !           475:        enumerator_t *e;
        !           476:        peer_cfg_t *peer_cfg = NULL;
        !           477: 
        !           478:        e = this->db->query(this->db,
        !           479:                        "SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
        !           480:                        "c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
        !           481:                        "c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
        !           482:                        "c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
        !           483:                        "c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
        !           484:                        "FROM peer_configs AS c "
        !           485:                        "JOIN identities AS l ON c.local_id = l.id "
        !           486:                        "JOIN identities AS r ON c.remote_id = r.id "
        !           487:                        "LEFT JOIN identities AS p ON c.peer_id = p.id "
        !           488:                        "WHERE c.ike_version = ? AND c.name = ?",
        !           489:                        DB_INT, 2, DB_TEXT, name,
        !           490:                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
        !           491:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           492:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           493:                        DB_INT, DB_TEXT, DB_TEXT,
        !           494:                        DB_INT, DB_INT, DB_INT, DB_BLOB);
        !           495:        if (e)
        !           496:        {
        !           497:                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
        !           498:                e->destroy(e);
        !           499:        }
        !           500:        return peer_cfg;
        !           501: }
        !           502: 
        !           503: typedef struct {
        !           504:        /** implements enumerator */
        !           505:        enumerator_t public;
        !           506:        /** reference to context */
        !           507:        private_sql_config_t *this;
        !           508:        /** filtering own host */
        !           509:        host_t *me;
        !           510:        /** filtering remote host */
        !           511:        host_t *other;
        !           512:        /** inner SQL enumerator */
        !           513:        enumerator_t *inner;
        !           514:        /** currently enumerated peer config */
        !           515:        ike_cfg_t *current;
        !           516: } ike_enumerator_t;
        !           517: 
        !           518: METHOD(enumerator_t, ike_enumerator_enumerate, bool,
        !           519:        ike_enumerator_t *this, va_list args)
        !           520: {
        !           521:        ike_cfg_t **cfg;
        !           522: 
        !           523:        VA_ARGS_VGET(args, cfg);
        !           524:        DESTROY_IF(this->current);
        !           525:        this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
        !           526:        if (this->current)
        !           527:        {
        !           528:                *cfg = this->current;
        !           529:                return TRUE;
        !           530:        }
        !           531:        return FALSE;
        !           532: }
        !           533: 
        !           534: METHOD(enumerator_t, ike_enumerator_destroy, void,
        !           535:        ike_enumerator_t *this)
        !           536: {
        !           537:        DESTROY_IF(this->current);
        !           538:        this->inner->destroy(this->inner);
        !           539:        free(this);
        !           540: }
        !           541: 
        !           542: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
        !           543:        private_sql_config_t *this, host_t *me, host_t *other)
        !           544: {
        !           545:        ike_enumerator_t *e;
        !           546: 
        !           547:        INIT(e,
        !           548:                .public = {
        !           549:                        .enumerate = enumerator_enumerate_default,
        !           550:                        .venumerate = _ike_enumerator_enumerate,
        !           551:                        .destroy = _ike_enumerator_destroy,
        !           552:                },
        !           553:                .this = this,
        !           554:                .me = me,
        !           555:                .other = other,
        !           556:        );
        !           557:        e->inner = this->db->query(this->db,
        !           558:                                                           "SELECT c.id, c.certreq, c.force_encap, "
        !           559:                                                           "c.local, c.remote FROM ike_configs AS c",
        !           560:                                                           DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
        !           561:        if (!e->inner)
        !           562:        {
        !           563:                free(e);
        !           564:                return NULL;
        !           565:        }
        !           566:        return &e->public;
        !           567: }
        !           568: 
        !           569: 
        !           570: typedef struct {
        !           571:        /** implements enumerator */
        !           572:        enumerator_t public;
        !           573:        /** reference to context */
        !           574:        private_sql_config_t *this;
        !           575:        /** filtering own identity */
        !           576:        identification_t *me;
        !           577:        /** filtering remote identity */
        !           578:        identification_t *other;
        !           579:        /** inner SQL enumerator */
        !           580:        enumerator_t *inner;
        !           581:        /** currently enumerated peer config */
        !           582:        peer_cfg_t *current;
        !           583: } peer_enumerator_t;
        !           584: 
        !           585: METHOD(enumerator_t, peer_enumerator_enumerate, bool,
        !           586:        peer_enumerator_t *this, va_list args)
        !           587: {
        !           588:        peer_cfg_t **cfg;
        !           589: 
        !           590:        VA_ARGS_VGET(args, cfg);
        !           591:        DESTROY_IF(this->current);
        !           592:        this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
        !           593:        if (this->current)
        !           594:        {
        !           595:                *cfg = this->current;
        !           596:                return TRUE;
        !           597:        }
        !           598:        return FALSE;
        !           599: }
        !           600: 
        !           601: METHOD(enumerator_t, peer_enumerator_destroy, void,
        !           602:        peer_enumerator_t *this)
        !           603: {
        !           604:        DESTROY_IF(this->current);
        !           605:        this->inner->destroy(this->inner);
        !           606:        free(this);
        !           607: }
        !           608: 
        !           609: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
        !           610:        private_sql_config_t *this, identification_t *me, identification_t *other)
        !           611: {
        !           612:        peer_enumerator_t *e;
        !           613: 
        !           614:        INIT(e,
        !           615:                .public = {
        !           616:                        .enumerate = enumerator_enumerate_default,
        !           617:                        .venumerate = _peer_enumerator_enumerate,
        !           618:                        .destroy = _peer_enumerator_destroy,
        !           619:                },
        !           620:                .this = this,
        !           621:                .me = me,
        !           622:                .other = other,
        !           623:        );
        !           624: 
        !           625:        /* TODO: only get configs whose IDs match exactly or contain wildcards */
        !           626:        e->inner = this->db->query(this->db,
        !           627:                        "SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
        !           628:                        "c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
        !           629:                        "c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
        !           630:                        "c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
        !           631:                        "c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
        !           632:                        "FROM peer_configs AS c "
        !           633:                        "JOIN identities AS l ON c.local_id = l.id "
        !           634:                        "JOIN identities AS r ON c.remote_id = r.id "
        !           635:                        "LEFT JOIN identities AS p ON c.peer_id = p.id "
        !           636:                        "WHERE c.ike_version = ?",
        !           637:                        DB_INT, 2,
        !           638:                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
        !           639:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           640:                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
        !           641:                        DB_INT, DB_TEXT, DB_TEXT,
        !           642:                        DB_INT, DB_INT, DB_INT, DB_BLOB);
        !           643:        if (!e->inner)
        !           644:        {
        !           645:                free(e);
        !           646:                return NULL;
        !           647:        }
        !           648:        return &e->public;
        !           649: }
        !           650: 
        !           651: METHOD(sql_config_t, destroy, void,
        !           652:        private_sql_config_t *this)
        !           653: {
        !           654:        free(this);
        !           655: }
        !           656: 
        !           657: /**
        !           658:  * Described in header.
        !           659:  */
        !           660: sql_config_t *sql_config_create(database_t *db)
        !           661: {
        !           662:        private_sql_config_t *this;
        !           663: 
        !           664:        INIT(this,
        !           665:                .public = {
        !           666:                        .backend = {
        !           667:                                .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
        !           668:                                .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
        !           669:                                .get_peer_cfg_by_name = _get_peer_cfg_by_name,
        !           670:                        },
        !           671:                        .destroy = _destroy,
        !           672:                },
        !           673:                .db = db
        !           674:        );
        !           675: 
        !           676:        return &this->public;
        !           677: }

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