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>