2007-06-11 13:01:04 +01:00
|
|
|
/*
|
|
|
|
* Scyther : An automatic verifier for security protocols.
|
2012-04-24 12:56:51 +01:00
|
|
|
* Copyright (C) 2007-2012 Cas Cremers
|
2007-06-11 13:01:04 +01:00
|
|
|
*
|
|
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
%option yylineno
|
|
|
|
|
|
|
|
%{
|
|
|
|
/* scanner for security protocols language */
|
|
|
|
|
|
|
|
#include <strings.h>
|
|
|
|
#include "pheading.h"
|
|
|
|
#include "tac.h"
|
2006-04-12 13:42:04 +01:00
|
|
|
#include "switches.h"
|
2006-08-02 11:29:40 +01:00
|
|
|
#include "error.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
|
|
|
|
/* tokens for language */
|
2004-05-21 20:31:42 +01:00
|
|
|
#include "parser.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
|
|
|
|
void mkname(char *name);
|
|
|
|
void mkval(void);
|
|
|
|
void mktext(void);
|
|
|
|
|
|
|
|
int yyerror(char *s);
|
|
|
|
|
|
|
|
Symbol mkstring(char *name);
|
|
|
|
|
|
|
|
struct stringlist {
|
|
|
|
char* string;
|
|
|
|
struct stringlist* next;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct stringlist* Stringlist;
|
|
|
|
|
|
|
|
static Stringlist allocatedStrings = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int mylineno = 0;
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
comment1 "//".*
|
|
|
|
comment2 "#".*
|
2005-11-28 08:27:05 +00:00
|
|
|
delimiter [ \t\r\n]
|
2004-04-23 11:58:43 +01:00
|
|
|
whitespace {delimiter}+
|
|
|
|
uc_letter [A-Z]
|
|
|
|
lc_letter [a-z]
|
|
|
|
letter {lc_letter}|{uc_letter}
|
|
|
|
digit [0-9]
|
|
|
|
ascii_char [^\"\n]
|
|
|
|
escaped_char \\n|\\\"
|
|
|
|
integer {digit}+
|
|
|
|
text \"({ascii_char}|{escaped_char})*\"
|
2006-04-25 14:58:14 +01:00
|
|
|
id @?({letter}|{digit}|[\^\-!'])+
|
2004-04-23 11:58:43 +01:00
|
|
|
|
2006-04-12 13:42:04 +01:00
|
|
|
/* the "incl" state is used for picking up the name of an include file
|
|
|
|
*/
|
|
|
|
%x incl inclend
|
2006-08-01 10:09:44 +01:00
|
|
|
|
|
|
|
%{
|
|
|
|
#define MAX_INCLUDE_DEPTH 10
|
|
|
|
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
|
|
|
|
int include_stack_ptr = 0;
|
|
|
|
%}
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
%%
|
2006-04-12 13:42:04 +01:00
|
|
|
include BEGIN(incl);
|
|
|
|
<incl>[ \t]*\" /* eat the whitespace */
|
|
|
|
<incl>[^\"]+ { /* got the include file name */
|
2006-08-01 10:09:44 +01:00
|
|
|
if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
|
|
|
|
{
|
2006-08-02 11:29:40 +01:00
|
|
|
printfstderr( "Includes nested too deeply" );
|
2006-08-01 10:09:44 +01:00
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
include_stack[include_stack_ptr++] =
|
|
|
|
YY_CURRENT_BUFFER;
|
|
|
|
|
|
|
|
/* try to open, using scytherdirs environment variable as well. */
|
|
|
|
yyin = openFileSearch (yytext, NULL);
|
|
|
|
|
|
|
|
if (! yyin)
|
|
|
|
{
|
|
|
|
error ("could not open include file %s.", yytext);
|
|
|
|
}
|
|
|
|
|
|
|
|
yy_switch_to_buffer(
|
|
|
|
yy_create_buffer( yyin, YY_BUF_SIZE ) );
|
|
|
|
|
|
|
|
BEGIN(INITIAL);
|
2006-04-12 13:42:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
<inclend>\";? { /* eat the closing things */
|
|
|
|
BEGIN(INITIAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
<INITIAL><<EOF>> {
|
2006-08-01 10:09:44 +01:00
|
|
|
if ( --include_stack_ptr < 0 )
|
|
|
|
{
|
|
|
|
yyterminate();
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
yy_delete_buffer( YY_CURRENT_BUFFER );
|
|
|
|
yy_switch_to_buffer(
|
|
|
|
include_stack[include_stack_ptr] );
|
|
|
|
BEGIN(inclend);
|
|
|
|
}
|
2006-04-12 13:42:04 +01:00
|
|
|
}
|
2004-04-23 11:58:43 +01:00
|
|
|
|
|
|
|
"/*" {
|
|
|
|
register int c;
|
|
|
|
|
|
|
|
for ( ; ; )
|
|
|
|
{
|
|
|
|
while ( (c = input()) != '*' && c != '\n' && c != EOF )
|
|
|
|
; /* eat up text of comment */
|
|
|
|
|
|
|
|
if ( c == '*' )
|
|
|
|
{
|
|
|
|
while ( (c = input()) == '*' )
|
|
|
|
;
|
|
|
|
if ( c == '/' )
|
|
|
|
break; /* found the end */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == '\n')
|
|
|
|
mylineno++;
|
|
|
|
|
|
|
|
if ( c == EOF )
|
|
|
|
{
|
|
|
|
yyerror( "EOF in comment" );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
\n { mylineno++; }
|
|
|
|
{whitespace} { }
|
|
|
|
{comment1} { }
|
|
|
|
{comment2} { }
|
|
|
|
|
|
|
|
protocol { return PROTOCOL; }
|
|
|
|
role { return ROLE; }
|
|
|
|
read { return READT; }
|
2008-08-20 15:15:27 +01:00
|
|
|
recv { return RECVT; }
|
2004-04-23 11:58:43 +01:00
|
|
|
send { return SENDT; }
|
2012-11-21 10:28:40 +00:00
|
|
|
match { return MATCH; }
|
2012-11-21 12:40:15 +00:00
|
|
|
not { return NOT; }
|
2012-11-22 11:30:00 +00:00
|
|
|
macro { return MACRO; }
|
2004-04-23 11:58:43 +01:00
|
|
|
var { return VAR; }
|
|
|
|
const { return CONST; }
|
2010-01-05 12:45:19 +00:00
|
|
|
fresh { return FRESH; }
|
2004-04-23 11:58:43 +01:00
|
|
|
claim { return CLAIMT; }
|
|
|
|
run { return RUN; }
|
|
|
|
secret { return SECRET; }
|
|
|
|
inversekeys { return INVERSEKEYS; }
|
|
|
|
untrusted { return UNTRUSTED; }
|
|
|
|
compromised { return COMPROMISED; }
|
|
|
|
usertype { return USERTYPE; }
|
2006-01-02 16:05:53 +00:00
|
|
|
singular { return SINGULAR; }
|
2006-01-09 09:38:17 +00:00
|
|
|
function { return FUNCTION; }
|
|
|
|
hashfunction { return HASHFUNCTION; }
|
|
|
|
knows { return KNOWS; }
|
|
|
|
trusted { return TRUSTED; }
|
2012-12-14 22:53:04 +00:00
|
|
|
option { return OPTION; }
|
|
|
|
{text} {
|
|
|
|
if (strlen(yytext) >= 2)
|
|
|
|
{
|
|
|
|
// Make a copy without the surrounding
|
|
|
|
// double-quotes.
|
|
|
|
// TODO: Allow to unescape quotes inside string if
|
|
|
|
// needed later.
|
|
|
|
yylval.str = strndup(yytext+1,strlen(yytext)-2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If only one character, then simply copy
|
|
|
|
yylval.str = strdup(yytext);
|
|
|
|
}
|
|
|
|
return TEXT;
|
|
|
|
}
|
2004-04-23 11:58:43 +01:00
|
|
|
{id} {
|
|
|
|
yylval.symb = mkstring(yytext);
|
|
|
|
return ID;
|
|
|
|
}
|
|
|
|
. { return yytext[0]; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
Symbol mkstring(char *name)
|
|
|
|
{
|
|
|
|
Symbol t;
|
|
|
|
char* s;
|
|
|
|
Stringlist sl;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (( t = lookup(name)) != NULL)
|
|
|
|
{
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
// make new name
|
|
|
|
len = strlen(name);
|
2006-03-08 13:58:46 +00:00
|
|
|
s = (char *)malloc(len+1);
|
|
|
|
sl = (Stringlist) malloc(sizeof(struct stringlist));
|
2004-04-23 11:58:43 +01:00
|
|
|
strncpy(s,name,len);
|
|
|
|
sl->next = allocatedStrings;
|
|
|
|
allocatedStrings = sl;
|
|
|
|
sl->string = s;
|
|
|
|
s[len] = EOS;
|
|
|
|
|
|
|
|
t = get_symb();
|
|
|
|
t->lineno = yylineno;
|
|
|
|
t->type = T_UNDEF;
|
|
|
|
t->text = s;
|
|
|
|
|
|
|
|
insert(t);
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
void scanner_cleanup(void)
|
|
|
|
{
|
|
|
|
yy_delete_buffer (YY_CURRENT_BUFFER);
|
|
|
|
}
|
|
|
|
|
|
|
|
void strings_cleanup(void)
|
|
|
|
{
|
|
|
|
Stringlist sl;
|
|
|
|
while (allocatedStrings != NULL)
|
|
|
|
{
|
|
|
|
sl = allocatedStrings;
|
|
|
|
allocatedStrings = sl->next;
|
2006-03-08 13:58:46 +00:00
|
|
|
free(sl->string);
|
|
|
|
free(sl);
|
2004-04-23 11:58:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-17 20:35:54 +01:00
|
|
|
int yywrap (void)
|
|
|
|
{
|
2004-07-17 20:52:07 +01:00
|
|
|
/* signal true to let lex know that nothing else is coming */
|
|
|
|
return 1;
|
2004-07-17 20:35:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
/*
|
|
|
|
void mkval(void);
|
|
|
|
void mktext(void);
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// vim:ft=lex:
|