/* C declarations */ #include #include #include #include "uthash.h" #include "abac_util.h" #include "abac_pl_yy.h" static int debug=0; extern abac_list_t *generate_pl_clauses(abac_role_t *, abac_role_t *); extern void panic(char*); extern char *generate_pl_type_clause(char *, int); void _add_yy_id_certs(char *, int); abac_list_t *abac_yap_clauses=NULL; /* this is to track individual id credentials */ abac_stack_t *abac_yap_id_clauses=NULL; abac_role_t *abac_yap_head_role=NULL; abac_role_t *abac_yap_tail_role=NULL; /* XXX do we want to check whether the id cert is preexisting or not */ /* this is to track id certs within a rule clause */ typedef struct _abac_yy_id_cert_t { char *principalname; int type; /* keyidtype */ char *clause; UT_hash_handle hh; } abac_yy_id_cert_t; abac_list_t *abac_yy_id_certs = NULL; /* local principal structure [keyid:USC] */ struct _abac_yy_principal_t { int type; char *sha; char *cn; }; /* like [principal:?Z]:..., must match a principal name */ struct _abac_yy_param_principal_t { int type; /* this needs to be implicitly determined */ char *name; char *condition; }; /* if has condition, then it is a variable, ie, [int:?Year]:<1930..1932>, if no condition, then it is a constant, ie, [int:10] */ struct _abac_yy_param_data_t { int is_variable; int type; char *name; char *condition; }; /* local dterm structure, will distinguish it in the future */ struct _abac_yy_dterm_t { union { abac_yy_principal_t *n_ptr; abac_yy_param_principal_t *p_ptr; abac_yy_param_data_t *d_ptr; } term; int type; struct _abac_yy_dterm_t *next; int bcnt; /* this is to track number of dterms in this linked up list */ }; /* local role structure */ struct _abac_yy_role_t { int type; char *name; abac_yy_dterm_t *dterms; struct _abac_yy_role_t *next; int bcnt; /* this is to track number of roles in this linked up list */ }; struct _abac_yy_role_expression_t { int rtype; abac_yy_principal_t *principal; abac_yy_role_t *linked_role; abac_yy_role_t *role; struct _abac_yy_role_expression_t *next; int bcnt; }; static void _free_yy_dterm(abac_yy_dterm_t *ptr); /************************************************************************/ abac_stack_t *abac_get_yap_id_clauses() { return abac_yap_id_clauses; } abac_stack_t *abac_init_yap_id_clauses() { abac_yap_id_clauses=abac_stack_new(); return abac_yap_id_clauses; } void abac_free_yap_id_clauses() { if (abac_yap_id_clauses != NULL) abac_stack_free(abac_yap_id_clauses); } void set_yap_clauses(abac_list_t *clauses) { abac_yap_clauses=clauses; if(debug) { printf("printing out abac_yap_clauses:\n"); abac_print_clauses(abac_yap_clauses); } } abac_list_t *abac_get_yap_clauses() { return abac_yap_clauses; } void abac_free_yap_clauses() { if (abac_yap_clauses != NULL) { char *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) free(cur); ); abac_list_free(abac_yap_clauses); } } abac_role_t *abac_get_yap_head_role() { return abac_yap_head_role; } abac_role_t *abac_get_yap_tail_role() { return abac_yap_tail_role; } void abac_init_yy_id_certs() { abac_yy_id_certs = abac_list_new(); } void abac_free_yy_id_certs() { abac_yy_id_cert_t *id; abac_list_foreach(abac_yy_id_certs, id, if(id) free(id->principalname); free(id->clause); free(id); ); abac_list_free(abac_yy_id_certs); } int abac_cnt_yy_id_certs() { return abac_list_size(abac_yy_id_certs); } char *abac_string_yy_id_certs() { int first=1; char *tmp=NULL; abac_yy_id_cert_t *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) if(first) { tmp=abac_xstrdup(cur->clause); first=0; } else { int cnt=asprintf(&tmp,"%s,%s", tmp, cur->clause); } ); return tmp; } void _add_yy_id_certs(char *principalname, int type) { abac_yy_id_cert_t *id_cert=NULL; int found=0; abac_yy_id_cert_t *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) if(strcmp(cur->principalname,principalname)==0) { found=1; break; } ); if (found) { return; } else { id_cert=abac_xmalloc(sizeof(abac_yy_id_cert_t)); id_cert->principalname=abac_xstrdup(principalname); id_cert->type=type; id_cert->clause=generate_pl_type_clause(principalname,type); abac_list_add(abac_yy_id_certs, id_cert); } } /****************************************************************************/ abac_yy_principal_t *make_yy_principal(char *sha, char *cn, int type) { abac_yy_principal_t *ptr= (abac_yy_principal_t*)abac_xmalloc(sizeof(abac_yy_principal_t)); ptr->sha=abac_xstrdup(sha); ptr->cn=abac_xstrdup(cn); ptr->type=type; return ptr; } static void _free_yy_principal(abac_yy_principal_t *ptr) { free(ptr->sha); if(ptr->cn) free(ptr->cn); free(ptr); } abac_yy_role_t *make_yy_role(char *name, abac_yy_dterm_t *dterms) { abac_yy_role_t *ptr=(abac_yy_role_t*)abac_xmalloc(sizeof(abac_yy_role_t)); ptr->name=abac_xstrdup(name); ptr->dterms=dterms; ptr->next=NULL; ptr->bcnt=1; return ptr; } static void _free_yy_role(abac_yy_role_t *ptr) { free(ptr->name); if(ptr->dterms) _free_yy_dterm(ptr->dterms); if(ptr->next) _free_yy_role(ptr->next); free(ptr); } abac_yy_role_expression_t *make_yy_role_expression(int rtype, abac_yy_principal_t *principal, abac_yy_role_t *role, abac_yy_role_t *linked_role) { abac_yy_role_expression_t *ptr= (abac_yy_role_expression_t*)abac_xmalloc(sizeof(abac_yy_role_expression_t)); ptr->rtype = rtype; ptr->principal = principal; ptr->role = role; ptr->linked_role=linked_role; ptr->next=NULL; return ptr; } abac_yy_role_expression_t *add_yy_role_expression(abac_yy_role_expression_t *nexpr, abac_yy_role_expression_t *exprs) { int i=exprs->bcnt; nexpr->next=exprs; nexpr->bcnt=i+1; return nexpr; } static void _free_yy_role_expression(abac_yy_role_expression_t *ptr) { if(ptr->principal) _free_yy_principal(ptr->principal); if(ptr->role) _free_yy_role(ptr->role); if(ptr->linked_role) _free_yy_role(ptr->linked_role); if(ptr->next) _free_yy_role_expression(ptr->next); free(ptr); } abac_yy_param_data_t *make_yy_param_data(char* name, char* typestr) { int type=abac_verify_dterm_type(typestr); abac_yy_param_data_t *ptr= (abac_yy_param_data_t*)abac_xmalloc(sizeof(abac_yy_param_data_t)); ptr->name=abac_xstrdup(name); ptr->type=type; ptr->condition=NULL; ptr->is_variable=0; return ptr; } void set_yy_param_data_is_variable(abac_yy_param_data_t *ptr) { ptr->is_variable=1; } static void _free_yy_param_data(abac_yy_param_data_t *ptr) { free(ptr->name); if(ptr->condition) free(ptr->condition); free(ptr); } abac_yy_param_principal_t *make_yy_param_principal(char* name) { abac_yy_param_principal_t *ptr= (abac_yy_param_principal_t*)abac_xmalloc(sizeof(abac_yy_param_principal_t)); ptr->name=abac_xstrdup(name); ptr->condition=NULL; return ptr; } static void _free_yy_param_principal(abac_yy_param_principal_t *ptr) { free(ptr->name); if(ptr->condition) free(ptr->condition); free(ptr); } abac_yy_dterm_t *make_yy_dterm_anonymous() { abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t)); ptr->type = DTERM_ANONYMOUS; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_dterm_t *make_yy_dterm_principal(abac_yy_param_principal_t *pptr) { abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t)); ptr->type = DTERM_PRINCIPAL; ptr->term.p_ptr=pptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_dterm_t *make_yy_dterm_named(abac_yy_principal_t *nptr) { abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t)); ptr->type = DTERM_NAMED; ptr->term.n_ptr=nptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_dterm_t *make_yy_dterm_data(abac_yy_param_data_t *dptr) { abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t)); ptr->type = DTERM_DATA; ptr->term.d_ptr=dptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_dterm_t *add_yy_dterm(abac_yy_dterm_t *nterm, abac_yy_dterm_t *dterms) { int i=dterms->bcnt; nterm->next=dterms; nterm->bcnt=i+1; return nterm; } static void _free_yy_dterm(abac_yy_dterm_t *ptr) { switch (ptr->type) { case DTERM_DATA: _free_yy_param_data(ptr->term.d_ptr); break; case DTERM_NAMED: _free_yy_principal(ptr->term.n_ptr); break; case DTERM_PRINCIPAL: _free_yy_param_principal(ptr->term.p_ptr); break; case DTERM_ANONYMOUS: break; } if(ptr->next) _free_yy_dterm(ptr->next); free(ptr); } /****************************************************************/ static void _role_add_dterms(int linked, abac_role_t *role, abac_yy_dterm_t *dterms) { abac_yy_dterm_t *curr = dterms; int type; char *name=NULL; char *cond=NULL; while (curr) { switch (curr->type) { case DTERM_DATA: { abac_yy_param_data_t *ptr=curr->term.d_ptr; type=ptr->type; name=abac_xstrdup(ptr->name); cond=abac_xstrdup(ptr->condition); if(ptr->is_variable) { /* XXX do some tracking */ } break; } case DTERM_PRINCIPAL: { abac_yy_param_principal_t *ptr=curr->term.p_ptr; type=abac_verify_dterm_type("principal"); name=abac_xstrdup(ptr->name); cond=abac_xstrdup(ptr->condition); /* XXX variable one, do some tracking */ break; } case DTERM_NAMED: { abac_yy_principal_t *ptr=curr->term.n_ptr; type=ptr->type; /* XXX should be switching to sha in the future */ name=abac_xstrdup(ptr->cn); cond=NULL; break; } case DTERM_ANONYMOUS: { type=0; name=abac_xstrdup("_"); cond=NULL; break; } } if (linked) abac_role_role_add_linked_param(role, type, name, cond); else abac_role_role_add_param(role, type, name, cond); curr=curr->next; } } static void _role_add_linked_dterms(abac_role_t *role, abac_yy_dterm_t *dterms) { int linked=1; _role_add_dterms(linked, role, dterms); } static void _role_add_role_dterms(abac_role_t *role, abac_yy_dterm_t *dterms) { int linked=0; _role_add_dterms(linked, role, dterms); } abac_role_t *validate_intersected_tail_role(abac_role_t *role) { abac_role_t *ret_role=NULL; abac_list_t *prereqs = abac_list_new(); abac_list_add(prereqs, role); ret_role = abac_role_intersection_new("intersectingROLE", prereqs); return ret_role; } abac_role_t *validate_head_role(abac_yy_role_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; char *principalname=principal->sha; char *rolename=role->name; abac_yy_dterm_t *dterms=role->dterms; abac_role_t *ret_role=NULL; ret_role=abac_role_role_new(principalname, rolename); if (ret_role==NULL) { set_error_code(ABAC_RT_ROLE_INVALID); goto error; } if (!abac_role_is_role(ret_role)) { set_error_code(ABAC_RT_CERT_INVALID); goto error; } // insert the params for the role if(dterms) { _role_add_role_dterms(ret_role, dterms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: return NULL; } abac_role_t *validate_named_tail_role(abac_yy_role_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; char *principalname=principal->sha; abac_role_t *ret_role=NULL; ret_role = abac_role_principal_new(principalname); _add_yy_id_certs(principal->cn,principal->type); if (ret_role==NULL) goto error; return ret_role; error: panic("can not generate a simple named tail role"); return NULL; } abac_role_t *validate_role_tail_role(abac_yy_role_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; char *principalname=principal->sha; char *rolename=role->name; abac_yy_dterm_t *dterms=role->dterms; int ret; abac_role_t *ret_role=NULL; ret_role = abac_role_role_new(principalname, rolename); if (ret_role==NULL) goto error; if(dterms) { _role_add_role_dterms(ret_role, dterms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: panic("can not generate a simple tail role"); return NULL; } /* need to validate/generate a linked role out of this */ abac_role_t *validate_linked_tail_role(abac_yy_role_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; abac_yy_role_t *linked_role=expr->linked_role; char *principalname=principal->sha; char *rolename=role->name; abac_yy_dterm_t *dterms=role->dterms; char *linkedrolename=linked_role->name; abac_yy_dterm_t *linked_dterms=linked_role->dterms; int ret; abac_role_t *ret_role=NULL; ret_role = abac_role_linking_new(principalname, linkedrolename, rolename); if (ret_role==NULL) goto error; if(linked_dterms) { _role_add_linked_dterms(ret_role, linked_dterms); } if(dterms) { _role_add_role_dterms(ret_role, dterms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: panic("can not generate linked tail role"); return NULL; } abac_list_t *make_statement(abac_yy_role_expression_t *headexpr, abac_yy_role_expression_t *tailexpr) { abac_role_t *head_role=NULL; abac_role_t *tail_role=NULL; /* build up left side's abac role structure */ head_role=validate_head_role(headexpr); if(head_role == NULL) goto error; /* build up the right side's abac role structure */ abac_yy_role_expression_t *curr_tail = tailexpr; int intersecting=(tailexpr->next != NULL)? 1:0; abac_role_t *curr_role = NULL; while (curr_tail) { switch(curr_tail->rtype) { case EXPR_NAMED: curr_role=validate_named_tail_role(curr_tail); break; case EXPR_ROLE: curr_role=validate_role_tail_role(curr_tail); break; case EXPR_LINKED: curr_role=validate_linked_tail_role(curr_tail); break; } if(curr_role==NULL) goto error; /* check if first one */ if(tail_role==NULL) { if(intersecting) tail_role=validate_intersected_tail_role(curr_role); else tail_role=curr_role; } else { abac_role_add_intersecting_role(tail_role,curr_role); } curr_tail=curr_tail->next; } /* while */ /* collect up type clauses and generate rule clauses */ abac_list_t *tmp=generate_pl_clauses(head_role,tail_role); if(tmp == NULL) goto error; if(debug) { abac_print_role_string_with_condition(head_role); abac_print_role_string_with_condition(tail_role); } _free_yy_role_expression(headexpr); _free_yy_role_expression(tailexpr); abac_yap_head_role=head_role; abac_yap_tail_role=tail_role; return tmp; error: _free_yy_role_expression(headexpr); _free_yy_role_expression(tailexpr); if(head_role) abac_role_free(head_role); if(tail_role) abac_role_free(tail_role); return NULL; }