scyther/src/output.c

700 lines
14 KiB
C
Raw Normal View History

2004-04-23 11:58:43 +01:00
/*
* output.c
*
* Outputs an attack.
* Currently, every attack is printed.
* TODO move attacks to a buffer, and print _only_ the shortest one.
*/
#include <stdlib.h>
#include <stdio.h>
#include "system.h"
2004-04-23 11:58:43 +01:00
#include "latex.h"
void
linePrint (int i)
2004-04-23 11:58:43 +01:00
{
indent ();
while (i > 0)
{
printf ("--------");
i--;
2004-04-23 11:58:43 +01:00
}
printf ("\n");
2004-04-23 11:58:43 +01:00
}
int
correspondingSend (const System sys, int rd)
2004-04-23 11:58:43 +01:00
{
int labelMatch = 0;
int toMatch = 0;
int fromMatch = 0;
int tofromMatch = 0;
int messageMatch = 0;
int nMatches = 0;
int maxNMatches = 0;
int readEvent = rd;
int sendEvent = -1;
int bestSendEvent = -1;
for (sendEvent = readEvent; sendEvent >= 0; sendEvent--)
{
if (sys->traceEvent[sendEvent]->type == SEND)
{
/* do all the different kind of matchings first */
labelMatch =
isTermEqualFn (sys->traceEvent[sendEvent]->label,
sys->traceEvent[readEvent]->label);
toMatch =
isTermEqualFn (sys->traceEvent[sendEvent]->to,
sys->traceEvent[readEvent]->to);
fromMatch =
isTermEqualFn (sys->traceEvent[sendEvent]->from,
sys->traceEvent[readEvent]->from);
tofromMatch = toMatch || fromMatch;
messageMatch =
isTermEqualFn (sys->traceEvent[sendEvent]->message,
sys->traceEvent[readEvent]->message);
/* calculate the score */
nMatches = labelMatch + tofromMatch + messageMatch;
if (nMatches == 3)
{
/* bingo! success on all matches */
//printf("Found perfect match: %d\n", s);
bestSendEvent = sendEvent;
break;
2004-04-23 11:58:43 +01:00
}
if (nMatches > maxNMatches)
{
/* if we found a better candidate than we already had, we'll update */
2004-04-23 11:58:43 +01:00
//printf("Comparing SEND #%d: ",s);
//if (labelMatch) printf("label ");
//if (toMatch) printf("to ");
//if (fromMatch) printf("from ");
//if (messageMatch) printf("message ");
//printf("\n");
2004-04-23 11:58:43 +01:00
/* however, we first want to be sure that at least some matches are successful */
2004-04-23 11:58:43 +01:00
if (labelMatch && messageMatch)
{
/* strongest restriction: message and label should match */
2004-04-23 11:58:43 +01:00
maxNMatches = nMatches;
bestSendEvent = sendEvent;
2004-04-23 11:58:43 +01:00
}
else if (messageMatch)
{
/* if label AND message don't match: */
/* at least message should match */
2004-04-23 11:58:43 +01:00
maxNMatches = nMatches;
bestSendEvent = sendEvent;
}
else if (labelMatch)
{
/* if message doesn't match */
/* the label should matches */
2004-04-23 11:58:43 +01:00
maxNMatches = nMatches;
bestSendEvent = sendEvent;
2004-04-23 11:58:43 +01:00
}
//printf("Best match: %d maxNMatches: %d\n", s, maxNMatches);
2004-04-23 11:58:43 +01:00
}
}
}
//bestSendEvent = NULL;
if (bestSendEvent == -1)
{
/*Termlist tl;
Term t;
//newtl = knowledgeNew(sys->traceKnow[i],sys->traceKnow[i+1]);
for (tl = sys->traceKnow[rd]->basic; tl != NULL; tl = tl->next)
{
t = tl->term;
termPrint(t);
printf(" - ");
}
printf("\n");
for (tl = sys->traceKnow[rd]->encrypt; tl != NULL; tl = tl->next)
{
t = tl->term;
termPrint(t);
printf(" - ");
}
printf("\n");
for (tl = sys->traceKnow[rd]->inverses; tl != NULL; tl = tl->next)
{
t = tl->term;
termPrint(t);
printf(" - ");
}
printf("\n"); */
int u;
for (u = 0; u < rd; u++)
{
if (sys->traceEvent[u]->type == SEND)
{
//termPrint(readEvent->message);
//printf("\n");
knowledgePrint (sys->traceKnow[u]);
//printf("Is received message in knowledge after SEND %d? %d\n", u, inKnowledge(sys->traceKnow[u+1],readEvent->message));
if (inKnowledge
(sys->traceKnow[u + 1],
sys->traceEvent[readEvent]->message))
{
bestSendEvent = u;
break;
2004-04-23 11:58:43 +01:00
}
}
}
}
if (bestSendEvent == -1)
{
printf ("!! Could not find a matching SEND\n");
}
else
{
//latexMessagePrint(sys, bestSendEvent, readEvent);
//printf("Latex: ");
//termPrint(bestSendEvent->from);
//printf(" -> ");
if (!isTermEqualFn
(sys->traceEvent[bestSendEvent]->to,
sys->traceEvent[readEvent]->to))
{
//termPrint(bestSendEvent->to);
//printf(" -> ");
2004-04-23 11:58:43 +01:00
}
if (!isTermEqualFn
(sys->traceEvent[bestSendEvent]->from,
sys->traceEvent[readEvent]->from))
{
//termPrint(readEvent->from);
//printf(" -> ");
2004-04-23 11:58:43 +01:00
}
//termPrint(readEvent->to);
//printf("\n");
2004-04-23 11:58:43 +01:00
}
return bestSendEvent;
2004-04-23 11:58:43 +01:00
}
void
tracePrint (const System sys)
2004-04-23 11:58:43 +01:00
{
2004-05-26 13:17:09 +01:00
int i, j;
int lastrid;
int width;
Termlist newtl;
void sticks (int i)
{
while (i > 0)
{
printf ("|\t");
i--;
}
}
void sticksLine (void)
{
sticks (width);
printf ("\n");
}
if (sys->latex)
{
//latexTracePrint(sys);
return;
2004-04-23 11:58:43 +01:00
}
/* fix the 'next' knowledge, this is required because sometimes
* when calling this function, the next knowledge is not stored
* yet, but required for the general form of the output . */
2004-04-23 11:58:43 +01:00
sys->traceKnow[sys->step + 1] = sys->know;
2004-04-23 11:58:43 +01:00
/* how wide is the trace? */
width = 0;
for (i = 0; i <= sys->step; i++)
{
if (sys->traceRun[i] >= width)
width = sys->traceRun[i] + 1;
2004-04-23 11:58:43 +01:00
}
linePrint (width);
indent ();
printf ("Dumping trace:\n");
linePrint (width);
2004-04-23 11:58:43 +01:00
/* first some parameter issues */
2004-04-23 11:58:43 +01:00
knowledgePrint (sys->traceKnow[0]);
/* also print inverses */
indent ();
printf ("Inverses: ");
knowledgeInversesPrint (sys->traceKnow[0]);
printf ("\n");
2004-04-23 11:58:43 +01:00
/* Trace columns header. First the run identifier and role. On the
* second line we have the perceived agents for each partner role.
* These are printed in the same order as the role specification in the
* protocol. */
2004-04-23 11:58:43 +01:00
linePrint (width);
indent ();
2004-04-23 11:58:43 +01:00
for (i = 0; i < width; i++)
{
termPrint (sys->runs[i].role->nameterm);
printf ("#%i\t", i);
2004-04-23 11:58:43 +01:00
}
printf ("\n");
for (i = 0; i < width; i++)
{
termPrint (agentOfRun (sys, i));
printf ("\t");
2004-04-23 11:58:43 +01:00
}
printf ("\n");
2004-04-23 11:58:43 +01:00
for (i = 0; i < width; i++)
{
agentsOfRunPrint (sys, i);
printf ("\t");
2004-04-23 11:58:43 +01:00
}
printf ("\n");
2004-04-23 11:58:43 +01:00
/* now we print the actual trace */
2004-04-23 11:58:43 +01:00
linePrint (width);
lastrid = -1;
for (i = 0; i <= sys->step; i++)
{
/* yields extra newlines between switching of runs */
j = sys->traceRun[i];
if (j != lastrid)
{
sticksLine ();
lastrid = j;
2004-04-23 11:58:43 +01:00
}
/* print the actual event */
indent ();
sticks (j);
roledefPrint (sys->traceEvent[i]);
//if (sys->traceEvent[i]->type == READ && !sys->traceEvent[i]->internal)
//{
/* calls routine to find the best SEND-candidate */
/* the result is not yet being used */
// printf("\n");
// correspondingSend(sys, i);
//}
/* have we learnt anything new? */
newtl = knowledgeNew (sys->traceKnow[i], sys->traceKnow[i + 1]);
if (newtl != NULL)
{
printf ("\n");
sticksLine ();
sticks (width);
printf ("/* Intruder learns ");
termlistPrint (newtl);
termlistDelete (newtl);
printf (" */");
lastrid = -1;
2004-04-23 11:58:43 +01:00
}
/* new line */
printf ("\n");
2004-04-23 11:58:43 +01:00
}
switch (sys->clp)
{
2004-04-23 11:58:43 +01:00
case 1:
indent ();
printf ("---[ constraints ]-----\n");
constraintlistPrint (sys->constraints);
break;
2004-04-23 11:58:43 +01:00
default:
break;
2004-04-23 11:58:43 +01:00
}
linePrint (width);
2004-04-23 11:58:43 +01:00
}
void
attackDisplayAscii (const System sys)
2004-04-23 11:58:43 +01:00
{
int i, j;
int length;
int lastrid;
int width;
Termlist newtl;
struct tracebuf *tb;
2004-05-26 13:17:09 +01:00
void sticks (int i)
{
while (i > 0)
{
printf ("|\t");
i--;
}
}
void sticksLine (void)
{
sticks (width);
printf ("\n");
}
/* attack trace buffer */
tb = sys->attack;
length = sys->attack->length;
/* set variables */
varbufSet (sys, tb->variables);
/* how wide is the trace? */
width = 0;
for (i = 0; i < length; i++)
{
if (tb->run[i] >= width)
width = tb->run[i] + 1;
2004-04-23 11:58:43 +01:00
}
linePrint (width);
indent ();
printf ("Dumping trace:\n");
linePrint (width);
2004-04-23 11:58:43 +01:00
/* first some parameter issues */
2004-04-23 11:58:43 +01:00
knowledgePrint (tb->know[0]);
printf ("Variables: ");
termlistPrint (sys->variables);
printf ("\n");
2004-04-23 11:58:43 +01:00
/* Trace columns header. First the run identifier and role. On the
* second line we have the perceived agents for each partner role.
* These are printed in the same order as the role specification in the
* protocol. */
2004-04-23 11:58:43 +01:00
linePrint (width);
indent ();
2004-04-23 11:58:43 +01:00
for (i = 0; i < width; i++)
{
termPrint (sys->runs[i].role->nameterm);
printf ("#%i\t", i);
2004-04-23 11:58:43 +01:00
}
printf ("\n");
for (i = 0; i < width; i++)
{
termPrint (agentOfRun (sys, i));
printf ("\t");
2004-04-23 11:58:43 +01:00
}
printf ("\n");
2004-04-23 11:58:43 +01:00
for (i = 0; i < width; i++)
{
agentsOfRunPrint (sys, i);
printf ("\t");
2004-04-23 11:58:43 +01:00
}
printf ("\n");
2004-04-23 11:58:43 +01:00
/* now we print the actual trace */
2004-04-23 11:58:43 +01:00
linePrint (width);
lastrid = -1;
for (i = 0; i < length; i++)
{
/* yields extra newlines between switching of runs */
j = tb->run[i];
if (j != lastrid)
{
sticksLine ();
lastrid = j;
2004-04-23 11:58:43 +01:00
}
/* print the actual event */
indent ();
sticks (j);
roledefPrint (tb->event[i]);
//if (sys->traceEvent[i]->type == READ && !sys->traceEvent[i]->internal)
//{
/* calls routine to find the best SEND-candidate */
/* the result is not yet being used */
// printf("\n");
// correspondingSend(sys, i);
//}
/* have we learnt anything new? */
newtl = knowledgeNew (tb->know[i], tb->know[i + 1]);
if (newtl != NULL)
{
printf ("\n");
sticksLine ();
sticks (width);
printf ("/* Intruder learns ");
termlistPrint (newtl);
termlistDelete (newtl);
printf (" */");
lastrid = -1;
2004-04-23 11:58:43 +01:00
}
/* new line */
printf ("\n");
2004-04-23 11:58:43 +01:00
}
linePrint (width);
2004-04-23 11:58:43 +01:00
}
void
attackDisplay (const System sys)
2004-04-23 11:58:43 +01:00
{
if (sys->latex)
{
attackDisplayLatex (sys);
}
else
{
attackDisplayAscii (sys);
2004-04-23 11:58:43 +01:00
}
}
/*
*-------------------------------------------
* state space graph section
*-------------------------------------------
*/
void graphInit (const System sys)
{
Termlist tl;
2004-07-12 15:47:43 +01:00
/* drawing state space. */
printf ("digraph Statespace {\n");
2004-07-12 15:47:43 +01:00
/* label */
printf ("\tcomment = \"$");
commandlinePrint (stdout, sys);
printf ("\";\n");
2004-07-12 15:47:43 +01:00
/* fit stuff onto the page */
printf ("\trankdir=LR;\n");
printf ("\tsize=\"8.5,11\";\n");
//printf ("\tpage=\"8.5,11\";\n");
printf ("\tfontsize=\"6\";\n");
printf ("\tfontname=\"Helvetica\";\n");
printf ("\tmargin=0.5;\n");
printf ("\tnodesep=0.06;\n");
printf ("\tranksep=0.01;\n");
2004-07-12 15:47:43 +01:00
printf ("\torientation=landscape;\n");
printf ("\tcenter=true;\n");
// printf ("\tlabeljust=\"r\";\n");
printf ("\tconcentrate=true;\n");
/* node/edge defaults */
printf ("\tnode [shape=\"point\",fontsize=\"4\",fontname=\"Helvetica\"];\n");
printf ("\tedge [fontsize=\"4\",fontname=\"Helvetica\"];\n");
2004-07-12 15:47:43 +01:00
/* start with initial node 0 */
printf ("\tn");
statesFormat (stdout, STATES0);
printf (" [shape=box,height=0.2,label=\"M0: ");
tl = knowledgeSet (sys->know);
termlistPrint (tl);
termlistDelete (tl);
printf ("\"];\n");
}
void graphDone (const System sys)
{
/* drawing state space. close up. */
printf ("}\n");
}
void graphNode (const System sys)
{
Termlist newtl;
states_t thisNode, parentNode;
2004-07-13 12:37:55 +01:00
int index;
int run;
2004-07-13 12:37:55 +01:00
Roledef rd;
/* determine node numbers */
2004-07-13 12:37:55 +01:00
index = sys->step - 1;
parentNode = sys->traceNode[index];
thisNode = sys->states;
2004-07-13 12:37:55 +01:00
rd = sys->traceEvent[index];
run = sys->traceRun[index];
/* add node */
printf ("\tn");
statesFormat (stdout, thisNode);
printf (" [");
2004-07-13 12:37:55 +01:00
newtl = knowledgeNew (sys->traceKnow[index], sys->traceKnow[index+1]);
if (newtl != NULL)
{
/* knowledge added */
printf ("shape=box,height=0.2,label=\"M + ");
termlistPrint (newtl);
termlistDelete (newtl);
printf ("\"");
}
else
{
/* no added knowledge */
if (sys->switchScenario != 0 &&
rd != NULL &&
rd == sys->runs[run].start &&
rd->type == READ &&
run == sys->lastChooseRun)
{
/* last choose; scenario selected */
printf ("shape=box,height=0.2,label=\"Scenario %i: ", sys->countScenario);
scenarioPrint (sys);
printf ("\"");
}
else
{
printf ("label=\"\"");
}
}
printf ("];\n");
/* add edge */
printf ("\tn");
statesFormat (stdout, parentNode);
printf (" -> n");
statesFormat (stdout, thisNode);
/* add label */
printf (" [label=\"");
// Print step
printf ("%i:",sys->runs[run].step-1);
if (rd->type == CLAIM && untrustedAgent (sys, sys->runs[run].agents))
2004-07-13 12:37:55 +01:00
{
printf ("Skip claim in #%i\"", run);
2004-07-13 12:37:55 +01:00
}
else
{
// Print event
2004-07-13 12:37:55 +01:00
roledefPrint (rd);
printf ("#%i\"", run);
2004-07-13 12:37:55 +01:00
if (rd->type == CLAIM)
{
printf (",shape=house,color=green");
2004-07-13 12:37:55 +01:00
}
}
/* a choose? */
2004-07-13 12:37:55 +01:00
if (rd->type == READ && rd->internal)
{
printf (",color=blue");
//printf (",style=dotted");
}
printf ("]");
printf (";\n");
}
void graphNodePath (const System sys, const int length, const char* nodepar)
{
int i;
states_t thisNode;
i = 0;
while (i < length)
{
/* determine node number */
thisNode = sys->traceNode[i];
2004-07-13 10:56:19 +01:00
/* color node */
printf ("\tn");
statesFormat (stdout, thisNode);
printf (" [%s];\n", nodepar);
i++;
}
}
void graphEdgePath (const System sys, const int length, const char* edgepar)
{
int i;
states_t thisNode, prevNode;
i = 0;
prevNode = sys->traceNode[i];
while (i < length)
{
/* determine node number */
thisNode = sys->traceNode[i+1];
2004-07-13 10:56:19 +01:00
/* color edge */
printf ("\tn");
statesFormat (stdout, prevNode);
printf (" -> n");
statesFormat (stdout, thisNode);
printf (" [%s];\n", edgepar);
prevNode = thisNode;
i++;
}
}
void graphPath (const System sys, int length)
{
graphNodePath (sys,length,"style=bold,color=red");
graphEdgePath (sys,length-1,"style=bold,color=red");
}
//! Scenario for graph; bit of a hack
void
graphScenario (const System sys, const int run, const Roledef rd)
{
/* Add scenario node */
printf ("\ts%i [shape=box,height=0.2,label=\"Scenario %i: ",
sys->countScenario,
sys->countScenario);
scenarioPrint (sys);
printf ("\"];\n");
/* draw edge */
printf ("\tn%i -> s%i",
sys->traceNode[sys->step],
sys->countScenario);
printf (" [color=blue,label=\"");
printf ("%i:",sys->runs[run].step);
roledefPrint (rd);
printf ("#%i", run);
printf ("\"];\n");
}