source: libabac/abac_pl_yap.c @ 9335cfa

mei_rt2mei_rt2_fix_1
Last change on this file since 9335cfa was 9335cfa, checked in by Mei <mei@…>, 13 years ago

1) add handling of 'this' data term for the principal type
2) add payraise_rt1_typed example
3) expand more test cases for python/swig/libabac

  • Property mode set to 100644
File size: 14.1 KB
Line 
1
2/* copied from abac_graph.c
3   implementation of the low level using
4   yap prolog
5*/
6
7#include <err.h>
8#include <stdio.h>
9#include <assert.h>
10#include <stdlib.h>
11#include <string.h>
12#include <Yap/YapInterface.h>
13
14#include "abac_pl.h"
15#include "abac_pl_yap.h"
16
17#include "abac_list.h"
18#include "abac_util.h"
19
20#include "uthash.h"
21
22extern char *abac_cn_with_role(abac_role_t *);
23extern char *abac_cn_with_oset(abac_oset_t *);
24extern char *abac_principalname_with_role(abac_role_t *);
25extern char *abac_principalname_with_oset(abac_oset_t *);
26extern abac_list_t *abac_credential_clauses(abac_credential_t *);
27extern char *abac_id_clause(abac_id_cert_t *);
28extern abac_oset_t *abac_yy_get_rule_tail_oset();
29extern abac_oset_t *abac_yy_get_rule_head_oset();
30extern abac_role_t *abac_yy_get_rule_tail_role();
31extern abac_role_t *abac_yy_get_rule_head_role();
32
33
34static int debug=0;
35/* track constraint's external clause's -unique name id */
36static int constraint_label_count=0;
37static char *constraint_label="isABAC_constraint";
38
39// pl -- place holder for now
40struct _abac_pl_t {
41    FILE *fptr;
42    char *fname;
43    char *yap_certs;
44};
45
46/***********************************************************/
47static int _get_next_constraint_label_idx()
48{
49    constraint_label_count++;
50    return constraint_label_count;
51}
52
53static int _get_constraint_label_idx()
54{
55    return constraint_label_count;
56}
57
58/***********************************************************/
59
60static int _insert_clause(char *str)
61{
62    YAP_Term *eterm;
63    YAP_Term goalArgs=YAP_ReadBuffer(str, eterm);
64    char *tmp=YAP_CompileClause(goalArgs);
65    if (tmp!=NULL) { /* something is wrong */
66        printf("error: result of compile clause (%s)\n", tmp);
67        printf("error: str used (%s)\n", str);
68        return 1;
69    }
70    return 0;
71}
72
73static int _insert_cred_clause(char *cstr)
74{
75    int ret=ABAC_CERT_SUCCESS;
76    int rc=_insert_clause(cstr);
77    if (rc)
78        return ABAC_CERT_BAD_YAP;
79    return ABAC_CERT_SUCCESS;
80}
81
82static void _show_yap_db(char *msg)
83{
84    char lstr[]="listing";
85    YAP_Term *eterm; /* error term */
86
87    printf("\n\n========= yap db (%s)\n",msg);
88    YAP_Term goal=YAP_ReadBuffer(lstr, eterm);
89    int rc =YAP_RunGoal( goal );
90    if (rc) {
91        printf("listing ok.. \n");
92    } else {
93        printf("listing's rc is bad.. \n");
94        YAP_Exit(1);
95    }
96    printf("========= \n\n");
97}
98
99/**
100 * Include some utility routines
101 */
102abac_pl_t *abac_pl_utility(void) {
103/*
104append([],L,L).
105append([X|L1],L2,[X|L3]):-append(L1,L2,L3).
106
107appendL([],[]).
108appendL([H|T], L) :-
109   appendL(T,L2), append(H,L2,L).
110*/
111    if(_insert_clause("append([],L,L)"))
112        YAP_Exit(1);
113    if(_insert_clause("append([X|L1],L2,[X|L3]):-append(L1,L2,L3)"))
114        YAP_Exit(1);
115    if(_insert_clause("appendL([],[])"))
116        YAP_Exit(1);
117    if(_insert_clause("appendL([H|T], L) :- appendL(T,L2), append(H,L2,L)"))
118        YAP_Exit(1);
119}
120
121/**
122 * Create a new yap structure.
123 */
124abac_pl_t *abac_pl_new(void) {
125
126    if (YAP_FastInit(NULL) == YAP_BOOT_ERROR)
127        YAP_Exit(1);
128
129    if (YAP_RunGoal(YAP_MkAtomTerm(YAP_LookupAtom("source")))) {
130        if(debug) printf("calling source..\n");
131        } else {
132            if(debug) printf("calling source failed..\n");
133            YAP_Exit(1);
134    }
135
136    abac_pl_utility();
137 
138    abac_pl_t *pl = abac_xmalloc(sizeof(abac_pl_t));
139    pl->fptr=NULL;
140    pl->fname=NULL;
141    pl->yap_certs=NULL;
142    return pl;
143}
144
145/**
146 * Add a credential to the db
147 */
148int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
149{
150    int rc=0;
151    abac_list_t *clauses=abac_credential_clauses(cred);
152    if (clauses != NULL) {
153        char *cur;
154        abac_list_foreach(clauses, cur,
155            if(cur) {
156                if(debug) printf("inserting =>%s\n",cur);
157                rc=_insert_cred_clause(cur);
158            }
159        );
160    }
161    return rc;
162}
163
164int abac_pl_add_type_credential(abac_pl_t *pl, abac_id_cert_t *id_cert)
165{
166    char *clause=abac_id_clause(id_cert);
167    if (clause != NULL) {
168        int rc=_insert_cred_clause(clause);
169        return rc;
170    }
171    return 0;
172}
173
174/*  string1(S):- S="abc";S="efg";S="ijk" */
175char *abac_pl_add_range_constraint_clause(char *var, char *tmplist)
176{
177    int i=_get_next_constraint_label_idx();
178    char *tmp=NULL;
179    asprintf(&tmp,"%s_%d(%s) :- %s", constraint_label, i, var, tmplist); 
180    int rc=_insert_cred_clause(tmp);
181    free(tmp);
182    if(rc) 
183        panic("abac_pl_add_range_constraint_clause, failed to insert");
184    asprintf(&tmp,"%s_%d(%s)", constraint_label, i, var);
185    return tmp;
186}
187
188/* cases,
189     ['str']
190     ['str1','str2']
191     ([] is not possible, and don't care)
192*/
193static void _credentials_from_string(abac_stack_t *credentials,char *slist) {
194    char *cptr=slist; /* current ptr */
195    char *sptr; /* string ptr */
196    char *ptr;
197    int len=0;
198    char *string;
199    abac_credential_t *cred=NULL;
200    int cnt=0;
201
202    /* find first [' */ 
203    ptr=strstr(cptr,"['");
204    if(ptr == NULL) 
205         return;
206    cptr=ptr+2;
207    sptr=cptr;
208    while (1) {
209        /* find next ',' or '] */
210        ptr=strstr(cptr,"','");
211        if(ptr!=NULL) {
212             cptr=ptr+3;
213             len=(ptr-sptr);
214             string=strndup(sptr,len);
215             cred=abac_credential_lookup(string);
216             free(string); 
217             if(cred) {
218                 int i=abac_stack_unique_push(credentials, cred);
219                 if(i) cnt++;
220                 } else {
221                 printf("BAD BAD BAD\n");
222             }
223             sptr=cptr;
224             } else {
225             ptr=strstr(cptr,"']");
226             if(ptr!=NULL) {
227                 len=(ptr-sptr);
228                 string=strndup(sptr,len);
229                 cred=abac_credential_lookup(string);
230                 free(string);
231                 if(cred) {
232                     int i=abac_stack_unique_push(credentials, cred);
233                     if(i) cnt++;
234                     } else {
235                     printf("BAD BAD BAD\n");
236                 }
237                 break;
238             }
239        }
240    }
241    if(debug)
242        printf("DEBUG:total %d credentials\n", cnt);
243}
244
245/* make a query and extract just 1 set of result */
246static abac_stack_t *_make_yap_query(char *prin, char *rule, char* estring)
247{
248    YAP_Term *eterm0;
249    YAP_Term *eterm1;
250    YAP_Term arg[3];
251    char tmp[5000];
252    abac_stack_t *cred_list = abac_stack_new();
253
254    if(debug) printf(" the principal part(%s)\n", prin);
255    if(prin[0]=='\'' || prin[0]=='"') {
256        arg[0]=YAP_ReadBuffer(prin,eterm0);
257        } else {
258            arg[0]=YAP_MkAtomTerm(YAP_LookupAtom(prin)); 
259    }
260    if(debug) printf(" the role/oset part(%s)\n", estring);
261    arg[1]=YAP_ReadBuffer(estring,eterm1);
262
263    /* var for credential list */
264    arg[2]=YAP_MkVarTerm();
265
266    YAP_Atom f = YAP_LookupAtom("isMember");
267    YAP_Functor func = YAP_MkFunctor(f, 3);
268    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
269
270    int rc =YAP_RunGoal( goal );
271    if (rc) {
272        printf("YAP query succeed\n");
273        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
274        /* this is returned as ['string1','string2'] */
275        if(debug) printf("    query answer : %s\n", tmp);
276        _credentials_from_string(cred_list,tmp); 
277/**** XXX
278        while (YAP_RestartGoal()) {
279            if(debug) printf("another success\n");
280            YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
281        if(debug) printf("    restart query answer : %s\n", tmp);
282            _credentials_from_string(cred_list,tmp);
283        }
284***/
285    } else {
286        printf("YAP query failed\n");
287        /* YAP_Exit(1); */
288    }
289    return cred_list;
290}
291
292/* 2 types
293      acme.buys_rocket <- coyote (coyote=prin, acme.buys_rocket=role)
294        ==> isMember(coyote,role(acme,buys_rocket), L)
295
296      acme.buys_rocket <- acme.preferred_customer  -- NOT DONE YET */
297static abac_stack_t *_query_with_role(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin)
298{
299    char tmp[5000];
300    abac_stack_t *ret=NULL;
301
302    if(debug)
303        _show_yap_db("DEBUG:calling within _query_with_role");
304
305    /* if using cn */
306    char *prin_nm;
307    char *role_nm;
308    if(USE("ABAC_CN")) {
309        prin_nm=abac_cn_with_role(role_prin);
310        role_nm=abac_cn_with_role(role);
311        } else {
312           prin_nm=abac_principalname_with_role(role_prin);
313           role_nm=abac_principalname_with_role(role);
314    }
315
316    if(abac_role_role_name(role_prin)!=NULL) {
317        printf("fail, a.r <- b.r query is not implemented yet !!!\n");
318        YAP_Exit(1);
319    }
320
321    if (prin_nm == NULL || role_nm == NULL) {
322        printf("fail, query's call got bad roles.. \n");
323        YAP_Exit(1);
324    }
325
326    if(debug) printf("printing up the yap query ..\n");
327    char *pstring=abac_role_role_param_string(role);
328    if(pstring) {
329        sprintf(tmp,"role(%s,%s,%s)", role_nm, abac_role_role_name(role),pstring);
330        free(pstring);
331        } else {
332            sprintf(tmp,"role(%s,%s)", role_nm, abac_role_role_name(role));
333    }
334    ret=_make_yap_query(prin_nm,role_nm,tmp);
335    return ret;
336}
337
338static abac_stack_t *_query_with_oset(abac_pl_t *pl, abac_oset_t* oset, abac_oset_t* oset_obj)
339{
340    char tmp[5000];
341    abac_stack_t *ret=NULL;
342
343    if(debug)
344        _show_yap_db("DEBUG:calling within _query_with_oset");
345
346   
347    char *oset_nm=NULL;
348    if(USE("ABAC_CN")) oset_nm=abac_cn_with_oset(oset);
349        else oset_nm=abac_principalname_with_oset(oset);
350    /* could be obj or principal */
351    char *prin_nm=NULL;
352    if(abac_oset_is_object(oset_obj)) {
353        prin_nm=abac_oset_object_name(oset_obj);
354        } else {
355            if(USE("ABAC_CN")) prin_nm=abac_oset_principal_cn(oset_obj);
356                else prin_nm=abac_oset_principal_principalname(oset_obj);
357    }
358
359    if(abac_oset_oset_name(oset_obj)!=NULL) {
360        printf("fail, a.o <- b.o query is not implemented yet !!!\n");
361        YAP_Exit(1);
362    }
363
364    if (prin_nm == NULL || oset_nm == NULL) {
365        printf("fail, query's call got bad oset.. \n");
366        YAP_Exit(1);
367    }
368
369    if(debug) printf("printing up the yap query ..\n");
370    char *pstring=abac_oset_oset_param_string(oset);
371    if(pstring) {
372        sprintf(tmp,"oset(%s,%s,%s)", oset_nm, abac_oset_oset_name(oset),pstring);
373        free(pstring);
374        } else {
375            sprintf(tmp,"oset(%s,%s)", oset_nm, abac_oset_oset_name(oset));
376    }
377
378    ret=_make_yap_query(prin_nm,oset_nm,tmp);
379    return ret;
380}
381
382static abac_stack_t *_dump(abac_pl_t *pl)
383{
384    YAP_Term *eterm;
385    YAP_Term arg[3];
386    char tmp[5000];
387    abac_stack_t *cred_list = abac_stack_new();
388
389    if(USE("DUMP_DB"))
390        _show_yap_db("DEBUG:calling within _dump");
391
392    char *estring=NULL;
393    YAP_Term *eterm1;
394    YAP_Term *eterm2;
395    asprintf(&estring,"_");
396/*
397    arg[0]=YAP_ReadBuffer(estring,eterm1);
398    arg[1]=YAP_ReadBuffer(estring,eterm2);
399*/
400    arg[0]=YAP_MkVarTerm();
401    arg[1]=YAP_MkVarTerm();
402    arg[2]=YAP_MkVarTerm();
403    YAP_Atom f = YAP_LookupAtom("isMember");
404    YAP_Functor func = YAP_MkFunctor(f, 3);
405    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
406
407    int rc =YAP_RunGoal( goal );
408    if (rc) {
409        printf("YAP dump succeed\n");
410        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
411        if(debug) printf("    dump answer : %s\n", tmp);
412        /* this is returned as ['string1','string2'] */
413        _credentials_from_string(cred_list,tmp); 
414        while (YAP_RestartGoal()) {
415            if(debug) printf("another dump success\n");
416            YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
417            if(debug) printf("    dump restart answer : %s\n", tmp);
418            _credentials_from_string(cred_list,tmp); 
419        }
420    } else {
421        printf("YAP _dump query failed\n");
422        /* YAP_Exit(1); */
423    }
424    return cred_list;
425}
426
427/* findall(X,isMember(_,_,X),L) */
428static abac_stack_t *_dump2(abac_pl_t *pl)
429{
430    YAP_Term *eterm;
431    YAP_Term arg[3];
432    char tmp[5000];
433    abac_stack_t *cred_list = abac_stack_new();
434
435    if(debug)
436        _show_yap_db("DEBUG:calling within _dump");
437
438    char *estring="isMember(_,_,X)";
439    arg[0]=YAP_MkAtomTerm(YAP_LookupAtom("X"));
440    arg[1]=YAP_ReadBuffer(estring,eterm);
441    arg[2]=YAP_MkVarTerm();
442    YAP_Atom f = YAP_LookupAtom("findall");
443    YAP_Functor func = YAP_MkFunctor(f, 3);
444    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
445
446    int rc =YAP_RunGoal( goal );
447    if (rc) {
448        printf("YAP dump succeed\n");
449        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
450        if(debug) printf("    dump answer : %s\n", tmp);
451        /* this is returned as ['string1','string2'] */
452        _credentials_from_string(cred_list,tmp); 
453        } else {
454            printf("YAP _dump query failed\n");
455            /* YAP_Exit(1); */
456    }
457    return cred_list;
458}
459
460/**
461 * Get all the credentials (attribute/issuer cert pairs) from prolog
462 * (which returns in string form)
463 */
464abac_stack_t *abac_pl_credentials(abac_pl_t *pl)
465{
466    abac_stack_t *ret=_dump(pl);
467    return ret;
468}
469
470/**
471 * Make a query into prolog db
472--role acme.preferred_customer --principal coyote
473--role acme.prefer_customer.buy_rockets --principlal coyote
474--oset acme.rockets -- object mrx-21
475--oset acme.villans -- principal coyote
476 */
477abac_stack_t *abac_pl_query(abac_pl_t *pl, char *roleoset, char *prinobj)
478{
479    abac_stack_t *ret=NULL;
480    int len=strlen(roleoset)+strlen(prinobj)+5;
481    char* attr_string=(char *) abac_xmalloc(sizeof(char)*len);
482    sprintf(attr_string,"%s<-%s", roleoset, prinobj);
483
484    if(debug)
485        printf("abac_pl_query, query string is (%s)\n",attr_string);
486
487    /* call into yacc parser */
488    abac_reset_yyfptr(attr_string);
489    abac_yy_init();
490    int rc=yyparse();
491    if (rc) {
492        free(attr_string);
493        return NULL;
494    }
495
496    if(abac_yy_get_rule_is_oset()) {
497        abac_oset_t *head_oset = abac_yy_get_rule_head_oset();
498        abac_oset_t *tail_oset = abac_yy_get_rule_tail_oset();
499        ret=_query_with_oset(pl,head_oset,tail_oset);
500        } else {
501            abac_role_t *head_role = abac_yy_get_rule_head_role();
502            abac_role_t *tail_role = abac_yy_get_rule_tail_role();
503            ret=_query_with_role(pl,head_role,tail_role);
504    }
505    return ret;
506}
507
508void abac_pl_free(abac_pl_t *pl) {
509    if(pl->fptr) {
510        fflush(pl->fptr);
511        free(pl->fptr);
512    }
513    if(pl->fname) {
514        unlink(pl->fname);
515        free(pl->fname);
516    }
517    free(pl);
518}
519
Note: See TracBrowser for help on using the repository browser.