2004-08-11 10:51:17 +01:00
|
|
|
/**
|
|
|
|
*@file arachne.c
|
|
|
|
*
|
|
|
|
* Introduces a method for proofs akin to the Athena modelchecker
|
|
|
|
* http://www.ece.cmu.edu/~dawnsong/athena/
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
#include "term.h"
|
2004-08-11 15:09:12 +01:00
|
|
|
#include "termlist.h"
|
2004-08-11 13:08:10 +01:00
|
|
|
#include "role.h"
|
2004-08-11 10:51:17 +01:00
|
|
|
#include "system.h"
|
2004-08-15 17:44:54 +01:00
|
|
|
#include "knowledge.h"
|
2004-08-12 13:28:57 +01:00
|
|
|
#include "compiler.h"
|
2004-08-11 15:09:12 +01:00
|
|
|
#include "states.h"
|
|
|
|
#include "mgu.h"
|
2004-08-11 10:51:17 +01:00
|
|
|
#include "arachne.h"
|
2004-08-14 16:59:14 +01:00
|
|
|
#include "error.h"
|
|
|
|
#include "claim.h"
|
2004-08-14 17:12:32 +01:00
|
|
|
#include "debug.h"
|
2004-08-15 13:24:27 +01:00
|
|
|
#include "binding.h"
|
2004-08-11 10:51:17 +01:00
|
|
|
|
2004-08-15 15:07:34 +01:00
|
|
|
extern Term CLAIM_Secret;
|
|
|
|
extern Term CLAIM_Nisynch;
|
|
|
|
extern Term CLAIM_Niagree;
|
2004-08-15 17:44:54 +01:00
|
|
|
extern Term TERM_Agent;
|
2004-08-14 20:19:23 +01:00
|
|
|
|
2004-08-11 15:09:12 +01:00
|
|
|
static System sys;
|
2004-08-12 13:28:57 +01:00
|
|
|
Protocol INTRUDER; // Pointers, to be set by the Init
|
2004-08-17 12:30:03 +01:00
|
|
|
Role I_M; // Same here.
|
|
|
|
Role I_F;
|
|
|
|
Role I_T;
|
|
|
|
Role I_V;
|
|
|
|
Role I_R;
|
|
|
|
Role I_E;
|
|
|
|
Role I_D;
|
2004-08-11 13:08:10 +01:00
|
|
|
|
2004-08-13 12:11:59 +01:00
|
|
|
static int indentDepth;
|
|
|
|
|
2004-08-11 22:04:52 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-12 10:14:31 +01:00
|
|
|
static char *explanation; // Pointer to a string that describes what we just tried to do
|
2004-08-12 13:28:57 +01:00
|
|
|
static int e_run;
|
|
|
|
static Term e_term1;
|
|
|
|
static Term e_term2;
|
|
|
|
static Term e_term3;
|
2004-08-11 22:04:52 +01:00
|
|
|
#endif
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
struct goalstruct
|
|
|
|
{
|
|
|
|
int run;
|
|
|
|
int index;
|
2004-08-11 15:09:12 +01:00
|
|
|
Roledef rd;
|
2004-08-11 13:08:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct goalstruct Goal;
|
|
|
|
|
2004-08-11 15:09:12 +01:00
|
|
|
/**
|
|
|
|
* Forward declarations
|
|
|
|
*/
|
|
|
|
|
|
|
|
int iterate ();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Program code
|
|
|
|
*/
|
|
|
|
|
2004-08-11 12:22:20 +01:00
|
|
|
//! Init Arachne engine
|
|
|
|
void
|
2004-08-11 15:09:12 +01:00
|
|
|
arachneInit (const System mysys)
|
2004-08-11 12:22:20 +01:00
|
|
|
{
|
2004-08-12 12:55:03 +01:00
|
|
|
Roledef rd = NULL;
|
2004-08-15 17:44:54 +01:00
|
|
|
Termlist tl, know0;
|
2004-08-12 12:55:03 +01:00
|
|
|
|
|
|
|
void add_event (int event, Term message)
|
2004-08-12 13:28:57 +01:00
|
|
|
{
|
|
|
|
rd = roledefAdd (rd, event, NULL, NULL, NULL, message, NULL);
|
|
|
|
}
|
|
|
|
Role add_role (const char *rolenamestring)
|
|
|
|
{
|
|
|
|
Role r;
|
|
|
|
Term rolename;
|
|
|
|
|
|
|
|
rolename = makeGlobalConstant (rolenamestring);
|
|
|
|
r = roleCreate (rolename);
|
|
|
|
r->roledef = rd;
|
|
|
|
rd = NULL;
|
|
|
|
r->next = INTRUDER->roles;
|
|
|
|
INTRUDER->roles = r;
|
2004-08-12 14:22:49 +01:00
|
|
|
// compute_role_variables (sys, INTRUDER, r);
|
2004-08-12 13:28:57 +01:00
|
|
|
return r;
|
|
|
|
}
|
2004-08-12 12:55:03 +01:00
|
|
|
|
2004-08-11 15:09:12 +01:00
|
|
|
sys = mysys; // make sys available for this module as a global
|
2004-08-14 15:23:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Very important: turn role terms that are local to a run, into variables.
|
|
|
|
*/
|
|
|
|
term_rolelocals_are_variables ();
|
|
|
|
|
2004-08-11 12:22:20 +01:00
|
|
|
/*
|
|
|
|
* Add intruder protocol roles
|
|
|
|
*/
|
2004-08-12 12:55:03 +01:00
|
|
|
|
|
|
|
INTRUDER = protocolCreate (makeGlobalConstant (" INTRUDER "));
|
|
|
|
|
2004-08-17 12:30:03 +01:00
|
|
|
add_event (SEND, NULL);
|
|
|
|
I_M = add_role ("I_M: Atomic message");
|
2004-08-12 12:55:03 +01:00
|
|
|
|
2004-08-17 12:30:03 +01:00
|
|
|
add_event (READ, NULL);
|
|
|
|
add_event (READ, NULL);
|
2004-08-16 15:49:41 +01:00
|
|
|
add_event (SEND, NULL);
|
2004-08-17 12:30:03 +01:00
|
|
|
I_D = add_role ("I_D: Decrypt");
|
2004-08-16 15:49:41 +01:00
|
|
|
|
2004-08-11 12:22:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Close Arachne engine
|
|
|
|
void
|
2004-08-11 15:09:12 +01:00
|
|
|
arachneDone ()
|
2004-08-11 12:22:20 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Detail
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
|
|
* runs[rid].step is now the number of 'valid' events within the run, but we
|
|
|
|
* call it 'length' here.
|
|
|
|
*/
|
|
|
|
#define INVALID -1
|
2004-08-11 15:09:12 +01:00
|
|
|
#define isGoal(rd) (rd->type == READ && !rd->internal)
|
2004-08-15 13:24:27 +01:00
|
|
|
#define isBound(rd) (rd->bound)
|
2004-08-11 13:08:10 +01:00
|
|
|
#define length step
|
|
|
|
|
2004-08-12 12:35:13 +01:00
|
|
|
//! Indent print
|
|
|
|
void
|
|
|
|
indentPrint ()
|
|
|
|
{
|
2004-08-13 11:50:56 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-12 12:35:13 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < indentDepth; i++)
|
2004-08-15 13:24:27 +01:00
|
|
|
eprintf ("%i ", i);
|
2004-08-13 11:50:56 +01:00
|
|
|
#else
|
|
|
|
eprintf (">> ");
|
2004-08-12 12:35:13 +01:00
|
|
|
#endif
|
2004-08-13 11:50:56 +01:00
|
|
|
}
|
2004-08-12 12:35:13 +01:00
|
|
|
|
2004-08-11 15:09:12 +01:00
|
|
|
//! Iterate but discard the info of the termlist
|
|
|
|
int
|
|
|
|
mgu_iterate (const Termlist tl)
|
|
|
|
{
|
|
|
|
return iterate ();
|
|
|
|
}
|
|
|
|
|
2004-08-17 16:52:52 +01:00
|
|
|
//! After a role instance, or an extension of a run, we might need to add some goals
|
|
|
|
/**
|
|
|
|
* From old to new. Sets the new length to new.
|
|
|
|
*@returns The number of goals added (for destructions)
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
add_read_goals (const int run, int old, int new)
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
int i;
|
|
|
|
Roledef rd;
|
|
|
|
|
|
|
|
sys->runs[run].length = new;
|
|
|
|
i = old;
|
|
|
|
rd = roledef_shift (sys->runs[run], i);
|
|
|
|
while (i < new)
|
|
|
|
{
|
|
|
|
if (rd->type == READ)
|
|
|
|
{
|
|
|
|
goal_add (rd->message, run, i);
|
|
|
|
}
|
|
|
|
rd = rd->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Remove n goals
|
|
|
|
void
|
|
|
|
remove_read_goals (int n)
|
|
|
|
{
|
|
|
|
while (n>0)
|
|
|
|
{
|
|
|
|
goal_remove_last ();
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-14 15:23:21 +01:00
|
|
|
//! Determine the run that follows from a substitution.
|
|
|
|
/**
|
|
|
|
* After an Arachne unification, stuff might go wrong w.r.t. nonce instantiation.
|
|
|
|
* This function determines the run that is implied by a substitution list.
|
|
|
|
* @returns >= 0: a run, -1 for invalid, -2 for any run.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
determine_unification_run (Termlist tl)
|
|
|
|
{
|
|
|
|
int run;
|
|
|
|
|
|
|
|
run = -2;
|
|
|
|
while (tl != NULL)
|
|
|
|
{
|
|
|
|
//! Again, hardcoded reference to compiler.c. Level -3 means a local constant for a role.
|
|
|
|
if (tl->term->type != VARIABLE && tl->term->right.runid == -3)
|
|
|
|
{
|
|
|
|
Term t;
|
|
|
|
|
|
|
|
t = tl->term->subst;
|
|
|
|
|
|
|
|
// It is required that it is actually a leaf, because we construct it.
|
|
|
|
if (!realTermLeaf (t))
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (run == -2)
|
|
|
|
{
|
|
|
|
// Any run
|
|
|
|
run = t->right.runid;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Specific run: compare
|
|
|
|
if (run != t->right.runid)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tl = tl->next;
|
|
|
|
}
|
|
|
|
return run;
|
|
|
|
}
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Sub
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
2004-08-11 15:09:12 +01:00
|
|
|
//! Iterate over all send types in the roles (including the intruder ones)
|
|
|
|
/**
|
|
|
|
* Function is called with (protocol pointer, role pointer, roledef pointer, index)
|
|
|
|
* and returns an integer. If it is false, iteration aborts.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
iterate_role_sends (int (*func) ())
|
|
|
|
{
|
|
|
|
Protocol p;
|
|
|
|
|
|
|
|
p = sys->protocols;
|
|
|
|
while (p != NULL)
|
|
|
|
{
|
|
|
|
Role r;
|
|
|
|
|
|
|
|
r = p->roles;
|
|
|
|
while (r != NULL)
|
|
|
|
{
|
|
|
|
Roledef rd;
|
|
|
|
int index;
|
|
|
|
|
|
|
|
rd = r->roledef;
|
|
|
|
index = 0;
|
|
|
|
while (rd != NULL)
|
|
|
|
{
|
|
|
|
if (rd->type == SEND)
|
|
|
|
{
|
2004-08-12 13:37:30 +01:00
|
|
|
if (!func (p, r, rd, index))
|
2004-08-11 15:09:12 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
rd = rd->next;
|
|
|
|
}
|
|
|
|
r = r->next;
|
|
|
|
}
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-08-16 10:50:37 +01:00
|
|
|
//! Try to bind a specific existing run to a goal.
|
2004-08-15 20:58:26 +01:00
|
|
|
/**
|
2004-08-16 10:50:37 +01:00
|
|
|
* The key goals are bound to the goal.
|
|
|
|
*@param subterm determines whether it is a subterm unification or not.
|
2004-08-15 20:58:26 +01:00
|
|
|
*/
|
2004-08-11 15:09:12 +01:00
|
|
|
int
|
2004-08-17 16:52:52 +01:00
|
|
|
bind_existing_to_goal (const Binding b, const int index, const int run,
|
2004-08-16 10:50:37 +01:00
|
|
|
const int subterm)
|
|
|
|
{
|
|
|
|
Roledef rd;
|
|
|
|
int flag;
|
2004-08-16 14:18:04 +01:00
|
|
|
int old_length;
|
2004-08-16 10:50:37 +01:00
|
|
|
|
|
|
|
int subterm_iterate (Termlist substlist, Termlist keylist)
|
|
|
|
{
|
|
|
|
int keycount;
|
|
|
|
int flag;
|
|
|
|
|
|
|
|
|
2004-08-16 14:18:04 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Adding key list : ");
|
|
|
|
termlistPrint (keylist);
|
|
|
|
eprintf ("\n");
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-16 10:50:37 +01:00
|
|
|
flag = 1;
|
|
|
|
keycount = 0;
|
|
|
|
while (flag && keylist != NULL)
|
|
|
|
{
|
2004-08-16 14:18:04 +01:00
|
|
|
int keyrun;
|
|
|
|
|
|
|
|
keyrun = create_intruder_goal (keylist->term);
|
2004-08-17 12:03:18 +01:00
|
|
|
if (!binding_add (keyrun, 0, goal.run, goal.index, keylist->term))
|
2004-08-16 10:50:37 +01:00
|
|
|
flag = 0;
|
|
|
|
keylist = keylist->next;
|
|
|
|
keycount++;
|
|
|
|
}
|
|
|
|
flag = flag && iterate ();
|
|
|
|
while (keycount > 0)
|
|
|
|
{
|
|
|
|
binding_remove_last ();
|
2004-08-16 14:18:04 +01:00
|
|
|
roleInstanceDestroy (sys);
|
2004-08-16 10:50:37 +01:00
|
|
|
keycount--;
|
|
|
|
}
|
2004-08-16 14:18:04 +01:00
|
|
|
termlistDestroy (keylist);
|
2004-08-16 10:50:37 +01:00
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
int interm_iterate (Termlist substlist)
|
|
|
|
{
|
|
|
|
iterate ();
|
|
|
|
}
|
|
|
|
|
2004-08-16 14:18:04 +01:00
|
|
|
//----------------------------
|
2004-08-16 10:50:37 +01:00
|
|
|
// Roledef entry
|
|
|
|
rd = roledef_shift (sys->runs[run].start, index);
|
|
|
|
|
2004-08-16 14:18:04 +01:00
|
|
|
// Fix length
|
|
|
|
old_length = sys->runs[run].length;
|
|
|
|
if ((index + 1) > old_length)
|
|
|
|
sys->runs[run].length = index + 1;
|
|
|
|
|
2004-08-16 10:50:37 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
explanation = "Bind existing run (generic) ";
|
|
|
|
e_run = run;
|
|
|
|
e_term1 = goal.rd->message;
|
|
|
|
e_term2 = rd->message;
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-17 12:03:18 +01:00
|
|
|
if (binding_add (run, index, goal.run, goal.index, goal.rd->message))
|
2004-08-16 10:50:37 +01:00
|
|
|
{
|
|
|
|
if (subterm)
|
|
|
|
{
|
2004-08-16 14:18:04 +01:00
|
|
|
flag = termMguSubTerm (goal.rd->message, rd->message,
|
2004-08-16 10:50:37 +01:00
|
|
|
subterm_iterate, sys->know->inverses, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-16 14:18:04 +01:00
|
|
|
flag = termMguInTerm (goal.rd->message, rd->message,
|
2004-08-16 10:50:37 +01:00
|
|
|
interm_iterate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Aborted binding existing run because of cycle.\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2004-08-16 14:18:04 +01:00
|
|
|
binding_remove_last ();
|
|
|
|
// Reset length
|
|
|
|
sys->runs[run].length = old_length;
|
|
|
|
return flag;
|
2004-08-16 10:50:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Bind a goal to an existing regular run, if possible
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
bind_existing_run (const Goal goal, const Protocol p, const Role r,
|
2004-08-16 10:50:37 +01:00
|
|
|
const int index, const int subterm)
|
2004-08-11 15:09:12 +01:00
|
|
|
{
|
|
|
|
int run, flag;
|
|
|
|
|
2004-08-13 21:56:51 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (4))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Trying to bind ");
|
|
|
|
termPrint (goal.rd->message);
|
|
|
|
eprintf (" to an existing instance of ");
|
|
|
|
termPrint (p->nameterm);
|
|
|
|
eprintf (", ");
|
|
|
|
termPrint (r->nameterm);
|
2004-08-16 14:18:04 +01:00
|
|
|
eprintf (" (%i)\n", subterm);
|
2004-08-14 17:12:32 +01:00
|
|
|
}
|
2004-08-13 21:56:51 +01:00
|
|
|
#endif
|
2004-08-11 15:09:12 +01:00
|
|
|
flag = 1;
|
|
|
|
for (run = 0; run < sys->maxruns; run++)
|
|
|
|
{
|
2004-08-16 14:18:04 +01:00
|
|
|
if (sys->runs[run].protocol == p && sys->runs[run].role == r)
|
|
|
|
{
|
|
|
|
flag = flag && bind_existing_to_goal (goal, index, run, subterm);
|
|
|
|
}
|
2004-08-11 15:09:12 +01:00
|
|
|
}
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Bind a goal to a new run
|
|
|
|
int
|
|
|
|
bind_new_run (const Goal goal, const Protocol p, const Role r,
|
2004-08-16 10:50:37 +01:00
|
|
|
const int index, const int subterm)
|
2004-08-11 15:09:12 +01:00
|
|
|
{
|
2004-08-11 16:05:13 +01:00
|
|
|
int run;
|
|
|
|
int flag;
|
|
|
|
|
2004-08-16 15:49:41 +01:00
|
|
|
roleInstance (sys, p, r, NULL, NULL);
|
|
|
|
run = sys->maxruns - 1;
|
2004-08-16 14:18:04 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (4))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Trying to bind ");
|
|
|
|
termPrint (goal.rd->message);
|
|
|
|
eprintf (" to a new instance of ");
|
|
|
|
termPrint (p->nameterm);
|
|
|
|
eprintf (", ");
|
|
|
|
termPrint (r->nameterm);
|
2004-08-16 15:49:41 +01:00
|
|
|
eprintf (", run %i (subterm:%i)\n", run, subterm);
|
2004-08-16 14:18:04 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
flag = bind_existing_to_goal (goal, index, run, subterm);
|
2004-08-11 16:05:13 +01:00
|
|
|
roleInstanceDestroy (sys);
|
|
|
|
return flag;
|
2004-08-11 15:09:12 +01:00
|
|
|
}
|
|
|
|
|
2004-08-13 09:29:11 +01:00
|
|
|
//! Print the current semistate
|
|
|
|
void
|
|
|
|
printSemiState ()
|
|
|
|
{
|
|
|
|
int run;
|
2004-08-14 15:38:30 +01:00
|
|
|
int open;
|
2004-08-15 18:50:41 +01:00
|
|
|
List bl;
|
|
|
|
|
|
|
|
int binding_indent_print (void *data)
|
2004-08-15 20:58:26 +01:00
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("!! ");
|
|
|
|
binding_print (data);
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-13 09:29:11 +01:00
|
|
|
|
2004-08-14 15:38:30 +01:00
|
|
|
indentPrint ();
|
|
|
|
eprintf ("!! --=[ Semistate ]=--\n");
|
|
|
|
open = 0;
|
2004-08-13 09:29:11 +01:00
|
|
|
for (run = 0; run < sys->maxruns; run++)
|
|
|
|
{
|
|
|
|
int index;
|
2004-08-15 18:16:13 +01:00
|
|
|
Role r;
|
2004-08-13 09:29:11 +01:00
|
|
|
Roledef rd;
|
2004-08-15 18:16:13 +01:00
|
|
|
Term oldagent;
|
2004-08-13 09:29:11 +01:00
|
|
|
|
2004-08-15 18:16:13 +01:00
|
|
|
indentPrint ();
|
|
|
|
eprintf ("!!\n");
|
2004-08-13 09:29:11 +01:00
|
|
|
indentPrint ();
|
2004-08-14 15:38:30 +01:00
|
|
|
eprintf ("!! [ Run %i, ", run);
|
2004-08-15 18:16:13 +01:00
|
|
|
termPrint (sys->runs[run].protocol->nameterm);
|
|
|
|
eprintf (", ");
|
|
|
|
r = sys->runs[run].role;
|
|
|
|
oldagent = r->nameterm->subst;
|
|
|
|
r->nameterm->subst = NULL;
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
r->nameterm->subst = oldagent;
|
|
|
|
if (oldagent != NULL)
|
|
|
|
{
|
|
|
|
eprintf (": ");
|
|
|
|
termPrint (oldagent);
|
|
|
|
}
|
2004-08-13 09:29:11 +01:00
|
|
|
eprintf (" ]\n");
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
rd = sys->runs[run].start;
|
|
|
|
while (index < sys->runs[run].length)
|
|
|
|
{
|
|
|
|
indentPrint ();
|
2004-08-14 15:38:30 +01:00
|
|
|
eprintf ("!! %i ", index);
|
2004-08-13 09:29:11 +01:00
|
|
|
roledefPrint (rd);
|
|
|
|
eprintf ("\n");
|
2004-08-14 15:38:30 +01:00
|
|
|
if (isGoal (rd) && !isBound (rd))
|
2004-08-14 17:12:32 +01:00
|
|
|
open++;
|
2004-08-13 09:29:11 +01:00
|
|
|
index++;
|
|
|
|
rd = rd->next;
|
|
|
|
}
|
|
|
|
}
|
2004-08-15 18:50:41 +01:00
|
|
|
if (sys->bindings != NULL)
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("!!\n");
|
|
|
|
list_iterate (sys->bindings, binding_indent_print);
|
|
|
|
}
|
2004-08-14 15:38:30 +01:00
|
|
|
indentPrint ();
|
2004-08-15 18:16:13 +01:00
|
|
|
eprintf ("!!\n");
|
|
|
|
indentPrint ();
|
2004-08-14 15:38:30 +01:00
|
|
|
eprintf ("!! - open: %i -\n", open);
|
2004-08-13 09:29:11 +01:00
|
|
|
}
|
|
|
|
|
2004-08-11 22:04:52 +01:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Larger logical componentents
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//! Goal selection
|
|
|
|
/**
|
|
|
|
* Should be ordered to prefer most constrained; for now, it is simply the first one encountered.
|
|
|
|
*/
|
|
|
|
Goal
|
|
|
|
select_goal ()
|
|
|
|
{
|
|
|
|
Goal goal;
|
|
|
|
int run;
|
|
|
|
|
|
|
|
goal.run = INVALID;
|
|
|
|
goal.rd = NULL;
|
|
|
|
for (run = 0; run < sys->maxruns; run++)
|
|
|
|
{
|
|
|
|
Roledef rd;
|
|
|
|
int index;
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
rd = sys->runs[run].start;
|
|
|
|
while (rd != NULL && index < sys->runs[run].length)
|
|
|
|
{
|
|
|
|
if (isGoal (rd) && !isBound (rd))
|
|
|
|
{
|
|
|
|
// Return this goal
|
|
|
|
goal.run = run;
|
|
|
|
goal.index = index;
|
|
|
|
goal.rd = rd;
|
|
|
|
return goal;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
rd = rd->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return goal;
|
|
|
|
}
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
//! Bind a regular goal
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
bind_goal_regular (const Goal goal)
|
2004-08-11 13:08:10 +01:00
|
|
|
{
|
2004-08-13 21:56:51 +01:00
|
|
|
int flag;
|
2004-08-11 15:09:12 +01:00
|
|
|
/*
|
|
|
|
* This is a local function so we have access to goal
|
|
|
|
*/
|
2004-08-13 21:56:51 +01:00
|
|
|
int bind_this_role_send (Protocol p, Role r, Roledef rd, int index)
|
2004-08-11 15:09:12 +01:00
|
|
|
{
|
2004-08-16 10:50:37 +01:00
|
|
|
int test_unification (Termlist substlist)
|
|
|
|
{
|
|
|
|
// A unification exists; return the signal
|
|
|
|
return 0;
|
2004-08-11 15:09:12 +01:00
|
|
|
}
|
|
|
|
|
2004-08-13 21:56:51 +01:00
|
|
|
if (p == INTRUDER)
|
|
|
|
{
|
|
|
|
/* only bind to regular runs */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Test for interm unification
|
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Checking send candidate with message ");
|
|
|
|
termPrint (rd->message);
|
|
|
|
eprintf (" from ");
|
|
|
|
termPrint (p->nameterm);
|
|
|
|
eprintf (", ");
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
eprintf (", index %i\n", index);
|
|
|
|
}
|
2004-08-13 21:56:51 +01:00
|
|
|
#endif
|
2004-08-16 14:18:04 +01:00
|
|
|
if (!termMguInTerm (goal.rd->message, rd->message, test_unification))
|
2004-08-16 10:50:37 +01:00
|
|
|
{
|
|
|
|
// A good candidate
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Term ");
|
|
|
|
termPrint (goal.rd->message);
|
|
|
|
eprintf (" can possibly be bound by role ");
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
eprintf (", index %i\n", index);
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-16 14:18:04 +01:00
|
|
|
return (bind_new_run (goal, p, r, index, 0) &&
|
|
|
|
bind_existing_run (goal, p, r, index, 0));
|
2004-08-16 10:50:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Cannot unify: no attacks
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-13 21:56:51 +01:00
|
|
|
}
|
2004-08-11 15:09:12 +01:00
|
|
|
}
|
|
|
|
|
2004-08-13 11:25:23 +01:00
|
|
|
// Bind to all possible sends or intruder node;
|
2004-08-13 21:56:51 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Try regular role send.\n");
|
|
|
|
}
|
2004-08-13 21:56:51 +01:00
|
|
|
#endif
|
|
|
|
flag = iterate_role_sends (bind_this_role_send);
|
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Try intruder send.\n");
|
|
|
|
}
|
2004-08-13 21:56:51 +01:00
|
|
|
#endif
|
|
|
|
return (flag && add_intruder_goal_iterate (goal));
|
2004-08-13 11:25:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Bind an intruder goal to a regular run
|
|
|
|
int
|
2004-08-13 21:09:12 +01:00
|
|
|
bind_intruder_to_regular (Goal goal)
|
2004-08-13 11:25:23 +01:00
|
|
|
{
|
2004-08-13 21:09:12 +01:00
|
|
|
int bind_this_roleevent (Protocol p, Role r, Roledef rd, int index)
|
2004-08-13 11:25:23 +01:00
|
|
|
{
|
2004-08-16 10:50:37 +01:00
|
|
|
int cannotUnify;
|
2004-08-13 21:09:12 +01:00
|
|
|
|
2004-08-16 10:50:37 +01:00
|
|
|
int test_unification (Termlist substlist, Termlist keylist)
|
|
|
|
{
|
|
|
|
// Signal that unification is possible.
|
|
|
|
return 0;
|
2004-08-11 15:09:12 +01:00
|
|
|
}
|
2004-08-13 11:25:23 +01:00
|
|
|
|
2004-08-13 21:09:12 +01:00
|
|
|
/**
|
|
|
|
* Note that we only bind to regular runs here
|
|
|
|
*/
|
|
|
|
if (p == INTRUDER)
|
|
|
|
{
|
|
|
|
return 1; // don't abort scans
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Test for subterm unification
|
2004-08-16 10:50:37 +01:00
|
|
|
if (termMguSubTerm
|
|
|
|
(goal.rd->message, rd->message, test_unification,
|
|
|
|
sys->know->inverses, NULL))
|
|
|
|
{
|
|
|
|
// cannot unify
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Either from an existing, or from a new run.
|
|
|
|
*/
|
2004-08-16 14:18:04 +01:00
|
|
|
return (bind_new_run (goal, p, r, index, 1)
|
|
|
|
&& bind_existing_run (goal, p, r, index, 1));
|
2004-08-16 10:50:37 +01:00
|
|
|
}
|
2004-08-13 21:09:12 +01:00
|
|
|
}
|
2004-08-13 11:25:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Bind to all possible sends?
|
2004-08-13 21:09:12 +01:00
|
|
|
return iterate_role_sends (bind_this_roleevent);
|
2004-08-11 13:08:10 +01:00
|
|
|
}
|
|
|
|
|
2004-08-13 11:25:23 +01:00
|
|
|
//! Bind an intruder goal by intruder construction
|
2004-08-13 21:56:51 +01:00
|
|
|
/**
|
|
|
|
* Handles the case where the intruder constructs a composed term himself.
|
|
|
|
*/
|
2004-08-13 11:25:23 +01:00
|
|
|
int
|
|
|
|
bind_intruder_to_construct (const Goal goal)
|
|
|
|
{
|
2004-08-13 21:09:12 +01:00
|
|
|
Term term;
|
2004-08-16 15:49:41 +01:00
|
|
|
Termlist m0tl;
|
|
|
|
int flag;
|
|
|
|
int run;
|
2004-08-13 21:09:12 +01:00
|
|
|
|
2004-08-16 15:49:41 +01:00
|
|
|
flag = 1;
|
2004-08-13 21:09:12 +01:00
|
|
|
term = goal.rd->message;
|
2004-08-16 15:49:41 +01:00
|
|
|
/**
|
|
|
|
* Two options.
|
|
|
|
*
|
|
|
|
* 1. Constructed from composite terms
|
|
|
|
*/
|
2004-08-13 21:09:12 +01:00
|
|
|
if (!realTermLeaf (term))
|
|
|
|
{
|
|
|
|
Term t1, t2;
|
|
|
|
|
|
|
|
if (realTermTuple (term))
|
|
|
|
{
|
|
|
|
// tuple construction
|
|
|
|
t1 = term->left.op1;
|
|
|
|
t2 = term->right.op2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// must be encryption
|
|
|
|
t1 = term->left.op;
|
|
|
|
t2 = term->right.key;
|
|
|
|
}
|
|
|
|
|
2004-08-16 15:49:41 +01:00
|
|
|
run = create_intruder_goal (t1);
|
2004-08-17 12:03:18 +01:00
|
|
|
if (binding_add (run, 0, goal.run, goal.index, t1))
|
2004-08-16 15:49:41 +01:00
|
|
|
{
|
|
|
|
run = create_intruder_goal (t2);
|
2004-08-17 12:30:03 +01:00
|
|
|
if (binding_add (run, 0, goal.run, goal.index, t2))
|
2004-08-16 15:49:41 +01:00
|
|
|
{
|
|
|
|
flag = flag && iterate ();
|
|
|
|
}
|
|
|
|
binding_remove_last ();
|
|
|
|
roleInstanceDestroy (sys);
|
|
|
|
}
|
|
|
|
binding_remove_last ();
|
2004-08-13 21:09:12 +01:00
|
|
|
roleInstanceDestroy (sys);
|
|
|
|
}
|
2004-08-16 15:49:41 +01:00
|
|
|
/**
|
|
|
|
* 2. Retrieved from M_0
|
|
|
|
*/
|
|
|
|
m0tl = knowledgeSet (sys->know);
|
|
|
|
while (flag && m0tl != NULL)
|
2004-08-13 21:09:12 +01:00
|
|
|
{
|
2004-08-16 15:49:41 +01:00
|
|
|
Term m0t;
|
|
|
|
Termlist subst;
|
|
|
|
|
|
|
|
m0t = m0tl->term;
|
|
|
|
subst = termMguTerm (term, m0t);
|
|
|
|
if (subst != MGUFAIL)
|
|
|
|
{
|
|
|
|
int run;
|
|
|
|
|
2004-08-17 12:30:03 +01:00
|
|
|
roleInstance (sys, INTRUDER, I_M, NULL, NULL);
|
2004-08-16 15:49:41 +01:00
|
|
|
run = sys->maxruns - 1;
|
2004-08-17 12:30:03 +01:00
|
|
|
sys->runs[run].start->message = termDuplicate (term);
|
2004-08-16 15:49:41 +01:00
|
|
|
sys->runs[run].length = 1;
|
2004-08-17 12:30:03 +01:00
|
|
|
if (binding_add (run, 0, goal.run, goal.index, term))
|
2004-08-16 15:49:41 +01:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Retrieving ");
|
|
|
|
termPrint (term);
|
|
|
|
eprintf (" from the initial knowledge.\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
iterate ();
|
|
|
|
}
|
|
|
|
binding_remove_last ();
|
|
|
|
roleInstanceDestroy (sys);
|
|
|
|
termlistSubstReset (subst);
|
2004-08-17 12:30:03 +01:00
|
|
|
termlistDelete (subst);
|
2004-08-16 15:49:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
m0tl = m0tl->next;
|
2004-08-13 21:09:12 +01:00
|
|
|
}
|
2004-08-16 15:49:41 +01:00
|
|
|
termlistDelete (m0tl);
|
|
|
|
/**
|
|
|
|
* return result
|
|
|
|
*/
|
|
|
|
return flag;
|
2004-08-13 11:25:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
//! Bind an intruder goal
|
2004-08-13 11:25:23 +01:00
|
|
|
/**
|
|
|
|
* Computes F2 as in Athena explanations.
|
|
|
|
*/
|
2004-08-11 13:08:10 +01:00
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
bind_goal_intruder (const Goal goal)
|
2004-08-11 13:08:10 +01:00
|
|
|
{
|
2004-08-15 18:07:38 +01:00
|
|
|
/**
|
|
|
|
* Special case: when the intruder can bind it to the initial knowledge.
|
|
|
|
*/
|
|
|
|
Termlist tl;
|
|
|
|
int flag;
|
|
|
|
|
|
|
|
flag = 1;
|
|
|
|
tl = knowledgeSet (sys->know);
|
|
|
|
while (flag && tl != NULL)
|
|
|
|
{
|
|
|
|
int hasvars;
|
|
|
|
Termlist substlist;
|
|
|
|
|
|
|
|
substlist = termMguTerm (tl->term, goal.rd->message);
|
|
|
|
if (substlist != MGUFAIL)
|
|
|
|
{
|
|
|
|
// This seems to work
|
|
|
|
flag = flag && iterate ();
|
2004-08-15 18:16:13 +01:00
|
|
|
termlistSubstReset (substlist);
|
2004-08-16 15:49:41 +01:00
|
|
|
termlistDelete (substlist);
|
2004-08-15 18:07:38 +01:00
|
|
|
}
|
|
|
|
tl = tl->next;
|
|
|
|
}
|
|
|
|
termlistDelete (tl);
|
|
|
|
return (flag && bind_intruder_to_regular (goal) &&
|
2004-08-13 11:25:23 +01:00
|
|
|
bind_intruder_to_construct (goal));
|
2004-08-11 13:08:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Bind a goal in all possible ways
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
bind_goal (const Goal goal)
|
2004-08-11 13:08:10 +01:00
|
|
|
{
|
2004-08-15 13:24:27 +01:00
|
|
|
if (!goal.rd->bound)
|
2004-08-11 13:08:10 +01:00
|
|
|
{
|
2004-08-15 13:24:27 +01:00
|
|
|
int flag;
|
|
|
|
goal.rd->bound = 1;
|
|
|
|
if (sys->runs[goal.run].protocol == INTRUDER)
|
|
|
|
{
|
|
|
|
flag = bind_goal_intruder (goal);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
flag = bind_goal_regular (goal);
|
|
|
|
}
|
|
|
|
goal.rd->bound = 0;
|
|
|
|
return flag;
|
2004-08-11 13:08:10 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-15 13:24:27 +01:00
|
|
|
return 1;
|
2004-08-11 13:08:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-11 12:22:20 +01:00
|
|
|
//! Prune determination
|
|
|
|
/**
|
|
|
|
*@returns true iff this state is invalid for some reason
|
|
|
|
*/
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
prune ()
|
2004-08-11 12:22:20 +01:00
|
|
|
{
|
2004-08-15 17:44:54 +01:00
|
|
|
Termlist tl;
|
|
|
|
|
2004-08-16 14:18:04 +01:00
|
|
|
if (indentDepth > 20)
|
2004-08-13 14:25:25 +01:00
|
|
|
{
|
|
|
|
// Hardcoded limit on iterations
|
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Pruned because too many iteration levels.\n");
|
|
|
|
}
|
2004-08-13 14:25:25 +01:00
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-16 15:49:41 +01:00
|
|
|
if (sys->maxruns > sys->switchRuns)
|
2004-08-12 12:35:13 +01:00
|
|
|
{
|
|
|
|
// Hardcoded limit on runs
|
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Pruned because too many runs.\n");
|
|
|
|
}
|
2004-08-12 12:35:13 +01:00
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-15 17:44:54 +01:00
|
|
|
|
|
|
|
// Check if all agents are valid
|
|
|
|
tl = sys->runs[0].agents;
|
|
|
|
while (tl != NULL)
|
|
|
|
{
|
|
|
|
Term agent;
|
|
|
|
|
|
|
|
agent = deVar (tl->term);
|
|
|
|
if (!realTermLeaf (agent))
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Pruned because agent cannot be compound term.\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!inTermlist (agent->stype, TERM_Agent))
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Pruned because agent must contain agent type.\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-16 15:49:41 +01:00
|
|
|
if (!realTermVariable (agent) && inTermlist (sys->untrusted, agent))
|
2004-08-15 17:44:54 +01:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
2004-08-17 12:30:03 +01:00
|
|
|
eprintf
|
|
|
|
("Pruned because all agents of the claim run must be trusted.\n");
|
2004-08-15 17:44:54 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
tl = tl->next;
|
|
|
|
}
|
|
|
|
|
2004-08-11 12:22:20 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-08-14 20:19:23 +01:00
|
|
|
//! Setup system for specific claim test
|
|
|
|
add_claim_specifics (Claimlist cl, Roledef rd)
|
|
|
|
{
|
2004-08-15 15:07:34 +01:00
|
|
|
if (cl->type == CLAIM_Secret)
|
2004-08-14 20:19:23 +01:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Secrecy claim
|
|
|
|
*/
|
|
|
|
create_intruder_goal (rd->message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-11 13:08:10 +01:00
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Main logic core
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
2004-08-11 10:51:17 +01:00
|
|
|
//! Main recursive procedure for Arachne
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
iterate ()
|
2004-08-11 12:22:20 +01:00
|
|
|
{
|
2004-08-11 22:04:52 +01:00
|
|
|
int flag;
|
2004-08-11 13:08:10 +01:00
|
|
|
Goal goal;
|
|
|
|
|
2004-08-11 22:04:52 +01:00
|
|
|
flag = 1;
|
2004-08-12 10:14:31 +01:00
|
|
|
indentDepth++;
|
2004-08-12 12:35:13 +01:00
|
|
|
if (!prune ())
|
2004-08-11 22:04:52 +01:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Not pruned: count
|
|
|
|
*/
|
2004-08-11 15:09:12 +01:00
|
|
|
|
2004-08-11 22:04:52 +01:00
|
|
|
sys->states = statesIncrease (sys->states);
|
|
|
|
#ifdef DEBUG
|
2004-08-14 17:12:32 +01:00
|
|
|
if (DEBUGL (3) && explanation != NULL)
|
2004-08-11 22:04:52 +01:00
|
|
|
{
|
2004-08-17 12:30:03 +01:00
|
|
|
indentDepth--;
|
2004-08-12 12:35:13 +01:00
|
|
|
indentPrint ();
|
2004-08-17 12:30:03 +01:00
|
|
|
indentDepth++;
|
2004-08-14 19:38:43 +01:00
|
|
|
eprintf ("ITERATE: %s", explanation);
|
2004-08-12 13:28:57 +01:00
|
|
|
|
|
|
|
if (e_run != INVALID)
|
|
|
|
eprintf ("#%i ", e_run);
|
|
|
|
if (e_term1 != NULL)
|
|
|
|
{
|
|
|
|
termPrint (e_term1);
|
|
|
|
eprintf (" ");
|
|
|
|
}
|
|
|
|
if (e_term2 != NULL)
|
|
|
|
{
|
|
|
|
termPrint (e_term2);
|
|
|
|
eprintf (" ");
|
|
|
|
}
|
|
|
|
if (e_term3 != NULL)
|
|
|
|
{
|
|
|
|
termPrint (e_term3);
|
|
|
|
eprintf (" ");
|
|
|
|
}
|
2004-08-14 19:38:43 +01:00
|
|
|
eprintf (" ]}>=--\n");
|
2004-08-11 22:04:52 +01:00
|
|
|
}
|
|
|
|
#endif
|
2004-08-11 13:08:10 +01:00
|
|
|
|
2004-08-11 22:04:52 +01:00
|
|
|
/**
|
|
|
|
* Check whether its a final state (i.e. all goals bound)
|
2004-08-11 13:08:10 +01:00
|
|
|
*/
|
2004-08-11 22:04:52 +01:00
|
|
|
|
|
|
|
goal = select_goal ();
|
|
|
|
if (goal.run == INVALID)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* all goals bound, check for property
|
|
|
|
*/
|
2004-08-13 09:29:11 +01:00
|
|
|
sys->claims = statesIncrease (sys->claims);
|
2004-08-14 17:12:32 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (3))
|
|
|
|
{
|
|
|
|
printSemiState ();
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-11 22:04:52 +01:00
|
|
|
//!@todo Property check in Arachne.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-12 12:35:13 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-14 17:26:57 +01:00
|
|
|
if (DEBUGL (3))
|
2004-08-14 17:12:32 +01:00
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Trying to bind goal ");
|
|
|
|
termPrint (goal.rd->message);
|
|
|
|
eprintf (" from run %i, index %i.\n", goal.run, goal.index);
|
|
|
|
}
|
2004-08-12 12:35:13 +01:00
|
|
|
#endif
|
2004-08-11 22:04:52 +01:00
|
|
|
/*
|
|
|
|
* bind this goal in all possible ways and iterate
|
|
|
|
*/
|
|
|
|
flag = bind_goal (goal);
|
|
|
|
}
|
2004-08-11 13:08:10 +01:00
|
|
|
}
|
2004-08-13 21:09:12 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
explanation = NULL;
|
|
|
|
e_run = INVALID;
|
|
|
|
e_term1 = NULL;
|
|
|
|
e_term2 = NULL;
|
|
|
|
e_term3 = NULL;
|
|
|
|
#endif
|
2004-08-12 10:14:31 +01:00
|
|
|
indentDepth--;
|
2004-08-11 22:04:52 +01:00
|
|
|
return flag;
|
2004-08-11 12:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Main code for Arachne
|
|
|
|
/**
|
|
|
|
* For this test, we manually set up some stuff.
|
2004-08-12 12:35:13 +01:00
|
|
|
*
|
|
|
|
* But later, this will just iterate over all claims.
|
2004-08-11 12:22:20 +01:00
|
|
|
*/
|
|
|
|
int
|
2004-08-11 15:09:12 +01:00
|
|
|
arachne ()
|
2004-08-11 10:51:17 +01:00
|
|
|
{
|
2004-08-14 16:59:14 +01:00
|
|
|
Claimlist cl;
|
2004-08-11 12:22:20 +01:00
|
|
|
/*
|
|
|
|
* set up claim role(s)
|
|
|
|
*/
|
2004-08-12 12:35:13 +01:00
|
|
|
|
|
|
|
if (sys->maxruns > 0)
|
|
|
|
{
|
2004-08-14 16:59:14 +01:00
|
|
|
error ("Something is wrong, number of runs >0.");
|
2004-08-12 12:35:13 +01:00
|
|
|
}
|
|
|
|
|
2004-08-13 21:56:51 +01:00
|
|
|
int print_send (Protocol p, Role r, Roledef rd, int index)
|
|
|
|
{
|
|
|
|
eprintf ("IRS: ");
|
|
|
|
termPrint (p->nameterm);
|
|
|
|
eprintf (", ");
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
eprintf (", %i, ", index);
|
|
|
|
roledefPrint (rd);
|
|
|
|
eprintf ("\n");
|
|
|
|
}
|
|
|
|
|
2004-08-14 17:12:32 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (1))
|
|
|
|
{
|
|
|
|
iterate_role_sends (print_send);
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-13 21:56:51 +01:00
|
|
|
|
2004-08-13 12:11:59 +01:00
|
|
|
indentDepth = 0;
|
2004-08-14 16:59:14 +01:00
|
|
|
cl = sys->claimlist;
|
|
|
|
while (cl != NULL)
|
|
|
|
{
|
2004-08-15 17:44:54 +01:00
|
|
|
/**
|
|
|
|
* Check each claim
|
|
|
|
*/
|
2004-08-14 16:59:14 +01:00
|
|
|
Protocol p;
|
|
|
|
Role r;
|
2004-08-11 12:22:20 +01:00
|
|
|
|
2004-08-15 17:44:54 +01:00
|
|
|
if (sys->switchClaimToCheck == NULL
|
|
|
|
|| sys->switchClaimToCheck == cl->type)
|
2004-08-14 17:12:32 +01:00
|
|
|
{
|
2004-08-16 10:50:37 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-15 17:44:54 +01:00
|
|
|
explanation = NULL;
|
|
|
|
e_run = INVALID;
|
|
|
|
e_term1 = NULL;
|
|
|
|
e_term2 = NULL;
|
|
|
|
e_term3 = NULL;
|
2004-08-16 10:50:37 +01:00
|
|
|
#endif
|
2004-08-15 17:44:54 +01:00
|
|
|
|
|
|
|
p = (Protocol) cl->protocol;
|
|
|
|
r = (Role) cl->role;
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (DEBUGL (2))
|
|
|
|
{
|
|
|
|
indentPrint ();
|
|
|
|
eprintf ("Testing Claim ");
|
|
|
|
termPrint (cl->type);
|
|
|
|
eprintf (" in protocol ");
|
|
|
|
termPrint (p->nameterm);
|
|
|
|
eprintf (", role ");
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
eprintf (" at index %i.\n", cl->ev);
|
|
|
|
}
|
2004-08-14 17:12:32 +01:00
|
|
|
#endif
|
2004-08-14 16:59:14 +01:00
|
|
|
|
2004-08-15 20:58:26 +01:00
|
|
|
roleInstance (sys, p, r, NULL, NULL);
|
2004-08-15 17:44:54 +01:00
|
|
|
sys->runs[0].length = cl->ev + 1;
|
2004-08-14 20:19:23 +01:00
|
|
|
|
2004-08-15 17:44:54 +01:00
|
|
|
/**
|
|
|
|
* Add specific goal info
|
|
|
|
*/
|
|
|
|
add_claim_specifics (cl,
|
|
|
|
roledef_shift (sys->runs[0].start, cl->ev));
|
2004-08-14 20:19:23 +01:00
|
|
|
|
2004-08-14 16:59:14 +01:00
|
|
|
#ifdef DEBUG
|
2004-08-15 17:44:54 +01:00
|
|
|
if (DEBUGL (5))
|
|
|
|
{
|
|
|
|
printSemiState ();
|
|
|
|
}
|
2004-08-14 16:59:14 +01:00
|
|
|
#endif
|
|
|
|
|
2004-08-15 17:44:54 +01:00
|
|
|
/*
|
|
|
|
* iterate
|
|
|
|
*/
|
|
|
|
iterate ();
|
2004-08-14 16:59:14 +01:00
|
|
|
|
2004-08-15 17:44:54 +01:00
|
|
|
//! Destroy
|
|
|
|
while (sys->maxruns > 0)
|
|
|
|
{
|
|
|
|
roleInstanceDestroy (sys);
|
|
|
|
}
|
2004-08-14 20:19:23 +01:00
|
|
|
}
|
2004-08-14 16:59:14 +01:00
|
|
|
// next
|
|
|
|
cl = cl->next;
|
|
|
|
}
|
2004-08-11 10:51:17 +01:00
|
|
|
}
|
2004-08-17 16:52:52 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Done: add_read_goals, remove_read_goals.
|
|
|
|
*
|
|
|
|
* Now we must make the new algorithm.
|
|
|
|
* At role instance (of e.g. claim), fix add_read_goals.
|
|
|
|
*
|
|
|
|
* Iterate on roles. Create new roles for intruder (encrypt RRS, decrypt RRS, and M_0 S)
|
|
|
|
* Check for bindings_c_minimal.
|
|
|
|
*/
|