Annotation of embedaddon/strongswan/src/pool/pool_attributes.c, revision 1.1.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>