/* 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_list.h" /* lex tie-ins flag */ int yyerror (char *s); static int debug=0; FILE *abac_yyout = NULL; char *abac_yyfptr = NULL; char *abac_yyfptr_encoded = NULL; #define USE(evalue) ((getenv(evalue)!=NULL)?1:0) 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 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 { abac_yy_set_rule_clauses($1); } ; /* generate/concate prolog credentials clauses */ stmt : roleleft DERIVE roleright { abac_yy_expression_t *headexpr=$1; abac_yy_expression_t *tailexpr=$3; abac_list_t *ret=make_role_statement(headexpr, tailexpr); if(ret == NULL) { panic("unable to parse the role rule statment"); YYERROR; } else { $$=ret; } } | osetleft DERIVE osetright { abac_yy_expression_t *headexpr=$1; abac_yy_expression_t *tailexpr=$3; abac_list_t *ret=make_oset_statement(headexpr, tailexpr); if(ret == NULL) { panic("unable to parse the oset rule statment"); YYERROR; } else { $$=ret; } } ; /* [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_push_keyid_yystate(); } KEYID_CONSTANT { abac_pop_yystate(); } RSQUARE { int idtype=abac_verify_idtype_type($2); char *tmp=NULL; asprintf(&tmp,"%s",$5); 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] [principal:?this] [int:99] [int:?Z] [?] */ 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 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 */ otypetail : VARIABLE_CONSTANT COLON { abac_pop_yystate(); abac_push_range_yystate(); } rangetype { abac_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; } | VARIABLE_CONSTANT { abac_pop_yystate(); } osetleft { 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; } | VARIABLE_CONSTANT { abac_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; } | OTYPE_CONSTANT { abac_pop_yystate(); abac_yy_term_data_t *ptr=make_yy_term_data(); set_yy_term_data_name(ptr,$1); $$=ptr; } | QMARK { abac_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_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}] */ principalpart : LSQUARE PRINCIPAL COLON QMARK IDEN roleleft 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; } | LSQUARE PRINCIPAL COLON QMARK IDEN RSQUARE { abac_yy_term_principal_t *ptr=make_yy_term_principal(); set_yy_term_principal_name(ptr,$5); $$ = ptr; } | LSQUARE PRINCIPAL COLON QMARK RSQUARE { abac_yy_term_principal_t *ptr=make_yy_term_principal(); set_yy_term_principal_is_anonymous(ptr); $$ = ptr; } ; 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; } | 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; } | keypart { abac_yy_principal_t *keypart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_NAMED,keypart,NULL,NULL); $$=expr; } ; 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; } | 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; } | keypart { abac_yy_principal_t *keypart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_NAMED,keypart,NULL,NULL); $$=expr; } | typedpart { abac_yy_term_data_t *objpart=$1; abac_yy_expression_t *expr= make_yy_expression(e_yy_EXPR_OBJECT,objpart,NULL,NULL); $$=expr; } ; /* 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; } ; osetright : osetterm AND osetright { abac_yy_expression_t *nexpr=$1; abac_yy_expression_t *exprs=$3; $$=add_yy_expression(nexpr,exprs); } | osetterm { $$=$1; } ; %% /* 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_get_yyout(); abac_yyfptr = abac_get_yyfptr(); abac_yyfptr_encoded = abac_get_yyfptr_encoded(); if(debug) fprintf (abac_yyout,"\n=======================================\n"); } void panic(char *msg) { yyerror(msg); }