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>