Annotation of embedaddon/strongswan/src/libcharon/plugins/sql/sql_config.c, revision 1.1.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>