%{
/**
 * A client-side 802.1x implementation supporting EAP/TLS
 *
 * This code is released under both the GPL version 2 and BSD licenses.
 * Either license may be used.  The respective licenses are found below.
 *
 * Copyright (C) 2002 Bryan D. Payne & Nick L. Petroni Jr.
 * All Rights Reserved
 *
 * --- GPL Version 2 License ---
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * --- BSD License ---
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  - All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *       This product includes software developed by the University of
 *       Maryland at College Park and its contributors.
 *  - Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*******************************************************************
 * Tokens for configuration file
 * 
 * File: config_lexicon.l
 *
 * Authors: bdpayne@cs.umd.edu, npetroni@cs.umd.edu
 *
 * $Id: config_lexicon.l,v 1.17 2004/08/19 02:28:06 chessing Exp $
 * $Date: 2004/08/19 02:28:06 $
 * $Log: config_lexicon.l,v $
 * Revision 1.17  2004/08/19 02:28:06  chessing
 * First piece of WPA patch.  (The patch is growing fast, and this commit is to save what is done so far.)
 *
 * Revision 1.16  2004/08/12 01:40:06  chessing
 *
 * Added "association" option to the global configuration file sections.  It can be set to either auto, or manual.  Setting "association" to auto means that XSupplicant will attempt to associate to a network with the lowest value in the "priority" setting.  The default for "association" is auto.  The other option added is "priority" which is a numeric value from 1..256.  A value of 1 is the highest priority, and will be the first network chosen.  (Assuming the network can be found in a scan.)  The default value for "priority" is 0, which means that network will be checked last.   --  Although the options are now in the config file, the actual functionality for auto association/priority is not yet complete.  (So, basically these options don't do anything yet. ;)
 *
 * Revision 1.15  2004/06/29 01:35:34  chessing
 *
 * Added credit to eapleap.c for Gilbert Goodwill (who gave me the clues I needed to figure out the keying piece for LEAP).  Added patch from Toby Collett to make PEAP work for broken implementations of IAS.  (New option ias_quirk has been added.)
 *
 * Revision 1.14  2004/06/21 05:19:12  chessing
 *
 * Added a few minor fixes to EAP-AKA support.  Added "allmulti" as a global configuration option.  (By default, allmulti is now on!)
 *
 * Revision 1.13  2004/06/15 03:35:19  chessing
 *
 * New updates including fixes to LEAP (keying now works with wireless) and adding EAP-AKA.
 *
 * Revision 1.12  2004/06/15 03:22:17  chessing
 *
 * XSupplicant Release 1.0
 *
 *
 *******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "config_grammar.h"
#include "config.h"
#include "xsup_debug.h"
#include "xsup_err.h"

int config_linenum = 1;
extern struct config_data config_info;
%}

HEXDIGIT    [0-9a-fA-F]

%x fname
%%
"network_list"      {return TK_NETWORK_LIST; }
"default_netname"   {return TK_DEFAULT_NETNAME; }
"all"               {return TK_ALL; }
"startup_command"   {return TK_STARTUP_COMMAND; }
"first_auth_command" {return TK_FIRST_AUTH_COMMAND; }
"reauth_command"    {return TK_REAUTH_COMMAND; }
"logfile"           {return TK_LOGFILE; }
"auth_period"       {return TK_AUTH_PERIOD; }
"held_period"       {return TK_HELD_PERIOD; }
"max_starts"        {return TK_MAX_STARTS; }
"allmulti"          {return TK_ALLMULTI; }
"allow_interfaces"  {return TK_ALLOW_INTERFACES; }
"deny_interfaces"   {return TK_DENY_INTERFACES; }
"association"       {return TK_ASSOCIATION; }
"auto"              {return TK_AUTO; }
"manual"            {return TK_MANUAL; }

"type"              { return TK_TYPE; }
"allow_types"       { return TK_ALLOW_TYPES; }
"wireless"          { return TK_WIRELESS; }
"wired"             { return TK_WIRED; }
"identity"          { return TK_IDENTITY; }
"priority"          { return TK_PRIORITY; }
"dest_mac"          { return TK_DEST_MAC; }
"ssid"              { return TK_SSID; }
"wireless_control"  { return TK_CONTROL_WIRELESS; }
"crypt_method"      { return TK_CRYPT_METHOD; }
"wep"               { return TK_WEP; }
"wpa-tkip"          { return TK_WPA_TKIP; }
"wpa-ccmp"          { return TK_WPA_CCMP; }
"wpa"               { return TK_WPA_ENT; }
"any"               { return TK_ANY; }

"wpa_psk"           { return TK_WPA_PSK; }
"key"               { BEGIN(fname);  return TK_WPA_PSK_KEY; }
"hex-key"           { BEGIN(fname);  return TK_WPA_PSK_HEX_KEY; }

"eap_tls"           { return TK_EAP_TLS; }
"eap-tls"           { return TK_EAP_TLS; }
"user_cert"          { BEGIN(fname); return TK_USER_CERT; }
"user_key"           { BEGIN(fname); return TK_USER_KEY; }
"user_key_pass"      { return TK_USER_KEY_PASS; }
"root_cert"          { BEGIN(fname); return TK_ROOT_CERT; }
"root_dir"          { BEGIN(fname); return TK_ROOT_DIR; }
"crl_dir"          { BEGIN(fname); return TK_CRL_DIR; }
"session_resume"   { return TK_SESSION_RESUME; }
"chunk_size"    { return TK_CHUNK_SIZE; }
"random_file"   { BEGIN(fname); return TK_RANDOM_FILE; }
"cncheck"       { BEGIN(fname); return TK_CNCHECK; }
"cnexact"       { return TK_CNEXACT; }


"eap_md5"           { return TK_EAP_MD5; }
"eap-md5"           { return TK_EAP_MD5; }
"username"          { return TK_USERNAME; }
"password"          { return TK_PASSWORD; }

"eap-ttls"          { return TK_EAP_TTLS; }
"eap_ttls"          { return TK_EAP_TTLS; }
"phase2_type"       { return TK_PHASE2_TYPE; }
"pap"               { return TK_PAP;  }
"chap"              { return TK_CHAP;  }
"mschap"            { return TK_MSCHAP;  }
"mschapv2"          { return TK_MSCHAPV2;  }

"eap-leap"          { return TK_EAP_LEAP; }
"eap_leap"          { return TK_EAP_LEAP; }

"eap-mschapv2"      { return TK_EAP_MSCHAPV2; }
"eap_mschapv2"      { return TK_EAP_MSCHAPV2; }
"ias_quirk"         { return TK_IAS_QUIRK; }
"ias-quirk"         { return TK_IAS_QUIRK; }

"eap-peap"          { return TK_EAP_PEAP; }
"eap_peap"          { return TK_EAP_PEAP; }

"eap-sim"           { return TK_EAP_SIM; }
"eap_sim"           { return TK_EAP_SIM; }
"auto_realm"        { return TK_AUTO_REALM; }
"yes"               { return TK_YES; }
"no"                { return TK_NO; }

"eap-aka"           { return TK_EAP_AKA; }
"eap_aka"           { return TK_EAP_AKA; }

"eap-gtc"           { return TK_EAP_GTC; }
"eap_gtc"           { return TK_EAP_GTC; }

"eap-otp"           { return TK_EAP_OTP; }
"eap_otp"           { return TK_EAP_OTP; }



<INITIAL,fname>"="  { return yytext[0];     }
"{"             { return yytext[0];     }
"}"             { return yytext[0];     }
","             { return yytext[0];     }


[0123456789]+   {
                    yylval.num = atoi(yytext);
                    return TK_NUMBER;
                }


[[:alnum:]\-\_\\/\.]+  {
                     yylval.str = strdup(yytext);
                     return TK_NETNAME;
                   }

{HEXDIGIT}{2}":"{HEXDIGIT}{2}":"{HEXDIGIT}{2}":"{HEXDIGIT}{2}":"{HEXDIGIT}{2}":"{HEXDIGIT}{2} {
                     yylval.str = strdup(yytext);
                     return TK_MACADDRESS;
                   }

<fname>[[:alnum:]/_\-\\\.]+ {
                     yylval.str = strdup(yytext);
                     BEGIN(0);
                     return TK_FNAME;
                   }

"#".*          /* skip comments */  

<INITIAL,fname>[ \t]+          /* de nada  */

\n              { config_linenum++;             }


"<BEGIN_ID>".+"<END_ID>"  { int len = strlen(yytext)-10-8;
                            yylval.str = 
                             (char *)malloc(sizeof(char) * (len+1));
                            strncpy(yylval.str, yytext+10,len);
                            yylval.str[len] = '\0';
                            return TK_IDENTITY_VAL;}

"<BEGIN_SSID>".+"<END_SSID>"  { int len = strlen(yytext)-12-10;
                            yylval.str = 
                             (char *)malloc(sizeof(char) * (len+1));
                            strncpy(yylval.str, yytext+12,len);
                            yylval.str[len] = '\0';
                            return TK_SSID_VAL;}

"<BEGIN_PASS>".+"<END_PASS>"  { int len = strlen(yytext)-12-10;
                            yylval.str = 
                             (char *)malloc(sizeof(char) * (len+1));
                            strncpy(yylval.str, yytext+12,len);
                            yylval.str[len] = '\0';
                            return TK_PASS;}

"<BEGIN_UNAME>".+"<END_UNAME>"  { int len = strlen(yytext)-13-11;
                            yylval.str = 
                             (char *)malloc(sizeof(char) * (len+1));
                            strncpy(yylval.str, yytext+13,len);
                            yylval.str[len] = '\0';
                            return TK_USERNAME_VAL;}

"<BEGIN_COMMAND>".+"<END_COMMAND>"  { int len = strlen(yytext)-15-13;
                            yylval.str = 
                             (char *)malloc(sizeof(char) * (len+1));
                            strncpy(yylval.str, yytext+15,len);
                            yylval.str[len] = '\0';
                            return TK_COMMAND;}

%%

int
yywrap(void)
{
	return 1;
}

int
yyerror(char *e)
{
	debug_printf(DEBUG_NORMAL, 
		     "Error %s, %d: Unkown token '%s'\n",
		     config_info.config_fname,
		     config_linenum, yylval.str);
	return XECONFIGPARSEFAIL;
}
