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
RevLine 
[e95d652]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 *);
[da5afdf]23extern char *abac_cn_with_oset(abac_oset_t *);
[7727f26]24extern char *abac_principalname_with_role(abac_role_t *);
25extern char *abac_principalname_with_oset(abac_oset_t *);
[da5afdf]26extern abac_list_t *abac_credential_clauses(abac_credential_t *);
27extern char *abac_id_clause(abac_id_cert_t *);
[0d0c3a9]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
[da5afdf]33
[202a7f9]34static int debug=0;
[d5bbd3e]35/* track constraint's external clause's -unique name id */
36static int constraint_label_count=0;
37static char *constraint_label="isABAC_constraint";
[e95d652]38
[da5afdf]39// pl -- place holder for now
[e95d652]40struct _abac_pl_t {
41    FILE *fptr;
42    char *fname;
43    char *yap_certs;
44};
45
[d5bbd3e]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
[53e540d]60static int _insert_clause(char *str)
[e95d652]61{
[202a7f9]62    YAP_Term *eterm;
[53e540d]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;
[e95d652]69    }
[53e540d]70    return 0;
[e95d652]71}
72
[53e540d]73static int _insert_cred_clause(char *cstr)
[e95d652]74{
75    int ret=ABAC_CERT_SUCCESS;
[53e540d]76    int rc=_insert_clause(cstr);
77    if (rc)
78        return ABAC_CERT_BAD_YAP;
79    return ABAC_CERT_SUCCESS;
[e95d652]80}
81
82static void _show_yap_db(char *msg)
83{
84    char lstr[]="listing";
[da5afdf]85    YAP_Term *eterm; /* error term */
[e95d652]86
[53e540d]87    printf("\n\n========= yap db (%s)\n",msg);
[e95d652]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    }
[53e540d]96    printf("========= \n\n");
[e95d652]97}
98
[53e540d]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);
[e95d652]119}
120
[53e540d]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")))) {
[202a7f9]130        if(debug) printf("calling source..\n");
[53e540d]131        } else {
[202a7f9]132            if(debug) printf("calling source failed..\n");
133            YAP_Exit(1);
[53e540d]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;
[e95d652]143}
144
[53e540d]145/**
[202a7f9]146 * Add a credential to the db
[53e540d]147 */
148int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
149{
150    int rc=0;
[202a7f9]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        );
[53e540d]160    }
161    return rc;
162}
[e95d652]163
[202a7f9]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
[d5bbd3e]174/*  string1(S):- S="abc";S="efg";S="ijk" */
[7b548fa]175char *abac_pl_add_range_constraint_clause(char *var, char *tmplist)
[d5bbd3e]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) 
[7b548fa]183        panic("abac_pl_add_range_constraint_clause, failed to insert");
[d5bbd3e]184    asprintf(&tmp,"%s_%d(%s)", constraint_label, i, var);
185    return tmp;
186}
187
[da5afdf]188/* cases,
[e95d652]189     ['str']
190     ['str1','str2']
191     ([] is not possible, and don't care)
192*/
[202a7f9]193static void _credentials_from_string(abac_stack_t *credentials,char *slist) {
[e95d652]194    char *cptr=slist; /* current ptr */
195    char *sptr; /* string ptr */
196    char *ptr;
[202a7f9]197    int len=0;
[e95d652]198    char *string;
199    abac_credential_t *cred=NULL;
[202a7f9]200    int cnt=0;
201
[e95d652]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;
[202a7f9]213             len=(ptr-sptr);
[e95d652]214             string=strndup(sptr,len);
215             cred=abac_credential_lookup(string);
[202a7f9]216             free(string); 
[e95d652]217             if(cred) {
[7b548fa]218                 int i=abac_stack_unique_push(credentials, cred);
219                 if(i) cnt++;
[e95d652]220                 } else {
221                 printf("BAD BAD BAD\n");
222             }
223             sptr=cptr;
224             } else {
225             ptr=strstr(cptr,"']");
226             if(ptr!=NULL) {
[202a7f9]227                 len=(ptr-sptr);
[e95d652]228                 string=strndup(sptr,len);
229                 cred=abac_credential_lookup(string);
[202a7f9]230                 free(string);
[e95d652]231                 if(cred) {
[7b548fa]232                     int i=abac_stack_unique_push(credentials, cred);
233                     if(i) cnt++;
[e95d652]234                     } else {
235                     printf("BAD BAD BAD\n");
236                 }
237                 break;
238             }
239        }
240    }
[202a7f9]241    if(debug)
242        printf("DEBUG:total %d credentials\n", cnt);
[e95d652]243}
244
[9335cfa]245/* make a query and extract just 1 set of result */
[7727f26]246static abac_stack_t *_make_yap_query(char *prin, char *rule, char* estring)
[e95d652]247{
[36b100a]248    YAP_Term *eterm0;
249    YAP_Term *eterm1;
[e95d652]250    YAP_Term arg[3];
[da5afdf]251    char tmp[5000];
[202a7f9]252    abac_stack_t *cred_list = abac_stack_new();
253
[7727f26]254    if(debug) printf(" the principal part(%s)\n", prin);
255    if(prin[0]=='\'' || prin[0]=='"') {
256        arg[0]=YAP_ReadBuffer(prin,eterm0);
[36b100a]257        } else {
[7727f26]258            arg[0]=YAP_MkAtomTerm(YAP_LookupAtom(prin)); 
[36b100a]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 */
[da5afdf]264    arg[2]=YAP_MkVarTerm();
[36b100a]265
[da5afdf]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'] */
[7b548fa]275        if(debug) printf("    query answer : %s\n", tmp);
[da5afdf]276        _credentials_from_string(cred_list,tmp); 
[9335cfa]277/**** XXX
[da5afdf]278        while (YAP_RestartGoal()) {
279            if(debug) printf("another success\n");
280            YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
[7b548fa]281        if(debug) printf("    restart query answer : %s\n", tmp);
[da5afdf]282            _credentials_from_string(cred_list,tmp);
283        }
[9335cfa]284***/
[da5afdf]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
[c586a3c]302    if(debug)
[da5afdf]303        _show_yap_db("DEBUG:calling within _query_with_role");
[e95d652]304
[7727f26]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    }
[e95d652]315
316    if(abac_role_role_name(role_prin)!=NULL) {
[202a7f9]317        printf("fail, a.r <- b.r query is not implemented yet !!!\n");
[e95d652]318        YAP_Exit(1);
319    }
320
[7727f26]321    if (prin_nm == NULL || role_nm == NULL) {
[e95d652]322        printf("fail, query's call got bad roles.. \n");
323        YAP_Exit(1);
324    }
[da5afdf]325
326    if(debug) printf("printing up the yap query ..\n");
327    char *pstring=abac_role_role_param_string(role);
328    if(pstring) {
[7727f26]329        sprintf(tmp,"role(%s,%s,%s)", role_nm, abac_role_role_name(role),pstring);
[da5afdf]330        free(pstring);
331        } else {
[7727f26]332            sprintf(tmp,"role(%s,%s)", role_nm, abac_role_role_name(role));
[da5afdf]333    }
[7727f26]334    ret=_make_yap_query(prin_nm,role_nm,tmp);
[da5afdf]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
[7727f26]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);
[da5afdf]350    /* could be obj or principal */
[7727f26]351    char *prin_nm=NULL;
[da5afdf]352    if(abac_oset_is_object(oset_obj)) {
[7727f26]353        prin_nm=abac_oset_object_name(oset_obj);
[da5afdf]354        } else {
[7727f26]355            if(USE("ABAC_CN")) prin_nm=abac_oset_principal_cn(oset_obj);
356                else prin_nm=abac_oset_principal_principalname(oset_obj);
[da5afdf]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
[7727f26]364    if (prin_nm == NULL || oset_nm == NULL) {
[da5afdf]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) {
[7727f26]372        sprintf(tmp,"oset(%s,%s,%s)", oset_nm, abac_oset_oset_name(oset),pstring);
[da5afdf]373        free(pstring);
374        } else {
[7727f26]375            sprintf(tmp,"oset(%s,%s)", oset_nm, abac_oset_oset_name(oset));
[da5afdf]376    }
377
[7727f26]378    ret=_make_yap_query(prin_nm,oset_nm,tmp);
[da5afdf]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
[7727f26]389    if(USE("DUMP_DB"))
[da5afdf]390        _show_yap_db("DEBUG:calling within _dump");
391
[d5bbd3e]392    char *estring=NULL;
393    YAP_Term *eterm1;
394    YAP_Term *eterm2;
395    asprintf(&estring,"_");
[7b548fa]396/*
[d5bbd3e]397    arg[0]=YAP_ReadBuffer(estring,eterm1);
398    arg[1]=YAP_ReadBuffer(estring,eterm2);
[7b548fa]399*/
[da5afdf]400    arg[0]=YAP_MkVarTerm();
401    arg[1]=YAP_MkVarTerm();
[e95d652]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);
[da5afdf]406
[e95d652]407    int rc =YAP_RunGoal( goal );
408    if (rc) {
[da5afdf]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);
[e95d652]412        /* this is returned as ['string1','string2'] */
413        _credentials_from_string(cred_list,tmp); 
414        while (YAP_RestartGoal()) {
[da5afdf]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);
[e95d652]418            _credentials_from_string(cred_list,tmp); 
419        }
420    } else {
[da5afdf]421        printf("YAP _dump query failed\n");
422        /* YAP_Exit(1); */
[e95d652]423    }
424    return cred_list;
425}
426
[0d0c3a9]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
[da5afdf]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
[e95d652]470/**
471 * Make a query into prolog db
472--role acme.preferred_customer --principal coyote
473--role acme.prefer_customer.buy_rockets --principlal coyote
[da5afdf]474--oset acme.rockets -- object mrx-21
475--oset acme.villans -- principal coyote
[e95d652]476 */
[da5afdf]477abac_stack_t *abac_pl_query(abac_pl_t *pl, char *roleoset, char *prinobj)
[e95d652]478{
[202a7f9]479    abac_stack_t *ret=NULL;
[da5afdf]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);
[e95d652]486
[da5afdf]487    /* call into yacc parser */
488    abac_reset_yyfptr(attr_string);
[b5a3da4]489    abac_yy_init();
[da5afdf]490    int rc=yyparse();
491    if (rc) {
492        free(attr_string);
[e95d652]493        return NULL;
494    }
495
[b5a3da4]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();
[da5afdf]499        ret=_query_with_oset(pl,head_oset,tail_oset);
500        } else {
[b5a3da4]501            abac_role_t *head_role = abac_yy_get_rule_head_role();
502            abac_role_t *tail_role = abac_yy_get_rule_tail_role();
[da5afdf]503            ret=_query_with_role(pl,head_role,tail_role);
504    }
[e95d652]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.