source: libabac/abac_pl_gen.c @ e97d2e2

mei_rt2_fix_1
Last change on this file since e97d2e2 was abf8d5d, checked in by Mei <mei@…>, 12 years ago

1) add backtrack/multiple solutions proof code changes and new

examples.

  • Property mode set to 100644
File size: 22.3 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
40void generate_pl_set_abac_yyfptr_encoded(char *string)
41{
42   abac_yyfptr_encoded=abac_xstrdup(string);
43}
44
45char *generate_pl_type_clause(char *principalname, int type);
46
47
48/***********************************************************************/
49char *prologIt(char *str)
50{
51    char *tmp=NULL;
52    asprintf(&tmp,"p%s",str);
53    return tmp;
54}
55
56static char* isX()
57{
58    static char x_string[2]="X";
59    static char this_string[5]="This";
60    if(using_this)
61        return this_string;
62        else 
63           return x_string;
64}
65
66static int _get_next_cred_idx()
67{
68    cred_count++;
69    return cred_count;
70}
71
72/* remember to free the returned string */
73static char *_compose_cred_list()
74{
75    int i=cred_count;
76    if(cred_count==0) return "";
77
78    char *clist=(char *)abac_xmalloc(sizeof(char)*(cred_count)*3);
79    strcpy(clist,"C1");
80    if (cred_count==1) return clist;
81
82    i=1;
83    while(i!=cred_count) {
84        i++;
85        sprintf(clist,"%s,C%d",clist,i);
86    }
87    return clist;
88}
89
90
91/************************************************************************/
92/* this is for tracking prolog constraints */
93void abac_pl_init_constraints()
94{
95    abac_pl_constraints = abac_list_new();
96}
97
98void abac_pl_free_constraints()
99{
100    char *cur;
101    abac_list_foreach(abac_pl_constraints, cur,
102        if(cur)
103            free(cur);
104    );
105    abac_list_free(abac_pl_constraints);
106    abac_pl_constraints=NULL;
107}
108
109int abac_pl_cnt_constraints()
110{
111    return abac_list_size(abac_pl_constraints);
112}
113
114char *abac_pl_string_constraints()
115{
116    int first=1;
117    char *tmp=NULL;
118    char *final=NULL;
119    char* cur;
120    abac_list_foreach(abac_pl_constraints, cur,
121        if(cur)
122            if(first) {
123                final=abac_xstrdup(cur);
124                first=0;
125                } else {
126                    tmp=final;
127                    final=NULL;
128                    int cnt=asprintf(&final,"%s,%s", tmp, cur);
129            }
130    );
131    return final;
132}
133
134void abac_pl_add_constraints(char *constraint)
135{
136    if(abac_pl_constraints == NULL)
137        abac_pl_init_constraints();
138    char* nptr=abac_xstrdup(constraint);
139    abac_list_add(abac_pl_constraints, nptr);
140}
141
142
143/************************************************************************/
144void abac_pl_init_id_certs()
145{
146    abac_pl_id_certs = abac_list_new();
147}
148
149void abac_pl_free_id_certs()
150{
151    if(abac_pl_id_certs==NULL)
152        return;
153
154    abac_id_cert_t *id;
155    abac_list_foreach(abac_pl_id_certs, id,
156        if(id) 
157            free(id->principalname);
158            free(id->clause);
159            free(id);
160    );
161    abac_list_free(abac_pl_id_certs);
162    abac_pl_id_certs = NULL;
163}
164
165int abac_pl_cnt_id_certs()
166{
167    return abac_list_size(abac_pl_id_certs);
168}
169
170char *abac_pl_string_id_certs()
171{
172    int first=1;
173    char *tmp=NULL;
174    abac_id_cert_t *cur;
175    abac_list_foreach(abac_pl_id_certs, cur,
176        if(cur) 
177            if(first) {
178                tmp=abac_xstrdup(cur->clause);
179                first=0;
180                } else {
181                    int cnt=asprintf(&tmp,"%s,%s", tmp, cur->clause);
182            }
183    );
184    return tmp;
185}
186
187void abac_pl_add_id_certs(char *principalname, int type)
188{
189    abac_id_cert_t *id_cert=NULL;
190    int found=0;
191    abac_id_cert_t *cur;
192
193    if(debug) {
194         fprintf(stderr,"add_id_certs: adding --> (%s)\n", principalname);
195    }
196
197    if(abac_pl_id_certs == NULL) {
198        abac_pl_init_id_certs();
199        } else {
200            abac_list_foreach(abac_pl_id_certs, cur,
201                if(cur) 
202                    if(strcmp(cur->principalname,principalname)==0) {
203                       found=1;
204                       break;
205                    }
206            );
207    }
208
209    if (found) {
210        return;
211        } else {
212            id_cert=abac_xmalloc(sizeof(abac_id_cert_t));
213            id_cert->principalname=abac_xstrdup(principalname);
214            id_cert->type=type;
215            id_cert->clause=generate_pl_type_clause(principalname,type);
216            abac_list_add(abac_pl_id_certs, id_cert);
217    }
218}
219
220/***********************************************************************/
221/* generate role(p_name, r_name, param..)                              */
222/*          or oset(p_name, r_name, param..)                           */
223static char* generate_pl_head_string(abac_aspect_t *ptr)
224{
225     char *tmp=NULL;
226     char *principalname;
227     PROLOG(principalname=abac_aspect_principal_name(ptr););
228     char *aspectname=abac_aspect_aspect_name(ptr);
229     char *typestring=abac_aspect_type_string(ptr);
230     char *param_string=NULL;
231     int cnt=0;
232
233     /* can not be a linked role */
234     abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr);
235     if(aspect_params) {
236        PROLOG(param_string=abac_param_list_string(aspect_params););
237     }
238
239     if (param_string != NULL) {
240         cnt=asprintf(&tmp,"%s(%s,%s,%s)", 
241                        typestring, principalname, aspectname, param_string);
242         free(param_string);
243         } else {
244             cnt=asprintf(&tmp,"%s(%s,%s)", 
245                        typestring, principalname, aspectname);
246     }
247
248     if(debug && tmp) fprintf(stderr,"generate_pl_head_string: (%s)\n",tmp);
249     if(cnt>0)
250        return tmp;
251        else
252           return NULL;
253}
254
255/* generate role(p_name, r_name, param..) with isMember call ?? */
256/* generate oset(p_name, r_name, param..) with isMember call ?? */
257static char* generate_pl_tail_string(abac_aspect_t *ptr)
258{
259
260     char *tmp=NULL;
261
262/* for oset case,
263   A.oset <- B
264   A.oset <- Obj
265   A.oset <- B.oset
266   A.oset <- B.role.oset
267*/
268     /* o only if it is an oset and object */
269     if(abac_aspect_is_object(ptr)) {
270         char *objectname=abac_aspect_object_name(ptr);
271         tmp=abac_xstrdup(objectname);
272         return tmp;
273     } else {
274         char *principalname;
275         PROLOG(principalname=abac_aspect_principal_name(ptr););
276         char *aspectname=abac_aspect_aspect_name(ptr);
277         char *linkedname=abac_aspect_linked_role_name(ptr);
278         char *typestring=abac_aspect_type_string(ptr);
279
280         char *param_string=NULL;
281         char *linked_param_string=NULL;
282         int cnt=0;
283   
284         abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr);
285         if(aspect_params) {
286            PROLOG(param_string=abac_param_list_string(aspect_params););
287         }
288   
289         abac_param_list_t *linked_role_params=abac_aspect_linked_role_params(ptr);
290         if(linked_role_params) {
291            PROLOG(linked_param_string=abac_param_list_string(linked_role_params););
292         }
293   
294         /* b.r.r */
295         if(linkedname!=NULL && aspectname!=NULL && principalname!=NULL ) {
296             int fst=_get_next_cred_idx();
297             int snd=_get_next_cred_idx();
298             if(linked_param_string !=NULL) {
299                 if (param_string != NULL) {
300                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
301                            principalname,
302                            linkedname,linked_param_string,fst,
303                            isX(), typestring,
304                            aspectname,param_string,snd);
305                     free(param_string);
306                     } else {
307                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
308                            principalname,
309                            linkedname,linked_param_string,fst,
310                            isX(), typestring,
311                            aspectname,snd);
312                 }
313                 free(linked_param_string);
314                 } else {
315                     if (aspect_params != NULL) {
316                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s,%s),C%d)",
317                            principalname,
318                            linkedname,fst,
319                            isX(),typestring,
320                            aspectname,param_string,snd);
321                         free(param_string);
322                         } else {
323                             cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(%s,%s(Y,%s),C%d)",
324                                principalname,
325                                linkedname,fst,
326                                isX(),typestring,
327                                aspectname,snd);
328                   }
329             }
330             if(cnt>0)
331                 return tmp;
332                 else
333                     return NULL;
334         } 
335         /* b.r */
336         if(linkedname==NULL && aspectname!=NULL && principalname!=NULL ) {
337             int fst=_get_next_cred_idx();
338             if(param_string != NULL) {
339                 cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s,%s),C%d)",
340                              isX(),typestring,
341                              principalname, aspectname, param_string, fst);
342                 free(param_string);
343                 } else {
344                     cnt=asprintf(&tmp,"isMember(%s,%s(%s,%s),C%d)",
345                              isX(), typestring,
346                              principalname, aspectname, fst);
347             }
348             if(cnt>0)
349                 return tmp;
350                 else
351                     return NULL;
352         } 
353         /* b */
354         if(linkedname==NULL && aspectname==NULL && principalname!=NULL ) {
355             tmp=abac_xstrdup(principalname);
356             return tmp;
357         } 
358   
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         fprintf(stderr,"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) fprintf(stderr,"  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) fprintf(stderr,"      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 prolog 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 prolog 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        fprintf(stderr,"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.