source: libabac/abac_pl_yap.c @ ca72963

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

1) wrap up refactoring to move all the code gen to abac structure
2) all original testsuite passed
3) add couple more ui calls in abac.hh ie. manage constraint's

creation, hook to dump yap db.

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