2006-07-27 12:55:24 +01:00
|
|
|
/**
|
|
|
|
* Initial intruder knowledge computation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "intruderknowledge.h"
|
|
|
|
|
|
|
|
//! Add a (copy of) a term to the intruder knowledge
|
|
|
|
void
|
|
|
|
addSTerm (const System sys, Term t, Termlist fromlist, Termlist tolist)
|
|
|
|
{
|
|
|
|
Term t2;
|
|
|
|
|
|
|
|
t2 = termLocal (t, fromlist, tolist);
|
2006-07-31 12:08:51 +01:00
|
|
|
|
2006-07-31 12:30:08 +01:00
|
|
|
if (switches.check)
|
|
|
|
{
|
2006-07-31 12:31:52 +01:00
|
|
|
globalError++;
|
2006-07-31 12:30:08 +01:00
|
|
|
eprintf ("[ Adding ");
|
|
|
|
termPrint (t2);
|
|
|
|
eprintf (" to the initial intruder knowledge]\n");
|
2006-07-31 12:31:52 +01:00
|
|
|
globalError--;
|
2006-07-31 12:30:08 +01:00
|
|
|
}
|
2006-07-27 12:55:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Unfold the term for all possible options
|
|
|
|
void
|
|
|
|
addEnumTerm (const System sys, Term t, Term actor, Termlist todo,
|
|
|
|
Termlist fromlist, Termlist tolist)
|
|
|
|
{
|
|
|
|
if (todo == NULL)
|
|
|
|
{
|
|
|
|
addSTerm (sys, t, fromlist, tolist);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (termSubTerm (t, todo->term))
|
|
|
|
{
|
|
|
|
// Occurs, we have to iterate
|
|
|
|
void iterateThis (Term to)
|
|
|
|
{
|
|
|
|
tolist = termlistPrepend (tolist, to);
|
|
|
|
|
|
|
|
addEnumTerm (sys, t, actor, todo->next, fromlist, tolist);
|
|
|
|
|
|
|
|
tolist = termlistDelTerm (tolist);
|
|
|
|
}
|
|
|
|
|
2007-01-06 18:01:36 +00:00
|
|
|
fromlist = termlistPrepend (fromlist, todo->term);
|
2006-07-27 12:55:24 +01:00
|
|
|
if (isTermEqual (todo->term, actor))
|
|
|
|
{
|
|
|
|
// Untrusted agents only
|
|
|
|
Termlist tl;
|
|
|
|
|
|
|
|
for (tl = sys->untrusted; tl != NULL; tl = tl->next)
|
|
|
|
{
|
|
|
|
iterateThis (tl->term);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// any agents
|
|
|
|
Termlist tl;
|
|
|
|
|
|
|
|
for (tl = sys->agentnames; tl != NULL; tl = tl->next)
|
|
|
|
{
|
|
|
|
iterateThis (tl->term);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fromlist = termlistDelTerm (fromlist);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Simply proceed to next
|
|
|
|
addEnumTerm (sys, t, actor, todo->next, fromlist, tolist);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Does t contain any of sublist?
|
|
|
|
int
|
|
|
|
anySubTerm (Term t, Termlist sublist)
|
|
|
|
{
|
|
|
|
while (sublist != NULL)
|
|
|
|
{
|
|
|
|
if (termSubTerm (t, sublist->term))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
sublist = sublist->next;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
initialIntruderKnowledge (const System sys)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* display initial role knowledge
|
|
|
|
*/
|
|
|
|
int deriveFromRole (Protocol p, Role r)
|
|
|
|
{
|
|
|
|
void addListKnowledge (Termlist tl, Term actor)
|
|
|
|
{
|
|
|
|
void addTermKnowledge (Term t)
|
|
|
|
{
|
|
|
|
if (anySubTerm (t, p->rolenames))
|
|
|
|
{
|
2006-07-27 15:19:19 +01:00
|
|
|
Term f;
|
2006-07-27 12:55:24 +01:00
|
|
|
// Has rolename subterms. We have to enumerate those.
|
2006-07-27 15:19:19 +01:00
|
|
|
/**
|
|
|
|
* Hack. Enumerating is not always good (or even desirable).
|
|
|
|
* If some I knows sk(I), sk should not be in the intruder knowledge.
|
|
|
|
* But for hash(I), we typically would have h; but if it is never used differently, it would suffice.
|
2007-01-06 14:45:29 +00:00
|
|
|
* To summarize, the operational semantics definition is perfectly fine, but maybe a bit strict sometimes.
|
2006-07-27 15:19:19 +01:00
|
|
|
*
|
|
|
|
* The hack is that if function application:
|
|
|
|
*/
|
|
|
|
f = getTermFunction (t);
|
|
|
|
if (f != NULL)
|
|
|
|
{
|
|
|
|
// it's a function, right. So we see whether it is public. It is if it does not contain the actor...
|
|
|
|
if (!termSubTerm (t, actor))
|
|
|
|
{
|
|
|
|
// no actor, then nothing secret I guess.
|
|
|
|
addSTerm (sys, f, NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// has actor. but does it contain even more?
|
|
|
|
|
|
|
|
int allagents (Term t)
|
|
|
|
{
|
|
|
|
if (!inTermlist (sys->agentnames, t))
|
|
|
|
{
|
|
|
|
if (!inTermlist (p->rolenames, t))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!term_iterate_leaves (TermOp (t), allagents))
|
|
|
|
{
|
|
|
|
// something else as well, so that probably means a hash or something like that.
|
|
|
|
addSTerm (sys, f, NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// otherwise, we enumerate
|
2006-07-27 12:55:24 +01:00
|
|
|
addEnumTerm (sys, t, actor, p->rolenames, NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No actor subterm. Simply add.
|
|
|
|
addSTerm (sys, t, NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (tl != NULL)
|
|
|
|
{
|
|
|
|
addTermKnowledge (tl->term);
|
|
|
|
tl = tl->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-31 12:08:51 +01:00
|
|
|
if (switches.check)
|
|
|
|
{
|
2006-07-31 12:31:52 +01:00
|
|
|
globalError++;
|
2006-07-31 12:08:51 +01:00
|
|
|
eprintf ("Role ");
|
|
|
|
termPrint (r->nameterm);
|
|
|
|
eprintf (" knows ");
|
|
|
|
termlistPrint (r->knows);
|
|
|
|
eprintf ("\n");
|
2006-07-31 12:31:52 +01:00
|
|
|
globalError--;
|
2006-07-31 12:08:51 +01:00
|
|
|
}
|
2006-07-27 12:55:24 +01:00
|
|
|
addListKnowledge (r->knows, r->nameterm);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-01-06 18:01:36 +00:00
|
|
|
if (switches.check)
|
|
|
|
{
|
|
|
|
globalError++;
|
|
|
|
eprintf ("Computing initial intruder knowledge.\n\n");
|
|
|
|
eprintf ("Agent names : ");
|
|
|
|
termlistPrint (sys->agentnames);
|
|
|
|
eprintf ("\n");
|
|
|
|
eprintf ("Untrusted agents : ");
|
|
|
|
termlistPrint (sys->untrusted);
|
|
|
|
eprintf ("\n");
|
|
|
|
globalError--;
|
|
|
|
}
|
|
|
|
|
2006-07-27 12:55:24 +01:00
|
|
|
iterateRoles (sys, deriveFromRole);
|
|
|
|
}
|