2007-06-11 13:01:04 +01:00
|
|
|
/*
|
|
|
|
* Scyther : An automatic verifier for security protocols.
|
|
|
|
* Copyright (C) 2007 Cas Cremers
|
|
|
|
*
|
|
|
|
* 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-05-15 16:26:21 +01:00
|
|
|
/**
|
|
|
|
*@file main.c
|
|
|
|
* \brief The main file.
|
|
|
|
*
|
|
|
|
* Contains the main switch handling, and passes everything to the core logic.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \mainpage
|
|
|
|
*
|
|
|
|
* \section intro Introduction
|
|
|
|
*
|
|
|
|
* Scyther is a model checker for security protocols.
|
|
|
|
*
|
|
|
|
* \section install Installation
|
|
|
|
*
|
|
|
|
* How to install Scyther.
|
2004-05-15 16:45:08 +01:00
|
|
|
*
|
2004-05-26 20:40:40 +01:00
|
|
|
* \section exit Exit codes
|
|
|
|
*
|
|
|
|
* 0 Okay No attack found, claims encountered
|
2004-07-28 13:22:40 +01:00
|
|
|
*
|
2004-07-28 13:03:42 +01:00
|
|
|
* 1 Error Something went wrong (error) E.g. switch error, or scenario ran out.
|
2004-07-28 13:22:40 +01:00
|
|
|
*
|
2004-05-26 20:40:40 +01:00
|
|
|
* 2 Okay No attack found (because) no claims encountered
|
2004-07-28 13:22:40 +01:00
|
|
|
*
|
2004-05-26 20:40:40 +01:00
|
|
|
* 3 Okay Attack found
|
|
|
|
*
|
|
|
|
* \section coding Coding conventions
|
2004-05-15 16:45:08 +01:00
|
|
|
*
|
|
|
|
* Usually, each source file except main.c has an myfileInit() and myfileDone() function
|
|
|
|
* available. These allow any initialisation and destruction of required structures.
|
|
|
|
*
|
|
|
|
* GNU indent rules are used, but K&R derivatives are allowed as well. Conversion can
|
|
|
|
* be done for any style using the GNU indent program.
|
2004-05-15 16:26:21 +01:00
|
|
|
*/
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <limits.h>
|
2004-07-24 16:08:35 +01:00
|
|
|
#include "system.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
#include "debug.h"
|
2004-07-24 20:07:29 +01:00
|
|
|
#include "symbol.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
#include "pheading.h"
|
2004-07-24 20:07:29 +01:00
|
|
|
#include "symbol.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
#include "tac.h"
|
2005-01-05 15:29:27 +00:00
|
|
|
#include "timer.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
#include "compiler.h"
|
2004-08-15 12:55:22 +01:00
|
|
|
#include "binding.h"
|
2005-04-10 16:30:47 +01:00
|
|
|
#include "switches.h"
|
2005-06-16 15:10:07 +01:00
|
|
|
#include "specialterm.h"
|
2005-12-28 15:27:22 +00:00
|
|
|
#include "color.h"
|
2006-01-02 21:06:08 +00:00
|
|
|
#include "error.h"
|
2006-08-01 06:58:02 +01:00
|
|
|
#include "claim.h"
|
2007-01-06 14:45:29 +00:00
|
|
|
#include "arachne.h"
|
|
|
|
#include "xmlout.h"
|
2004-04-23 11:58:43 +01:00
|
|
|
|
2006-01-02 21:06:08 +00:00
|
|
|
//! The global system state pointer
|
2004-08-09 22:43:55 +01:00
|
|
|
System sys;
|
|
|
|
|
2006-01-02 21:06:08 +00:00
|
|
|
//! Pointer to the tac node container
|
2004-04-23 11:58:43 +01:00
|
|
|
extern struct tacnode *spdltac;
|
2006-01-02 21:06:08 +00:00
|
|
|
//! Match mode
|
2004-08-15 17:44:54 +01:00
|
|
|
extern int mgu_match;
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
void scanner_cleanup (void);
|
|
|
|
void strings_cleanup (void);
|
|
|
|
int yyparse (void);
|
|
|
|
|
|
|
|
void MC_incRuns (const System sys);
|
|
|
|
void MC_incTraces (const System sys);
|
|
|
|
void MC_single (const System sys);
|
|
|
|
int modelCheck (const System sys);
|
|
|
|
|
2004-05-14 18:29:26 +01:00
|
|
|
//! The main body, as called by the environment.
|
2004-04-23 11:58:43 +01:00
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
2004-08-24 14:09:39 +01:00
|
|
|
int exitcode = EXIT_NOATTACK;
|
2004-04-23 11:58:43 +01:00
|
|
|
|
|
|
|
/* initialize symbols */
|
|
|
|
termsInit ();
|
2004-06-14 10:15:42 +01:00
|
|
|
termmapsInit ();
|
2004-04-23 11:58:43 +01:00
|
|
|
termlistsInit ();
|
|
|
|
knowledgeInit ();
|
|
|
|
symbolsInit ();
|
|
|
|
tacInit ();
|
|
|
|
|
2004-07-28 12:39:08 +01:00
|
|
|
/*
|
|
|
|
* ------------------------------------------------
|
2004-08-09 11:05:58 +01:00
|
|
|
* generate system
|
2004-07-28 12:39:08 +01:00
|
|
|
* ------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2005-06-07 16:02:27 +01:00
|
|
|
/* process any command-line switches */
|
|
|
|
switchesInit (argc, argv);
|
2004-07-29 14:15:29 +01:00
|
|
|
|
2005-12-28 15:27:22 +00:00
|
|
|
/* process colors */
|
|
|
|
colorInit ();
|
|
|
|
|
2005-06-07 16:02:27 +01:00
|
|
|
/* start system */
|
|
|
|
sys = systemInit ();
|
2004-07-26 13:43:19 +01:00
|
|
|
|
2005-04-10 16:30:47 +01:00
|
|
|
/* init compiler for this system */
|
|
|
|
compilerInit (sys);
|
2004-07-19 10:32:12 +01:00
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
sys->know = emptyKnowledge ();
|
|
|
|
|
2004-08-09 10:42:58 +01:00
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
/* parse input */
|
|
|
|
|
|
|
|
yyparse ();
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (1))
|
|
|
|
tacPrint (spdltac);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* compile */
|
|
|
|
|
2007-05-03 12:40:58 +01:00
|
|
|
// Compile no runs for Arachne and preprocess
|
2006-03-08 13:58:46 +00:00
|
|
|
compile (spdltac, 0);
|
2004-04-23 11:58:43 +01:00
|
|
|
scanner_cleanup ();
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (1))
|
|
|
|
{
|
|
|
|
printf ("\nCompilation yields:\n\n");
|
|
|
|
printf ("untrusted agents: ");
|
|
|
|
termlistPrint (sys->untrusted);
|
|
|
|
printf ("\n");
|
|
|
|
knowledgePrint (sys->know);
|
|
|
|
printf ("inverses: ");
|
|
|
|
knowledgeInversesPrint (sys->know);
|
|
|
|
printf ("\n");
|
|
|
|
locVarPrint (sys->locals);
|
|
|
|
protocolsPrint (sys->protocols);
|
|
|
|
|
|
|
|
printf ("\nInstantiated runs:\n\n");
|
|
|
|
runsPrint (sys);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* allocate memory for traces, based on runs */
|
|
|
|
systemStart (sys);
|
|
|
|
sys->traceKnow[0] = sys->know; // store initial knowledge
|
|
|
|
|
|
|
|
/* add parameters to system */
|
|
|
|
|
2004-07-29 11:13:13 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ---------------------------------------
|
|
|
|
* Switches consistency checking.
|
|
|
|
* ---------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2004-10-18 14:49:20 +01:00
|
|
|
if (DEBUGL (4))
|
|
|
|
{
|
2005-06-07 16:02:27 +01:00
|
|
|
warning ("Selected output method is %i", switches.output);
|
2004-10-18 14:49:20 +01:00
|
|
|
}
|
2004-07-29 11:13:13 +01:00
|
|
|
#endif
|
2004-08-11 12:22:20 +01:00
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
arachneInit (sys);
|
|
|
|
|
2004-07-29 11:13:13 +01:00
|
|
|
/*
|
|
|
|
* ---------------------------------------
|
|
|
|
* Start real stuff
|
|
|
|
* ---------------------------------------
|
|
|
|
*/
|
2004-04-23 11:58:43 +01:00
|
|
|
|
2005-05-03 10:45:54 +01:00
|
|
|
/* xml init */
|
2005-06-07 16:02:27 +01:00
|
|
|
if (switches.xml)
|
2005-05-03 10:45:54 +01:00
|
|
|
xmlOutInit ();
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
/* model check system */
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (1))
|
2004-07-29 11:13:13 +01:00
|
|
|
warning ("Start modelchecking system.");
|
2004-04-23 11:58:43 +01:00
|
|
|
#endif
|
2005-04-10 16:30:47 +01:00
|
|
|
MC_single (sys);
|
2004-08-09 11:05:58 +01:00
|
|
|
|
2004-08-09 11:41:25 +01:00
|
|
|
/*
|
|
|
|
* ---------------------------------------
|
|
|
|
* After checking the system, results
|
|
|
|
* ---------------------------------------
|
|
|
|
*/
|
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
/* Exitcodes are *not* correct anymore */
|
2004-07-29 13:04:53 +01:00
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
exitcode = EXIT_ATTACK;
|
2004-04-23 11:58:43 +01:00
|
|
|
|
2005-05-03 10:45:54 +01:00
|
|
|
/* xml closeup */
|
2005-06-07 16:02:27 +01:00
|
|
|
if (switches.xml)
|
2005-05-03 10:45:54 +01:00
|
|
|
xmlOutDone ();
|
|
|
|
|
2004-04-23 11:58:43 +01:00
|
|
|
/*
|
|
|
|
* Now we clean up any memory that was allocated.
|
|
|
|
*/
|
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
arachneDone ();
|
2004-04-23 11:58:43 +01:00
|
|
|
knowledgeDestroy (sys->know);
|
|
|
|
systemDone (sys);
|
2005-12-28 15:27:22 +00:00
|
|
|
colorDone ();
|
2004-08-09 10:42:58 +01:00
|
|
|
compilerDone ();
|
2004-04-23 11:58:43 +01:00
|
|
|
|
|
|
|
/* done symbols */
|
|
|
|
tacDone ();
|
|
|
|
symbolsDone ();
|
|
|
|
knowledgeDone ();
|
|
|
|
termlistsDone ();
|
2004-06-14 10:15:42 +01:00
|
|
|
termmapsDone ();
|
2004-04-23 11:58:43 +01:00
|
|
|
termsDone ();
|
|
|
|
|
|
|
|
/* memory clean up? */
|
|
|
|
strings_cleanup ();
|
|
|
|
|
2008-06-16 17:57:28 +01:00
|
|
|
if (switches.exitCodes)
|
|
|
|
{
|
|
|
|
return exitcode;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2004-04-23 11:58:43 +01:00
|
|
|
}
|
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
//! Analyse the model
|
2004-05-14 18:29:26 +01:00
|
|
|
/**
|
|
|
|
* Traditional handywork.
|
2004-04-23 11:58:43 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
MC_single (const System sys)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* simple one-time check
|
|
|
|
*/
|
|
|
|
|
|
|
|
systemReset (sys); // reset any globals
|
2004-07-28 12:39:08 +01:00
|
|
|
systemRuns (sys); // init runs data
|
2004-04-23 11:58:43 +01:00
|
|
|
modelCheck (sys);
|
|
|
|
}
|
|
|
|
|
2004-05-14 18:29:26 +01:00
|
|
|
//! Model check the system, given all parameters.
|
2004-04-23 11:58:43 +01:00
|
|
|
/*
|
|
|
|
* Precondition: the system was reset with the corresponding parameters.
|
2004-05-15 16:26:21 +01:00
|
|
|
* Reports time and states traversed.
|
|
|
|
* Note that the return values doubles as the number of failed claims.
|
|
|
|
*@return True iff any claim failed, and thus an attack was found.
|
2004-04-23 11:58:43 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
modelCheck (const System sys)
|
|
|
|
{
|
2006-08-01 07:10:12 +01:00
|
|
|
int claimcount;
|
|
|
|
|
2004-07-21 11:35:39 +01:00
|
|
|
/* modelcheck the system */
|
2006-08-01 07:10:12 +01:00
|
|
|
claimcount = arachne ();
|
2004-07-21 11:35:39 +01:00
|
|
|
|
2006-08-01 07:10:12 +01:00
|
|
|
if (claimcount == 0)
|
|
|
|
{
|
|
|
|
warning ("No claims in system.");
|
|
|
|
}
|
|
|
|
|
2004-07-21 11:35:39 +01:00
|
|
|
return (sys->failed != STATES0);
|
2004-04-23 11:58:43 +01:00
|
|
|
}
|