source: libabac/abac_pl_gen.c @ 888df49

mei_rt2mei_rt2_fix_1
Last change on this file since 888df49 was 2efdff5, checked in by Mei <mei@…>, 12 years ago

1) fix the missing check for 'This' rt2.y when called from creddy/prover

combo

2) patch up the stringify of abac_term that is of time type.
3) update the testing to reflect the changes to baseline output

  • Property mode set to 100644
File size: 22.1 KB
Line 
1
2/***********************************************************************/
3/* clause generation called  to  generate credential clauses with a    */
4/* given credential syntax structure (made from parser or from a       */
5/* pre-existing structure                                              */
6/* There are 2 passes,                                                 */
7/*  first pass, process named cred id, and constraint range/role/oset  */
8/*  2nd pass, process rule left / right                                */
9/***********************************************************************/
10#include <stdio.h>
11#include <assert.h>
12#include <stdlib.h>
13
14#include "abac_internal.h"
15#include "abac_set.h"
16#include "abac_util.h"
17
18#include "uthash.h"
19
20// index to generate C1,C2..
21static int cred_count=0;
22
23static int debug=0;
24int ABAC_IN_PROLOG=0;
25
26abac_list_t *abac_pl_constraints=NULL;
27
28/* to track id certs within a rule clause */
29typedef struct _abac_id_cert_t {
30    char *principalname;
31    int type; /* keyidtype */
32    char *clause;
33} abac_id_cert_t;
34abac_list_t *abac_pl_id_certs = NULL;
35
36extern int using_this;
37
38extern char* abac_yyfptr_encoded;
39
40char *generate_pl_type_clause(char *principalname, int type);
41
42
43/***********************************************************************/
44char *prologIt(char *str)
45{
46    char *tmp=NULL;
47    asprintf(&tmp,"p%s",str);
48    return tmp;
49}
50
51static char* isX()
52{
53    static char x_string[2]="X";
54    static char this_string[5]="This";
55    if(using_this)
56        return this_string;
57        else 
58           return x_string;
59}
60
61static int _get_next_cred_idx()
62{
63    cred_count++;
64    return cred_count;
65}
66
67/* remember to free the returned string */
68static char *_compose_cred_list()
69{
70    int i=cred_count;
71    if(cred_count==0) return "";
72
73    char *clist=(char *)abac_xmalloc(sizeof(char)*(cred_count)*3);
74    strcpy(clist,"C1");
75    if (cred_count==1) return clist;
76
77    i=1;
78    while(i!=cred_count) {
79        i++;
80        sprintf(clist,"%s,C%d",clist,i);
81    }
82    return clist;
83}
84
85
86/************************************************************************/
87/* this is for tracking prolog constraints */
88void abac_pl_init_constraints()
89{
90    abac_pl_constraints = abac_list_new();
91}
92
93void abac_pl_free_constraints()
94{
95    char *cur;
96    abac_list_foreach(abac_pl_constraints, cur,
97        if(cur)
98            free(cur);
99    );
100    abac_list_free(abac_pl_constraints);
101    abac_pl_constraints=NULL;
102}
103
104int abac_pl_cnt_constraints()
105{
106    return abac_list_size(abac_pl_constraints);
107}
108
109char *abac_pl_string_constraints()
110{
111    int first=1;
112    char *tmp=NULL;
113    char *final=NULL;
114    char* cur;
115    abac_list_foreach(abac_pl_constraints, cur,
116        if(cur)
117            if(first) {
118                final=abac_xstrdup(cur);
119                first=0;
120                } else {
121                    tmp=final;
122                    final=NULL;
123                    int cnt=asprintf(&final,"%s,%s", tmp, cur);
124            }
125    );
126    return final;
127}
128
129void abac_pl_add_constraints(char *constraint)
130{
131    if(abac_pl_constraints == NULL)
132        abac_pl_init_constraints();
133    char* nptr=abac_xstrdup(constraint);
134    abac_list_add(abac_pl_constraints, nptr);
135}
136
137
138/************************************************************************/
139void abac_pl_init_id_certs()
140{
141    abac_pl_id_certs = abac_list_new();
142}
143
144void abac_pl_free_id_certs()
145{
146    if(abac_pl_id_certs==NULL)
147        return;
148
149    abac_id_cert_t *id;
150    abac_list_foreach(abac_pl_id_certs, id,
151        if(id) 
152            free(id->principalname);
153            free(id->clause);
154            free(id);
155    );
156    abac_list_free(abac_pl_id_certs);
157    abac_pl_id_certs = NULL;
158}
159
160int abac_pl_cnt_id_certs()
161{
162    return abac_list_size(abac_pl_id_certs);
163}
164
165char *abac_pl_string_id_certs()
166{
167    int first=1;
168    char *tmp=NULL;
169    abac_id_cert_t *cur;
170    abac_list_foreach(abac_pl_id_certs, cur,
171        if(cur) 
172            if(first) {
173                tmp=abac_xstrdup(cur->clause);
174                first=0;
175                } else {
176                    int cnt=asprintf(&tmp,"%s,%s", tmp, cur->clause);
177            }
178    );
179    return tmp;
180}
181
182void abac_pl_add_id_certs(char *principalname, int type)
183{
184    abac_id_cert_t *id_cert=NULL;
185    int found=0;
186    abac_id_cert_t *cur;
187
188    if(debug) {
189         printf("add_id_certs: adding --> (%s)\n", principalname);
190    }
191
192    if(abac_pl_id_certs == NULL) {
193        abac_pl_init_id_certs();
194        } else {
195            abac_list_foreach(abac_pl_id_certs, cur,
196                if(cur) 
197                    if(strcmp(cur->principalname,principalname)==0) {
198                       found=1;
199                       break;
200                    }
201            );
202    }
203
204    if (found) {
205        return;
206        } else {
207            id_cert=abac_xmalloc(sizeof(abac_id_cert_t));
208            id_cert->principalname=abac_xstrdup(principalname);
209            id_cert->type=type;
210            id_cert->clause=generate_pl_type_clause(principalname,type);
211            abac_list_add(abac_pl_id_certs, id_cert);
212    }
213}
214
215/***********************************************************************/
216/* generate role(p_name, r_name, param..)                              */
217/*          or oset(p_name, r_name, param..)                           */
218static char* generate_pl_head_string(abac_aspect_t *ptr)
219{
220     char *tmp=NULL;
221     char *principalname;
222     PROLOG(principalname=abac_aspect_principal_name(ptr););
223     char *aspectname=abac_aspect_aspect_name(ptr);
224     char *typestring=abac_aspect_type_string(ptr);
225     char *param_string=NULL;
226     int cnt=0;
227
228     /* can not be a linked role */
229     abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr);
230     if(aspect_params) {
231        PROLOG(param_string=abac_param_list_string(aspect_params););
232     }
233
234     if (param_string != NULL) {
235         cnt=asprintf(&tmp,"%s(%s,%s,%s)", 
236                        typestring, principalname, aspectname, param_string);
237         free(param_string);
238         } else {
239             cnt=asprintf(&tmp,"%s(%s,%s)", 
240                        typestring, principalname, aspectname);
241     }
242
243     if(debug && tmp) printf("generate_pl_head_string: (%s)\n",tmp);
244     if(cnt>0)
245        return tmp;
246        else
247           return NULL;
248}
249
250/* generate role(p_name, r_name, param..) with isMember call ?? */
251/* generate oset(p_name, r_name, param..) with isMember call ?? */
252static char* generate_pl_tail_string(abac_aspect_t *ptr)
253{
254
255     char *tmp=NULL;
256
257/* for oset case,
258   A.oset <- B
259   A.oset <- Obj
260   A.oset <- B.oset
261   A.oset <- B.role.oset
262*/
263     /* o only if it is an oset and object */
264     if(abac_aspect_is_object(ptr)) {
265         char *objectname=abac_aspect_object_name(ptr);
266         tmp=abac_xstrdup(objectname);
267         return tmp;
268     } else {
269         char *principalname;
270         PROLOG(principalname=abac_aspect_principal_name(ptr););
271         char *aspectname=abac_aspect_aspect_name(ptr);
272         char *linkedname=abac_aspect_linked_role_name(ptr);
273         char *typestring=abac_aspect_type_string(ptr);
274
275         char *param_string=NULL;
276         char *linked_param_string=NULL;
277         int cnt=0;
278   
279         abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr);
280         if(aspect_params) {
281            PROLOG(param_string=abac_param_list_string(aspect_params););
282         }
283   
284         abac_param_list_t *linked_role_params=abac_aspect_linked_role_params(ptr);
285         if(linked_role_params) {
286            PROLOG(linked_param_string=abac_param_list_string(linked_role_params););
287         }
288   
289         /* b.r.r */
290         if(linkedname!=NULL && aspectname!=NULL && principalname!=NULL ) {
291             int fst=_get_next_cred_idx();
292             int snd=_get_next_cred_idx();
293             if(linked_param_string !=NULL) {
294                 if (param_string != NULL) {
295                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
296                            principalname,
297                            linkedname,linked_param_string,fst,
298                            isX(), typestring,
299                            aspectname,param_string,snd);
300                     free(param_string);
301                     } else {
302                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
303                            principalname,
304                            linkedname,linked_param_string,fst,
305                            isX(), typestring,
306                            aspectname,snd);
307                 }
308                 free(linked_param_string);
309                 } else {
310                     if (aspect_params != NULL) {
311                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
312                            principalname,
313                            linkedname,fst,
314                            isX(),typestring,
315                            aspectname,param_string,snd);
316                         free(param_string);
317                         } else {
318                             cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
319                                principalname,
320                                linkedname,fst,
321                                isX(),typestring,
322                                aspectname,snd);
323                   }
324             }
325             if(cnt>0)
326                 return tmp;
327                 else
328                     return NULL;
329         } 
330         /* b.r */
331         if(linkedname==NULL && aspectname!=NULL && principalname!=NULL ) {
332             int fst=_get_next_cred_idx();
333             if(param_string != NULL) {
334                 cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s,%s),C%d)",
335                              isX(),typestring,
336                              principalname, aspectname, param_string, fst);
337                 free(param_string);
338                 } else {
339                     cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s),C%d)",
340                              isX(), typestring,
341                              principalname, aspectname, fst);
342             }
343             if(cnt>0)
344                 return tmp;
345                 else
346                     return NULL;
347         } 
348         /* b */
349         if(linkedname==NULL && aspectname==NULL && principalname!=NULL ) {
350             tmp=abac_xstrdup(principalname);
351             return tmp;
352         } 
353   
354         return tmp;
355         }
356    return tmp;
357}
358   
359
360/********************************************************************************/
361
362static char *_build_constraint_rule_clause(char *head_string, char *tail_string)
363{
364    /*only,  A.R <- B */
365    if(debug) 
366         printf("calling _build_constraint_rule_clause (%s)(%s)\n", head_string, tail_string);
367    char *tmp;
368    int idx=_get_next_cred_idx();
369    asprintf(&tmp, "isMember(%s,%s,C%d)", tail_string,head_string,idx);
370    return tmp;
371}
372
373static char *_build_rule_clause(char *aspectname, char *head_string,
374char *tail_string, char *id_string, char *constraint_string)
375{
376    char *tmp=NULL;
377
378    if(aspectname == NULL) {
379        /* A.R <- B */
380        if(id_string == NULL && constraint_string == NULL) {
381            asprintf(&tmp, "isMember(%s,%s,['%s'])",
382                     tail_string,head_string,abac_yyfptr_encoded);
383            } else {
384                if(id_string == NULL) {
385                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
386                         tail_string,head_string,abac_yyfptr_encoded,
387                         constraint_string);
388                } else if(constraint_string == NULL) {
389                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
390                         tail_string,head_string,abac_yyfptr_encoded,
391                         id_string);
392                } else { asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s,%s",
393                         tail_string,head_string,abac_yyfptr_encoded,
394                         id_string, constraint_string);
395                }
396        }
397        } else {
398             /* A.R <- B.R */
399             /* A.R <- B.R.R */
400             if (cred_count==0) {
401                 if(id_string == NULL && constraint_string == NULL) {
402                     asprintf(&tmp,"isMember(%s,%s,['%s']):-%s",
403                           isX(),
404                           head_string, abac_yyfptr_encoded, tail_string);
405                     } else {
406                         if(id_string == NULL) {
407                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s",
408                                 isX(),
409                                 head_string, abac_yyfptr_encoded, tail_string,
410                                 constraint_string);
411                         } else if(constraint_string == NULL) {
412                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s",
413                                 isX(),
414                                 head_string, abac_yyfptr_encoded, id_string,
415                                 tail_string);
416                         } else { 
417                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s,%s",
418                                 isX(),
419                                 head_string, abac_yyfptr_encoded, id_string,
420                                 tail_string, constraint_string);
421                         }
422                 }
423                 } else {
424                     char *tmp_cred_list=_compose_cred_list();
425                     if(id_string == NULL && constraint_string == NULL) {
426                         asprintf(&tmp,"isMember(%s,%s,L):-%s, appendL([['%s'],%s],L)",
427                                  isX(),
428                                  head_string, tail_string,
429                                  abac_yyfptr_encoded, tmp_cred_list);
430                         } else {
431                            if(id_string == NULL) {
432                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
433                                  isX(),
434                                  head_string, tail_string, constraint_string,
435                                  abac_yyfptr_encoded, tmp_cred_list);
436                            } else if(constraint_string == NULL) {
437                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
438                                  isX(),
439                                  head_string, id_string, tail_string,
440                                  abac_yyfptr_encoded, tmp_cred_list);
441                            } else { 
442                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, %s, appendL([['%s'],%s],L)",
443                                  isX(),
444                                  head_string, id_string, tail_string,
445                                  constraint_string,
446                                  abac_yyfptr_encoded, tmp_cred_list);
447                            }
448                     }
449                     free(tmp_cred_list);
450                     cred_count=0;
451             }
452    }
453    return tmp;
454}
455
456
457static char *generate_pl_rule_clause(char *head_rule_string,
458abac_aspect_t *tail_rule, char *id_string, char *constraint_string)
459{
460    char *aspectname=abac_aspect_aspect_name(tail_rule);
461    char *tail_rule_string=generate_pl_tail_string(tail_rule);
462    if(aspectname == NULL && tail_rule_string == NULL) 
463        goto error;
464    char *tmp=_build_rule_clause(aspectname,head_rule_string, tail_rule_string,
465                                          id_string, constraint_string);
466    if(tail_rule_string) free(tail_rule_string);
467    return tmp;
468
469error:
470    if(tail_rule_string) free(tail_rule_string);
471    return NULL;
472}
473
474static char *_add_string(char *dstr, char *nstr)
475{
476    if(strlen(dstr)==0) {
477        dstr=abac_xstrdup(nstr);
478        return dstr;
479        } else { 
480            int len = strlen(dstr)+strlen(nstr)+2;
481            char *tmp=abac_xmalloc(len*sizeof(char));
482            sprintf(tmp,"%s,%s", dstr,nstr);
483            free(dstr);
484            return tmp;
485    }
486    return NULL;
487}
488
489static char *_build_intersecting_clause(char *head_role_string,
490char *tail_role_string, char* id_string, char* constraint_string)
491{
492    char *tmp;
493
494    if (cred_count==0) {
495        if(id_string == NULL && constraint_string == NULL) {
496            asprintf(&tmp,"isMember(%s,%s,['%s']):-%s",
497                   isX(),
498                   head_role_string, abac_yyfptr_encoded, tail_role_string);
499            } else {
500             if(id_string == NULL) {
501                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s",
502                       isX(),
503                       head_role_string, abac_yyfptr_encoded, 
504                       tail_role_string, constraint_string);
505             } else if(constraint_string == NULL) {
506                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s",
507                       isX(),
508                       head_role_string, abac_yyfptr_encoded, 
509                       id_string, tail_role_string);
510             } else {   
511                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s, %s",
512                       isX(),
513                       head_role_string, abac_yyfptr_encoded, 
514                       id_string, tail_role_string, constraint_string);
515             }           
516        }
517        } else {
518            char *tmp_cred_list=_compose_cred_list();
519            if(id_string == NULL && constraint_string == NULL) {
520                asprintf(&tmp,"isMember(%s,%s,L):-%s, appendL([['%s'],%s],L)",
521                                isX(),
522                                head_role_string, tail_role_string,
523                                abac_yyfptr_encoded, tmp_cred_list);
524                } else {
525                    if(id_string == NULL) {
526                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
527                            isX(),
528                            head_role_string, tail_role_string, constraint_string,
529                            abac_yyfptr_encoded, tmp_cred_list);
530                    } else if(constraint_string == NULL) {
531                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
532                            isX(),
533                            head_role_string, id_string, tail_role_string,
534                            abac_yyfptr_encoded, tmp_cred_list);
535                    } else {   
536                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, %s, appendL([['%s'],%s],L)",
537                            isX(),
538                            head_role_string, id_string, tail_role_string, constraint_string,
539                            abac_yyfptr_encoded, tmp_cred_list);
540                    }           
541            }
542            free(tmp_cred_list);
543            cred_count=0;
544    }
545    return tmp;
546}
547
548static char *generate_pl_intersecting_clause(char *head_role_string,
549abac_aspect_t *tail_role, char* id_string, char* constraint_string)
550{
551    char *tmp=NULL;
552    char* tail_role_string=NULL;
553    abac_list_t *list=abac_aspect_prereqs(tail_role);
554    /* A.R <- B.R & C.R.R */
555    /* A.O <- B.O & C.R.O */
556
557    if (list != NULL) {
558        abac_aspect_t *cur;
559        abac_list_foreach(list, cur,
560            char *ntmp=generate_pl_tail_string(cur);
561            if(debug) printf("  intersecting tail: (%s)\n",ntmp);
562            if(tail_role_string==NULL) {
563                 tail_role_string=abac_xstrdup(ntmp);
564                 } else {
565                    tmp=tail_role_string;
566                    tail_role_string=NULL; 
567                    asprintf(&tail_role_string,"%s, %s",tmp,ntmp);
568                    free(tmp);
569            }
570            free(ntmp);
571        );
572    }
573
574    if(debug) printf("      final intersecting tail: (%s)\n",tail_role_string);
575    tmp=_build_intersecting_clause(head_role_string, tail_role_string, id_string,constraint_string);
576    if(tail_role_string) free(tail_role_string);
577    return tmp;
578}
579
580/* generate the yap isMember rule clause for the credential stmt */
581abac_list_t *generate_pl_clauses(abac_aspect_t *head_aspect, abac_aspect_t *tail_aspect)
582{
583   char *tmp=NULL;
584   char *id_clauses_string=NULL;
585   char *constraint_clauses_string=NULL;
586   abac_list_t *clauses=abac_list_new();
587 
588   int cnt=abac_pl_cnt_id_certs();
589   if(cnt > 0) { /* string it up */
590       id_clauses_string=abac_pl_string_id_certs();
591       abac_pl_free_id_certs();
592   }
593
594   /* make a loop here */
595   cnt=abac_pl_cnt_constraints();
596   if(cnt > 0) {
597      constraint_clauses_string=abac_pl_string_constraints();
598      abac_pl_free_constraints();
599   }
600
601/* generate head's string */
602    char *head_string=generate_pl_head_string(head_aspect);
603    if(head_string == NULL)
604        goto error;
605
606/* tail side */
607    if(abac_aspect_is_intersection(tail_aspect)) {
608       tmp=generate_pl_intersecting_clause(head_string, tail_aspect,
609                    id_clauses_string, constraint_clauses_string);
610       } else {
611           tmp=generate_pl_rule_clause(head_string, tail_aspect,
612                    id_clauses_string, constraint_clauses_string);
613    }
614    if(tmp==NULL)
615        goto error;
616 
617    abac_list_add(clauses,tmp);
618    return clauses;
619
620error:
621    if(head_string) free(head_string);
622    if(id_clauses_string) free(id_clauses_string);
623    if(constraint_clauses_string) free(constraint_clauses_string);
624    return clauses;
625}
626
627/* should be just 1 */
628char *generate_pl_constraint_clause(abac_aspect_t *head_aspect, char *tail_string)
629{
630/* generate head's role or oset string */
631    char *head_string=generate_pl_head_string(head_aspect);
632    if(head_string == NULL)
633        goto error;
634
635/* tail side */
636    char *tmp=_build_constraint_rule_clause(head_string, tail_string);
637    if(tmp==NULL)
638        goto error;
639
640    return tmp;
641
642error:
643    if(head_string) free(head_string);
644    return NULL;
645}
646
647/* integer(X)<10 */
648/* X='abc' */
649char *generate_pl_range_constraint(char *typestr,char *var,char *val,char *op)
650{
651   char *tmp=NULL;
652   if(typestr)
653      asprintf(&tmp,"%s(%s)%s%s",typestr,var,op,val);
654      else
655          asprintf(&tmp,"%s%s%s",var,op,val);
656   return tmp;
657}
658
659/* compare(op,var,val) */
660char *generate_pl_range_time_constraint(char *var,char *val,char *op)
661{
662   char *tmp=NULL;
663   asprintf(&tmp,"compare(%s,%s,%s)",op,var,val);
664   return tmp;
665}
666
667/* generate the yap isType rule clause for the type,
668   isType(Acme, keyid); */
669char *generate_pl_type_clause(char *principalname, int type)
670{
671    char *tmp=NULL;
672    char *typeid= abac_idtype_string(type);
673    if(typeid==NULL || strcmp(typeid,"NULL")==0)
674        panic("generate_pl_type_clause: can not have null typeid");
675    if(debug)
676        printf("generate type clause, (%s)\n", principalname);
677    int cnt=asprintf(&tmp,"isType(%s,%s)",
678                                principalname, typeid);
679    return tmp;
680}
681
Note: See TracBrowser for help on using the repository browser.