Annotation of embedaddon/strongswan/src/starter/args.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2014 Tobias Brunner
                      3:  * Copyright (C) 2006 Andreas Steffen
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include <stddef.h>
                     18: #include <stdlib.h>
                     19: #include <string.h>
                     20: 
                     21: #include <library.h>
                     22: #include <utils/debug.h>
                     23: 
                     24: #include "confread.h"
                     25: #include "args.h"
                     26: 
                     27: /* argument types */
                     28: 
                     29: typedef enum {
                     30:        ARG_NONE,
                     31:        ARG_ENUM,
                     32:        ARG_UINT,
                     33:        ARG_TIME,
                     34:        ARG_ULNG,
                     35:        ARG_ULLI,
                     36:        ARG_UBIN,
                     37:        ARG_PCNT,
                     38:        ARG_STR,
                     39:        ARG_MISC
                     40: } arg_t;
                     41: 
                     42: /* various keyword lists */
                     43: 
                     44: static const char *LST_bool[] = {
                     45:        "no",
                     46:        "yes",
                     47:         NULL
                     48: };
                     49: 
                     50: static const char *LST_sendcert[] = {
                     51:        "always",
                     52:        "ifasked",
                     53:        "never",
                     54:        "yes",
                     55:        "no",
                     56:         NULL
                     57: };
                     58: 
                     59: static const char *LST_unique[] = {
                     60:        "no",
                     61:        "yes",
                     62:        "replace",
                     63:        "keep",
                     64:        "never",
                     65:         NULL
                     66: };
                     67: 
                     68: static const char *LST_strict[] = {
                     69:        "no",
                     70:        "yes",
                     71:        "ifuri",
                     72:         NULL
                     73: };
                     74: static const char *LST_dpd_action[] = {
                     75:        "none",
                     76:        "clear",
                     77:        "hold",
                     78:        "restart",
                     79:         NULL
                     80: };
                     81: 
                     82: static const char *LST_startup[] = {
                     83:        "ignore",
                     84:        "add",
                     85:        "route",
                     86:        "start",
                     87:         NULL
                     88: };
                     89: 
                     90: static const char *LST_keyexchange[] = {
                     91:        "ike",
                     92:        "ikev1",
                     93:        "ikev2",
                     94:         NULL
                     95: };
                     96: 
                     97: static const char *LST_authby[] = {
                     98:        "psk",
                     99:        "secret",
                    100:        "pubkey",
                    101:        "rsa",
                    102:        "rsasig",
                    103:        "ecdsa",
                    104:        "ecdsasig",
                    105:        "xauthpsk",
                    106:        "xauthrsasig",
                    107:        "never",
                    108:         NULL
                    109: };
                    110: 
                    111: static const char *LST_fragmentation[] = {
                    112:        "no",
                    113:        "accept",
                    114:        "yes",
                    115:        "force",
                    116:         NULL
                    117: };
                    118: 
                    119: typedef struct {
                    120:        arg_t       type;
                    121:        size_t      offset;
                    122:        const char  **list;
                    123: } token_info_t;
                    124: 
                    125: static const token_info_t token_info[] =
                    126: {
                    127:        /* config setup keywords */
                    128:        { ARG_STR,  offsetof(starter_config_t, setup.charondebug),  NULL               },
                    129:        { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_unique            },
                    130:        { ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool              },
                    131:        { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_strict      },
                    132:        { ARG_MISC, 0, NULL  /* KW_PKCS11_DEPRECATED */                                },
                    133:        { ARG_MISC, 0, NULL  /* KW_SETUP_DEPRECATED */                                 },
                    134: 
                    135:        /* conn section keywords */
                    136:        { ARG_STR,  offsetof(starter_conn_t, name), NULL                               },
                    137:        { ARG_ENUM, offsetof(starter_conn_t, startup), LST_startup                     },
                    138:        { ARG_ENUM, offsetof(starter_conn_t, keyexchange), LST_keyexchange             },
                    139:        { ARG_MISC, 0, NULL  /* KW_TYPE */                                             },
                    140:        { ARG_MISC, 0, NULL  /* KW_COMPRESS */                                         },
                    141:        { ARG_ENUM, offsetof(starter_conn_t, install_policy), LST_bool                 },
                    142:        { ARG_ENUM, offsetof(starter_conn_t, aggressive), LST_bool                     },
                    143:        { ARG_STR,  offsetof(starter_conn_t, authby), LST_authby                       },
                    144:        { ARG_STR,  offsetof(starter_conn_t, eap_identity), NULL                       },
                    145:        { ARG_STR,  offsetof(starter_conn_t, aaa_identity), NULL                       },
                    146:        { ARG_MISC, 0, NULL  /* KW_MOBIKE */                                           },
                    147:        { ARG_MISC, 0, NULL  /* KW_FORCEENCAPS */                                      },
                    148:        { ARG_ENUM, offsetof(starter_conn_t, fragmentation), LST_fragmentation         },
                    149:        { ARG_UBIN, offsetof(starter_conn_t, ikedscp), NULL                            },
                    150:        { ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL                },
                    151:        { ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL              },
                    152:        { ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL                    },
                    153:        { ARG_ULLI, offsetof(starter_conn_t, sa_ipsec_life_bytes), NULL                },
                    154:        { ARG_ULLI, offsetof(starter_conn_t, sa_ipsec_margin_bytes), NULL              },
                    155:        { ARG_ULLI, offsetof(starter_conn_t, sa_ipsec_life_packets), NULL              },
                    156:        { ARG_ULLI, offsetof(starter_conn_t, sa_ipsec_margin_packets), NULL            },
                    157:        { ARG_MISC, 0, NULL  /* KW_KEYINGTRIES */                                      },
                    158:        { ARG_PCNT, offsetof(starter_conn_t, sa_rekey_fuzz), NULL                      },
                    159:        { ARG_MISC, 0, NULL  /* KW_REKEY */                                            },
                    160:        { ARG_MISC, 0, NULL  /* KW_REAUTH */                                           },
                    161:        { ARG_STR,  offsetof(starter_conn_t, ike), NULL                                },
                    162:        { ARG_STR,  offsetof(starter_conn_t, esp), NULL                                },
                    163:        { ARG_STR,  offsetof(starter_conn_t, ah), NULL                                 },
                    164:        { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL                          },
                    165:        { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL                        },
                    166:        { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action               },
                    167:        { ARG_ENUM, offsetof(starter_conn_t, close_action), LST_dpd_action             },
                    168:        { ARG_ENUM, offsetof(starter_conn_t, sha256_96), LST_bool                      },
                    169:        { ARG_TIME, offsetof(starter_conn_t, inactivity), NULL                         },
                    170:        { ARG_MISC, 0, NULL  /* KW_MODECONFIG */                                       },
                    171:        { ARG_MISC, 0, NULL  /* KW_XAUTH */                                            },
                    172:        { ARG_STR,  offsetof(starter_conn_t, xauth_identity), NULL                     },
                    173:        { ARG_ENUM, offsetof(starter_conn_t, me_mediation), LST_bool                   },
                    174:        { ARG_STR,  offsetof(starter_conn_t, me_mediated_by), NULL                     },
                    175:        { ARG_STR,  offsetof(starter_conn_t, me_peerid), NULL                          },
                    176:        { ARG_UINT, offsetof(starter_conn_t, reqid), NULL                              },
                    177:        { ARG_UINT, offsetof(starter_conn_t, replay_window), NULL                      },
                    178:        { ARG_MISC, 0, NULL  /* KW_MARK */                                             },
                    179:        { ARG_MISC, 0, NULL  /* KW_MARK_IN */                                          },
                    180:        { ARG_MISC, 0, NULL  /* KW_MARK_OUT */                                         },
                    181:        { ARG_MISC, 0, NULL  /* KW_TFC */                                              },
                    182:        { ARG_MISC, 0, NULL  /* KW_PFS_DEPRECATED */                                   },
                    183:        { ARG_MISC, 0, NULL  /* KW_CONN_DEPRECATED */                                  },
                    184: 
                    185:        /* ca section keywords */
                    186:        { ARG_STR,  offsetof(starter_ca_t, name), NULL                                 },
                    187:        { ARG_ENUM, offsetof(starter_ca_t, startup), LST_startup                       },
                    188:        { ARG_STR,  offsetof(starter_ca_t, cacert), NULL                               },
                    189:        { ARG_STR,  offsetof(starter_ca_t, crluri), NULL                               },
                    190:        { ARG_STR,  offsetof(starter_ca_t, crluri2), NULL                              },
                    191:        { ARG_STR,  offsetof(starter_ca_t, ocspuri), NULL                              },
                    192:        { ARG_STR,  offsetof(starter_ca_t, ocspuri2), NULL                             },
                    193:        { ARG_STR,  offsetof(starter_ca_t, certuribase), NULL                          },
                    194:        { ARG_MISC, 0, NULL  /* KW_CA_DEPRECATED */                                    },
                    195: 
                    196:        /* end keywords */
                    197:        { ARG_STR,  offsetof(starter_end_t, host), NULL                                },
                    198:        { ARG_UINT, offsetof(starter_end_t, ikeport), NULL                             },
                    199:        { ARG_STR,  offsetof(starter_end_t, subnet), NULL                              },
                    200:        { ARG_MISC, 0, NULL  /* KW_PROTOPORT */                                        },
                    201:        { ARG_STR,  offsetof(starter_end_t, sourceip), NULL                            },
                    202:        { ARG_STR,  offsetof(starter_end_t, dns), NULL                                 },
                    203:        { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool                        },
                    204:        { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool                      },
                    205:        { ARG_ENUM, offsetof(starter_end_t, allow_any), LST_bool                       },
                    206:        { ARG_STR,  offsetof(starter_end_t, updown), NULL                              },
                    207:        { ARG_STR,  offsetof(starter_end_t, auth), NULL                                },
                    208:        { ARG_STR,  offsetof(starter_end_t, auth2), NULL                               },
                    209:        { ARG_STR,  offsetof(starter_end_t, id), NULL                                  },
                    210:        { ARG_STR,  offsetof(starter_end_t, id2), NULL                                 },
                    211:        { ARG_STR,  offsetof(starter_end_t, rsakey), NULL                              },
                    212:        { ARG_STR,  offsetof(starter_end_t, cert), NULL                                },
                    213:        { ARG_STR,  offsetof(starter_end_t, cert2), NULL                               },
                    214:        { ARG_STR,  offsetof(starter_end_t, cert_policy), NULL                         },
                    215:        { ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert                    },
                    216:        { ARG_STR,  offsetof(starter_end_t, ca), NULL                                  },
                    217:        { ARG_STR,  offsetof(starter_end_t, ca2), NULL                                 },
                    218:        { ARG_STR,  offsetof(starter_end_t, groups), NULL                              },
                    219:        { ARG_STR,  offsetof(starter_end_t, groups2), NULL                             },
                    220:        { ARG_MISC, 0, NULL  /* KW_END_DEPRECATED */                                   },
                    221: };
                    222: 
                    223: /*
                    224:  * assigns an argument value to a struct field
                    225:  */
                    226: bool assign_arg(kw_token_t token, kw_token_t first, char *key, char *value,
                    227:                                void *base, bool *assigned)
                    228: {
                    229:        char *p = (char*)base + token_info[token].offset;
                    230:        const char **list = token_info[token].list;
                    231:        int index = -1;  /* used for enumeration arguments */
                    232: 
                    233:        *assigned = FALSE;
                    234: 
                    235:        DBG3(DBG_APP, "  %s=%s", key, value);
                    236: 
                    237:        /* is there a keyword list? */
                    238:        if (list != NULL)
                    239:        {
                    240:                bool match = FALSE;
                    241: 
                    242:                while (*list != NULL && !match)
                    243:                {
                    244:                        index++;
                    245:                        match = streq(value, *list++);
                    246:                }
                    247:                if (!match)
                    248:                {
                    249:                        DBG1(DBG_APP, "# bad value: %s=%s", key, value);
                    250:                        return FALSE;
                    251:                }
                    252:        }
                    253: 
                    254:        switch (token_info[token].type)
                    255:        {
                    256:                case ARG_NONE:
                    257:                        DBG1(DBG_APP, "# option '%s' not supported yet", key);
                    258:                        return FALSE;
                    259:                case ARG_ENUM:
                    260:                {
                    261:                        if (index < 0)
                    262:                        {
                    263:                                DBG1(DBG_APP, "# bad enumeration value: %s=%s (%d)",
                    264:                                         key, value, index);
                    265:                                return FALSE;
                    266:                        }
                    267: 
                    268:                        if (token_info[token].list == LST_bool)
                    269:                        {
                    270:                                bool *b = (bool *)p;
                    271:                                *b = (index > 0);
                    272:                        }
                    273:                        else
                    274:                        {       /* FIXME: this is not entirely correct as the args are enums */
                    275:                                int *i = (int *)p;
                    276:                                *i = index;
                    277:                        }
                    278:                        break;
                    279:                }
                    280:                case ARG_UINT:
                    281:                {
                    282:                        char *endptr;
                    283:                        u_int *u = (u_int *)p;
                    284: 
                    285:                        *u = strtoul(value, &endptr, 10);
                    286: 
                    287:                        if (*endptr != '\0')
                    288:                        {
                    289:                                DBG1(DBG_APP, "# bad integer value: %s=%s", key, value);
                    290:                                return FALSE;
                    291:                        }
                    292:                        break;
                    293:                }
                    294:                case ARG_ULNG:
                    295:                case ARG_PCNT:
                    296:                {
                    297:                        char *endptr;
                    298:                        unsigned long *l = (unsigned long *)p;
                    299: 
                    300:                        *l = strtoul(value, &endptr, 10);
                    301: 
                    302:                        if (token_info[token].type == ARG_ULNG)
                    303:                        {
                    304:                                if (*endptr != '\0')
                    305:                                {
                    306:                                        DBG1(DBG_APP, "# bad integer value: %s=%s", key, value);
                    307:                                        return FALSE;
                    308:                                }
                    309:                        }
                    310:                        else
                    311:                        {
                    312:                                if ((*endptr != '%') || (endptr[1] != '\0') || endptr == value)
                    313:                                {
                    314:                                        DBG1(DBG_APP, "# bad percent value: %s=%s", key, value);
                    315:                                        return FALSE;
                    316:                                }
                    317:                        }
                    318:                        break;
                    319:                }
                    320:                case ARG_ULLI:
                    321:                {
                    322:                        char *endptr;
                    323:                        unsigned long long *ll = (unsigned long long *)p;
                    324: 
                    325:                        *ll = strtoull(value, &endptr, 10);
                    326: 
                    327:                        if (*endptr != '\0')
                    328:                        {
                    329:                                DBG1(DBG_APP, "# bad integer value: %s=%s", key, value);
                    330:                                return FALSE;
                    331:                        }
                    332:                        break;
                    333:                }
                    334:                case ARG_UBIN:
                    335:                {
                    336:                        char *endptr;
                    337:                        u_int *u = (u_int *)p;
                    338: 
                    339:                        *u = strtoul(value, &endptr, 2);
                    340: 
                    341:                        if (*endptr != '\0')
                    342:                        {
                    343:                                DBG1(DBG_APP, "# bad binary value: %s=%s", key, value);
                    344:                                return FALSE;
                    345:                        }
                    346:                        break;
                    347:                }
                    348:                case ARG_TIME:
                    349:                {
                    350:                        char *endptr;
                    351:                        time_t *t = (time_t *)p;
                    352: 
                    353:                        *t = strtoul(value, &endptr, 10);
                    354: 
                    355:                        /* time in seconds? */
                    356:                        if (*endptr == '\0' || (*endptr == 's' && endptr[1] == '\0'))
                    357:                        {
                    358:                                break;
                    359:                        }
                    360:                        if (endptr[1] == '\0')
                    361:                        {
                    362:                                if (*endptr == 'm')  /* time in minutes? */
                    363:                                {
                    364:                                        *t *= 60;
                    365:                                        break;
                    366:                                }
                    367:                                if (*endptr == 'h')  /* time in hours? */
                    368:                                {
                    369:                                        *t *= 3600;
                    370:                                        break;
                    371:                                }
                    372:                                if (*endptr == 'd')  /* time in days? */
                    373:                                {
                    374:                                        *t *= 3600*24;
                    375:                                        break;
                    376:                                }
                    377:                        }
                    378:                        DBG1(DBG_APP, "# bad duration value: %s=%s", key, value);
                    379:                        return FALSE;
                    380:                }
                    381:                case ARG_STR:
                    382:                {
                    383:                        char **cp = (char **)p;
                    384: 
                    385:                        /* free any existing string */
                    386:                        free(*cp);
                    387:                        /* assign the new string */
                    388:                        *cp = strdupnull(value);
                    389:                        break;
                    390:                }
                    391:                default:
                    392:                        return TRUE;
                    393:        }
                    394: 
                    395:        *assigned = TRUE;
                    396:        return TRUE;
                    397: }
                    398: 
                    399: /*
                    400:  *  frees all dynamically allocated arguments in a struct
                    401:  */
                    402: void free_args(kw_token_t first, kw_token_t last, void *base)
                    403: {
                    404:        kw_token_t token;
                    405: 
                    406:        for (token = first; token <= last; token++)
                    407:        {
                    408:                char *p = (char*)base + token_info[token].offset;
                    409: 
                    410:                switch (token_info[token].type)
                    411:                {
                    412:                        case ARG_STR:
                    413:                        {
                    414:                                char **cp = (char **)p;
                    415: 
                    416:                                free(*cp);
                    417:                                *cp = NULL;
                    418:                                break;
                    419:                        }
                    420:                        default:
                    421:                                break;
                    422:                }
                    423:        }
                    424: }
                    425: 
                    426: /*
                    427:  *  compare all arguments in a struct
                    428:  */
                    429: bool cmp_args(kw_token_t first, kw_token_t last, void *base1, void *base2)
                    430: {
                    431:        kw_token_t token;
                    432: 
                    433:        for (token = first; token <= last; token++)
                    434:        {
                    435:                char *p1 = (char*)base1 + token_info[token].offset;
                    436:                char *p2 = (char*)base2 + token_info[token].offset;
                    437: 
                    438:                switch (token_info[token].type)
                    439:                {
                    440:                        case ARG_ENUM:
                    441:                        {
                    442:                                if (token_info[token].list == LST_bool)
                    443:                                {
                    444:                                        bool *b1 = (bool *)p1;
                    445:                                        bool *b2 = (bool *)p2;
                    446: 
                    447:                                        if (*b1 != *b2)
                    448:                                        {
                    449:                                                return FALSE;
                    450:                                        }
                    451:                                }
                    452:                                else
                    453:                                {
                    454:                                        int *i1 = (int *)p1;
                    455:                                        int *i2 = (int *)p2;
                    456: 
                    457:                                        if (*i1 != *i2)
                    458:                                        {
                    459:                                                return FALSE;
                    460:                                        }
                    461:                                }
                    462:                                break;
                    463:                        }
                    464:                        case ARG_UINT:
                    465:                        {
                    466:                                u_int *u1 = (u_int *)p1;
                    467:                                u_int *u2 = (u_int *)p2;
                    468: 
                    469:                                if (*u1 != *u2)
                    470:                                {
                    471:                                        return FALSE;
                    472:                                }
                    473:                                break;
                    474:                        }
                    475:                        case ARG_ULNG:
                    476:                        case ARG_PCNT:
                    477:                        {
                    478:                                unsigned long *l1 = (unsigned long *)p1;
                    479:                                unsigned long *l2 = (unsigned long *)p2;
                    480: 
                    481:                                if (*l1 != *l2)
                    482:                                {
                    483:                                        return FALSE;
                    484:                                }
                    485:                                break;
                    486:                        }
                    487:                        case ARG_ULLI:
                    488:                        {
                    489:                                unsigned long long *ll1 = (unsigned long long *)p1;
                    490:                                unsigned long long *ll2 = (unsigned long long *)p2;
                    491: 
                    492:                                if (*ll1 != *ll2)
                    493:                                {
                    494:                                        return FALSE;
                    495:                                }
                    496:                                break;
                    497:                        }
                    498:                        case ARG_TIME:
                    499:                        {
                    500:                                time_t *t1 = (time_t *)p1;
                    501:                                time_t *t2 = (time_t *)p2;
                    502: 
                    503:                                if (*t1 != *t2)
                    504:                                {
                    505:                                        return FALSE;
                    506:                                }
                    507:                                break;
                    508:                        }
                    509:                        case ARG_STR:
                    510:                        {
                    511:                                char **cp1 = (char **)p1;
                    512:                                char **cp2 = (char **)p2;
                    513: 
                    514:                                if (*cp1 == NULL && *cp2 == NULL)
                    515:                                {
                    516:                                        break;
                    517:                                }
                    518:                                if (*cp1 == NULL || *cp2 == NULL || strcmp(*cp1, *cp2) != 0)
                    519:                                {
                    520:                                        return FALSE;
                    521:                                }
                    522:                                break;
                    523:                        }
                    524:                        default:
                    525:                                break;
                    526:                }
                    527:        }
                    528:        return TRUE;
                    529: }

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