source: libabac/abac_pl_yap.c @ 718ad924

mei_rt2mei_rt2_fix_1meiyap-rt1rt2
Last change on this file since 718ad924 was 53e540d, checked in by Mei <mei@…>, 13 years ago

1) adding appendL to do the credential list appending

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