source: libabac/abac_pl_gen.c @ 440ba20

mei_rt2mei_rt2_fix_1
Last change on this file since 440ba20 was 440ba20, checked in by Mei <mei@…>, 12 years ago

1) wrap up refactoring to move all the code gen to abac structure
2) all original testsuite passed
3) add couple more ui calls in abac.hh ie. manage constraint's

creation, hook to dump yap db.

  • Property mode set to 100644
File size: 22.5 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         if(debug && tmp) printf("tail_string1: (%s)\n",tmp);
268         return tmp;
269     } else {
270         char *principalname;
271         PROLOG(principalname=abac_aspect_principal_name(ptr););
272         char *aspectname=abac_aspect_aspect_name(ptr);
273         char *linkedname=abac_aspect_linked_role_name(ptr);
274         char *typestring=abac_aspect_type_string(ptr);
275
276         char *param_string=NULL;
277         char *linked_param_string=NULL;
278         int cnt=0;
279   
280         abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr);
281         if(aspect_params) {
282            PROLOG(param_string=abac_param_list_string(aspect_params););
283         }
284   
285         abac_param_list_t *linked_role_params=abac_aspect_linked_role_params(ptr);
286         if(linked_role_params) {
287            PROLOG(linked_param_string=abac_param_list_string(linked_role_params););
288         }
289   
290         /* b.r.r */
291         if(linkedname!=NULL && aspectname!=NULL && principalname!=NULL ) {
292             int fst=_get_next_cred_idx();
293             int snd=_get_next_cred_idx();
294             if(linked_param_string !=NULL) {
295                 if (param_string != NULL) {
296                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
297                            principalname,
298                            linkedname,linked_param_string,fst,
299                            isX(), typestring,
300                            aspectname,param_string,snd);
301                     free(param_string);
302                     } else {
303                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
304                            principalname,
305                            linkedname,linked_param_string,fst,
306                            isX(), typestring,
307                            aspectname,snd);
308                 }
309                 free(linked_param_string);
310                 } else {
311                     if (aspect_params != NULL) {
312                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
313                            principalname,
314                            linkedname,fst,
315                            isX(),typestring,
316                            aspectname,param_string,snd);
317                         free(param_string);
318                         } else {
319                             cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
320                                principalname,
321                                linkedname,fst,
322                                isX(),typestring,
323                                aspectname,snd);
324                   }
325             }
326             if(debug && tmp) printf("tail_string1: (%s)\n",tmp);
327             if(cnt>0)
328                 return tmp;
329                 else
330                     return NULL;
331         } 
332         /* b.r */
333         if(linkedname==NULL && aspectname!=NULL && principalname!=NULL ) {
334             int fst=_get_next_cred_idx();
335             if(param_string != NULL) {
336                 cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s,%s),C%d)",
337                              isX(),typestring,
338                              principalname, aspectname, param_string, fst);
339                 free(param_string);
340                 } else {
341                     cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s),C%d)",
342                              isX(), typestring,
343                              principalname, aspectname, fst);
344             }
345             if(debug && tmp) printf("tail_string2: (%s)\n",tmp);
346             if(cnt>0)
347                 return tmp;
348                 else
349                     return NULL;
350         } 
351         /* b */
352         if(linkedname==NULL && aspectname==NULL && principalname!=NULL ) {
353             tmp=abac_xstrdup(principalname);
354             if(debug && tmp) printf("tail_string3: (%s)\n",tmp);
355             return tmp;
356         } 
357   
358         if(debug && tmp) printf("tail_string4: (%s)\n",tmp);
359         return tmp;
360         }
361    return tmp;
362}
363   
364
365/********************************************************************************/
366
367static char *_build_constraint_rule_clause(char *head_string, char *tail_string)
368{
369    /*only,  A.R <- B */
370    if(debug) 
371         printf("calling _build_constraint_rule_clause (%s)(%s)\n", head_string, tail_string);
372    char *tmp;
373    int idx=_get_next_cred_idx();
374    asprintf(&tmp, "isMember(%s,%s,C%d)", tail_string,head_string,idx);
375    return tmp;
376}
377
378static char *_build_rule_clause(char *aspectname, char *head_string,
379char *tail_string, char *id_string, char *constraint_string)
380{
381    char *tmp=NULL;
382
383    if(aspectname == NULL) {
384        /* A.R <- B */
385        if(id_string == NULL && constraint_string == NULL) {
386            asprintf(&tmp, "isMember(%s,%s,['%s'])",
387                     tail_string,head_string,abac_yyfptr_encoded);
388            } else {
389                if(id_string == NULL) {
390                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
391                         tail_string,head_string,abac_yyfptr_encoded,
392                         constraint_string);
393                } else if(constraint_string == NULL) {
394                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
395                         tail_string,head_string,abac_yyfptr_encoded,
396                         id_string);
397                } else { asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s,%s",
398                         tail_string,head_string,abac_yyfptr_encoded,
399                         id_string, constraint_string);
400                }
401        }
402        } else {
403             /* A.R <- B.R */
404             /* A.R <- B.R.R */
405             if (cred_count==0) {
406                 if(id_string == NULL && constraint_string == NULL) {
407                     asprintf(&tmp,"isMember(%s,%s,['%s']):-%s",
408                           isX(),
409                           head_string, abac_yyfptr_encoded, tail_string);
410                     } else {
411                         if(id_string == NULL) {
412                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s",
413                                 isX(),
414                                 head_string, abac_yyfptr_encoded, tail_string,
415                                 constraint_string);
416                         } else if(constraint_string == NULL) {
417                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s",
418                                 isX(),
419                                 head_string, abac_yyfptr_encoded, id_string,
420                                 tail_string);
421                         } else { 
422                             asprintf(&tmp,"isMember(%s,%s,['%s']):-%s,%s,%s",
423                                 isX(),
424                                 head_string, abac_yyfptr_encoded, id_string,
425                                 tail_string, constraint_string);
426                         }
427                 }
428                 } else {
429                     char *tmp_cred_list=_compose_cred_list();
430                     if(id_string == NULL && constraint_string == NULL) {
431                         asprintf(&tmp,"isMember(%s,%s,L):-%s, appendL([['%s'],%s],L)",
432                                  isX(),
433                                  head_string, tail_string,
434                                  abac_yyfptr_encoded, tmp_cred_list);
435                         } else {
436                            if(id_string == NULL) {
437                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
438                                  isX(),
439                                  head_string, tail_string, constraint_string,
440                                  abac_yyfptr_encoded, tmp_cred_list);
441                            } else if(constraint_string == NULL) {
442                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
443                                  isX(),
444                                  head_string, id_string, tail_string,
445                                  abac_yyfptr_encoded, tmp_cred_list);
446                            } else { 
447                               asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, %s, appendL([['%s'],%s],L)",
448                                  isX(),
449                                  head_string, id_string, tail_string,
450                                  constraint_string,
451                                  abac_yyfptr_encoded, tmp_cred_list);
452                            }
453                     }
454                     free(tmp_cred_list);
455                     cred_count=0;
456             }
457    }
458    return tmp;
459}
460
461
462static char *generate_pl_rule_clause(char *head_rule_string,
463abac_aspect_t *tail_rule, char *id_string, char *constraint_string)
464{
465    char *aspectname=abac_aspect_aspect_name(tail_rule);
466    char *tail_rule_string=generate_pl_tail_string(tail_rule);
467    if(aspectname == NULL && tail_rule_string == NULL) 
468        goto error;
469    char *tmp=_build_rule_clause(aspectname,head_rule_string, tail_rule_string,
470                                          id_string, constraint_string);
471    if(tail_rule_string) free(tail_rule_string);
472    return tmp;
473
474error:
475    if(tail_rule_string) free(tail_rule_string);
476    return NULL;
477}
478
479static char *_add_string(char *dstr, char *nstr)
480{
481    if(strlen(dstr)==0) {
482        dstr=abac_xstrdup(nstr);
483        return dstr;
484        } else { 
485            int len = strlen(dstr)+strlen(nstr)+2;
486            char *tmp=abac_xmalloc(len*sizeof(char));
487            sprintf(tmp,"%s,%s", dstr,nstr);
488            free(dstr);
489            return tmp;
490    }
491    return NULL;
492}
493
494static char *_build_intersecting_clause(char *head_role_string,
495char *tail_role_string, char* id_string, char* constraint_string)
496{
497    char *tmp;
498
499    if (cred_count==0) {
500        if(id_string == NULL && constraint_string == NULL) {
501            asprintf(&tmp,"isMember(%s,%s,['%s']):-%s",
502                   isX(),
503                   head_role_string, abac_yyfptr_encoded, tail_role_string);
504            } else {
505             if(id_string == NULL) {
506                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s",
507                       isX(),
508                       head_role_string, abac_yyfptr_encoded, 
509                       tail_role_string, constraint_string);
510             } else if(constraint_string == NULL) {
511                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s",
512                       isX(),
513                       head_role_string, abac_yyfptr_encoded, 
514                       id_string, tail_role_string);
515             } else {   
516                asprintf(&tmp,"isMember(%s,%s,['%s']):-%s, %s, %s",
517                       isX(),
518                       head_role_string, abac_yyfptr_encoded, 
519                       id_string, tail_role_string, constraint_string);
520             }           
521        }
522        } else {
523            char *tmp_cred_list=_compose_cred_list();
524            if(id_string == NULL && constraint_string == NULL) {
525                asprintf(&tmp,"isMember(%s,%s,L):-%s, appendL([['%s'],%s],L)",
526                                isX(),
527                                head_role_string, tail_role_string,
528                                abac_yyfptr_encoded, tmp_cred_list);
529                } else {
530                    if(id_string == NULL) {
531                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
532                            isX(),
533                            head_role_string, tail_role_string, constraint_string,
534                            abac_yyfptr_encoded, tmp_cred_list);
535                    } else if(constraint_string == NULL) {
536                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, appendL([['%s'],%s],L)",
537                            isX(),
538                            head_role_string, id_string, tail_role_string,
539                            abac_yyfptr_encoded, tmp_cred_list);
540                    } else {   
541                        asprintf(&tmp,"isMember(%s,%s,L):-%s, %s, %s, appendL([['%s'],%s],L)",
542                            isX(),
543                            head_role_string, id_string, tail_role_string, constraint_string,
544                            abac_yyfptr_encoded, tmp_cred_list);
545                    }           
546            }
547            free(tmp_cred_list);
548            cred_count=0;
549    }
550    return tmp;
551}
552
553static char *generate_pl_intersecting_clause(char *head_role_string,
554abac_aspect_t *tail_role, char* id_string, char* constraint_string)
555{
556    char *tmp=NULL;
557    char* tail_role_string=NULL;
558    abac_list_t *list=abac_aspect_prereqs(tail_role);
559    /* A.R <- B.R & C.R.R */
560    /* A.O <- B.O & C.R.O */
561
562    if (list != NULL) {
563        abac_aspect_t *cur;
564        abac_list_foreach(list, cur,
565            char *ntmp=generate_pl_tail_string(cur);
566            if(debug) printf("  intersecting tail: (%s)\n",ntmp);
567            if(tail_role_string==NULL) {
568                 tail_role_string=abac_xstrdup(ntmp);
569                 } else {
570                    tmp=tail_role_string;
571                    tail_role_string=NULL; 
572                    asprintf(&tail_role_string,"%s, %s",tmp,ntmp);
573                    free(tmp);
574            }
575            free(ntmp);
576        );
577    }
578
579    if(debug) printf("      final intersecting tail: (%s)\n",tail_role_string);
580    tmp=_build_intersecting_clause(head_role_string, tail_role_string, id_string,constraint_string);
581    if(tail_role_string) free(tail_role_string);
582    return tmp;
583}
584
585/* generate the yap isMember rule clause for the credential stmt */
586abac_list_t *generate_pl_clauses(abac_aspect_t *head_aspect, abac_aspect_t *tail_aspect)
587{
588   char *tmp=NULL;
589   char *id_clauses_string=NULL;
590   char *constraint_clauses_string=NULL;
591   abac_list_t *clauses=abac_list_new();
592 
593   int cnt=abac_pl_cnt_id_certs();
594   if(cnt > 0) { /* string it up */
595       id_clauses_string=abac_pl_string_id_certs();
596       abac_pl_free_id_certs();
597   }
598
599   /* make a loop here */
600   cnt=abac_pl_cnt_constraints();
601   if(cnt > 0) {
602      constraint_clauses_string=abac_pl_string_constraints();
603      abac_pl_free_constraints();
604   }
605
606/* generate head's string */
607    char *head_string=generate_pl_head_string(head_aspect);
608    if(head_string == NULL)
609        goto error;
610
611/* tail side */
612    if(abac_aspect_is_intersection(tail_aspect)) {
613       tmp=generate_pl_intersecting_clause(head_string, tail_aspect,
614                    id_clauses_string, constraint_clauses_string);
615       } else {
616           tmp=generate_pl_rule_clause(head_string, tail_aspect,
617                    id_clauses_string, constraint_clauses_string);
618    }
619    if(tmp==NULL)
620        goto error;
621 
622    abac_list_add(clauses,tmp);
623    return clauses;
624
625error:
626    if(head_string) free(head_string);
627    if(id_clauses_string) free(id_clauses_string);
628    if(constraint_clauses_string) free(constraint_clauses_string);
629    return clauses;
630}
631
632/* should be just 1 */
633char *generate_pl_constraint_clause(abac_aspect_t *head_aspect, char *tail_string)
634{
635/* generate head's role or oset string */
636    char *head_string=generate_pl_head_string(head_aspect);
637    if(head_string == NULL)
638        goto error;
639
640/* tail side */
641    char *tmp=_build_constraint_rule_clause(head_string, tail_string);
642    if(tmp==NULL)
643        goto error;
644
645    return tmp;
646
647error:
648    if(head_string) free(head_string);
649    return NULL;
650}
651
652/* integer(X)<10 */
653/* X='abc' */
654char *generate_pl_range_constraint(char *typestr,char *var,char *val,char *op)
655{
656   char *tmp=NULL;
657   if(typestr)
658      asprintf(&tmp,"%s(%s)%s%s",typestr,var,op,val);
659      else
660          asprintf(&tmp,"%s%s%s",var,op,val);
661   return tmp;
662}
663
664/* compare(op,var,val) */
665char *generate_pl_range_time_constraint(char *var,char *val,char *op)
666{
667   char *tmp=NULL;
668   asprintf(&tmp,"compare(%s,%s,%s)",op,var,val);
669   return tmp;
670}
671
672/* generate the yap isType rule clause for the type,
673   isType(Acme, keyid); */
674char *generate_pl_type_clause(char *principalname, int type)
675{
676    char *tmp=NULL;
677    char *typeid= abac_idtype_string(type);
678    if(typeid==NULL || strcmp(typeid,"NULL")==0)
679        panic("generate_pl_type_clause: can not have null typeid");
680    if(debug)
681        printf("generate type clause, (%s)\n", principalname);
682    int cnt=asprintf(&tmp,"isType(%s,%s)",
683                                principalname, typeid);
684    return tmp;
685}
686
Note: See TracBrowser for help on using the repository browser.