scyther/src/main.c

285 lines
6.0 KiB
C
Raw Normal View History

/*
* Scyther : An automatic verifier for security protocols.
2013-10-05 23:56:12 +01:00
* Copyright (C) 2007-2013 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
*
* \section exit Exit codes
*
* 0 Okay No attack found, claims encountered
*
* 1 Error Something went wrong (error) E.g. switch error, or scenario ran out.
*
* 2 Okay No attack found (because) no claims encountered
*
* 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>
#include "system.h"
2004-04-23 11:58:43 +01:00
#include "debug.h"
#include "symbol.h"
2004-04-23 11:58:43 +01:00
#include "pheading.h"
#include "symbol.h"
2004-04-23 11:58:43 +01:00
#include "tac.h"
#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"
#include "switches.h"
#include "specialterm.h"
#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"
#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
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
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);
//! The main body, as called by the environment.
2004-04-23 11:58:43 +01:00
int
main (int argc, char **argv)
{
int exitcode = EXIT_NOATTACK;
2004-04-23 11:58:43 +01:00
/* initialize symbols */
termsInit ();
termmapsInit ();
2004-04-23 11:58:43 +01:00
termlistsInit ();
knowledgeInit ();
symbolsInit ();
tacInit ();
/*
* ------------------------------------------------
* generate system
* ------------------------------------------------
*/
/* process any command-line switches */
switchesInit (argc, argv);
/* process colors */
colorInit ();
/* start system */
sys = systemInit ();
/* init knowledge. Needs to go before compiler init for special term init */
2004-04-23 11:58:43 +01:00
sys->know = emptyKnowledge ();
/* init compiler for this system */
compilerInit (sys);
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
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);
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 */
/*
* ---------------------------------------
* Switches consistency checking.
* ---------------------------------------
*/
#ifdef DEBUG
if (DEBUGL (4))
{
warning ("Selected output method is %i", switches.output);
}
#endif
arachneInit (sys);
/*
* ---------------------------------------
* Start real stuff
* ---------------------------------------
*/
2004-04-23 11:58:43 +01:00
/* xml init */
if (switches.xml)
xmlOutInit ();
2004-04-23 11:58:43 +01:00
/* model check system */
#ifdef DEBUG
if (DEBUGL (1))
warning ("Start modelchecking system.");
2004-04-23 11:58:43 +01:00
#endif
MC_single (sys);
2004-08-09 11:41:25 +01:00
/*
* ---------------------------------------
* After checking the system, results
* ---------------------------------------
*/
/* Exitcodes are *not* correct anymore */
2004-07-29 13:04:53 +01:00
exitcode = EXIT_ATTACK;
2004-04-23 11:58:43 +01:00
/* xml closeup */
if (switches.xml)
xmlOutDone ();
2004-04-23 11:58:43 +01:00
/*
* Now we clean up any memory that was allocated.
*/
arachneDone ();
2004-04-23 11:58:43 +01:00
knowledgeDestroy (sys->know);
systemDone (sys);
colorDone ();
2008-08-21 15:58:12 +01:00
switchesDone ();
compilerDone ();
2004-04-23 11:58:43 +01:00
/* done symbols */
tacDone ();
symbolsDone ();
knowledgeDone ();
termlistsDone ();
termmapsDone ();
2004-04-23 11:58:43 +01:00
termsDone ();
/* memory clean up? */
strings_cleanup ();
if (switches.exitCodes)
{
return exitcode;
}
else
{
return 0;
}
2004-04-23 11:58:43 +01:00
}
//! Analyse the model
/**
* 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
systemRuns (sys); // init runs data
2004-04-23 11:58:43 +01:00
modelCheck (sys);
}
//! 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)
{
int claimcount;
/* modelcheck the system */
claimcount = arachne ();
if (claimcount == 0)
{
warning ("No claims in system.");
}
return (sys->failed != STATES0);
2004-04-23 11:58:43 +01:00
}