source: libabac/abac_pl_yap.c @ d5bbd3e

mei_rt2mei_rt2_fix_1meiyap-rt1rt2
Last change on this file since d5bbd3e was d5bbd3e, checked in by Mei <mei@…>, 12 years ago

1) add alumni2_rt1_typed

(target static range constraint)

2) add another rule for fruits example
3) add target static range constraint handling for string & urn

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