Annotation of embedaddon/strongswan/src/pool/pool_attributes.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2009-2010 Andreas Steffen
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #define _GNU_SOURCE
        !            17: #include <string.h>
        !            18: 
        !            19: #include <library.h>
        !            20: #include <networking/host.h>
        !            21: 
        !            22: #include "pool_attributes.h"
        !            23: #include "pool_usage.h"
        !            24: 
        !            25: /**
        !            26:  * global database handle
        !            27:  */
        !            28: extern database_t *db;
        !            29: 
        !            30: #define UNITY_NETWORK_LEN      14
        !            31: 
        !            32: ENUM(value_type_names, VALUE_HEX, VALUE_SUBNET,
        !            33:        "hex",
        !            34:        "string",
        !            35:        "addr",
        !            36:        "subnet"
        !            37: );
        !            38: 
        !            39: typedef struct attr_info_t attr_info_t;
        !            40: 
        !            41: struct attr_info_t {
        !            42:        char*                           keyword;
        !            43:        value_type_t                    value_type;
        !            44:        configuration_attribute_type_t  type;
        !            45:        configuration_attribute_type_t  type_ip6;
        !            46: };
        !            47: 
        !            48: static const attr_info_t attr_info[] = {
        !            49:        { "internal_ip4_netmask", VALUE_ADDR,   INTERNAL_IP4_NETMASK, 0 },
        !            50:        { "internal_ip6_netmask", VALUE_ADDR,   INTERNAL_IP6_NETMASK, 0 },
        !            51:        { "netmask",              VALUE_ADDR,   INTERNAL_IP4_NETMASK,
        !            52:                                                                                        INTERNAL_IP6_NETMASK    },
        !            53:        { "internal_ip4_dns",     VALUE_ADDR,   INTERNAL_IP4_DNS,     0 },
        !            54:        { "internal_ip6_dns",     VALUE_ADDR,   INTERNAL_IP6_DNS,     0 },
        !            55:        { "dns",                  VALUE_ADDR,   INTERNAL_IP4_DNS,
        !            56:                                                                                        INTERNAL_IP6_DNS        },
        !            57:        { "internal_ip4_nbns",    VALUE_ADDR,   INTERNAL_IP4_NBNS,    0 },
        !            58:        { "internal_ip6_nbns",    VALUE_ADDR,   INTERNAL_IP6_NBNS,    0 },
        !            59:        { "nbns",                 VALUE_ADDR,   INTERNAL_IP4_NBNS,
        !            60:                                                                                        INTERNAL_IP6_NBNS       },
        !            61:        { "wins",                 VALUE_ADDR,   INTERNAL_IP4_NBNS,
        !            62:                                                                                        INTERNAL_IP6_NBNS       },
        !            63:        { "internal_ip4_dhcp",    VALUE_ADDR,   INTERNAL_IP4_DHCP,    0 },
        !            64:        { "internal_ip6_dhcp",    VALUE_ADDR,   INTERNAL_IP6_DHCP,    0 },
        !            65:        { "dhcp",                 VALUE_ADDR,   INTERNAL_IP4_DHCP,
        !            66:                                                                                        INTERNAL_IP6_DHCP       },
        !            67:        { "internal_ip4_server",  VALUE_ADDR,   INTERNAL_IP4_SERVER,  0 },
        !            68:        { "internal_ip6_server",  VALUE_ADDR,   INTERNAL_IP6_SERVER,  0 },
        !            69:        { "server",               VALUE_ADDR,   INTERNAL_IP4_SERVER,
        !            70:                                                                                        INTERNAL_IP6_SERVER     },
        !            71:        { "application_version",  VALUE_STRING, APPLICATION_VERSION,  0 },
        !            72:        { "version",              VALUE_STRING, APPLICATION_VERSION,  0 },
        !            73:        { "unity_banner",         VALUE_STRING, UNITY_BANNER,         0 },
        !            74:        { "banner",               VALUE_STRING, UNITY_BANNER,         0 },
        !            75:        { "unity_def_domain",     VALUE_STRING, UNITY_DEF_DOMAIN,     0 },
        !            76:        { "unity_splitdns_name",  VALUE_STRING, UNITY_SPLITDNS_NAME,  0 },
        !            77:        { "unity_split_include",  VALUE_SUBNET, UNITY_SPLIT_INCLUDE,  0 },
        !            78:        { "unity_split_exclude",  VALUE_SUBNET, UNITY_LOCAL_LAN,      0 },
        !            79:        { "unity_local_lan",      VALUE_SUBNET, UNITY_LOCAL_LAN,      0 },
        !            80: };
        !            81: 
        !            82: /**
        !            83:  * Determine the type of the attribute and its value
        !            84:  */
        !            85: static bool parse_attributes(char *name, char *value, value_type_t *value_type,
        !            86:                                                         configuration_attribute_type_t *type,
        !            87:                                                         configuration_attribute_type_t *type_ip6,
        !            88:                                                         chunk_t *blob)
        !            89: {
        !            90:        host_t *addr = NULL, *mask = NULL;
        !            91:        chunk_t addr_chunk, mask_chunk, blob_next;
        !            92:        char *text = "", *pos_addr, *pos_mask, *pos_next, *endptr;
        !            93:        int i;
        !            94: 
        !            95:        switch (*value_type)
        !            96:        {
        !            97:                case VALUE_STRING:
        !            98:                        *blob = chunk_create(value, strlen(value));
        !            99:                        *blob = chunk_clone(*blob);
        !           100:                        break;
        !           101:                case VALUE_HEX:
        !           102:                        *blob = chunk_from_hex(chunk_create(value, strlen(value)), NULL);
        !           103:                        break;
        !           104:                case VALUE_ADDR:
        !           105:                        addr = host_create_from_string(value, 0);
        !           106:                        if (addr == NULL)
        !           107:                        {
        !           108:                                fprintf(stderr, "invalid IP address: '%s'.\n", value);
        !           109:                                return FALSE;
        !           110:                        }
        !           111:                        addr_chunk = addr->get_address(addr);
        !           112:                        *blob = chunk_clone(addr_chunk);
        !           113:                        break;
        !           114:                case VALUE_SUBNET:
        !           115:                        *blob = chunk_empty;
        !           116:                        pos_next = value;
        !           117: 
        !           118:                        do
        !           119:                        {
        !           120:                                pos_addr = pos_next;
        !           121:                                pos_next = strchr(pos_next, ',');
        !           122:                                if (pos_next)
        !           123:                                {
        !           124:                                        *pos_next = '\0';
        !           125:                                        pos_next += 1;
        !           126:                                }
        !           127:                                pos_mask = strchr(pos_addr, '/');
        !           128:                                if (pos_mask == NULL)
        !           129:                                {
        !           130:                                        fprintf(stderr, "invalid IPv4 subnet: '%s'.\n", pos_addr);
        !           131:                                        free(blob->ptr);
        !           132:                                        return FALSE;
        !           133:                                }
        !           134:                                *pos_mask = '\0';
        !           135:                                pos_mask += 1;
        !           136:                                addr = host_create_from_string(pos_addr, 0);
        !           137:                                mask = host_create_from_string(pos_mask, 0);
        !           138:                                if (addr == NULL || addr->get_family(addr) != AF_INET ||
        !           139:                                        mask == NULL || mask->get_family(addr) != AF_INET)
        !           140:                                {
        !           141:                                        fprintf(stderr, "invalid IPv4 subnet: '%s/%s'.\n",
        !           142:                                                                        pos_addr, pos_mask);
        !           143:                                        DESTROY_IF(addr);
        !           144:                                        DESTROY_IF(mask);
        !           145:                                        free(blob->ptr);
        !           146:                                        return FALSE;
        !           147:                                }
        !           148:                                addr_chunk = addr->get_address(addr);
        !           149:                                mask_chunk = mask->get_address(mask);
        !           150:                                blob_next = chunk_alloc(blob->len + UNITY_NETWORK_LEN);
        !           151:                                memcpy(blob_next.ptr, blob->ptr, blob->len);
        !           152:                                pos_addr = blob_next.ptr + blob->len;
        !           153:                                memset(pos_addr, 0x00, UNITY_NETWORK_LEN);
        !           154:                                memcpy(pos_addr,     addr_chunk.ptr, 4);
        !           155:                                memcpy(pos_addr + 4, mask_chunk.ptr, 4);
        !           156:                                addr->destroy(addr);
        !           157:                                addr = NULL;
        !           158:                                mask->destroy(mask);
        !           159:                                chunk_free(blob);
        !           160:                                *blob = blob_next;
        !           161:                        }
        !           162:                        while (pos_next);
        !           163:                        break;
        !           164:                case VALUE_NONE:
        !           165:                        *blob = chunk_empty;
        !           166:                        break;
        !           167:        }
        !           168: 
        !           169:        /* init the attribute type */
        !           170:        *type     = 0;
        !           171:        *type_ip6 = 0;
        !           172: 
        !           173:        for (i = 0; i < countof(attr_info); i++)
        !           174:        {
        !           175:                if (strcaseeq(name, attr_info[i].keyword))
        !           176:                {
        !           177:                        *type      = attr_info[i].type;
        !           178:                        *type_ip6  = attr_info[i].type_ip6;
        !           179: 
        !           180:                        if (*value_type == VALUE_NONE)
        !           181:                        {
        !           182:                                *value_type = attr_info[i].value_type;
        !           183:                                return TRUE;
        !           184:                        }
        !           185: 
        !           186:                        if (*value_type != attr_info[i].value_type &&
        !           187:                                *value_type != VALUE_HEX)
        !           188:                        {
        !           189:                                switch (attr_info[i].value_type)
        !           190:                                {
        !           191:                                        case VALUE_STRING:
        !           192:                                                text = "a string";
        !           193:                                                break;
        !           194:                                        case VALUE_HEX:
        !           195:                                                text = "a hex";
        !           196:                                                break;
        !           197:                                        case VALUE_ADDR:
        !           198:                                                text = "an IP address";
        !           199:                                                break;
        !           200:                                        case VALUE_SUBNET:
        !           201:                                                text = "a subnet";
        !           202:                                                break;
        !           203:                                        case VALUE_NONE:
        !           204:                                                text = "no";
        !           205:                                                break;
        !           206:                                }
        !           207:                                fprintf(stderr, "the %s attribute requires %s value.\n",
        !           208:                                                                 name, text);
        !           209:                                DESTROY_IF(addr);
        !           210:                                free(blob->ptr);
        !           211:                                return FALSE;
        !           212:                        }
        !           213: 
        !           214:                        if (*value_type == VALUE_ADDR)
        !           215:                        {
        !           216:                                *type = (addr->get_family(addr) == AF_INET) ?
        !           217:                                                        attr_info[i].type : attr_info[i].type_ip6;
        !           218:                                addr->destroy(addr);
        !           219:                        }
        !           220:                        else if (*value_type == VALUE_HEX)
        !           221:                        {
        !           222:                                *value_type = attr_info[i].value_type;
        !           223: 
        !           224:                                if (*value_type == VALUE_ADDR)
        !           225:                                {
        !           226:                                        if (blob->len == 16)
        !           227:                                        {
        !           228:                                                *type = attr_info[i].type_ip6;
        !           229:                                        }
        !           230:                                        else if (blob->len != 4)
        !           231:                                        {
        !           232:                                                fprintf(stderr, "the %s attribute requires "
        !           233:                                                                                "a valid IP address.\n", name);
        !           234:                                                free(blob->ptr);
        !           235:                                                return FALSE;
        !           236:                                        }
        !           237:                                }
        !           238:                        }
        !           239:                        return TRUE;
        !           240:                }
        !           241:        }
        !           242: 
        !           243:        /* clean up */
        !           244:        DESTROY_IF(addr);
        !           245: 
        !           246:        /* is the attribute type numeric? */
        !           247:        *type = strtol(name, &endptr, 10);
        !           248: 
        !           249:        if (*endptr != '\0')
        !           250:        {
        !           251:                fprintf(stderr, "the %s attribute is not recognized.\n", name);
        !           252:                free(blob->ptr);
        !           253:                return FALSE;
        !           254:        }
        !           255:        if (*type < 1 || *type > 32767)
        !           256:        {
        !           257:                fprintf(stderr, "the attribute type must lie in the range 1..32767.\n");
        !           258:                free(blob->ptr);
        !           259:                return FALSE;
        !           260:        }
        !           261:        if (*value_type == VALUE_NONE)
        !           262:        {
        !           263:                *value_type = VALUE_HEX;
        !           264:        }
        !           265:        return TRUE;
        !           266: }
        !           267: 
        !           268: /**
        !           269:  * Lookup/insert an attribute pool by name
        !           270:  */
        !           271: static u_int get_attr_pool(char *name)
        !           272: {
        !           273:        enumerator_t *e;
        !           274:        u_int row = 0;
        !           275: 
        !           276:        /* look for an existing attribute pool in the table */
        !           277:        e = db->query(db, "SELECT id FROM attribute_pools WHERE name = ?",
        !           278:                                  DB_TEXT, name, DB_UINT);
        !           279:        if (e && e->enumerate(e, &row))
        !           280:        {
        !           281:                e->destroy(e);
        !           282:                return row;
        !           283:        }
        !           284:        DESTROY_IF(e);
        !           285:        /* not found, insert new one */
        !           286:        if (db->execute(db, &row, "INSERT INTO attribute_pools (name) VALUES (?)",
        !           287:                                        DB_TEXT, name) != 1)
        !           288:        {
        !           289:                fprintf(stderr, "creating attribute pool '%s' failed.\n", name);
        !           290:                return 0;
        !           291:        }
        !           292:        return row;
        !           293: }
        !           294: 
        !           295: /**
        !           296:  * Lookup/insert an identity
        !           297:  */
        !           298: u_int get_identity(identification_t *id)
        !           299: {
        !           300:        enumerator_t *e;
        !           301:        u_int row;
        !           302: 
        !           303:        /* look for peer identity in the identities table */
        !           304:        e = db->query(db, "SELECT id FROM identities WHERE type = ? AND data = ?",
        !           305:                        DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id), DB_UINT);
        !           306:        if (e && e->enumerate(e, &row))
        !           307:        {
        !           308:                e->destroy(e);
        !           309:                return row;
        !           310:        }
        !           311:        DESTROY_IF(e);
        !           312:        /* not found, insert new one */
        !           313:        if (db->execute(db, &row, "INSERT INTO identities (type,data) VALUES (?,?)",
        !           314:                                  DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) != 1)
        !           315:        {
        !           316:                fprintf(stderr, "creating id '%Y' failed.\n", id);
        !           317:                return 0;
        !           318:        }
        !           319:        return row;
        !           320: }
        !           321: 
        !           322: /**
        !           323:  * ipsec pool --addattr <type> - add attribute entry
        !           324:  */
        !           325: void add_attr(char *name, char *pool, char *identity,
        !           326:                          char *value, value_type_t value_type)
        !           327: {
        !           328:        configuration_attribute_type_t type, type_ip6;
        !           329:        u_int pool_id = 0, identity_id = 0;
        !           330:        char id_pool_str[128] = "";
        !           331:        chunk_t blob;
        !           332:        bool success;
        !           333: 
        !           334:        if (pool)
        !           335:        {
        !           336:                pool_id = get_attr_pool(pool);
        !           337:                if (pool_id == 0)
        !           338:                {
        !           339:                        exit(EXIT_FAILURE);
        !           340:                }
        !           341: 
        !           342:                if (identity)
        !           343:                {
        !           344:                        identification_t *id;
        !           345: 
        !           346:                        id = identification_create_from_string(identity);
        !           347:                        identity_id = get_identity(id);
        !           348:                        id->destroy(id);
        !           349:                        if (identity_id == 0)
        !           350:                        {
        !           351:                                exit(EXIT_FAILURE);
        !           352:                        }
        !           353:                        snprintf(id_pool_str, sizeof(id_pool_str),
        !           354:                                         " for '%s' in pool '%s'", identity, pool);
        !           355:                }
        !           356:                else
        !           357:                {
        !           358:                        snprintf(id_pool_str, sizeof(id_pool_str), " in pool '%s'", pool);
        !           359:                }
        !           360:        }
        !           361: 
        !           362:        if (value_type == VALUE_NONE)
        !           363:        {
        !           364:                fprintf(stderr, "the value of the %s attribute is missing.\n", name);
        !           365:                usage();
        !           366:        }
        !           367:        if (!parse_attributes(name, value, &value_type, &type, &type_ip6, &blob))
        !           368:        {
        !           369:                exit(EXIT_FAILURE);
        !           370:        }
        !           371: 
        !           372:        success = db->execute(db, NULL,
        !           373:                                "INSERT INTO attributes (identity, pool, type, value) "
        !           374:                                "VALUES (?, ?, ?, ?)", DB_UINT, identity_id, DB_UINT, pool_id,
        !           375:                                DB_INT, type, DB_BLOB, blob) == 1;
        !           376:        free(blob.ptr);
        !           377: 
        !           378:        if (success)
        !           379:        {
        !           380:                printf("added %s attribute (%N)%s.\n", name,
        !           381:                           configuration_attribute_type_names, type, id_pool_str);
        !           382:        }
        !           383:        else
        !           384:        {
        !           385:                fprintf(stderr, "adding %s attribute (%N)%s failed.\n", name,
        !           386:                                                configuration_attribute_type_names, type, id_pool_str);
        !           387:        }
        !           388: }
        !           389: 
        !           390: /**
        !           391:  * ipsec pool --delattr <type> - delete attribute entry
        !           392:  */
        !           393: void del_attr(char *name, char *pool, char *identity,
        !           394:                          char *value, value_type_t value_type)
        !           395: {
        !           396:        configuration_attribute_type_t type, type_ip6, type_db;
        !           397:        u_int pool_id = 0, identity_id = 0;
        !           398:        char id_pool_str[128] = "";
        !           399:        chunk_t blob, blob_db;
        !           400:        u_int id;
        !           401:        enumerator_t *query;
        !           402:        bool found = FALSE;
        !           403: 
        !           404:        if (pool)
        !           405:        {
        !           406:                pool_id = get_attr_pool(pool);
        !           407:                if (pool_id == 0)
        !           408:                {
        !           409:                        exit(EXIT_FAILURE);
        !           410:                }
        !           411: 
        !           412:                if (identity)
        !           413:                {
        !           414:                        identification_t *id;
        !           415: 
        !           416:                        id = identification_create_from_string(identity);
        !           417:                        identity_id = get_identity(id);
        !           418:                        id->destroy(id);
        !           419:                        if (identity_id == 0)
        !           420:                        {
        !           421:                                exit(EXIT_FAILURE);
        !           422:                        }
        !           423:                        snprintf(id_pool_str, sizeof(id_pool_str),
        !           424:                                         " for '%s' in pool '%s'", identity, pool);
        !           425:                }
        !           426:                else
        !           427:                {
        !           428:                        snprintf(id_pool_str, sizeof(id_pool_str), " in pool '%s'", pool);
        !           429:                }
        !           430:        }
        !           431: 
        !           432:        if (!parse_attributes(name, value, &value_type, &type, &type_ip6, &blob))
        !           433:        {
        !           434:                exit(EXIT_FAILURE);
        !           435:        }
        !           436: 
        !           437:        if (blob.len > 0)
        !           438:        {
        !           439:                query = db->query(db,
        !           440:                                        "SELECT id, type, value FROM attributes "
        !           441:                                        "WHERE identity = ? AND pool = ? AND type = ? AND value = ?",
        !           442:                                        DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type,
        !           443:                                        DB_BLOB, blob, DB_UINT, DB_INT, DB_BLOB);
        !           444:        }
        !           445:        else if (type_ip6 == 0)
        !           446:        {
        !           447:                query = db->query(db,
        !           448:                                        "SELECT id, type, value FROM attributes "
        !           449:                                        "WHERE identity = ? AND pool = ? AND type = ?",
        !           450:                                        DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type,
        !           451:                                        DB_UINT, DB_INT, DB_BLOB);
        !           452:        }
        !           453:        else
        !           454:        {
        !           455:                query = db->query(db,
        !           456:                                        "SELECT id, type, value FROM attributes "
        !           457:                                        "WHERE identity = ? AND pool = ? AND (type = ? OR type = ?)",
        !           458:                                        DB_UINT, identity_id, DB_UINT, pool_id, DB_INT, type,
        !           459:                                        DB_INT, type_ip6, DB_UINT, DB_INT, DB_BLOB);
        !           460:        }
        !           461: 
        !           462:        if (!query)
        !           463:        {
        !           464:                fprintf(stderr, "deleting '%s' attribute (%N)%s failed.\n",
        !           465:                                name, configuration_attribute_type_names, type, id_pool_str);
        !           466:                free(blob.ptr);
        !           467:                exit(EXIT_FAILURE);
        !           468:        }
        !           469: 
        !           470:        while (query->enumerate(query, &id, &type_db, &blob_db))
        !           471:        {
        !           472:                host_t *server = NULL;
        !           473: 
        !           474:                found = TRUE;
        !           475: 
        !           476:                if (value_type == VALUE_ADDR)
        !           477:                {
        !           478:                        int family = (type_db == type_ip6) ? AF_INET6 : AF_INET;
        !           479: 
        !           480:                        server = host_create_from_chunk(family, blob_db, 0);
        !           481:                }
        !           482: 
        !           483:                if (db->execute(db, NULL,
        !           484:                                        "DELETE FROM attributes WHERE id = ?",
        !           485:                                         DB_UINT, id) != 1)
        !           486:                {
        !           487:                        if (server)
        !           488:                        {
        !           489:                                fprintf(stderr, "deleting %s server %H%s failed\n",
        !           490:                                                name, server, id_pool_str);
        !           491:                                server->destroy(server);
        !           492:                        }
        !           493:                        else if (value_type == VALUE_STRING)
        !           494:                        {
        !           495:                                fprintf(stderr, "deleting %s attribute (%N) with value '%.*s'%s failed.\n",
        !           496:                                                                name, configuration_attribute_type_names, type,
        !           497:                                                                (int)blob_db.len, blob_db.ptr, id_pool_str);
        !           498:                        }
        !           499: 
        !           500:                        else
        !           501:                        {
        !           502:                                fprintf(stderr, "deleting %s attribute (%N) with value %#B%s failed.\n",
        !           503:                                                                name, configuration_attribute_type_names, type,
        !           504:                                                                &blob_db, id_pool_str);
        !           505:                        }
        !           506:                        query->destroy(query);
        !           507:                        free(blob.ptr);
        !           508:                        exit(EXIT_FAILURE);
        !           509:                }
        !           510:                if (server)
        !           511:                {
        !           512:                        printf("deleted %s server %H%s\n", name, server, id_pool_str);
        !           513:                        server->destroy(server);
        !           514:                }
        !           515:                else if (value_type == VALUE_STRING)
        !           516:                {
        !           517:                        printf("deleted %s attribute (%N) with value '%.*s'%s.\n",
        !           518:                                   name, configuration_attribute_type_names, type,
        !           519:                                   (int)blob_db.len, blob_db.ptr, id_pool_str);
        !           520:                }
        !           521:                else
        !           522:                {
        !           523:                        printf("deleted %s attribute (%N) with value %#B%s.\n",
        !           524:                                   name, configuration_attribute_type_names, type,
        !           525:                                   &blob_db, id_pool_str);
        !           526:                }
        !           527:        }
        !           528:        query->destroy(query);
        !           529: 
        !           530:        if (!found)
        !           531:        {
        !           532:                if (blob.len == 0)
        !           533:                {
        !           534:                        if (type_ip6 == 0)
        !           535:                        {
        !           536:                                fprintf(stderr, "no %s attribute (%N) was found%s.\n", name,
        !           537:                                                configuration_attribute_type_names, type, id_pool_str);
        !           538:                        }
        !           539:                        else
        !           540:                        {
        !           541:                                fprintf(stderr, "no %s attribute%s was found.\n",
        !           542:                                                name, id_pool_str);
        !           543:                        }
        !           544:                }
        !           545:                else
        !           546:                {
        !           547:                        if (value_type == VALUE_ADDR)
        !           548:                        {
        !           549:                                host_t *server = host_create_from_chunk(AF_UNSPEC, blob, 0);
        !           550: 
        !           551:                                fprintf(stderr, "the %s server %H%s was not found.\n", name,
        !           552:                                                                 server, id_pool_str);
        !           553:                                server->destroy(server);
        !           554:                        }
        !           555:                        else
        !           556:                        {
        !           557:                                fprintf(stderr, "the %s attribute (%N) with value '%.*s'%s "
        !           558:                                                                "was not found.\n", name,
        !           559:                                                                 configuration_attribute_type_names, type,
        !           560:                                                                 (int)blob.len, blob.ptr, id_pool_str);
        !           561:                        }
        !           562:                }
        !           563:        }
        !           564:        free(blob.ptr);
        !           565: }
        !           566: 
        !           567: /**
        !           568:  * ipsec pool --statusattr - show all attribute entries
        !           569:  */
        !           570: void status_attr(bool hexout)
        !           571: {
        !           572:        configuration_attribute_type_t type;
        !           573:        value_type_t value_type;
        !           574:        chunk_t value, addr_chunk, mask_chunk, identity_chunk;
        !           575:        identification_t *identity;
        !           576:        enumerator_t *enumerator;
        !           577:        host_t *addr, *mask;
        !           578:        char type_name[30];
        !           579:        bool first = TRUE;
        !           580:        int i, identity_type;
        !           581:        char *pool_name;
        !           582: 
        !           583:        /* enumerate over all attributes */
        !           584:        enumerator = db->query(db,
        !           585:                                        "SELECT attributes.type, attribute_pools.name, "
        !           586:                                        "identities.type, identities.data, attributes.value "
        !           587:                                        "FROM attributes "
        !           588:                                        "LEFT OUTER JOIN identities "
        !           589:                                        "ON attributes.identity = identities.id "
        !           590:                                        "LEFT OUTER JOIN attribute_pools "
        !           591:                                        "ON attributes.pool = attribute_pools.id "
        !           592:                                        "ORDER BY attributes.type, attribute_pools.name, "
        !           593:                                        "identities.type, identities.data, attributes.value",
        !           594:                                        DB_INT, DB_TEXT, DB_INT, DB_BLOB, DB_BLOB);
        !           595:        if (enumerator)
        !           596:        {
        !           597:                while (enumerator->enumerate(enumerator, &type,&pool_name,
        !           598:                                                                         &identity_type, &identity_chunk, &value))
        !           599:                {
        !           600:                        if (first)
        !           601:                        {
        !           602:                                printf(" type  description           pool       "
        !           603:                                           " identity              value\n");
        !           604:                                first = FALSE;
        !           605:                        }
        !           606:                        snprintf(type_name, sizeof(type_name), "%N",
        !           607:                                         configuration_attribute_type_names, type);
        !           608:                        if (type_name[0] == '(')
        !           609:                        {
        !           610:                                type_name[0] = '\0';
        !           611:                        }
        !           612:                        printf("%5d  %-20s ",type, type_name);
        !           613: 
        !           614:                        printf(" %-10s ", (pool_name ? pool_name : ""));
        !           615: 
        !           616:                        if (identity_type)
        !           617:                        {
        !           618:                                identity = identification_create_from_encoding(identity_type, identity_chunk);
        !           619:                                printf(" %-20.20Y ", identity);
        !           620:                                identity->destroy(identity);
        !           621:                        }
        !           622:                        else
        !           623:                        {
        !           624:                                printf("                      ");
        !           625:                        }
        !           626: 
        !           627:                        value_type = VALUE_HEX;
        !           628:                        if (!hexout)
        !           629:                        {
        !           630:                                for (i = 0; i < countof(attr_info); i++)
        !           631:                                {
        !           632:                                        if (type == attr_info[i].type)
        !           633:                                        {
        !           634:                                                value_type = attr_info[i].value_type;
        !           635:                                                break;
        !           636:                                        }
        !           637:                                }
        !           638:                        }
        !           639:                        switch (value_type)
        !           640:                        {
        !           641:                                case VALUE_ADDR:
        !           642:                                        addr = host_create_from_chunk(AF_UNSPEC, value, 0);
        !           643:                                        if (addr)
        !           644:                                        {
        !           645:                                                printf(" %H\n", addr);
        !           646:                                                addr->destroy(addr);
        !           647:                                        }
        !           648:                                        else
        !           649:                                        {
        !           650:                                                /* value cannot be represented as an IP address */
        !           651:                                                printf(" %#B\n", &value);
        !           652:                                        }
        !           653:                                        break;
        !           654:                                case VALUE_SUBNET:
        !           655:                                        if (value.len % UNITY_NETWORK_LEN == 0)
        !           656:                                        {
        !           657:                                                for (i = 0; i < value.len / UNITY_NETWORK_LEN; i++)
        !           658:                                                {
        !           659:                                                        addr_chunk = chunk_create(value.ptr + i*UNITY_NETWORK_LEN, 4);
        !           660:                                                        addr = host_create_from_chunk(AF_INET, addr_chunk, 0);
        !           661:                                                        mask_chunk = chunk_create(addr_chunk.ptr + 4, 4);
        !           662:                                                        mask = host_create_from_chunk(AF_INET, mask_chunk, 0);
        !           663:                                                        printf("%s%H/%H", (i > 0) ? "," : " ", addr, mask);
        !           664:                                                        addr->destroy(addr);
        !           665:                                                        mask->destroy(mask);
        !           666:                                                }
        !           667:                                                printf("\n");
        !           668:                                        }
        !           669:                                        else
        !           670:                                        {
        !           671:                                                /* value cannot be represented as a list of subnets */
        !           672:                                                printf(" %#B\n", &value);
        !           673:                                        }
        !           674:                                        break;
        !           675:                                case VALUE_STRING:
        !           676:                                        printf("\"%.*s\"\n", (int)value.len, value.ptr);
        !           677:                                        break;
        !           678:                                case VALUE_HEX:
        !           679:                                default:
        !           680:                                        printf(" %#B\n", &value);
        !           681:                        }
        !           682:                }
        !           683:                enumerator->destroy(enumerator);
        !           684:        }
        !           685: }
        !           686: 
        !           687: /**
        !           688:  * ipsec pool --showattr - show all supported attribute keywords
        !           689:  */
        !           690: void show_attr(void)
        !           691: {
        !           692:        int i;
        !           693: 
        !           694:        for (i = 0; i < countof(attr_info); i++)
        !           695:        {
        !           696:                char value_name[10];
        !           697: 
        !           698: 
        !           699:                snprintf(value_name, sizeof(value_name), "%N",
        !           700:                        value_type_names, attr_info[i].value_type);
        !           701: 
        !           702:                printf("%-20s  --%-6s  (%N",
        !           703:                                attr_info[i].keyword, value_name,
        !           704:                                configuration_attribute_type_names, attr_info[i].type);
        !           705: 
        !           706:                if (attr_info[i].type_ip6)
        !           707:                {
        !           708:                        printf(", %N)\n",
        !           709:                                configuration_attribute_type_names, attr_info[i].type_ip6);
        !           710:                }
        !           711:                else
        !           712:                {
        !           713:                        printf(")\n");
        !           714:                }
        !           715:        }
        !           716: }

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