source: libabac/abac_pl_yap.c @ 9937351

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

1) add environment variables DUMP_DB, ABAC_CN.

ABAC_CN will switch to using CNs for keyid insead of SHAs

2) add/modified couple of doc files.

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