3531bf77cee1daeb90bf76a55fdaf272b3ac0521
1 /* automatic handling of confread struct arguments
2 * Copyright (C) 2006 Andreas Steffen
3 * Hochschule fuer Technik Rapperswil, Switzerland
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 #include "../pluto/constants.h"
24 #include "../pluto/defs.h"
45 /* various keyword lists */
47 static const char *LST_bool
[] = {
53 static const char *LST_sendcert
[] = {
62 static const char *LST_unique
[] = {
70 static const char *LST_strict
[] = {
76 static const char *LST_dpd_action
[] = {
84 static const char *LST_startup
[] = {
92 static const char *LST_packetdefault
[] = {
99 static const char *LST_keyexchange
[] = {
106 static const char *LST_pfsgroup
[] = {
122 static const char *LST_plutodebug
[] = {
141 static const char *LST_klipsdebug
[] = {
158 static const char *LST_authby
[] = {
178 static const token_info_t token_info
[] =
180 /* config setup keywords */
181 { ARG_LST
, offsetof(starter_config_t
, setup
.interfaces
), NULL
},
182 { ARG_STR
, offsetof(starter_config_t
, setup
.dumpdir
), NULL
},
183 { ARG_ENUM
, offsetof(starter_config_t
, setup
.charonstart
), LST_bool
},
184 { ARG_ENUM
, offsetof(starter_config_t
, setup
.plutostart
), LST_bool
},
186 /* pluto/charon keywords */
187 { ARG_LST
, offsetof(starter_config_t
, setup
.plutodebug
), LST_plutodebug
},
188 { ARG_STR
, offsetof(starter_config_t
, setup
.charondebug
), NULL
},
189 { ARG_STR
, offsetof(starter_config_t
, setup
.prepluto
), NULL
},
190 { ARG_STR
, offsetof(starter_config_t
, setup
.postpluto
), NULL
},
191 { ARG_STR
, offsetof(starter_config_t
, setup
.plutostderrlog
), NULL
},
192 { ARG_ENUM
, offsetof(starter_config_t
, setup
.uniqueids
), LST_unique
},
193 { ARG_UINT
, offsetof(starter_config_t
, setup
.overridemtu
), NULL
},
194 { ARG_TIME
, offsetof(starter_config_t
, setup
.crlcheckinterval
), NULL
},
195 { ARG_ENUM
, offsetof(starter_config_t
, setup
.cachecrls
), LST_bool
},
196 { ARG_ENUM
, offsetof(starter_config_t
, setup
.strictcrlpolicy
), LST_strict
},
197 { ARG_ENUM
, offsetof(starter_config_t
, setup
.nocrsend
), LST_bool
},
198 { ARG_ENUM
, offsetof(starter_config_t
, setup
.nat_traversal
), LST_bool
},
199 { ARG_TIME
, offsetof(starter_config_t
, setup
.keep_alive
), NULL
},
200 { ARG_ENUM
, offsetof(starter_config_t
, setup
.force_keepalive
), LST_bool
},
201 { ARG_STR
, offsetof(starter_config_t
, setup
.virtual_private
), NULL
},
202 { ARG_STR
, offsetof(starter_config_t
, setup
.pkcs11module
), NULL
},
203 { ARG_STR
, offsetof(starter_config_t
, setup
.pkcs11initargs
), NULL
},
204 { ARG_ENUM
, offsetof(starter_config_t
, setup
.pkcs11keepstate
), LST_bool
},
205 { ARG_ENUM
, offsetof(starter_config_t
, setup
.pkcs11proxy
), LST_bool
},
208 { ARG_LST
, offsetof(starter_config_t
, setup
.klipsdebug
), LST_klipsdebug
},
209 { ARG_ENUM
, offsetof(starter_config_t
, setup
.fragicmp
), LST_bool
},
210 { ARG_STR
, offsetof(starter_config_t
, setup
.packetdefault
), LST_packetdefault
},
211 { ARG_ENUM
, offsetof(starter_config_t
, setup
.hidetos
), LST_bool
},
213 /* conn section keywords */
214 { ARG_STR
, offsetof(starter_conn_t
, name
), NULL
},
215 { ARG_ENUM
, offsetof(starter_conn_t
, startup
), LST_startup
},
216 { ARG_ENUM
, offsetof(starter_conn_t
, keyexchange
), LST_keyexchange
},
217 { ARG_MISC
, 0, NULL
/* KW_TYPE */ },
218 { ARG_MISC
, 0, NULL
/* KW_PFS */ },
219 { ARG_MISC
, 0, NULL
/* KW_COMPRESS */ },
220 { ARG_ENUM
, offsetof(starter_conn_t
, install_policy
), LST_bool
},
221 { ARG_ENUM
, offsetof(starter_conn_t
, aggressive
), LST_bool
},
222 { ARG_MISC
, 0, NULL
/* KW_AUTH */ },
223 { ARG_STR
, offsetof(starter_conn_t
, authby
), LST_authby
},
224 { ARG_STR
, offsetof(starter_conn_t
, eap_identity
), NULL
},
225 { ARG_STR
, offsetof(starter_conn_t
, aaa_identity
), NULL
},
226 { ARG_MISC
, 0, NULL
/* KW_MOBIKE */ },
227 { ARG_MISC
, 0, NULL
/* KW_FORCEENCAPS */ },
228 { ARG_TIME
, offsetof(starter_conn_t
, sa_ike_life_seconds
), NULL
},
229 { ARG_TIME
, offsetof(starter_conn_t
, sa_ipsec_life_seconds
), NULL
},
230 { ARG_TIME
, offsetof(starter_conn_t
, sa_rekey_margin
), NULL
},
231 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_life_bytes
), NULL
},
232 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_margin_bytes
), NULL
},
233 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_life_packets
), NULL
},
234 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_margin_packets
), NULL
},
235 { ARG_MISC
, 0, NULL
/* KW_KEYINGTRIES */ },
236 { ARG_PCNT
, offsetof(starter_conn_t
, sa_rekey_fuzz
), NULL
},
237 { ARG_MISC
, 0, NULL
/* KW_REKEY */ },
238 { ARG_MISC
, 0, NULL
/* KW_REAUTH */ },
239 { ARG_STR
, offsetof(starter_conn_t
, ike
), NULL
},
240 { ARG_STR
, offsetof(starter_conn_t
, esp
), NULL
},
241 { ARG_STR
, offsetof(starter_conn_t
, pfsgroup
), LST_pfsgroup
},
242 { ARG_TIME
, offsetof(starter_conn_t
, dpd_delay
), NULL
},
243 { ARG_TIME
, offsetof(starter_conn_t
, dpd_timeout
), NULL
},
244 { ARG_ENUM
, offsetof(starter_conn_t
, dpd_action
), LST_dpd_action
},
245 { ARG_ENUM
, offsetof(starter_conn_t
, close_action
), LST_dpd_action
},
246 { ARG_TIME
, offsetof(starter_conn_t
, inactivity
), NULL
},
247 { ARG_MISC
, 0, NULL
/* KW_MODECONFIG */ },
248 { ARG_MISC
, 0, NULL
/* KW_XAUTH */ },
249 { ARG_STR
, offsetof(starter_conn_t
, xauth_identity
), NULL
},
250 { ARG_ENUM
, offsetof(starter_conn_t
, me_mediation
), LST_bool
},
251 { ARG_STR
, offsetof(starter_conn_t
, me_mediated_by
), NULL
},
252 { ARG_STR
, offsetof(starter_conn_t
, me_peerid
), NULL
},
253 { ARG_UINT
, offsetof(starter_conn_t
, reqid
), NULL
},
254 { ARG_MISC
, 0, NULL
/* KW_MARK */ },
255 { ARG_MISC
, 0, NULL
/* KW_MARK_IN */ },
256 { ARG_MISC
, 0, NULL
/* KW_MARK_OUT */ },
257 { ARG_MISC
, 0, NULL
/* KW_TFC */ },
259 /* ca section keywords */
260 { ARG_STR
, offsetof(starter_ca_t
, name
), NULL
},
261 { ARG_ENUM
, offsetof(starter_ca_t
, startup
), LST_startup
},
262 { ARG_STR
, offsetof(starter_ca_t
, cacert
), NULL
},
263 { ARG_STR
, offsetof(starter_ca_t
, ldaphost
), NULL
},
264 { ARG_STR
, offsetof(starter_ca_t
, ldapbase
), NULL
},
265 { ARG_STR
, offsetof(starter_ca_t
, crluri
), NULL
},
266 { ARG_STR
, offsetof(starter_ca_t
, crluri2
), NULL
},
267 { ARG_STR
, offsetof(starter_ca_t
, ocspuri
), NULL
},
268 { ARG_STR
, offsetof(starter_ca_t
, ocspuri2
), NULL
},
269 { ARG_STR
, offsetof(starter_ca_t
, certuribase
), NULL
},
272 { ARG_STR
, offsetof(starter_end_t
, host
), NULL
},
273 { ARG_UINT
, offsetof(starter_end_t
, ikeport
), NULL
},
274 { ARG_STR
, offsetof(starter_end_t
, subnet
), NULL
},
275 { ARG_MISC
, 0, NULL
/* KW_SUBNETWITHIN */ },
276 { ARG_MISC
, 0, NULL
/* KW_PROTOPORT */ },
277 { ARG_STR
, offsetof(starter_end_t
, sourceip
), NULL
},
278 { ARG_MISC
, 0, NULL
/* KW_NATIP */ },
279 { ARG_ENUM
, offsetof(starter_end_t
, firewall
), LST_bool
},
280 { ARG_ENUM
, offsetof(starter_end_t
, hostaccess
), LST_bool
},
281 { ARG_ENUM
, offsetof(starter_end_t
, allow_any
), LST_bool
},
282 { ARG_STR
, offsetof(starter_end_t
, updown
), NULL
},
283 { ARG_STR
, offsetof(starter_end_t
, auth
), NULL
},
284 { ARG_STR
, offsetof(starter_end_t
, auth2
), NULL
},
285 { ARG_STR
, offsetof(starter_end_t
, id
), NULL
},
286 { ARG_STR
, offsetof(starter_end_t
, id2
), NULL
},
287 { ARG_STR
, offsetof(starter_end_t
, rsakey
), NULL
},
288 { ARG_STR
, offsetof(starter_end_t
, cert
), NULL
},
289 { ARG_STR
, offsetof(starter_end_t
, cert2
), NULL
},
290 { ARG_STR
, offsetof(starter_end_t
, cert_policy
), NULL
},
291 { ARG_ENUM
, offsetof(starter_end_t
, sendcert
), LST_sendcert
},
292 { ARG_STR
, offsetof(starter_end_t
, ca
), NULL
},
293 { ARG_STR
, offsetof(starter_end_t
, ca2
), NULL
},
294 { ARG_STR
, offsetof(starter_end_t
, groups
), NULL
},
295 { ARG_STR
, offsetof(starter_end_t
, iface
), NULL
}
298 static void free_list(char **list
)
302 for (s
= list
; *s
; s
++)
309 char** new_list(char *value
)
311 char *val
, *b
, *e
, *end
, **ret
;
314 val
= strdupnull(value
);
319 end
= val
+ strlen(val
);
320 for (b
= val
, count
= 0; b
< end
;)
322 for (e
= b
; ((*e
!= ' ') && (*e
!= '\0')); e
++);
335 ret
= (char **)malloc((count
+1) * sizeof(char *));
337 for (b
= val
, count
= 0; b
< end
; )
339 for (e
= b
; (*e
!= '\0'); e
++);
342 ret
[count
++] = strdupnull(b
);
353 * assigns an argument value to a struct field
355 bool assign_arg(kw_token_t token
, kw_token_t first
, kw_list_t
*kw
, char *base
,
358 char *p
= base
+ token_info
[token
].offset
;
359 const char **list
= token_info
[token
].list
;
361 int index
= -1; /* used for enumeration arguments */
363 lset_t
*seen
= (lset_t
*)base
; /* seen flags are at the top of the struct */
364 lset_t f
= LELEM(token
- first
); /* compute flag position of argument */
368 DBG3(DBG_APP
, " %s=%s", kw
->entry
->name
, kw
->value
);
372 DBG1(DBG_APP
, "# duplicate '%s' option", kw
->entry
->name
);
376 /* set flag that this argument has been seen */
379 /* is there a keyword list? */
380 if (list
!= NULL
&& token_info
[token
].type
!= ARG_LST
)
384 while (*list
!= NULL
&& !match
)
387 match
= streq(kw
->value
, *list
++);
391 DBG1(DBG_APP
, "# bad value: %s=%s", kw
->entry
->name
, kw
->value
);
396 switch (token_info
[token
].type
)
399 DBG1(DBG_APP
, "# option '%s' not supported yet", kw
->entry
->name
);
405 DBG1(DBG_APP
, "# bad enumeration value: %s=%s (%d)",
406 kw
->entry
->name
, kw
->value
, index
);
410 if (token_info
[token
].list
== LST_bool
)
426 u_int
*u
= (u_int
*)p
;
428 *u
= strtoul(kw
->value
, &endptr
, 10);
432 DBG1(DBG_APP
, "# bad integer value: %s=%s", kw
->entry
->name
,
442 unsigned long *l
= (unsigned long *)p
;
444 *l
= strtoul(kw
->value
, &endptr
, 10);
446 if (token_info
[token
].type
== ARG_ULNG
)
450 DBG1(DBG_APP
, "# bad integer value: %s=%s", kw
->entry
->name
,
457 if ((*endptr
!= '%') || (endptr
[1] != '\0') || endptr
== kw
->value
)
459 DBG1(DBG_APP
, "# bad percent value: %s=%s", kw
->entry
->name
,
470 unsigned long long *ll
= (unsigned long long *)p
;
472 *ll
= strtoull(kw
->value
, &endptr
, 10);
476 DBG1(DBG_APP
, "# bad integer value: %s=%s", kw
->entry
->name
,
485 time_t *t
= (time_t *)p
;
487 *t
= strtoul(kw
->value
, &endptr
, 10);
489 /* time in seconds? */
490 if (*endptr
== '\0' || (*endptr
== 's' && endptr
[1] == '\0'))
494 if (endptr
[1] == '\0')
496 if (*endptr
== 'm') /* time in minutes? */
501 if (*endptr
== 'h') /* time in hours? */
506 if (*endptr
== 'd') /* time in days? */
512 DBG1(DBG_APP
, "# bad duration value: %s=%s", kw
->entry
->name
,
518 char **cp
= (char **)p
;
520 /* free any existing string */
523 /* assign the new string */
524 *cp
= strdupnull(kw
->value
);
529 char ***listp
= (char ***)p
;
531 /* free any existing list */
536 /* create a new list and assign values */
537 *listp
= new_list(kw
->value
);
539 /* is there a keyword list? */
544 for (lst
= *listp
; lst
&& *lst
; lst
++)
548 list
= token_info
[token
].list
;
550 while (*list
!= NULL
&& !match
)
552 match
= streq(*lst
, *list
++);
556 DBG1(DBG_APP
, "# bad value: %s=%s",
557 kw
->entry
->name
, *lst
);
573 * frees all dynamically allocated arguments in a struct
575 void free_args(kw_token_t first
, kw_token_t last
, char *base
)
579 for (token
= first
; token
<= last
; token
++)
581 char *p
= base
+ token_info
[token
].offset
;
583 switch (token_info
[token
].type
)
587 char **cp
= (char **)p
;
595 char ***listp
= (char ***)p
;
611 * clone all dynamically allocated arguments in a struct
613 void clone_args(kw_token_t first
, kw_token_t last
, char *base1
, char *base2
)
617 for (token
= first
; token
<= last
; token
++)
619 if (token_info
[token
].type
== ARG_STR
)
621 char **cp1
= (char **)(base1
+ token_info
[token
].offset
);
622 char **cp2
= (char **)(base2
+ token_info
[token
].offset
);
624 *cp1
= strdupnull(*cp2
);
629 static bool cmp_list(char **list1
, char **list2
)
631 if ((list1
== NULL
) && (list2
== NULL
))
635 if ((list1
== NULL
) || (list2
== NULL
))
640 for ( ; *list1
&& *list2
; list1
++, list2
++)
642 if (strcmp(*list1
,*list2
) != 0)
648 if ((*list1
!= NULL
) || (*list2
!= NULL
))
657 * compare all arguments in a struct
659 bool cmp_args(kw_token_t first
, kw_token_t last
, char *base1
, char *base2
)
663 for (token
= first
; token
<= last
; token
++)
665 char *p1
= base1
+ token_info
[token
].offset
;
666 char *p2
= base2
+ token_info
[token
].offset
;
668 switch (token_info
[token
].type
)
671 if (token_info
[token
].list
== LST_bool
)
673 bool *b1
= (bool *)p1
;
674 bool *b2
= (bool *)p2
;
694 u_int
*u1
= (u_int
*)p1
;
695 u_int
*u2
= (u_int
*)p2
;
706 unsigned long *l1
= (unsigned long *)p1
;
707 unsigned long *l2
= (unsigned long *)p2
;
717 unsigned long long *ll1
= (unsigned long long *)p1
;
718 unsigned long long *ll2
= (unsigned long long *)p2
;
728 time_t *t1
= (time_t *)p1
;
729 time_t *t2
= (time_t *)p2
;
739 char **cp1
= (char **)p1
;
740 char **cp2
= (char **)p2
;
742 if (*cp1
== NULL
&& *cp2
== NULL
)
746 if (*cp1
== NULL
|| *cp2
== NULL
|| strcmp(*cp1
, *cp2
) != 0)
754 char ***listp1
= (char ***)p1
;
755 char ***listp2
= (char ***)p2
;
757 if (!cmp_list(*listp1
, *listp2
))