/* bison grammar rules for process new rt2 statements */ %{ // include the GNU extension of asprintf #define _GNU_SOURCE /* C declarations */ #include #include #include "abac_pl_yy.h" #include "abac_verifier.h" /* lex tie-ins flag */ int yyerror (char *s); static int debug=0; FILE *abac_yyout = NULL; char *abac_yyfptr = NULL; void *abac_yyctxt=NULL; #define USE(evalue) ((getenv(evalue)!=NULL)?1:0) #define OUT(msg) { if(debug) fprintf(abac_yyout,"\n===%s\n",msg); } void panic(char *msg); %} /* Bison declarations */ %union { struct _abac_yy_principal_t *pstruct; struct _abac_yy_term_principal_t *ppstruct; struct _abac_yy_term_data_t *pdstruct; struct _abac_yy_roleoset_t *rostruct; struct _abac_yy_term_t *dstruct; struct _abac_yy_expression_t *estruct; struct _abac_list_t *lstruct; char *string; /* For returning char strings */ int intval; /* for returning some value */ } %start input %type stmt %type rolepart %type roleleft %type roleright %type roleterm %type osetpart %type osetleft %type osetright %type osetterm %type keypart %type terms %type term %type typedpart %type otypetail %type principalpart %type rangetype %type values %token IDEN /* keyname or rolename or osetname */ %token CAPIDEN /* variable name */ %token ROLE /* the word, role */ %token OSET /* the word, oset */ %token PRINCIPAL /* the word, principal */ %token THIS /* the word, this */ %token OTYPE /* integer,boolean,urn,time,string,float */ %token OTYPE_CONSTANT %token VARIABLE_CONSTANT /* constant for ?AAA */ %token KEYTYPE /* keyid | or something else */ %token KEYID_CONSTANT /* keyid | or something else */ %token VALUE /* range value in static constraint */ %token DERIVE "<-" %token DOT "." %token AND "&" %token LPAREN "(" %token RPAREN ")" %token LSQUARE "[" %token RSQUARE "]" %token LANGLE "<" %token RANGLE ">" %token COLON ":" %token COMMA "," %token QMARK "?" %token DOTDOT ".." %% /* Grammar rules */ input: /* empty */ { } | stmt { /* SUCCESS */ } ; /* generate/concate prolog credentials clauses */ stmt : roleleft DERIVE roleright { abac_yy_expression_t *headexpr=$1; abac_yy_expression_t *tailexpr=$3; int rc=make_role_statement(headexpr, tailexpr); if(rc) { panic("unable to parse the role rule statment"); YYERROR; } else { $$=rc; } } | osetleft DERIVE osetright { abac_yy_expression_t *headexpr=$1; abac_yy_expression_t *tailexpr=$3; int rc=make_oset_statement(headexpr, tailexpr); if(rc) { panic("unable to parse the oset rule statment"); YYERROR; } else { $$=rc; } } ; /* [keyid:isi].role:modifyBy([keyid:mike]) [keyid:acme].role:preferred */ roleleft : keypart DOT rolepart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *rolepart=$3; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_ROLE,keypart,rolepart,NULL); $$=expr; } ; /* [keyid:mike] */ keypart : LSQUARE KEYTYPE COLON { abac_ll_push_keyid_yystate(); } KEYID_CONSTANT { abac_ll_pop_yystate(); } RSQUARE { int idtype=abac_verify_idtype_type($2); char *tmp=NULL; asprintf(&tmp,"%s",$5); $$=make_yy_principal(tmp, tmp, idtype); char *cn=abac_cn_with_sha(tmp); if(cn && idtype) { $$=make_yy_principal(tmp, cn, idtype); } else { if((USE("ABAC_CN")) && (cn==NULL)) { if(debug) asprintf(&tmp,"encountered an invalid SHA id(%s)",$5); else asprintf(&tmp,"encountered an invalid SHA id"); panic(tmp); free(tmp); YYERROR; } $$=make_yy_principal(tmp, NULL, idtype); } } ; /* role:modifyBy([keyid:mike],[keyid:ted]) role:modifyBy([keyid:mike]) role:preferred */ rolepart : ROLE COLON IDEN LPAREN terms RPAREN { $$=make_yy_roleoset_role($3,$5); } | ROLE COLON IDEN { $$=make_yy_roleoset_role($3,NULL); } ; /* [keyid:mike],[keyid:ted] [keyid:mike] [principal:?Z] [int:99] [int:?Z] [?this], this could be any of type... [?] */ terms : term COMMA terms { abac_yy_term_t *nterm=$1; abac_yy_term_t *terms=$3; $$=add_yy_term(nterm, terms); } | term { $$=$1; } ; term : LSQUARE QMARK THIS RSQUARE { $$= make_yy_term_dterm_this(); } | LSQUARE QMARK RSQUARE { $$= make_yy_term_dterm_anonymous(); } | keypart { $$= make_yy_term_dterm_named($1); } | principalpart { $$= make_yy_term_dterm_principal($1); } | typedpart { $$= make_yy_term_dterm_data($1); } ; values : VALUE COMMA values { $$=add_yy_val_range($3, $1); } | VALUE { $$=make_yy_val_range($1); } ; rangetype : LSQUARE VALUE DOTDOT VALUE RSQUARE { $$=make_yy_minmax_range($2,$4); } | LSQUARE DOTDOT VALUE RSQUARE { $$=make_yy_max_range($3); } | LSQUARE VALUE DOTDOT RSQUARE { $$=make_yy_min_range($2); } | LSQUARE values RSQUARE { $$=$2; } ; /* [otype:?Z{oset-constraint}] */ /* [int:?I:[10 .. 20] */ /* [float:?F:[0.5 .. 2.5] */ /* [string:?S:["abc",'efg',"hij"] -only listed range */ /* urn same as string */ /* time like int but with quoted string values */ /* XXX would have to extend this if want the linked oset in the constraints.. [otype:?Z{linked oset-constraint}] */ otypetail : VARIABLE_CONSTANT COLON { abac_ll_pop_yystate(); abac_ll_push_range_yystate(); } rangetype { abac_ll_pop_yystate(); abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_name(ptr,$1); set_yy_term_data_is_variable(ptr); set_yy_term_data_cond_range(ptr,$4); $$=ptr; OUT("otypetail_1"); } | VARIABLE_CONSTANT { abac_ll_pop_yystate(); } osetterm { abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_name(ptr,$1); set_yy_term_data_is_variable(ptr); set_yy_term_data_cond_head_expr(ptr,$3); $$=ptr; OUT("otypetail_2"); } | VARIABLE_CONSTANT { abac_ll_pop_yystate(); abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_name(ptr,$1); set_yy_term_data_is_variable(ptr); $$=ptr; OUT("otypetail_3"); } | OTYPE_CONSTANT { abac_ll_pop_yystate(); abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_name(ptr,$1); $$=ptr; OUT("otypetail_4"); } | QMARK { abac_ll_pop_yystate(); abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_is_anonymous(ptr); $$= ptr; } ; typedpart : LSQUARE OTYPE COLON { abac_ll_push_yystate($2); } otypetail RSQUARE { abac_yy_term_data_t *ptr=$5; set_yy_term_data_type(ptr,$2); if(is_yy_term_data_has_constraint(ptr)) { char *tail_string=get_yy_term_data_name(ptr); make_yy_range_constraint(ptr); make_yy_oset_constraint(ptr,tail_string); } $$=$5; } ; /* [principal:?] */ /* [principal:?Z] */ /* [principal:?This] */ /* [principal:?Z{role-constraint}] */ /* XXX if want to allow linked role constraint need to swap roleleft into roleterm.. but make sure the tree is right 3/21/13, [principal:?Z[keyid:A].role:roleA.role:roleB([string:?P])] */ principalpart : LSQUARE PRINCIPAL COLON QMARK IDEN roleterm RSQUARE { abac_yy_expression_t *expr=$6; char *tail_string=$5; abac_yy_term_principal_t *ptr=make_yy_term_principal(); set_yy_term_principal_name(ptr,tail_string); set_yy_term_principal_cond_head_expr(ptr,expr); make_yy_role_constraint(ptr,tail_string); $$=ptr; OUT("principalpart_1"); } | LSQUARE PRINCIPAL COLON QMARK IDEN RSQUARE { abac_yy_term_principal_t *ptr=make_yy_term_principal(); set_yy_term_principal_name(ptr,$5); $$ = ptr; OUT("principalpart_2"); } | LSQUARE PRINCIPAL COLON QMARK RSQUARE { abac_yy_term_principal_t *ptr=make_yy_term_principal(); set_yy_term_principal_is_anonymous(ptr); $$ = ptr; OUT("principalpart_3"); } ; roleright : roleterm AND roleright { abac_yy_expression_t *nexpr=$1; abac_yy_expression_t *exprs=$3; $$=add_yy_expression(nexpr,exprs); } | roleterm { $$=$1; } ; /* role at tail/right side [keyid:usc].role:employee.role:friend [keyid:usc].role:worker [keyid:mike] */ roleterm : keypart DOT rolepart DOT rolepart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *linked_rolepart=$3; abac_yy_roleoset_t *rolepart=$5; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_LINKED,keypart,rolepart,linked_rolepart); $$=expr; OUT("roleterm_1"); } | keypart DOT rolepart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *rolepart=$3; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_ROLE,keypart,rolepart,NULL); $$=expr; OUT("roleterm_2"); } | keypart { abac_yy_principal_t *keypart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_NAMED,keypart,NULL,NULL); $$=expr; OUT("roleterm_3"); } ; osetterm : keypart DOT rolepart DOT osetpart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *linked_rolepart=$3; abac_yy_roleoset_t *osetpart=$5; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_LINKED,keypart,osetpart,linked_rolepart); $$=expr; OUT("osetterm_1"); } | keypart DOT osetpart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *osetpart=$3; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_OSET,keypart,osetpart,NULL); $$=expr; OUT("osetterm_2"); } | keypart { abac_yy_principal_t *keypart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_NAMED,keypart,NULL,NULL); $$=expr; OUT("osetterm_3"); } | typedpart { abac_yy_term_data_t *objpart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_OBJECT,objpart,NULL,NULL); $$=expr; OUT("osetterm_4"); } ; /* oset:access([urn:'fileA']) */ osetpart : OSET COLON IDEN LPAREN terms RPAREN { $$=make_yy_roleoset_oset($3,$5); } | OSET COLON IDEN { $$=make_yy_roleoset_oset($3,NULL); } ; osetleft : keypart DOT osetpart { abac_yy_principal_t *keypart=$1; abac_yy_roleoset_t *osetpart=$3; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_OSET,keypart,osetpart,NULL); $$=expr; OUT("osetleft"); } ; osetright : osetterm AND osetright { abac_yy_expression_t *nexpr=$1; abac_yy_expression_t *exprs=$3; $$=add_yy_expression(nexpr,exprs); OUT("osetright_1"); } | osetterm { $$=$1; OUT("osetright_2"); } ; %% /* Additional C code */ int yywrap() { /* exit when done lexing the current input */ return 1; } int yyerror (char *s) { fprintf (abac_yyout,"yyerror: %s\n", s); } /* setting defaults */ void abac_yyinit() { abac_yyout=abac_ll_get_yyout(); abac_yyfptr = abac_ll_get_yyfptr(); OUT("======================================"); } void panic(char *msg) { OUT("panic, EEEEKKKKKK..."); yyerror(msg); }