Annotation of embedaddon/strongswan/src/starter/args.c, revision 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>