source: libabac/abac_pl_yap.c @ 202a7f9

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

commited modified files for rt1

  • Property mode set to 100644
File size: 7.9 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 abac_list_t *abac_credential_clauses(abac_credential_t *cred);
24static int debug=0;
25
26// pl
27struct _abac_pl_t {
28    FILE *fptr;
29    char *fname;
30    char *yap_certs;
31};
32
33static int _insert_clause(char *str)
34{
35    YAP_Term *eterm;
36    YAP_Term goalArgs=YAP_ReadBuffer(str, eterm);
37    char *tmp=YAP_CompileClause(goalArgs);
38    if (tmp!=NULL) { /* something is wrong */
39        printf("error: result of compile clause (%s)\n", tmp);
40        printf("error: str used (%s)\n", str);
41        return 1;
42    }
43    return 0;
44}
45
46static int _insert_cred_clause(char *cstr)
47{
48    int ret=ABAC_CERT_SUCCESS;
49    int rc=_insert_clause(cstr);
50    if (rc)
51        return ABAC_CERT_BAD_YAP;
52    return ABAC_CERT_SUCCESS;
53}
54
55static void _show_yap_db(char *msg)
56{
57    char lstr[]="listing";
58    YAP_Term *eterm;
59
60    printf("\n\n========= yap db (%s)\n",msg);
61    YAP_Term goal=YAP_ReadBuffer(lstr, eterm);
62    int rc =YAP_RunGoal( goal );
63    if (rc) {
64        printf("listing ok.. \n");
65    } else {
66        printf("listing's rc is bad.. \n");
67        YAP_Exit(1);
68    }
69    printf("========= \n\n");
70}
71
72static void _set_dbg(abac_pl_t *pl)
73{
74    char *fname=strdup( "/tmp/abac_yap-XXXXXX.pl" );
75    int fd = mkstemps( pl->fname, 3 );
76    if ( fd == -1) {
77        printf("Couldn't get a valid temp name %s\n", fname);
78        free((void*)fname);
79        YAP_Exit(1);
80    }
81    FILE *fptr = fdopen(fd, "w");
82    if (fptr == NULL) {
83        printf("Couldn't open %s for writing\n", fname);
84        free((void*)fname);
85        YAP_Exit(1);
86    }
87    pl->fptr=fptr;
88    pl->fname=fname;
89}
90
91/**
92 * Include some utility routines
93 */
94abac_pl_t *abac_pl_utility(void) {
95/*
96append([],L,L).
97append([X|L1],L2,[X|L3]):-append(L1,L2,L3).
98
99appendL([],[]).
100appendL([H|T], L) :-
101   appendL(T,L2), append(H,L2,L).
102*/
103    if(_insert_clause("append([],L,L)"))
104        YAP_Exit(1);
105    if(_insert_clause("append([X|L1],L2,[X|L3]):-append(L1,L2,L3)"))
106        YAP_Exit(1);
107    if(_insert_clause("appendL([],[])"))
108        YAP_Exit(1);
109    if(_insert_clause("appendL([H|T], L) :- appendL(T,L2), append(H,L2,L)"))
110        YAP_Exit(1);
111}
112
113/**
114 * Create a new yap structure.
115 */
116abac_pl_t *abac_pl_new(void) {
117
118    if (YAP_FastInit(NULL) == YAP_BOOT_ERROR)
119        YAP_Exit(1);
120
121    if (YAP_RunGoal(YAP_MkAtomTerm(YAP_LookupAtom("source")))) {
122        if(debug) printf("calling source..\n");
123        } else {
124            if(debug) printf("calling source failed..\n");
125            YAP_Exit(1);
126    }
127
128    abac_pl_utility();
129 
130    abac_pl_t *pl = abac_xmalloc(sizeof(abac_pl_t));
131    pl->fptr=NULL;
132    pl->fname=NULL;
133    pl->yap_certs=NULL;
134    return pl;
135}
136
137/**
138 * Add a credential to the db
139 */
140int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
141{
142    int rc=0;
143    abac_list_t *clauses=abac_credential_clauses(cred);
144    if (clauses != NULL) {
145        char *cur;
146        abac_list_foreach(clauses, cur,
147            if(cur) {
148                if(debug) printf("inserting =>%s\n",cur);
149                rc=_insert_cred_clause(cur);
150            }
151        );
152    }
153    return rc;
154}
155
156int abac_pl_add_type_credential(abac_pl_t *pl, abac_id_cert_t *id_cert)
157{
158    char *clause=abac_id_clause(id_cert);
159    if (clause != NULL) {
160        int rc=_insert_cred_clause(clause);
161        return rc;
162    }
163    return 0;
164}
165
166/* cases,
167     ['str']
168     ['str1','str2']
169     ([] is not possible, and don't care)
170*/
171static void _credentials_from_string(abac_stack_t *credentials,char *slist) {
172    char *cptr=slist; /* current ptr */
173    char *sptr; /* string ptr */
174    char *ptr;
175    int len=0;
176    char *string;
177    abac_credential_t *cred=NULL;
178    int cnt=0;
179
180    if(debug)
181        printf("DEBUG:responds from yap(%s)\n",slist);
182
183    /* find first [' */ 
184    ptr=strstr(cptr,"['");
185    if(ptr == NULL) 
186         return;
187    cptr=ptr+2;
188    sptr=cptr;
189    while (1) {
190        /* find next ',' or '] */
191        ptr=strstr(cptr,"','");
192        if(ptr!=NULL) {
193             cptr=ptr+3;
194             len=(ptr-sptr);
195             string=strndup(sptr,len);
196             cred=abac_credential_lookup(string);
197             free(string); 
198             if(cred) {
199                 abac_stack_push(credentials, cred);
200                 cnt++;
201                 } else {
202                 printf("BAD BAD BAD\n");
203             }
204             sptr=cptr;
205             } else {
206             ptr=strstr(cptr,"']");
207             if(ptr!=NULL) {
208                 len=(ptr-sptr);
209                 string=strndup(sptr,len);
210                 cred=abac_credential_lookup(string);
211                 free(string);
212                 if(cred) {
213                     abac_stack_push(credentials, cred);
214                     cnt++;
215                     } else {
216                     printf("BAD BAD BAD\n");
217                 }
218                 break;
219             }
220        }
221    }
222    if(debug)
223        printf("DEBUG:total %d credentials\n", cnt);
224}
225
226/* 2 types
227      acme.buys_rocket <- coyote (coyote=prin, acme.buys_rocket=role)
228      acme.buys_rocket <- acme.preferred_customer  -- NOT DONE YET */
229static abac_stack_t *_query(abac_pl_t *pl, abac_role_t* role, abac_role_t* role_prin )
230{
231    YAP_Term *eterm;
232    YAP_Term arg[3];
233    char tmp[2000];
234    abac_stack_t *cred_list = abac_stack_new();
235
236    if(debug)
237        _show_yap_db("DEBUG:calling within _query");
238
239    char *cn_prin=abac_cn_with_role(role_prin);
240    char *cn_role=abac_cn_with_role(role);
241
242    if(abac_role_role_name(role_prin)!=NULL) {
243        printf("fail, a.r <- b.r query is not implemented yet !!!\n");
244        YAP_Exit(1);
245    }
246
247    if (cn_prin == NULL || cn_role == NULL) {
248        printf("fail, query's call got bad roles.. \n");
249        YAP_Exit(1);
250    }
251    sprintf(tmp,"role(%s,%s)", cn_role, abac_role_role_name(role));
252    arg[0]=YAP_MkAtomTerm(YAP_LookupAtom(cn_prin));
253    arg[1]=YAP_ReadBuffer(tmp,eterm);
254    arg[2]=YAP_MkVarTerm();
255    YAP_Atom f = YAP_LookupAtom("isMember");
256    YAP_Functor func = YAP_MkFunctor(f, 3);
257    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
258    int rc =YAP_RunGoal( goal );
259    if (rc) {
260        printf("success, query call ok.. \n");
261        YAP_WriteBuffer(arg[2], tmp, 2000,YAP_WRITE_HANDLE_VARS);
262        /* printf("    answer : %s(%d)\n", tmp, strlen(tmp)); */
263        /* this is returned as ['string1','string2'] */
264        _credentials_from_string(cred_list,tmp); 
265        while (YAP_RestartGoal()) {
266            printf("another success\n");
267            YAP_WriteBuffer(arg[2], tmp, 2000,YAP_WRITE_HANDLE_VARS);
268            /* printf("    answer : %s\n", tmp); */
269            _credentials_from_string(cred_list,tmp); 
270        }
271    } else {
272        printf("fail, query's call is bad.. \n");
273        YAP_Exit(1);
274    }
275    return cred_list;
276}
277
278/**
279 * Make a query into prolog db
280--role acme.preferred_customer --principal coyote
281--role acme.prefer_customer.buy_rockets --principlal coyote
282 */
283abac_stack_t *abac_pl_query(abac_pl_t *pl, char *role_name, char *principal)
284{
285    abac_role_t *role = abac_role_from_string(role_name);
286    abac_role_t *prin_role = abac_role_from_string(principal);
287    abac_stack_t *ret=NULL;
288
289    // give up on bogus roles
290    if (role == NULL || prin_role == NULL) {
291        return NULL;
292    }
293
294    ret=_query(pl,role,prin_role);
295
296    return ret;
297}
298
299/**
300 * Get all the credentials (attribute/issuer cert pairs) from prolog
301 * (which returns in string form)
302 */
303abac_stack_t *abac_pl_credentials(abac_pl_t *pl) {
304    abac_stack_t *credentials = abac_stack_new();
305    /* fix up a stream to stream the credentials from prolog engine */
306    return credentials;
307}
308
309void abac_pl_free(abac_pl_t *pl) {
310    if(pl->fptr) {
311        fflush(pl->fptr);
312        free(pl->fptr);
313    }
314    if(pl->fname) {
315        unlink(pl->fname);
316        free(pl->fname);
317    }
318    free(pl);
319}
320
Note: See TracBrowser for help on using the repository browser.