2 * Copyright (C) 2014 Tobias Brunner
3 * Copyright (C) 2006 Andreas Steffen
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
21 #include <utils/debug.h>
41 /* various keyword lists */
43 static const char *LST_bool
[] = {
49 static const char *LST_sendcert
[] = {
58 static const char *LST_unique
[] = {
67 static const char *LST_strict
[] = {
73 static const char *LST_dpd_action
[] = {
81 static const char *LST_startup
[] = {
89 static const char *LST_keyexchange
[] = {
96 static const char *LST_authby
[] = {
110 static const char *LST_fragmentation
[] = {
124 static const token_info_t token_info
[] =
126 /* config setup keywords */
127 { ARG_STR
, offsetof(starter_config_t
, setup
.charondebug
), NULL
},
128 { ARG_ENUM
, offsetof(starter_config_t
, setup
.uniqueids
), LST_unique
},
129 { ARG_ENUM
, offsetof(starter_config_t
, setup
.cachecrls
), LST_bool
},
130 { ARG_ENUM
, offsetof(starter_config_t
, setup
.strictcrlpolicy
), LST_strict
},
131 { ARG_MISC
, 0, NULL
/* KW_PKCS11_DEPRECATED */ },
132 { ARG_MISC
, 0, NULL
/* KW_SETUP_DEPRECATED */ },
134 /* conn section keywords */
135 { ARG_STR
, offsetof(starter_conn_t
, name
), NULL
},
136 { ARG_ENUM
, offsetof(starter_conn_t
, startup
), LST_startup
},
137 { ARG_ENUM
, offsetof(starter_conn_t
, keyexchange
), LST_keyexchange
},
138 { ARG_MISC
, 0, NULL
/* KW_TYPE */ },
139 { ARG_MISC
, 0, NULL
/* KW_COMPRESS */ },
140 { ARG_ENUM
, offsetof(starter_conn_t
, install_policy
), LST_bool
},
141 { ARG_ENUM
, offsetof(starter_conn_t
, aggressive
), LST_bool
},
142 { ARG_STR
, offsetof(starter_conn_t
, authby
), LST_authby
},
143 { ARG_STR
, offsetof(starter_conn_t
, eap_identity
), NULL
},
144 { ARG_STR
, offsetof(starter_conn_t
, aaa_identity
), NULL
},
145 { ARG_MISC
, 0, NULL
/* KW_MOBIKE */ },
146 { ARG_MISC
, 0, NULL
/* KW_FORCEENCAPS */ },
147 { ARG_ENUM
, offsetof(starter_conn_t
, fragmentation
), LST_fragmentation
},
148 { ARG_UBIN
, offsetof(starter_conn_t
, ikedscp
), NULL
},
149 { ARG_TIME
, offsetof(starter_conn_t
, sa_ike_life_seconds
), NULL
},
150 { ARG_TIME
, offsetof(starter_conn_t
, sa_ipsec_life_seconds
), NULL
},
151 { ARG_TIME
, offsetof(starter_conn_t
, sa_rekey_margin
), NULL
},
152 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_life_bytes
), NULL
},
153 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_margin_bytes
), NULL
},
154 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_life_packets
), NULL
},
155 { ARG_ULLI
, offsetof(starter_conn_t
, sa_ipsec_margin_packets
), NULL
},
156 { ARG_MISC
, 0, NULL
/* KW_KEYINGTRIES */ },
157 { ARG_PCNT
, offsetof(starter_conn_t
, sa_rekey_fuzz
), NULL
},
158 { ARG_MISC
, 0, NULL
/* KW_REKEY */ },
159 { ARG_MISC
, 0, NULL
/* KW_REAUTH */ },
160 { ARG_STR
, offsetof(starter_conn_t
, ike
), NULL
},
161 { ARG_STR
, offsetof(starter_conn_t
, esp
), NULL
},
162 { ARG_STR
, offsetof(starter_conn_t
, ah
), NULL
},
163 { ARG_TIME
, offsetof(starter_conn_t
, dpd_delay
), NULL
},
164 { ARG_TIME
, offsetof(starter_conn_t
, dpd_timeout
), NULL
},
165 { ARG_ENUM
, offsetof(starter_conn_t
, dpd_action
), LST_dpd_action
},
166 { ARG_ENUM
, offsetof(starter_conn_t
, close_action
), LST_dpd_action
},
167 { ARG_ENUM
, offsetof(starter_conn_t
, sha256_96
), LST_bool
},
168 { ARG_TIME
, offsetof(starter_conn_t
, inactivity
), NULL
},
169 { ARG_MISC
, 0, NULL
/* KW_MODECONFIG */ },
170 { ARG_MISC
, 0, NULL
/* KW_XAUTH */ },
171 { ARG_STR
, offsetof(starter_conn_t
, xauth_identity
), NULL
},
172 { ARG_ENUM
, offsetof(starter_conn_t
, me_mediation
), LST_bool
},
173 { ARG_STR
, offsetof(starter_conn_t
, me_mediated_by
), NULL
},
174 { ARG_STR
, offsetof(starter_conn_t
, me_peerid
), NULL
},
175 { ARG_UINT
, offsetof(starter_conn_t
, reqid
), NULL
},
176 { ARG_UINT
, offsetof(starter_conn_t
, replay_window
), NULL
},
177 { ARG_MISC
, 0, NULL
/* KW_MARK */ },
178 { ARG_MISC
, 0, NULL
/* KW_MARK_IN */ },
179 { ARG_MISC
, 0, NULL
/* KW_MARK_OUT */ },
180 { ARG_MISC
, 0, NULL
/* KW_TFC */ },
181 { ARG_MISC
, 0, NULL
/* KW_PFS_DEPRECATED */ },
182 { ARG_MISC
, 0, NULL
/* KW_CONN_DEPRECATED */ },
184 /* ca section keywords */
185 { ARG_STR
, offsetof(starter_ca_t
, name
), NULL
},
186 { ARG_ENUM
, offsetof(starter_ca_t
, startup
), LST_startup
},
187 { ARG_STR
, offsetof(starter_ca_t
, cacert
), NULL
},
188 { ARG_STR
, offsetof(starter_ca_t
, crluri
), NULL
},
189 { ARG_STR
, offsetof(starter_ca_t
, crluri2
), NULL
},
190 { ARG_STR
, offsetof(starter_ca_t
, ocspuri
), NULL
},
191 { ARG_STR
, offsetof(starter_ca_t
, ocspuri2
), NULL
},
192 { ARG_STR
, offsetof(starter_ca_t
, certuribase
), NULL
},
193 { ARG_MISC
, 0, NULL
/* KW_CA_DEPRECATED */ },
196 { ARG_STR
, offsetof(starter_end_t
, host
), NULL
},
197 { ARG_UINT
, offsetof(starter_end_t
, ikeport
), NULL
},
198 { ARG_STR
, offsetof(starter_end_t
, subnet
), NULL
},
199 { ARG_MISC
, 0, NULL
/* KW_PROTOPORT */ },
200 { ARG_STR
, offsetof(starter_end_t
, sourceip
), NULL
},
201 { ARG_STR
, offsetof(starter_end_t
, dns
), NULL
},
202 { ARG_ENUM
, offsetof(starter_end_t
, firewall
), LST_bool
},
203 { ARG_ENUM
, offsetof(starter_end_t
, hostaccess
), LST_bool
},
204 { ARG_ENUM
, offsetof(starter_end_t
, allow_any
), LST_bool
},
205 { ARG_STR
, offsetof(starter_end_t
, updown
), NULL
},
206 { ARG_STR
, offsetof(starter_end_t
, auth
), NULL
},
207 { ARG_STR
, offsetof(starter_end_t
, auth2
), NULL
},
208 { ARG_STR
, offsetof(starter_end_t
, id
), NULL
},
209 { ARG_STR
, offsetof(starter_end_t
, id2
), NULL
},
210 { ARG_STR
, offsetof(starter_end_t
, rsakey
), NULL
},
211 { ARG_STR
, offsetof(starter_end_t
, cert
), NULL
},
212 { ARG_STR
, offsetof(starter_end_t
, cert2
), NULL
},
213 { ARG_STR
, offsetof(starter_end_t
, cert_policy
), NULL
},
214 { ARG_ENUM
, offsetof(starter_end_t
, sendcert
), LST_sendcert
},
215 { ARG_STR
, offsetof(starter_end_t
, ca
), NULL
},
216 { ARG_STR
, offsetof(starter_end_t
, ca2
), NULL
},
217 { ARG_STR
, offsetof(starter_end_t
, groups
), NULL
},
218 { ARG_STR
, offsetof(starter_end_t
, groups2
), NULL
},
219 { ARG_MISC
, 0, NULL
/* KW_END_DEPRECATED */ },
223 * assigns an argument value to a struct field
225 bool assign_arg(kw_token_t token
, kw_token_t first
, char *key
, char *value
,
226 void *base
, bool *assigned
)
228 char *p
= (char*)base
+ token_info
[token
].offset
;
229 const char **list
= token_info
[token
].list
;
230 int index
= -1; /* used for enumeration arguments */
234 DBG3(DBG_APP
, " %s=%s", key
, value
);
236 /* is there a keyword list? */
241 while (*list
!= NULL
&& !match
)
244 match
= streq(value
, *list
++);
248 DBG1(DBG_APP
, "# bad value: %s=%s", key
, value
);
253 switch (token_info
[token
].type
)
256 DBG1(DBG_APP
, "# option '%s' not supported yet", key
);
262 DBG1(DBG_APP
, "# bad enumeration value: %s=%s (%d)",
267 if (token_info
[token
].list
== LST_bool
)
273 { /* FIXME: this is not entirely correct as the args are enums */
282 u_int
*u
= (u_int
*)p
;
284 *u
= strtoul(value
, &endptr
, 10);
288 DBG1(DBG_APP
, "# bad integer value: %s=%s", key
, value
);
297 unsigned long *l
= (unsigned long *)p
;
299 *l
= strtoul(value
, &endptr
, 10);
301 if (token_info
[token
].type
== ARG_ULNG
)
305 DBG1(DBG_APP
, "# bad integer value: %s=%s", key
, value
);
311 if ((*endptr
!= '%') || (endptr
[1] != '\0') || endptr
== value
)
313 DBG1(DBG_APP
, "# bad percent value: %s=%s", key
, value
);
322 unsigned long long *ll
= (unsigned long long *)p
;
324 *ll
= strtoull(value
, &endptr
, 10);
328 DBG1(DBG_APP
, "# bad integer value: %s=%s", key
, value
);
336 u_int
*u
= (u_int
*)p
;
338 *u
= strtoul(value
, &endptr
, 2);
342 DBG1(DBG_APP
, "# bad binary value: %s=%s", key
, value
);
350 time_t *t
= (time_t *)p
;
352 *t
= strtoul(value
, &endptr
, 10);
354 /* time in seconds? */
355 if (*endptr
== '\0' || (*endptr
== 's' && endptr
[1] == '\0'))
359 if (endptr
[1] == '\0')
361 if (*endptr
== 'm') /* time in minutes? */
366 if (*endptr
== 'h') /* time in hours? */
371 if (*endptr
== 'd') /* time in days? */
377 DBG1(DBG_APP
, "# bad duration value: %s=%s", key
, value
);
382 char **cp
= (char **)p
;
384 /* free any existing string */
386 /* assign the new string */
387 *cp
= strdupnull(value
);
399 * frees all dynamically allocated arguments in a struct
401 void free_args(kw_token_t first
, kw_token_t last
, void *base
)
405 for (token
= first
; token
<= last
; token
++)
407 char *p
= (char*)base
+ token_info
[token
].offset
;
409 switch (token_info
[token
].type
)
413 char **cp
= (char **)p
;
426 * compare all arguments in a struct
428 bool cmp_args(kw_token_t first
, kw_token_t last
, void *base1
, void *base2
)
432 for (token
= first
; token
<= last
; token
++)
434 char *p1
= (char*)base1
+ token_info
[token
].offset
;
435 char *p2
= (char*)base2
+ token_info
[token
].offset
;
437 switch (token_info
[token
].type
)
441 if (token_info
[token
].list
== LST_bool
)
443 bool *b1
= (bool *)p1
;
444 bool *b2
= (bool *)p2
;
465 u_int
*u1
= (u_int
*)p1
;
466 u_int
*u2
= (u_int
*)p2
;
477 unsigned long *l1
= (unsigned long *)p1
;
478 unsigned long *l2
= (unsigned long *)p2
;
488 unsigned long long *ll1
= (unsigned long long *)p1
;
489 unsigned long long *ll2
= (unsigned long long *)p2
;
499 time_t *t1
= (time_t *)p1
;
500 time_t *t2
= (time_t *)p2
;
510 char **cp1
= (char **)p1
;
511 char **cp2
= (char **)p2
;
513 if (*cp1
== NULL
&& *cp2
== NULL
)
517 if (*cp1
== NULL
|| *cp2
== NULL
|| strcmp(*cp1
, *cp2
) != 0)