source: libabac/abac_pl_yap.c @ 7b548fa

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

1) add time static constraint
2) add example balltime_rt2_typed
3) change the way that time is being kept

from 20120228T080000 to time(2012,2,28,8,0,0) and
the constraint check is via compare(op,time1,time2)

  • 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_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_range_constraint_clause, failed to insert");
201    asprintf(&tmp,"%s_%d(%s)", constraint_label, i, var);
202    return tmp;
203}
204
205/* cases,
206     ['str']
207     ['str1','str2']
208     ([] is not possible, and don't care)
209*/
210static void _credentials_from_string(abac_stack_t *credentials,char *slist) {
211    char *cptr=slist; /* current ptr */
212    char *sptr; /* string ptr */
213    char *ptr;
214    int len=0;
215    char *string;
216    abac_credential_t *cred=NULL;
217    int cnt=0;
218
219    /* find first [' */ 
220    ptr=strstr(cptr,"['");
221    if(ptr == NULL) 
222         return;
223    cptr=ptr+2;
224    sptr=cptr;
225    while (1) {
226        /* find next ',' or '] */
227        ptr=strstr(cptr,"','");
228        if(ptr!=NULL) {
229             cptr=ptr+3;
230             len=(ptr-sptr);
231             string=strndup(sptr,len);
232             cred=abac_credential_lookup(string);
233             free(string); 
234             if(cred) {
235                 int i=abac_stack_unique_push(credentials, cred);
236                 if(i) cnt++;
237                 } else {
238                 printf("BAD BAD BAD\n");
239             }
240             sptr=cptr;
241             } else {
242             ptr=strstr(cptr,"']");
243             if(ptr!=NULL) {
244                 len=(ptr-sptr);
245                 string=strndup(sptr,len);
246                 cred=abac_credential_lookup(string);
247                 free(string);
248                 if(cred) {
249                     int i=abac_stack_unique_push(credentials, cred);
250                     if(i) cnt++;
251                     } else {
252                     printf("BAD BAD BAD\n");
253                 }
254                 break;
255             }
256        }
257    }
258    if(debug)
259        printf("DEBUG:total %d credentials\n", cnt);
260}
261
262static abac_stack_t *_make_yap_query_simple(char *cn_prin, char *cn_rule, char* estring)
263{
264    YAP_Term *eterm;
265    abac_stack_t *cred_list = abac_stack_new();
266    char *lstr=NULL;
267
268    asprintf(&lstr,"isMember(%s,%s,_)",cn_prin, estring);
269    if(debug)
270        printf("make_yap_query_simple --(%s)\n",lstr);
271
272    YAP_Term goal=YAP_ReadBuffer(lstr, eterm);
273    int rc =YAP_RunGoal( goal );
274    if (rc) {
275        printf("simple call ok.. \n");
276    } else {
277        printf("simple query call not good.. \n");
278        YAP_Exit(1);
279    }
280    printf("========= \n\n");
281    return cred_list;
282}
283
284static abac_stack_t *_make_yap_query(char *cn_prin, char *cn_rule, char* estring)
285{
286    YAP_Term *eterm0;
287    YAP_Term *eterm1;
288    YAP_Term arg[3];
289    char tmp[5000];
290    abac_stack_t *cred_list = abac_stack_new();
291
292    if(debug) printf(" the principal part(%s)\n", cn_prin);
293    if(cn_prin[0]=='\'' || cn_prin[0]=='"') {
294        arg[0]=YAP_ReadBuffer(cn_prin,eterm0);
295        } else {
296            arg[0]=YAP_MkAtomTerm(YAP_LookupAtom(cn_prin)); 
297    }
298    if(debug) printf(" the role/oset part(%s)\n", estring);
299    arg[1]=YAP_ReadBuffer(estring,eterm1);
300
301    /* var for credential list */
302    arg[2]=YAP_MkVarTerm();
303
304    YAP_Atom f = YAP_LookupAtom("isMember");
305    YAP_Functor func = YAP_MkFunctor(f, 3);
306    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
307
308    int rc =YAP_RunGoal( goal );
309    if (rc) {
310        printf("YAP query succeed\n");
311        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
312        /* this is returned as ['string1','string2'] */
313        if(debug) printf("    query answer : %s\n", tmp);
314        _credentials_from_string(cred_list,tmp); 
315/**** XXX somehow this got stuck in yap ??? */
316        while (YAP_RestartGoal()) {
317            if(debug) printf("another success\n");
318            YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
319        if(debug) printf("    restart query answer : %s\n", tmp);
320            _credentials_from_string(cred_list,tmp); 
321        }
322/***/
323    } else {
324        printf("YAP query failed\n");
325        /* YAP_Exit(1); */
326    }
327    return cred_list;
328}
329
330/* 2 types
331      acme.buys_rocket <- coyote (coyote=prin, acme.buys_rocket=role)
332        ==> isMember(coyote,role(acme,buys_rocket), L)
333
334      acme.buys_rocket <- acme.preferred_customer  -- NOT DONE YET */
335static abac_stack_t *_query_with_role(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin)
336{
337    char tmp[5000];
338    abac_stack_t *ret=NULL;
339
340    if(debug)
341        _show_yap_db("DEBUG:calling within _query_with_role");
342
343    char *cn_prin=abac_cn_with_role(role_prin);
344    char *cn_role=abac_cn_with_role(role);
345
346    if(abac_role_role_name(role_prin)!=NULL) {
347        printf("fail, a.r <- b.r query is not implemented yet !!!\n");
348        YAP_Exit(1);
349    }
350
351    if (cn_prin == NULL || cn_role == NULL) {
352        printf("fail, query's call got bad roles.. \n");
353        YAP_Exit(1);
354    }
355
356    if(debug) printf("printing up the yap query ..\n");
357    char *pstring=abac_role_role_param_string(role);
358    if(pstring) {
359        sprintf(tmp,"role(%s,%s,%s)", cn_role, abac_role_role_name(role),pstring);
360        free(pstring);
361        } else {
362            sprintf(tmp,"role(%s,%s)", cn_role, abac_role_role_name(role));
363    }
364    ret=_make_yap_query(cn_prin,cn_role,tmp);
365    return ret;
366}
367
368static abac_stack_t *_query_with_oset(abac_pl_t *pl, abac_oset_t* oset, abac_oset_t* oset_obj)
369{
370    char tmp[5000];
371    abac_stack_t *ret=NULL;
372
373    if(debug)
374        _show_yap_db("DEBUG:calling within _query_with_oset");
375
376    char *cn_oset=abac_cn_with_oset(oset);
377    /* could be obj or principal */
378    char *cn_prin=NULL;
379    if(abac_oset_is_object(oset_obj)) {
380        cn_prin=abac_oset_object_cn(oset_obj);
381        } else {
382            cn_prin=abac_oset_principal_cn(oset_obj);
383    }
384
385    if(abac_oset_oset_name(oset_obj)!=NULL) {
386        printf("fail, a.o <- b.o query is not implemented yet !!!\n");
387        YAP_Exit(1);
388    }
389
390    if (cn_prin == NULL || cn_oset == NULL) {
391        printf("fail, query's call got bad oset.. \n");
392        YAP_Exit(1);
393    }
394
395    if(debug) printf("printing up the yap query ..\n");
396    char *pstring=abac_oset_oset_param_string(oset);
397    if(pstring) {
398        sprintf(tmp,"oset(%s,%s,%s)", cn_oset, abac_oset_oset_name(oset),pstring);
399        free(pstring);
400        } else {
401            sprintf(tmp,"oset(%s,%s)", cn_oset, abac_oset_oset_name(oset));
402    }
403
404    ret=_make_yap_query(cn_prin,cn_oset,tmp);
405    return ret;
406}
407
408int dump_db()
409{
410    char *todump=getenv("DUMP_DICTIONARY");
411    if(todump != NULL)
412       return 1;
413    return 0;
414}
415
416static abac_stack_t *_dump(abac_pl_t *pl)
417{
418    YAP_Term *eterm;
419    YAP_Term arg[3];
420    char tmp[5000];
421    abac_stack_t *cred_list = abac_stack_new();
422
423    if(dump_db())
424        _show_yap_db("DEBUG:calling within _dump");
425
426    char *estring=NULL;
427    YAP_Term *eterm1;
428    YAP_Term *eterm2;
429    asprintf(&estring,"_");
430/*
431    arg[0]=YAP_ReadBuffer(estring,eterm1);
432    arg[1]=YAP_ReadBuffer(estring,eterm2);
433*/
434    arg[0]=YAP_MkVarTerm();
435    arg[1]=YAP_MkVarTerm();
436    arg[2]=YAP_MkVarTerm();
437    YAP_Atom f = YAP_LookupAtom("isMember");
438    YAP_Functor func = YAP_MkFunctor(f, 3);
439    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
440
441    int rc =YAP_RunGoal( goal );
442    if (rc) {
443        printf("YAP dump succeed\n");
444        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
445        if(debug) printf("    dump answer : %s\n", tmp);
446        /* this is returned as ['string1','string2'] */
447        _credentials_from_string(cred_list,tmp); 
448        while (YAP_RestartGoal()) {
449            if(debug) printf("another dump success\n");
450            YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
451            if(debug) printf("    dump restart answer : %s\n", tmp);
452            _credentials_from_string(cred_list,tmp); 
453        }
454    } else {
455        printf("YAP _dump query failed\n");
456        /* YAP_Exit(1); */
457    }
458    return cred_list;
459}
460
461/* findall(X,isMember(_,_,X),L) */
462static abac_stack_t *_dump2(abac_pl_t *pl)
463{
464    YAP_Term *eterm;
465    YAP_Term arg[3];
466    char tmp[5000];
467    abac_stack_t *cred_list = abac_stack_new();
468
469    if(debug)
470        _show_yap_db("DEBUG:calling within _dump");
471
472    char *estring="isMember(_,_,X)";
473    arg[0]=YAP_MkAtomTerm(YAP_LookupAtom("X"));
474    arg[1]=YAP_ReadBuffer(estring,eterm);
475    arg[2]=YAP_MkVarTerm();
476    YAP_Atom f = YAP_LookupAtom("findall");
477    YAP_Functor func = YAP_MkFunctor(f, 3);
478    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
479
480    int rc =YAP_RunGoal( goal );
481    if (rc) {
482        printf("YAP dump succeed\n");
483        YAP_WriteBuffer(arg[2], tmp, 5000,YAP_WRITE_HANDLE_VARS);
484        if(debug) printf("    dump answer : %s\n", tmp);
485        /* this is returned as ['string1','string2'] */
486        _credentials_from_string(cred_list,tmp); 
487        } else {
488            printf("YAP _dump query failed\n");
489            /* YAP_Exit(1); */
490    }
491    return cred_list;
492}
493
494/**
495 * Get all the credentials (attribute/issuer cert pairs) from prolog
496 * (which returns in string form)
497 */
498abac_stack_t *abac_pl_credentials(abac_pl_t *pl)
499{
500    abac_stack_t *ret=_dump(pl);
501    return ret;
502}
503
504/**
505 * Make a query into prolog db
506--role acme.preferred_customer --principal coyote
507--role acme.prefer_customer.buy_rockets --principlal coyote
508--oset acme.rockets -- object mrx-21
509--oset acme.villans -- principal coyote
510 */
511abac_stack_t *abac_pl_query(abac_pl_t *pl, char *roleoset, char *prinobj)
512{
513    abac_stack_t *ret=NULL;
514    int len=strlen(roleoset)+strlen(prinobj)+5;
515    char* attr_string=(char *) abac_xmalloc(sizeof(char)*len);
516    sprintf(attr_string,"%s<-%s", roleoset, prinobj);
517
518    if(debug)
519        printf("abac_pl_query, query string is (%s)\n",attr_string);
520
521    /* call into yacc parser */
522    abac_reset_yyfptr(attr_string);
523    abac_yy_init();
524    int rc=yyparse();
525    if (rc) {
526        free(attr_string);
527        return NULL;
528    }
529
530    if(abac_yy_get_rule_is_oset()) {
531        abac_oset_t *head_oset = abac_yy_get_rule_head_oset();
532        abac_oset_t *tail_oset = abac_yy_get_rule_tail_oset();
533        ret=_query_with_oset(pl,head_oset,tail_oset);
534        } else {
535            abac_role_t *head_role = abac_yy_get_rule_head_role();
536            abac_role_t *tail_role = abac_yy_get_rule_tail_role();
537            ret=_query_with_role(pl,head_role,tail_role);
538    }
539    return ret;
540}
541
542void abac_pl_free(abac_pl_t *pl) {
543    if(pl->fptr) {
544        fflush(pl->fptr);
545        free(pl->fptr);
546    }
547    if(pl->fname) {
548        unlink(pl->fname);
549        free(pl->fname);
550    }
551    free(pl);
552}
553
Note: See TracBrowser for help on using the repository browser.