source: libabac/abac.c @ d9c3886

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

1) add 2 more query calls in abac.hh that take Role and Oset instead of

strings. Add supporting code in libabac that will take abac_aspect_t
and make query term directly instead of doing stringify the structure
and do string->yyparse->abac_aspect_t again.

2) start on inline doc into abac.hh
3) tweaked some scripts in examples directory

  • Property mode set to 100644
File size: 11.4 KB
Line 
1
2/* abac.c using prolog */
3
4#include <assert.h>
5#include <err.h>
6#include <glob.h>
7
8#include <chunk.h>
9
10#include "abac_internal.h"
11
12#include "abac_pl_yap.h"
13#include "abac_util.h"
14#include "abac_verifier.h"
15
16static int debug=0;
17
18struct _abac_context_t {
19    abac_pl_t *pl;
20};
21
22/**
23 * Init the library.
24 */
25void libabac_init(void) {
26    void libabac_deinit(void);
27    static int has_been_init = 0;
28
29    // called every time a context is created, so only do it once
30    if (!has_been_init) {
31        abac_verifier_init();
32        atexit(libabac_deinit);
33        has_been_init = 1;
34    }
35}
36
37/**
38 * Deinit the library.
39 */
40void libabac_deinit(void) {
41    abac_verifier_deinit();
42}
43
44/**
45 * Create a new abac context.
46 */
47abac_context_t *abac_context_new(void) {
48    libabac_init();
49
50    abac_context_t *ctx = abac_xmalloc(sizeof(abac_context_t));
51    ctx->pl = abac_pl_new();
52    return ctx;
53}
54
55/**
56 * Deep copy an abac context. -- XXX dummy stub
57 */
58abac_context_t *abac_context_dup(abac_context_t *ctx) {
59    assert(ctx != NULL);
60    abac_context_t *dup = abac_xmalloc(sizeof(abac_context_t));
61    return dup;
62}
63
64
65/**
66 * Free an abac context.
67 */
68void abac_context_free(abac_context_t *ctx) {
69    assert(ctx != NULL);
70
71    abac_pl_free(ctx->pl);
72    free(ctx);
73}
74
75/**
76 * Load an ID cert from an abac_id_t.
77 */
78int abac_context_load_id_id(abac_context_t *ctx, abac_id_t *id) {
79    assert(ctx != NULL); assert(id);
80    abac_id_credential_t *id_cert=NULL;
81    int ret = abac_verifier_load_id_id(id,&id_cert);
82    if(id_cert) {
83        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
84    }
85    return ret;
86}
87
88/**
89 * Load an ID cert from a file.
90 */
91int abac_context_load_id_id_file_key_file(abac_context_t *ctx, char *filename, char *keyfilename) {
92    assert(ctx != NULL); assert(filename != NULL); assert(keyfilename!=NULL);
93    abac_id_credential_t *id_cert=NULL;
94    int ret = abac_verifier_load_id_file_key_file(filename,keyfilename,&id_cert);
95    if(id_cert) {
96        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
97    }
98    return ret;
99}
100/**
101 * Load an ID cert from a file, it may contain key part but not necessary.
102 */
103int abac_context_load_id_idkey_file(abac_context_t *ctx, char *filename) {
104    assert(ctx != NULL); assert(filename != NULL); 
105    abac_id_credential_t *id_cert=NULL;
106    int ret = abac_verifier_load_idkey_file(filename,&id_cert);
107    if(id_cert) {
108        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
109    }
110    return ret;
111}
112
113/**
114 * Load an ID cert from a chunk.
115 */
116int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert) {
117    assert(ctx != NULL);
118    abac_id_credential_t *id_cert=NULL;
119    chunk_t cert_chunk = { cert.ptr, cert.len };
120    int ret=abac_verifier_load_id_chunk(cert_chunk,&id_cert);
121    if(id_cert) {
122        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
123    }
124    return ret;
125}
126
127/**
128 * Load an attribute cert from an abac_attribute_t.
129 */
130int abac_context_load_attribute_attribute(abac_context_t *ctx, abac_attribute_t *ptr)
131{
132/* XXX */
133    int ret=0;
134    return ret;
135}
136
137/**
138 * Load an attribute cert from a file.
139 */
140int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
141    int ret, add_ret;
142    abac_credential_t *cred=NULL;
143
144    assert(ctx != NULL); assert(filename != NULL);
145
146    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
147    if (ret == ABAC_CERT_SUCCESS) {
148        add_ret = abac_pl_add_credential(ctx->pl, cred);
149        assert(add_ret != ABAC_PL_CRED_INVALID);
150    }
151
152    return ret;
153}
154
155/**
156 * Load an attribute cert from a chunk.
157 */
158int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
159    int ret, add_ret;
160    abac_credential_t *cred=NULL;
161
162    assert(ctx != NULL);
163
164    chunk_t cert_chunk = { cert.ptr, cert.len };
165
166    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
167    if (ret == ABAC_CERT_SUCCESS) {
168        add_ret = abac_pl_add_credential(ctx->pl, cred);
169        assert(add_ret != ABAC_PL_CRED_INVALID);
170        abac_credential_free(cred);
171    }
172
173    return ret;
174}
175
176#define KEY_PAT "/*_private.{der,pem}"
177#define ID_PAT "/*_ID.{der,pem}"
178#define ATTR_PAT "/*_attr.der"
179#define IDKEY_PAT "/*_IDKEY.{der,pem}"
180
181char *_make_key_filename(char *cert_file)
182{
183    char *p=strstr(cert_file,"_ID.");
184    char *head=strndup(cert_file,p-cert_file);
185    char *tail=p+4;
186    char *keyfile=NULL;
187    asprintf(&keyfile,"%s_private.%s",head,tail);
188    free(head);
189    return keyfile;
190}
191/**
192 * Load a directory full of certs.
193 */
194void abac_context_load_directory(abac_context_t *ctx, char *path) {
195    char *glob_pat, *key_pat;
196    glob_t glob_buf;
197    int i, ret;
198
199    assert(ctx != NULL); assert(path != NULL);
200
201    int dirlen = strlen(path);
202
203    /* make sure pick the larger one */
204    glob_pat = abac_xmalloc(dirlen + sizeof(IDKEY_PAT));
205    memcpy(glob_pat, path, dirlen);
206
207    // first load ID certs
208    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
209    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
210    for (i = 0; i < glob_buf.gl_pathc; ++i) {
211        /* blah_ID.pem */
212        char *cert_file = glob_buf.gl_pathv[i];
213        /* blah_private.pem */
214        char *key_file=_make_key_filename(cert_file);
215        if(debug) {
216            printf("--> ID cert... %s\n", cert_file);
217            printf("--> KEY cert... %s\n", key_file);
218        }
219        ret = abac_context_load_id_id_file_key_file(ctx, cert_file, key_file);
220        if (ret != ABAC_CERT_SUCCESS)
221            warnx("Couldn't load ID cert %s", cert_file);
222    }
223    globfree(&glob_buf);
224
225    // first load IDKEY certs
226    memcpy(glob_pat + dirlen, IDKEY_PAT, sizeof(IDKEY_PAT));
227    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
228    for (i = 0; i < glob_buf.gl_pathc; ++i) {
229        /* blah_IDKEY.pem */
230        char *certkey_file = glob_buf.gl_pathv[i];
231        if(debug) {
232            printf("--> IDKEY certkey... %s\n", certkey_file);
233        }
234        ret = abac_context_load_id_idkey_file(ctx, certkey_file);
235        if (ret != ABAC_CERT_SUCCESS)
236            warnx("Couldn't load ID/KEY IDKEY cert %s", certkey_file);
237    }
238    globfree(&glob_buf);
239
240    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
241    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
242    for (i = 0; i < glob_buf.gl_pathc; ++i) {
243        char *cert_file = glob_buf.gl_pathv[i];
244
245        if(debug) printf("--> attr file... %s\n", cert_file);
246        ret = abac_context_load_attribute_file(ctx, cert_file);
247        if (ret != ABAC_CERT_SUCCESS)
248            warnx("Couldn't load attribute cert %s", cert_file);
249        if(debug) printf("Loaded.. %s\n", cert_file);
250    }
251    globfree(&glob_buf);
252
253    free(glob_pat);
254}
255
256/**
257 * Run a query on the data in an abac context. Returns a NULL-terminated array
258 * of abac_credential_t. Success/failure in *success.
259 * queryfor(either role or oset), with(either keyid or object type)
260 */
261abac_credential_t **abac_context_query(abac_context_t *ctx, char *queryfor, char *with, int *success) {
262    if(debug) {
263         printf("abac_context_query about(%s) with(%s)\n", queryfor, with);
264    }
265    abac_credential_t **credentials = NULL, *cur;
266    assert(ctx != NULL); assert(queryfor != NULL);
267    assert(with != NULL); assert(success != NULL);
268
269    abac_stack_t *result = abac_pl_query(ctx->pl, queryfor, with);
270
271    int size = abac_stack_size(result);
272    if (size > 0) {
273        *success = 1;
274    } else {
275    // XXX NOT SURE YET..
276    // return partial proof
277        *success = 0;
278    }
279
280    // make the array (leave space to NULL terminate it)
281    //      n.b., even if the list is empty, we still return an array that
282    //            only contains the NULL terminator
283    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
284    int i = 0;
285    if(size) {
286        while(i<size) { 
287            cur=(abac_credential_t *) abac_stack_pop(result);
288            credentials[i++] = cur;
289        } 
290    }
291    credentials[i] = NULL;
292
293    if(result)
294        abac_stack_free(result);
295
296    return credentials;
297}
298
299abac_credential_t **abac_context_query_with_structure(abac_context_t *ctx,
300abac_aspect_t *queryfor, abac_aspect_t *with, int *success)
301{
302    if(debug) {
303         printf("abac_context_query_with_structure\n");
304    }
305    abac_credential_t **credentials = NULL, *cur;
306    assert(ctx != NULL); assert(queryfor != NULL);
307    assert(with != NULL); assert(success != NULL);
308
309    abac_stack_t *result = abac_pl_query_with_structure(ctx->pl, queryfor, with);
310
311    int size = abac_stack_size(result);
312    if (size > 0) {
313        *success = 1;
314    } else {
315    // XXX NOT SURE YET..
316    // return partial proof
317        *success = 0;
318    }
319
320    // make the array (leave space to NULL terminate it)
321    //      n.b., even if the list is empty, we still return an array that
322    //            only contains the NULL terminator
323    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
324    int i = 0;
325    if(size) {
326        while(i<size) { 
327            cur=(abac_credential_t *) abac_stack_pop(result);
328            credentials[i++] = cur;
329        } 
330    }
331    credentials[i] = NULL;
332
333    if(result)
334        abac_stack_free(result);
335
336    return credentials;
337}
338
339/**
340 * A NULL-terminated array of all the credentials in the context.
341 */
342abac_credential_t **abac_context_credentials(abac_context_t *ctx) {
343    abac_credential_t **credentials = NULL, *cur;
344    assert(ctx != NULL);
345
346    abac_stack_t *result = abac_pl_credentials(ctx->pl);
347    int size = abac_stack_size(result);
348
349    // make the array (leave space to NULL terminate it)
350    //      n.b., even if the list is empty, we still return an array that
351    //            only contains the NULL terminator
352    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
353    int i = 0;
354    if(size) {
355        while(i<size) { 
356            cur=(abac_credential_t *) abac_stack_pop(result);
357            /* if not in there yet, add into it */
358            credentials[i++] = cur;
359        } 
360    }
361    credentials[i] = NULL;
362
363    if(result)
364        abac_stack_free(result);
365    return credentials;
366}
367
368/**
369 * Frees a NULL-terminated list of credentials.
370 */
371void abac_context_credentials_free(abac_credential_t **credentials) {
372    int i;
373
374    if (credentials == NULL)
375        return;
376
377    for (i = 0; credentials[i] != NULL; ++i)
378        abac_credential_free(credentials[i]);
379    free(credentials);
380}
381
382/**
383 * A NULL-terminated array of all the principals in the context.
384 */
385abac_id_credential_t **abac_context_principals(abac_context_t *ctx) {
386    abac_id_credential_t **principals = NULL, *cur;
387    assert(ctx != NULL);
388
389    abac_stack_t *result = abac_pl_principals(ctx->pl);
390
391    int size = abac_stack_size(result);
392
393    // make the array (leave space to NULL terminate it)
394    //      n.b., even if the list is empty, we still return an array that
395    //            only contains the NULL terminator
396    principals = abac_xmalloc(sizeof(abac_id_credential_t *) * (size + 1));
397    int i = 0;
398    if(size) {
399        while(i<size) { 
400            cur=(abac_id_credential_t *) abac_stack_pop(result);
401            /* if not in there yet, add into it */
402            principals[i++] = cur;
403        } 
404    }
405    principals[i] = NULL;
406
407    if(result)
408        abac_stack_free(result);
409    return principals;
410}
411
412/**
413 * Frees a NULL-terminated list of principals.
414 */
415void abac_context_principals_free(abac_id_credential_t **principals) {
416    int i;
417
418    if (principals == NULL)
419        return;
420
421    for (i = 0; principals[i] != NULL; ++i)
422        abac_id_credential_free(principals[i]);
423    free(principals);
424}
425
Note: See TracBrowser for help on using the repository browser.