source: libabac/abac_pl_yap.c @ 13c9479

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

1) convert parser and libabac to use id cred and attr cred like

creddy (move those 2 files to libabac).

2) fix up abac.hh to work with expanded libabac. can now build

structure from python script

3) redid the credential dump using the internal credential table

instead of depending on a search in db.

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