- Preceding label sets are now correctly computed.

This commit is contained in:
ccremers 2004-06-16 10:39:13 +00:00
parent 9634034ebb
commit 1900f7d4fb
3 changed files with 364 additions and 14 deletions

View File

@ -748,22 +748,314 @@ tacTermlist (Tac tc)
}
//! Compute prec() sets for each claim.
/**
* Generates two auxiliary structures. First, a table that contains
* a mapping from all events to event/claim labels.
* A second table is used to compute the precedence order, and
* Warshall's algorithm is used to compute the transitive closure.
*@returns For each claim in the claim list, a preceding label set is defined.
*/
void
compute_prec_sets (const System sys)
{
Term *eventlabels; // array: maps events to labels
int *prec; // array: maps event*event to precedence
int size; // temp constant: rolecount * roleeventmax
int r1,r2,ev1,ev2; // some counters
int i,j;
Claimlist cl;
// Process each individual claim
// Assist: compute index from role, lev
int
index (int r, int lev)
{
return r * sys->roleeventmax + lev;
}
// Assist: compute matrix index from i*i
int
index2 (int i1, int i2)
{
return i1 * size + i2;
}
// Assist: yield roledef from r, lev
Roledef
roledef_re (int r, int lev)
{
Protocol pr;
Role ro;
Roledef rd;
pr = sys->protocols;
ro = pr->roles;
while (r > 0)
{
ro = ro->next;
if (ro == NULL)
{
pr = pr->next;
ro = pr->roles;
}
r--;
}
rd = ro->roledef;
while (lev > 0 && rd != NULL)
{
rd = rd->next;
lev--;
}
return rd;
}
// Assist: print matrix
void
show_matrix (void)
{
int r1, r2, ev1, ev2;
r1 = 0;
while (r1 < sys->rolecount)
{
ev1 = 0;
while (ev1 < sys->roleeventmax)
{
printf ("prec %i,%i: ", r1,ev1);
r2 = 0;
while (r2 < sys->rolecount)
{
ev2 = 0;
while (ev2 < sys->roleeventmax)
{
printf ("%i ", prec[index2 (index (r2,ev2), index (r1, ev1))]);
ev2++;
}
printf (" ");
r2++;
}
printf ("\n");
ev1++;
}
printf ("\n");
r1++;
}
printf ("\n");
}
/*
* Phase 1: Allocate structures and map to labels
*/
printf ("Rolecount: %i\n", sys->rolecount);
printf ("Maxevent : %i\n", sys->roleeventmax);
size = sys->rolecount * sys->roleeventmax;
eventlabels = memAlloc (size * sizeof(Term));
prec = memAlloc (size * size * sizeof(int));
// Clear tables
i = 0;
while (i < size)
{
eventlabels[i] = NULL;
j = 0;
while (j < size)
{
prec[index2(i,j)] = 0;
j++;
}
i++;
}
// Assign labels
r1 = 0;
while (r1 < sys->rolecount)
{
Roledef rd;
ev1 = 0;
rd = roledef_re (r1, ev1);
while (rd != NULL)
{
eventlabels[index(r1,ev1)] = rd->label;
termPrint (rd->label);
printf ("\t");
ev1++;
rd = rd->next;
}
printf ("\n");
r1++;
}
// Set simple precedence (progress within a role)
r1 = 0;
while (r1 < sys->rolecount)
{
ev1 = 0;
while (ev1 < (sys->roleeventmax - 1))
{
prec[index2 (index (r1,ev1),index (r1,ev1+1))] = 1;
ev1++;
}
r1++;
}
// Scan for label correspondence
r1 = 0;
while (r1 < sys->rolecount)
{
ev1 = 0;
while (ev1 < sys->roleeventmax)
{
Roledef rd1;
rd1 = roledef_re(r1,ev1);
if (rd1->type == SEND)
{
r2 = 0;
while (r2 < sys->rolecount)
{
ev2 = 0;
while (ev2 < sys->roleeventmax)
{
Roledef rd2;
rd2 = roledef_re(r2,ev2);
if (rd2->type == READ && isTermEqual(rd1->label, rd2->label))
{
prec[index2(index(r1,ev1),index(r2,ev2))] = 1;
}
ev2++;
}
r2++;
}
}
ev1++;
}
r1++;
}
//[x] show_matrix ();
/*
* Compute transitive closure (Warshall).
* If j<i and k<j, then k<i.
* Could be done more efficiently but that is irrelevant here.
*/
i = 0;
while (i < size)
{
j = 0;
while (j < size)
{
if (prec[index2 (j,i)] == 1)
{
int k;
k = 0;
while (k < size)
{
if (prec[index2 (k,j)] == 1)
{
prec[index2 (k,i)] = 1;
}
k++;
}
}
j++;
}
i++;
}
// [x] show_matrix ();
/*
* Last phase: Process all individual claims
*/
cl = sys->claimlist;
while (cl != NULL)
{
//!@todo compute transitive closure
Term t;
Roledef rd;
Term label;
label = cl->label;
// Locate r,lev from label, requires (TODO) unique labeling of claims!
r1 = 0;
ev1 = -1;
do
{
ev1++;
if (ev1 == sys->roleeventmax)
{
ev1 = 0;
r1++;
}
}
while (r1 < sys->rolecount && !isTermEqual (label, eventlabels[index(r1,ev1)]));
if (r1 == sys->rolecount)
{
error ("Prec() setup: Could not find the event corresponding to a claim label.");
}
rd = roledef_re (r1,ev1);
if (rd->type != CLAIM)
{
error ("Prec() setup: First event with claim label doesn't seem to be a claim.");
}
// Store in claimlist structure
cl->r = r1;
cl->ev = ev1;
/*
* We have found the claim roledef, and r1,ev1
* Now we compute the preceding label set
*/
cl->prec = NULL; // clear first
i = index (r1,ev1);
r2 = 0;
while (r2 < sys->rolecount)
{
Roledef rd2;
ev2 = 0;
rd = roledef_re (r2,ev2);
while (rd != NULL)
{
if (prec[index2 (index (r2,ev2),i)] == 1)
{
// This event precedes the claim
if (rd->type == READ)
{
// Only store read labels (but send would work as well)
cl->prec = termlistAdd (cl->prec, rd->label);
}
}
rd = rd->next;
ev2++;
}
r2++;
}
// Check for empty stuff
//@todo This is for debugging, mainly.
if (cl->prec == NULL)
{
fprintf (stderr, "Warning: claim with empty prec() set at r:%i, ev:%i\n",
r1,ev1);
}
else
{
printf ("Preceding label set for r:%i, ev:%i = ", r1,ev1);
termlistPrint (cl->prec);
printf ("\n");
}
// Proceed to next claim
cl = cl->next;
}
/*
* Cleanup
*/
memFree (eventlabels, size * sizeof(Term));
memFree (prec, size * size * sizeof(int));
}
//! Preprocess after system compilation
void
preprocess (const System sys)
{
sys->rolecount = compute_rolecount(sys);
sys->roleeventmax = compute_roleeventmax(sys);
compute_prec_sets(sys);
}

View File

@ -82,6 +82,8 @@ systemInit ()
sys->secrets = NULL; // list of claimed secrets
sys->attack = NULL;
/* no protocols => no protocol preprocessed */
sys->rolecount = 0;
sys->roleeventmax = 0;
sys->claimlist = NULL;
/* matching CLP */
@ -952,3 +954,52 @@ int attackLength(struct tracebuf* tb)
}
return len;
}
//! Get the number of roles in the system.
int compute_rolecount (const System sys)
{
Protocol pr;
int n;
n = 0;
pr = sys->protocols;
while (pr != NULL)
{
n = n + termlistLength(pr->rolenames);
pr = pr->next;
}
return n;
}
//! Compute the maximum number of events in a single role in the system.
int compute_roleeventmax (const System sys)
{
Protocol pr;
int maxev;
maxev = 0;
pr = sys->protocols;
while (pr != NULL)
{
Role r;
r = pr->roles;
while (r != NULL)
{
Roledef rd;
int n;
rd = r->roledef;
n = 0;
while (rd != NULL)
{
n++;
rd = rd->next;
}
if (n > maxev) maxev = n;
r = r->next;
}
pr = pr->next;
}
return maxev;
}

View File

@ -166,6 +166,8 @@ struct claimlist
int count;
//! Number of occurrences that failed.
int failed;
int r; //!< role number for mapping
int ev; //!< event index in role
//! Preceding label list
Termlist prec;
//! Next node pointer or NULL for the last element of the function.
@ -222,24 +224,26 @@ struct system
int clp; //!< Do we use clp?
/* protocol definition */
Protocol protocols;
Termlist locals;
Termlist variables;
Termlist untrusted;
Protocol protocols; //!< List of protocols in the system
Termlist locals; //!< List of local terms
Termlist variables; //!< List of all variables
Termlist untrusted; //!< List of untrusted agent names
/* protocol preprocessing */
Claimlist claimlist;
int rolecount; //!< Number of roles in the system
int roleeventmax; //!< Maximum number of events in a single role
Claimlist claimlist; //!< List of claims in the system, with occurrence counts
/* constructed trace pointers, static */
Roledef *traceEvent; // MaxRuns * maxRoledef
int *traceRun; // MaxRuns * maxRoledef
Knowledge *traceKnow; // Maxruns * maxRoledef
Roledef *traceEvent; //!< Trace roledefs: MaxRuns * maxRoledef
int *traceRun; //!< Trace run ids: MaxRuns * maxRoledef
Knowledge *traceKnow; //!< Trace intruder knowledge: Maxruns * maxRoledef
/* POR reduction assistance */
int PORphase; // -1: init (all sends), 0...: recurse reads
int PORdone; // simple bit to denote something was done.
int knowPhase; // which knowPhase have we already explored?
Constraintlist constraints; // only needed for CLP match
int PORphase; //!< -1: init (all sends), 0...: recurse reads
int PORdone; //!< Simple bit to denote something was done.
int knowPhase; //!< Which knowPhase have we already explored?
Constraintlist constraints; //!< Only needed for CLP match
//! Shortest attack storage.
struct tracebuf* attack;
@ -289,4 +293,7 @@ void agentsOfRunPrint (const System sys, const int run);
void violatedClaimPrint (const System sys, int i);
int attackLength(struct tracebuf* tb);
int compute_rolecount (const System sys);
int compute_roleeventmax (const System sys);
#endif