Improved checking of required parameters for various claims with informative error reporting.

This commit is contained in:
Cas Cremers 2012-05-01 16:37:18 +02:00
parent 8d0b704635
commit 6fabb3b1b4

View File

@ -483,6 +483,105 @@ isStringEqual (const char *s1, const char *s2)
return (strcmp (s1, s2) == 0); return (strcmp (s1, s2) == 0);
} }
//! Check sanity of the parameters occurring in a claim
/**
* Check if all variables have been received before.
* If not, aborts with error.
*/
void
checkParameterGround (Claimlist cl)
{
Termlist claimvars;
Termlist recvvars;
Termlist cli;
/* Compute received variables and those occurring in the claim parameter */
claimvars = termlistAddVariables (NULL, cl->parameter);
recvvars = compute_recv_variables (thisRole);
cli = claimvars;
while (cli != NULL)
{
if (!inTermlist (thisProtocol->rolenames, cli->term))
{
/* only if it is not a role */
if (!inTermlist (recvvars, cli->term))
{
/* this claimvar does not occur in the recvs? */
/* abort with error */
error_pre ();
globalError++;
eprintf ("Claim of role ");
termPrint (cl->rolename);
eprintf (" contains a variable ");
termPrint (cli->term);
eprintf
(" which is not initialized before (i.e., not received), on line %i.",
cl->lineno);
globalError--;
error_post ("");
}
}
cli = cli->next;
}
termlistDelete (claimvars);
termlistDelete (recvvars);
return;
}
//! Check if claim is of certain type, then check if meets parameter range, if not abort with error
void
checkParameterRange (const Claimlist cl, const Term claimtype, int minargs,
int maxargs)
{
Termlist params;
int num;
if (cl->type != claimtype)
{
return;
}
params = tuple_to_termlist (cl->parameter);
num = termlistLength (params);
if (minargs == -1)
{
minargs = num - 1;
}
if (maxargs == -1)
{
maxargs = num + 1;
}
if ((num < minargs) || (num > maxargs))
{
error_pre ();
globalError++;
termPrint (cl->type);
eprintf (" claim of role ");
termPrint (cl->rolename);
eprintf (" on line %i", cl->lineno);
if (maxargs == 0)
{
error_post (" does not require any arguments.");
}
else
{
if (num < minargs)
{
eprintf (" requires at least");
}
else
{
eprintf (" requires at most");
}
error_post (" %i arguments.", maxargs);
}
}
termlistDelete (params);
}
//! Create a claim and add it to the claims list, and add the role event. //! Create a claim and add it to the claims list, and add the role event.
Claimlist Claimlist
claimCreate (const System sys, const Protocol protocol, const Role role, claimCreate (const System sys, const Protocol protocol, const Role role,
@ -546,21 +645,23 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
/* possible special handlers for each claim */ /* possible special handlers for each claim */
if (claim == CLAIM_Secret) if ((claim == CLAIM_Secret) || (claim == CLAIM_SKR))
{ {
Termlist claimvars; Termlist claimvars;
Termlist recvvars; Termlist recvvars;
Termlist cli;
/* now check whether the claim contains variables that can actually be influenced by the intruder */ /* now check whether the claim contains variables that can actually be influenced by the intruder */
claimvars = termlistAddVariables (NULL, msg); claimvars = termlistAddVariables (NULL, cl->parameter);
recvvars = compute_recv_variables (thisRole); recvvars = compute_recv_variables (thisRole);
while (claimvars != NULL) cli = claimvars;
while (cli != NULL)
{ {
if (!inTermlist (protocol->rolenames, claimvars->term)) if (!inTermlist (thisProtocol->rolenames, cli->term))
{ {
/* only if it is not a role */ /* only if it is not a role */
if (!inTermlist (recvvars, claimvars->term)) if (!inTermlist (recvvars, cli->term))
{ {
/* this claimvar does not occur in the recvs? */ /* this claimvar does not occur in the recvs? */
/* then we should ignore it later */ /* then we should ignore it later */
@ -569,20 +670,26 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
/* show a warning for this */ /* show a warning for this */
globalError++; globalError++;
eprintf ("warning: secrecy claim of role "); warning_pre ();
eprintf ("Secrecy claim of role ");
termPrint (cl->rolename); termPrint (cl->rolename);
eprintf (" contains a variable "); eprintf (" contains a variable ");
termPrint (claimvars->term); termPrint (cli->term);
eprintf eprintf
(" which is never recv; therefore the claim will be true.\n"); (" which is never received; therefore the claim will be true.\n");
globalError--; globalError--;
} }
} }
claimvars = claimvars->next; cli = cli->next;
} }
termlistDelete (claimvars); termlistDelete (claimvars);
termlistDelete (recvvars); termlistDelete (recvvars);
} }
else
{
/* If it is NOT a SECRET claim, then check parameters are ground */
checkParameterGround (cl);
}
if ((claim == CLAIM_Commit) || (claim == CLAIM_Running)) if ((claim == CLAIM_Commit) || (claim == CLAIM_Running))
{ {
@ -596,14 +703,17 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
{ {
/* yield error */ /* yield error */
globalError++; globalError++;
eprintf ("warning: "); warning_pre ();
termPrint (claim); termPrint (claim);
eprintf (" claim of role "); eprintf (" claim of role ");
termPrint (cl->rolename); termPrint (cl->rolename);
eprintf eprintf
(" requires four arguments. Please specify both the target role and the data to agree on, as in:\n"); (" requires four arguments. Please specify both the target role and the data to agree on, as in:\n");
warning_pre ();
eprintf (" claim(R, Commit, R', data )\n"); eprintf (" claim(R, Commit, R', data )\n");
warning_pre ();
eprintf ("and\n"); eprintf ("and\n");
warning_pre ();
eprintf (" claim(R', Running, R, data ).\n"); eprintf (" claim(R', Running, R, data ).\n");
globalError--; globalError--;
error error
@ -620,16 +730,20 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
{ {
/* yield error */ /* yield error */
globalError++; globalError++;
eprintf ("warning: "); warning_pre ();
termPrint (claim); termPrint (claim);
eprintf (" claim of role "); eprintf (" claim of role ");
termPrint (cl->rolename); termPrint (cl->rolename);
eprintf (" specifies the target role to be '"); eprintf (" specifies the target role to be '");
termPrint (targetrole); termPrint (targetrole);
eprintf ("', which is not a role name.\n"); eprintf ("', which is not a role name.\n");
warning_pre ();
eprintf ("Please use:\n"); eprintf ("Please use:\n");
warning_pre ();
eprintf (" claim(R, Commit, R', data )\n"); eprintf (" claim(R, Commit, R', data )\n");
warning_pre ();
eprintf ("and\n"); eprintf ("and\n");
warning_pre ();
eprintf (" claim(R', Running, R, data ).\n"); eprintf (" claim(R', Running, R, data ).\n");
globalError--; globalError--;
error error
@ -637,8 +751,16 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
lineno); lineno);
} }
} }
} }
checkParameterRange (cl, CLAIM_Secret, 1, -1);
checkParameterRange (cl, CLAIM_SKR, 1, -1);
checkParameterRange (cl, CLAIM_Alive, 0, 0);
checkParameterRange (cl, CLAIM_Weakagree, 0, 0);
checkParameterRange (cl, CLAIM_Nisynch, 0, 0);
checkParameterRange (cl, CLAIM_Niagree, 0, 0);
checkParameterRange (cl, CLAIM_Empty, 0, 0);
checkParameterRange (cl, CLAIM_Reachable, 0, 0);
checkParameterRange (cl, CLAIM_SID, 1, -1);
return cl; return cl;
} }
@ -831,7 +953,7 @@ commEvent (int event, Tac tc)
/* handles claim types with different syntactic claims */ /* handles claim types with different syntactic claims */
if (claim == CLAIM_Secret) if ((claim == CLAIM_Secret) || (claim == CLAIM_SKR))
{ {
if (n == 0) if (n == 0)
{ {