source: libabac/abac_pl_yap.c @ 646e57e

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

1) add partial proof

  • Property mode set to 100644
File size: 24.8 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_internal.h"
15
16#include "abac_pl_yap.h"
17#include "abac_util.h"
18
19#include "uthash.h"
20
21extern abac_list_t *abac_credential_clauses(abac_credential_t *);
22extern char *abac_id_clause(abac_id_credential_t *);
23extern abac_aspect_t *abac_yy_get_rule_tail_aspect();
24extern abac_aspect_t *abac_yy_get_rule_head_aspect();
25
26static int debug=0;
27
28/* track constraint's external clause's -unique name id */
29
30static int constraint_label_count=0;
31static char *constraint_label="isABAC_constraint";
32
33/*
34x    can pLadybug buy_rockets from pAcme ? (_arg_for_fact)
35x    can pLadybug What from pAcme ? (_arg_for_what)
36x    Who can buy_rockets from pAcme ? (_arg_for_who)
37x    can pLadybug buy_rockets from Whom ? (_arg_for_whom)
38x    can pLadybug What from Whom ? (_arg_for_what_whom)
39the type ordering also dictates the order of partial proof query
40sequence
41*/
42enum _query_type_t {
43   e_PL_FACT=0,
44   e_PL_WHAT=1,
45   e_PL_WHAT_DFLT=2,
46   e_PL_WHO=3,   
47   e_PL_WHOM=4,
48   e_PL_WHAT_WHOM=5,
49   e_PL_NOMORE=6
50};
51
52// pl -- place holder for now
53struct _abac_pl_t {
54   /* a_term <- prin */
55    char *whom;
56    char *who;
57    char *aspect;
58    char *what;
59    char *whatwith;
60    int pcnt; /* pcnt=number of params in whatwith */
61
62    int query_made; /* 1+ yes, 0 no, rc is valid only if a query is made */
63    int query_rc; /* rc of query call */
64    int next_rc; /* rc of next-last query */
65      /* proof count = abac_list_size(proof_list) */
66    int is_partial;
67    int want_partial;
68    int query_type;
69    abac_list_t *proof_list; /* list of list of cred_list */ 
70    long safe_t; /* holding the YAP slot for the goal */
71};
72
73/***********************************************************/
74static int _get_next_constraint_label_idx()
75{
76    constraint_label_count++;
77    return constraint_label_count;
78}
79
80static int _get_constraint_label_idx()
81{
82    return constraint_label_count;
83}
84
85/***********************************************************/
86
87static int _insert_clause(char *str)
88{
89    YAP_Term eterm;
90    YAP_Term goalArgs=YAP_ReadBuffer(str, &eterm);
91    char *tmp=YAP_CompileClause(goalArgs);
92    if (tmp!=NULL) { /* something is wrong */
93        printf("error: result of compile clause (%s)\n", tmp);
94        printf("error: str used (%s)\n", str);
95        return 1;
96    }
97    return 0;
98}
99
100static int _insert_cred_clause(char *cstr)
101{
102    int ret=ABAC_CERT_SUCCESS;
103    int rc=_insert_clause(cstr);
104    if (rc)
105        return ABAC_CERT_BAD_YAP;
106    return ABAC_CERT_SUCCESS;
107}
108
109void show_yap_db(const char *msg)
110{
111    char lstr[]="listing";
112    YAP_Term eterm; /* error term */
113
114    printf("\n\n/* ========= yap db (%s) */\n",msg);
115    YAP_Term goal=YAP_ReadBuffer(lstr, &eterm);
116    int rc =YAP_RunGoal( goal );
117    if (rc) {
118        printf("/* listing ok.. */\n");
119    } else {
120        printf("/* listing's rc is bad.. */ \n");
121        YAP_Exit(1);
122    }
123    printf("/* ========= */\n\n");
124}
125
126/**
127 * Include some utility routines
128 */
129abac_pl_t *abac_pl_utility(void) {
130/*
131append([],L,L).
132append([X|L1],L2,[X|L3]):-append(L1,L2,L3).
133
134appendL([],[]).
135appendL([H|T], L) :-
136   appendL(T,L2), append(H,L2,L).
137*/
138    if(_insert_clause("append([],L,L)"))
139        YAP_Exit(1);
140    if(_insert_clause("append([X|L1],L2,[X|L3]):-append(L1,L2,L3)"))
141        YAP_Exit(1);
142    if(_insert_clause("appendL([],[])"))
143        YAP_Exit(1);
144    if(_insert_clause("appendL([H|T], L) :- appendL(T,L2), append(H,L2,L)"))
145        YAP_Exit(1);
146}
147
148/**
149 * Create a new yap structure.
150 */
151abac_pl_t *abac_pl_new(void) {
152
153    if (YAP_FastInit(NULL) == YAP_BOOT_ERROR)
154        YAP_Exit(1);
155
156    if (YAP_RunGoal(YAP_MkAtomTerm(YAP_LookupAtom("source")))) {
157        if(debug) fprintf(stderr, "calling source..\n");
158        } else {
159            if(debug) fprintf(stderr,"calling source failed..\n");
160            YAP_Exit(1);
161    }
162
163    abac_pl_utility();
164 
165    abac_pl_t *pl = abac_xmalloc(sizeof(abac_pl_t));
166
167    pl->who=NULL;
168    pl->whom = NULL;
169    pl->what = NULL;
170    pl->whatwith = NULL;
171    pl->aspect = NULL;
172    pl->pcnt=0;
173    pl->query_made=0;
174    pl->query_rc=0;
175    pl->is_partial=0;
176    pl->want_partial=1;
177    pl->query_type=e_PL_FACT;
178    pl->next_rc=0;
179    pl->proof_list=NULL;
180    pl->safe_t=0;
181    return pl;
182}
183
184int abac_pl_returning_partial(abac_pl_t *pl)
185{
186    return pl->is_partial;
187}
188
189/* returns the number of solution so far */
190int abac_pl_proof_cnt(abac_pl_t *pl)
191{
192    if(pl->proof_list)
193        return abac_list_size(pl->proof_list);
194    return 0;
195}
196
197int abac_pl_is_partial(abac_pl_t *pl)
198{
199    return pl->is_partial;
200}
201
202/* is this the conclusion of the query ? */
203/* 1 is yes, 0 N/A */
204int abac_pl_done_yet(abac_pl_t *pl)
205{
206    if(pl->query_made) {
207        if(pl->query_rc) {
208            if(!pl->next_rc) return 1;
209            return 0;
210        } else return 1; /* even init query failed */
211    }
212    return 0;
213}
214
215void abac_pl_set_no_partial(abac_pl_t *pl)
216{
217   pl->want_partial=0;
218}
219
220void abac_pl_set_want_partial(abac_pl_t *pl)
221{
222   pl->want_partial=1;
223}
224
225static void _free_p_list(abac_list_t *p)
226{
227    if( p != NULL ) {
228        if(abac_list_size(p) != 0) {
229            abac_credential_t *cur=NULL;
230            abac_list_foreach(p, cur,
231                abac_credential_free(cur);
232            );
233        }
234        abac_list_free(p);
235    }
236}
237
238static void _free_pf_list(abac_list_t *p)
239{
240   
241    if(p != NULL) {
242        if(abac_list_size(p) != 0) {
243            abac_list_t *cur=NULL;
244            abac_list_foreach(p, cur,
245                _free_p_list(cur);
246            );
247        }
248        abac_list_free(p);
249    }
250}
251
252void abac_pl_free(abac_pl_t *pl) {
253    if(pl->who) free(pl->who);
254    if(pl->whom) free(pl->whom);
255    if(pl->what) free(pl->what);
256    if(pl->whatwith) free(pl->whatwith);
257    if(pl->aspect) free(pl->aspect);
258    _free_pf_list(pl->proof_list);
259    free(pl);
260}
261
262/* this is done whenever a new query starts in */
263static void _reset_pl(abac_pl_t *pl, char *who,
264char *what, char *whom, char *aspect, char *whatwith, int pcnt)
265{
266    if(pl->safe_t) {
267        YAP_RecoverSlots(1);
268        YAP_Reset();
269    }
270    /* free the old ones */
271    if(pl->who) free(pl->who);
272    if(pl->whom) free(pl->whom);
273    if(pl->what) free(pl->what);
274    if(pl->whatwith) free(pl->whatwith);
275    if(pl->aspect) free(pl->aspect);
276
277    pl->who = (who !=NULL)?abac_xstrdup(who):NULL;
278    pl->whom = (whom !=NULL)?abac_xstrdup(whom):NULL;
279    pl->what = (what!=NULL)?abac_xstrdup(what):NULL;
280    pl->whatwith = (whatwith!=NULL)?abac_xstrdup(whatwith):NULL;
281    pl->aspect = (aspect!=NULL)?abac_xstrdup(aspect):NULL;
282
283    pl->pcnt=pcnt;
284
285    pl->query_made=0;
286    pl->query_rc=0;
287    pl->next_rc=0;
288    pl->is_partial=0;
289    pl->query_type=e_PL_FACT;
290    _free_pf_list(pl->proof_list);
291    pl->proof_list=abac_list_new();
292    pl->safe_t=0;
293}
294
295/**
296 * Add a credential to the db, not duplicating a copy and so
297 * don't try to free it after this call.
298 */
299int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
300{
301    int rc=0;
302    abac_list_t *clauses=abac_credential_clauses(cred);
303    if (clauses != NULL) {
304        char *cur;
305        abac_list_foreach(clauses, cur,
306            if(cur) {
307                if(debug) fprintf(stderr,"inserting =>%s\n",cur);
308                rc=_insert_cred_clause(cur);
309            }
310        );
311    }
312    return rc;
313}
314
315int abac_pl_add_type_credential(abac_pl_t *pl, abac_id_credential_t *id_cert)
316{
317    char *clause=abac_id_clause(id_cert);
318    if (clause != NULL) {
319        int rc=_insert_cred_clause(clause);
320        return rc;
321    }
322    return 0;
323}
324
325/*  string1(S):- S="abc";S="efg";S="ijk" */
326char *abac_pl_add_range_constraint_clause(char *var, char *tmplist)
327{
328    int i=_get_next_constraint_label_idx();
329    char *tmp=NULL;
330    asprintf(&tmp,"%s_%d(%s) :- %s", constraint_label, i, var, tmplist); 
331    int rc=_insert_cred_clause(tmp);
332    free(tmp);
333    if(rc) 
334        panic("abac_pl_add_range_constraint_clause, failed to insert");
335    asprintf(&tmp,"%s_%d(%s)", constraint_label, i, var);
336    return tmp;
337}
338
339/* cases,
340     ['str']
341     ['str1','str2']
342     ([] is not possible, and don't care)
343*/
344static void _credentials_from_string(abac_list_t *credentials,char *slist) {
345    char *cptr=slist; /* current ptr */
346    char *sptr; /* string ptr */
347    char *ptr;
348    int len=0;
349    char *string;
350    abac_credential_t *cred=NULL;
351    int cnt=0;
352
353    /* find first [' */ 
354    ptr=strstr(cptr,"['");
355    if(ptr == NULL) 
356         return;
357    cptr=ptr+2;
358    sptr=cptr;
359    while (1) {
360        /* find next ',' or '] */
361        ptr=strstr(cptr,"','");
362        if(ptr!=NULL) {
363             cptr=ptr+3;
364             len=(ptr-sptr);
365             string=strndup(sptr,len);
366             cred=abac_credential_lookup(string);
367             free(string); 
368             if(cred) {
369                 int i=abac_list_unique_add(credentials, cred);
370                 if(i) cnt++;
371                 } else {
372                 printf("BAD BAD\n");
373             }
374             sptr=cptr;
375             } else {
376             ptr=strstr(cptr,"']");
377             if(ptr!=NULL) {
378                 len=(ptr-sptr);
379                 string=strndup(sptr,len);
380                 cred=abac_credential_lookup(string);
381                 free(string);
382                 if(cred) {
383                     int i=abac_list_unique_add(credentials, cred);
384                     if(i) cnt++;
385                     } else {
386                     printf("BAD BAD BAD\n");
387                 }
388                 break;
389             }
390        }
391    }
392    if(debug)
393        fprintf(stderr,"DEBUG:total %d credentials\n", cnt);
394}
395
396/* MAX 1024x1024, double as it goes */
397static int try_again(int sz, char **tptr)
398{
399   int blk=1024*2; /* 2048 */
400   int max=1024*1024;
401   int size;
402   char *tmp = NULL;
403
404   if(sz==0) {
405       size = (sizeof(char) * (blk+1));
406       } else {
407           if (sz>=max) {
408               size=0;
409               *tptr=tmp;
410               return 0;
411           }
412           size=sz*2+1;
413           if(size > max) size=max;
414   }
415
416   tmp = (char *) YAP_AllocSpaceFromYap(size);
417   if(tmp==NULL) {
418       fprintf(stderr,"ERROR: malloc failed !!!\n");
419       YAP_Exit(1);
420   }
421   *tptr=tmp;
422   return size;
423}
424
425abac_list_t *run_goal(abac_pl_t *pl, YAP_Term *arg)
426{
427    abac_list_t *cred_list=abac_list_new();
428    YAP_Atom f = YAP_LookupAtom("isMember");
429    YAP_Functor func = YAP_MkFunctor(f, 3);
430    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
431
432    pl->safe_t = YAP_InitSlot(goal);
433    pl->query_rc =YAP_RunGoal(goal);
434    pl->query_made=1;
435    pl->next_rc=pl->query_rc;
436    if (pl->query_rc) {
437        if(pl->is_partial) 
438            printf("A partial proof(type:%d)\n",pl->query_type);
439            else printf("YAP query succeed\n");
440        char *tmp=NULL;
441        int tmp_sz=try_again(0, &tmp);
442        YAP_Term argterm=YAP_ArgOfTerm(3,YAP_GetFromSlot(pl->safe_t));
443        while(1) {
444/* not in 6.2.2
445            int rc=YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS);
446*/
447            YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS);
448/*
449if(debug) fprintf(stderr,"call YAP_WriteBuffer: rc(%d) tmp_sz(%d)\n", rc, tmp_sz);
450*/
451            if(strlen(tmp) > 5 && tmp[0]=='\[') {
452if(debug) fprintf(stderr,"what came back .. (%s)\n", tmp);
453                break;
454            }
455            tmp_sz=try_again(tmp_sz,&tmp);
456if(debug) fprintf(stderr,"try_again: tmp_sz(%d)\n", tmp_sz);
457            if(tmp_sz==0) {
458                fprintf(stderr," PANIC, run out of heap space..\n");
459                YAP_Exit(1);
460            }
461        }
462        /* this is returned as ['string1','string2'] */
463        if(debug) fprintf(stderr,"    query answer : %s(%d)\n", tmp, strlen(tmp));
464        _credentials_from_string(cred_list,tmp); 
465        if(abac_list_size(cred_list)==0) {
466            fprintf(stderr,"CAN NOT retrieve result properly from YAP!!!\n");
467            YAP_Exit(1);
468        }
469        abac_list_add(pl->proof_list, cred_list);
470        YAP_FreeSpaceFromYap(tmp);
471    } else {
472        /* don't print anything if it is running a parital proof goal */
473        if(!pl->is_partial) 
474            printf("YAP query failed\n");
475 
476    }
477    return cred_list;
478}
479
480/*************************************************************************/
481YAP_Term _make_term(char *term) {
482    YAP_Term eterm;
483    YAP_Term ret;
484    if(term[0]=='\'' || term[0]=='"') {
485        ret =YAP_ReadBuffer(term,&eterm);
486        } else {
487            ret = YAP_MkAtomTerm(YAP_LookupAtom(term));
488    }
489}
490
491// isMember(who,aspect(whom,what,whatwith))
492/* aspect(whom, what, whatwith) */
493YAP_Term _aspect_base(char *whom,char *aspect, char *what, char *whatwith)
494{
495    YAP_Term eterm;
496    YAP_Term ret;
497
498    char *estring=NULL;
499    if(whatwith)
500       asprintf(&estring, "%s(%s,%s,%s)",aspect,whom,what,whatwith);
501       else asprintf(&estring, "%s(%s,%s)",aspect,whom,what);
502    if(debug) fprintf(stderr,"_aspect_base, doing %s\n",estring);
503    ret=YAP_ReadBuffer(estring,&eterm);
504    free(estring);
505    return ret;
506}
507
508/* generate a string of whatwith that are of ?variable */
509char *_make_whatwith_var(char *whatwith, int pcnt)
510{
511/* this is a dumb count since it is in porting directory */
512   if(whatwith==NULL || pcnt==0) return NULL; 
513   char *tmp=NULL;
514   char *ptr=NULL;
515   int i;
516   for(i=0;i<pcnt;i++) {
517       ptr=tmp;
518       tmp=NULL;
519       if(i == 0)
520           asprintf(&tmp,"Whatwith%d",i);
521           else asprintf(&tmp,"%s,Whatwith%d",ptr,i);
522   }
523   return tmp;
524}
525
526/* aspect(X, Y, Whatwith) */
527YAP_Term _aspect_what_whom(char *whom,char *aspect, char *what, char *whatwith)
528{
529    YAP_Term ret=_aspect_base("Whom",aspect,"What",whatwith);
530    return ret;
531}
532
533/* aspect(whom,Y,Whatwith) */
534/* call with char *tmp=_make_whatwith_var(whatwith); */
535YAP_Term _aspect_what(char *whom,char *aspect, char *what, char *whatwith)
536{
537    YAP_Term ret=_aspect_base(whom,aspect,"What",whatwith);
538    return ret;
539}
540
541/* aspect(X,what,whatwith) */
542YAP_Term _aspect_whom(char *whom,char *aspect, char *what, char *whatwith)
543{
544    YAP_Term ret=_aspect_base("Whom",aspect,what,whatwith);
545    return ret;
546}
547
548/* aspect(whom,what,whatwith) */
549YAP_Term _aspect_fact(char *whom,char *aspect, char *what, char* whatwith)
550{
551    YAP_Term ret=_aspect_base(whom,aspect,what,whatwith);
552    return ret;
553}
554
555// Whom.What <- ladybug
556// isMember(ladybug, role(W1, W2), R)
557static void _arg_for_what_whom(YAP_Term *arg,char *who, char *whom,
558char *aspect, char*what, char *whatwith, int pcnt)
559{
560    arg[0] = _make_term(who);
561    char *tmp=_make_whatwith_var(whatwith,pcnt); 
562    arg[1] = _aspect_what_whom(who,aspect,what,tmp);
563    if(tmp) free(tmp);
564    arg[2] = YAP_MkVarTerm();
565}
566
567// pAcme.What <- ladybug
568// isMember(ladybug, role(pAcme, W), R)
569static void _arg_for_what(YAP_Term *arg,char *who, char* whom, 
570char *aspect, char*what, char*whatwith, int pcnt)
571{
572    arg[0] = _make_term(who);
573    char *tmp=_make_whatwith_var(whatwith,pcnt); 
574    arg[1] = _aspect_what(whom,aspect,what,tmp);
575    if(tmp) free(tmp);
576    arg[2] = YAP_MkVarTerm();
577}
578
579// W.rocket <- ladybug
580// isMember(ladybug, role(W, buy_rockets), R)
581static void _arg_for_whom(YAP_Term *arg, char *who, char*whom,
582char *aspect, char *what, char*whatwith)
583{
584    arg[0] = _make_term(who);
585    arg[1] = _aspect_whom(whom,aspect,what,whatwith);
586    arg[2] = YAP_MkVarTerm();
587}
588
589// Acme.rocket <- V
590// isMember(V, role(pAcme, buy_rockets), R)
591static int _arg_for_who(YAP_Term *arg, char *who,char *whom, 
592char *aspect, char* what, char*whatwith)
593{
594    arg[0] = YAP_MkVarTerm();
595    arg[1] = _aspect_fact(whom, aspect, what, whatwith);
596    arg[2] = YAP_MkVarTerm();
597}
598
599// Acme.rocket <- x
600// isMember(x, role(pAcme, buy_rockets), R)
601static void _arg_for_fact(YAP_Term *arg,char *who,char *whom, 
602char* aspect, char *what, char*whatwith)
603{
604    arg[0] = _make_term(who);
605    arg[1] = _aspect_fact(whom, aspect, what, whatwith);
606    arg[2] = YAP_MkVarTerm();
607}
608
609
610static abac_list_t *_make_partial_query(abac_pl_t *pl)
611{
612    abac_list_t *ret=abac_list_new();
613    pl->is_partial=1;
614    char *who=pl->who;
615    char *whom=pl->whom;
616    char *aspect=pl->aspect;
617    char *what=pl->what;
618    char *whatwith=pl->whatwith;
619    int pcnt=pl->pcnt;
620    if(debug) fprintf(stderr,"making make_partial_query..\n");
621
622    switch (pl->query_type) { 
623        case e_PL_FACT: /* try what */
624            {
625            YAP_Term arg[3];
626            if(debug) fprintf(stderr,"... 1st partial attempt\n");
627            pl->query_type = e_PL_WHAT;
628            _arg_for_what(arg,who,whom, aspect, what, whatwith, pcnt);
629            ret=run_goal(pl,arg);
630            if(pcnt==0) pl->query_type= e_PL_WHAT_DFLT;
631            if(pl->query_rc) return ret;
632            break;
633            }
634        case e_PL_WHAT: /* try what with no params if need to */
635            {
636            YAP_Term arg[3];
637            if(debug) fprintf(stderr,"... 2nd partial attempt\n");
638            pl->query_type = e_PL_WHAT_DFLT;
639            _arg_for_what(arg,who,whom, aspect, what, whatwith, 0);
640            ret=run_goal(pl,arg);
641            if(pl->query_rc) return ret;
642            break;
643            }
644        case e_PL_WHAT_DFLT: /* try who */
645            {
646            YAP_Term arg[3];
647            if(debug) fprintf(stderr,"... 2nd half partial attempt\n");
648            pl->query_type = e_PL_WHO;
649            _arg_for_who(arg,who,whom, aspect, what, whatwith);
650            ret=run_goal(pl,arg);
651            if(pl->query_rc) return ret;
652            break;
653            }
654        case e_PL_WHO: /* try whom */
655            {
656            YAP_Term arg[3];
657            if(debug) fprintf(stderr,"... 3rd partial attempt\n");
658            pl->query_type = e_PL_WHOM;
659            _arg_for_whom(arg,who,whom, aspect, what, whatwith);
660            ret=run_goal(pl,arg);
661            if(pl->query_rc) return ret;
662            break;
663            }
664        case e_PL_WHOM: /* try what-whom */
665            {
666            YAP_Term arg[3];
667            if(debug) fprintf(stderr,"... 4th partial attempt\n");
668            pl->query_type = e_PL_WHAT_WHOM;
669            _arg_for_what_whom(arg,who,whom, aspect, what, whatwith,pcnt);
670            ret=run_goal(pl,arg);
671            if(pl->query_rc) return ret;
672            break;
673            }
674        default :
675            {
676            if(debug) fprintf(stderr,"... no more partial query to try\n");
677            pl->query_type = e_PL_NOMORE;
678            }
679    }
680    return ret;
681}
682
683/* make a query and extract just first set of result,
684   simple = rt0
685   aspect => role/oset
686   aspect_string => rest of params
687   prin => principal
688   issuer => issuer
689   estring =>  aspect(issuer, aspect_type_string)
690*/
691static abac_list_t *_make_yap_query(abac_pl_t *pl, char *who,
692char *whom, char *aspect, char *what, char *whatwith, int pcnt)
693{
694    if(debug) { 
695       fprintf(stderr,"_make_yap_query: the who part(%s)\n", who);
696       fprintf(stderr,"_make_yap_query: whom part(%s)\n", whom);
697       fprintf(stderr,"_make_yap_query: the role/oset (%s)\n", aspect);
698       fprintf(stderr,"_make_yap_query: aspect what (%s)\n", what);
699       fprintf(stderr,"_make_yap_query: pcnt (%d)\n", pcnt);
700       if(whatwith)
701           fprintf(stderr,"_make_yap_query: aspect what part(%s)\n", whatwith);
702    } 
703    if(debug) fprintf(stderr,"making a yap query..\n");
704
705/* run query on fact goal */
706    YAP_Term arg[3];
707    _arg_for_fact(arg, who,whom, aspect, what, whatwith);
708    abac_list_t *ret=run_goal(pl,arg);
709
710/* fact query failed and so run partial query */
711    if(!pl->query_rc && pl->want_partial) {
712        while(pl->query_type != e_PL_NOMORE) {
713            abac_list_free(ret);
714            ret=_make_partial_query(pl);
715            if( pl->query_rc ) break;
716        }
717    }
718    return ret;
719}
720
721/* make a query for next possible solution proof */
722static abac_list_t *_query_again(abac_pl_t *pl)
723{
724    abac_list_t *cred_list=abac_list_new();
725
726    if(debug) fprintf(stderr,"making query_again call..\n");
727    pl->next_rc=YAP_RestartGoal();
728    pl->query_made++;
729
730    char *tmp=NULL;
731    int tmp_sz=try_again(0, &tmp);
732    YAP_Term argterm=YAP_ArgOfTerm(3,YAP_GetFromSlot(pl->safe_t));
733    if(pl->next_rc) {
734        if(debug) fprintf(stderr,"query_again: another success\n");
735        if(pl->is_partial)
736            printf("A partial proof(type:%d)\n",pl->query_type);
737        while(1) {
738            YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS);
739            if(strlen(tmp) > 5 && tmp[0]=='\[')
740                break;
741            tmp_sz=try_again(tmp_sz,&tmp);
742            if(tmp_sz==0) {
743                fprintf(stderr," PANIC, run out of heap space..\n");
744                YAP_Exit(1);
745            }
746        }
747        /* this is returned as ['string1','string2'] */
748        if(debug) fprintf(stderr,"    query answer : %s(%d)\n", tmp, strlen(tmp));
749        _credentials_from_string(cred_list,tmp); 
750        if(abac_list_size(cred_list)==0) {
751            fprintf(stderr,"CAN NOT retrieve result properly from YAP!!!\n");
752            YAP_Exit(1);
753        }
754        abac_list_add(pl->proof_list, cred_list);
755        YAP_FreeSpaceFromYap(tmp);
756        } else {
757            if(debug) fprintf(stderr,"query_again: fail finding next\n");
758            if(pl->is_partial) { /* if there is more partial query to make */
759                while(pl->query_type != e_PL_NOMORE) {
760                    abac_list_free(cred_list);
761                    cred_list=_make_partial_query(pl);
762                    if( pl->query_rc ) break;
763                }
764            }
765    }
766    return cred_list;
767}
768
769abac_stack_t *_make_cred_stack(abac_list_t *p)
770{
771    abac_stack_t *ret=abac_stack_new();
772    if(abac_list_size(p) != 0) {
773        abac_credential_t *cur=NULL;
774        abac_list_foreach(p, cur,
775            abac_stack_push(ret, (void *)abac_credential_dup(cur));
776        );
777    }
778    return ret;
779}
780
781/* force a  backtrack to get next solution proof */
782abac_stack_t *abac_pl_query_again(abac_pl_t *pl)
783{
784    abac_list_t *rlist=_query_again(pl);
785    abac_stack_t *ret=_make_cred_stack(rlist);
786    return ret;
787}
788
789/* 2 types
790      acme.buys_rocket <- coyote (coyote=prin, acme.buys_rocket=role)
791        ==> isMember(coyote,role(acme,buys_rocket), L)
792      acme.buys_rocket <- acme.preferred_customer  -- NOT valid
793*/
794static abac_stack_t *_query_with_aspect(abac_pl_t *pl, abac_aspect_t* head, abac_aspect_t* tail)
795{
796    abac_stack_t *ret=NULL;
797    char *tmp=NULL;
798
799    if(0)
800        show_yap_db("DEBUG:calling within _query_with_aspect");
801
802    char *whom=NULL;
803    PROLOG(whom=abac_aspect_principal_name(head););
804
805    /* could be obj or principal */
806    char *who=NULL;
807    if(abac_aspect_is_object(tail)) {
808        who=abac_aspect_object_name(tail);
809        } else {
810            PROLOG(who=abac_aspect_principal_name(tail););
811    }
812
813    if(abac_aspect_aspect_name(tail)!=NULL) {
814        printf("fail, a.o <- b.o and a.r <- a.r query is not implemented yet !!!\n");
815        YAP_Exit(1);
816    }
817
818    if (who == NULL || whom == NULL) {
819        printf("fail, query's call got bad aspect names .. \n");
820        YAP_Exit(1);
821    }
822
823    if(debug) fprintf(stderr,"printing up the yap query ..\n");
824
825    char *pstring;
826    PROLOG(pstring=abac_aspect_aspect_param_string(head););
827
828    char *aspect=abac_aspect_type_string(head);
829    int pcnt=abac_aspect_aspect_param_cnt(head);
830    char *what=abac_aspect_aspect_name(head);
831
832    _reset_pl(pl, who, what, whom, aspect, pstring, pcnt);
833
834    abac_list_t *rlist=NULL;
835    if(pcnt)
836        rlist=_make_yap_query(pl,who,whom,aspect,abac_aspect_aspect_name(head),pstring,pcnt);
837        else
838            rlist=_make_yap_query(pl,who,whom,aspect,abac_aspect_aspect_name(head),NULL,0);
839
840    /* generate the resulting stack from a list */
841    ret=_make_cred_stack(rlist);
842    if(tmp) free(tmp);
843    if(pstring) free(pstring);
844    return ret;
845}
846
847/**
848 * Get all the credentials (attribute/issuer cert pairs) from prolog
849 * (which returns in string form)
850 */
851abac_stack_t *abac_pl_credentials(abac_pl_t *pl)
852{
853    abac_stack_t *ret=abac_verifier_dump_creds();
854    return ret;
855}
856
857abac_stack_t *abac_pl_principals(abac_pl_t *pl)
858{
859    abac_stack_t *ret=abac_verifier_dump_principals();
860    return ret;
861}
862
863/**
864 * Make a query into prolog db
865--role acme.preferred_customer --principal coyote
866--role acme.prefer_customer.buy_rockets --principlal coyote
867--oset acme.rockets -- object mrx-21
868--oset acme.villans -- principal coyote
869 */
870abac_stack_t *abac_pl_query(abac_pl_t *pl, char *roleoset, char *prinobj)
871{
872    abac_stack_t *ret=NULL;
873    int len=strlen(roleoset)+strlen(prinobj)+5;
874    char* attr_string=(char *) abac_xmalloc(sizeof(char)*len);
875    sprintf(attr_string,"%s<-%s", roleoset, prinobj);
876
877    if(debug)
878        fprintf(stderr,"abac_pl_query, query string is (%s)\n",attr_string);
879
880    /* call into yacc parser */
881    abac_reset_yyfptr(attr_string);
882    abac_yy_init();
883    int rc=yyparse();
884    if (rc) {
885        free(attr_string);
886        return NULL;
887    }
888
889    abac_aspect_t *head_aspect = abac_yy_get_rule_head_aspect();
890    abac_aspect_t *tail_aspect = abac_yy_get_rule_tail_aspect();
891
892    ret=_query_with_aspect(pl,head_aspect,tail_aspect);
893
894    return ret;
895}
896
897abac_stack_t *abac_pl_query_with_structure(abac_pl_t *pl, abac_aspect_t *head_aspect, abac_aspect_t *tail_aspect)
898{
899    abac_stack_t *ret=NULL;
900    ret=_query_with_aspect(pl,head_aspect,tail_aspect);
901
902    return ret;
903}
Note: See TracBrowser for help on using the repository browser.