File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / starter / args.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:43 2020 UTC (4 years, 4 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    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>