source: libabac/abac_pl_yap.c @ f2d67a5

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

1) put back that yap info line in the saved example output

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