source: libabac/abac.c @ 9b43fc3

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

1) add code to load id into context with both cert chunk and privkey
chunk
2) test out the sample scripts in swig/perl and swig/python

  • Property mode set to 100644
File size: 12.5 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/**
129 * Load an ID cert and privkey from chunks.
130 */
131int abac_context_load_id_privkey_chunk(abac_context_t *ctx, abac_chunk_t cert, abac_chunk_t privkey) {
132    assert(ctx != NULL);
133    abac_id_credential_t *id_cert=NULL;
134    chunk_t cert_chunk = { cert.ptr, cert.len };
135    chunk_t privkey_chunk = { privkey.ptr, privkey.len };
136    int ret=abac_verifier_load_id_privkey_chunk(cert_chunk, privkey_chunk, &id_cert);
137
138    if(id_cert) {
139        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
140    }
141    return ret;
142}
143
144
145/**
146 * Load an attribute cert from an abac_attribute_t.
147 */
148int abac_context_load_attribute_attribute(abac_context_t *ctx, abac_attribute_t *ptr)
149{
150    int ret, add_ret;
151    abac_credential_t *cred=NULL;
152
153    assert(ctx != NULL);
154
155    ret = abac_verifier_load_attribute_cert_attribute(ptr, &cred);
156    if (ret == ABAC_CERT_SUCCESS) {
157        add_ret = abac_pl_add_credential(ctx->pl, cred);
158        assert(add_ret != ABAC_PL_CRED_INVALID);
159    }
160
161    return ret;
162
163}
164
165/**
166 * Load an attribute cert from a file.
167 */
168int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
169    int ret, add_ret;
170    abac_credential_t *cred=NULL;
171
172    assert(ctx != NULL); assert(filename != NULL);
173
174    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
175    if (ret == ABAC_CERT_SUCCESS) {
176        add_ret = abac_pl_add_credential(ctx->pl, cred);
177        assert(add_ret != ABAC_PL_CRED_INVALID);
178    }
179
180    return ret;
181}
182
183/**
184 * Load an attribute cert from a chunk.
185 */
186int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
187    int ret, add_ret;
188    abac_credential_t *cred=NULL;
189
190    assert(ctx != NULL);
191
192    chunk_t cert_chunk = { cert.ptr, cert.len };
193
194    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
195    if (ret == ABAC_CERT_SUCCESS) {
196        add_ret = abac_pl_add_credential(ctx->pl, cred);
197        assert(add_ret != ABAC_PL_CRED_INVALID);
198        /* abac_credential_free(cred); */
199    }
200
201    return ret;
202}
203
204#define KEY_PAT "/*_private.{der,pem}"
205#define ID_PAT "/*_ID.{der,pem}"
206#define ATTR_PAT "/*_attr.der"
207#define IDKEY_PAT "/*_IDKEY.{der,pem}"
208
209char *_make_key_filename(char *cert_file)
210{
211    char *p=strstr(cert_file,"_ID.");
212    char *head=strndup(cert_file,p-cert_file);
213    char *tail=p+4;
214    char *keyfile=NULL;
215    asprintf(&keyfile,"%s_private.%s",head,tail);
216    free(head);
217    return keyfile;
218}
219
220
221/**
222 * Load a directory full of principal certs.
223 */
224void abac_context_load_principals(abac_context_t *ctx, char *path) {
225    char *glob_pat, *key_pat;
226    glob_t glob_buf;
227    int i, ret;
228
229    assert(ctx != NULL); assert(path != NULL);
230
231    int dirlen = strlen(path);
232
233    /* make sure pick the larger one */
234    glob_pat = abac_xmalloc(dirlen + sizeof(IDKEY_PAT));
235    memcpy(glob_pat, path, dirlen);
236
237    // load ID certs
238    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
239    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
240    for (i = 0; i < glob_buf.gl_pathc; ++i) {
241        /* blah_ID.pem */
242        char *cert_file = glob_buf.gl_pathv[i];
243        /* blah_private.pem */
244        char *key_file=_make_key_filename(cert_file);
245        if(debug) {
246            printf("--> ID cert... %s\n", cert_file);
247            printf("--> KEY cert... %s\n", key_file);
248        }
249        ret = abac_context_load_id_id_file_key_file(ctx, cert_file, key_file);
250        if (ret != ABAC_CERT_SUCCESS)
251            warnx("Couldn't load ID cert %s", cert_file);
252    }
253    globfree(&glob_buf);
254
255    // next load IDKEY certs
256    memcpy(glob_pat + dirlen, IDKEY_PAT, sizeof(IDKEY_PAT));
257    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
258    for (i = 0; i < glob_buf.gl_pathc; ++i) {
259        /* blah_IDKEY.pem */
260        char *certkey_file = glob_buf.gl_pathv[i];
261        if(debug) printf("--> IDKEY certkey... %s\n", certkey_file);
262        ret = abac_context_load_id_idkey_file(ctx, certkey_file);
263        if (ret != ABAC_CERT_SUCCESS)
264            warnx("Couldn't load ID/KEY IDKEY cert %s", certkey_file);
265    }
266    globfree(&glob_buf);
267
268    free(glob_pat);
269}
270
271/**
272 * Load a directory full of certs.
273 */
274void abac_context_load_directory(abac_context_t *ctx, char *path) {
275    char *glob_pat, *key_pat;
276    glob_t glob_buf;
277    int i, ret;
278
279    abac_context_load_principals(ctx,path);
280    int dirlen = strlen(path);
281
282    /* make sure pick the larger one */
283    glob_pat = abac_xmalloc(dirlen + sizeof(IDKEY_PAT));
284    memcpy(glob_pat, path, dirlen);
285
286    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
287    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
288    for (i = 0; i < glob_buf.gl_pathc; ++i) {
289        char *cert_file = glob_buf.gl_pathv[i];
290
291        if(debug) printf("--> attr file... (%s)\n", cert_file);
292        ret = abac_context_load_attribute_file(ctx, cert_file);
293        if (ret != ABAC_CERT_SUCCESS)
294            warnx("Couldn't load attribute cert %s", cert_file);
295        if(debug) printf("Loaded.. (%s)\n", cert_file);
296    }
297    globfree(&glob_buf);
298
299    free(glob_pat);
300}
301
302/**
303 * Run a query on the data in an abac context. Returns a NULL-terminated array
304 * of abac_credential_t. Success/failure in *success.
305 * queryfor(either role or oset), with(either keyid or object type)
306 */
307abac_credential_t **abac_context_query(abac_context_t *ctx, char *queryfor, char *with, int *success) {
308    if(debug) printf("abac_context_query about(%s) with(%s)\n", queryfor, with);
309    abac_credential_t **credentials = NULL, *cur;
310    assert(ctx != NULL); assert(queryfor != NULL);
311    assert(with != NULL); assert(success != NULL);
312
313    abac_stack_t *result = abac_pl_query(ctx->pl, queryfor, with);
314
315    int size = abac_stack_size(result);
316    if (size > 0) {
317        *success = 1;
318    } else {
319    // XXX NOT SURE YET..
320    // return partial proof
321        *success = 0;
322    }
323
324    // make the array (leave space to NULL terminate it)
325    //      n.b., even if the list is empty, we still return an array that
326    //            only contains the NULL terminator
327    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
328    int i = 0;
329    if(size) {
330        while(i<size) { 
331            cur=(abac_credential_t *) abac_stack_pop(result);
332            credentials[i++] = cur;
333        } 
334    }
335    credentials[i] = NULL;
336
337    if(result)
338        abac_stack_free(result);
339
340    return credentials;
341}
342
343abac_credential_t **abac_context_query_with_structure(abac_context_t *ctx,
344abac_aspect_t *queryfor, abac_aspect_t *with, int *success)
345{
346    if(debug) printf("abac_context_query_with_structure\n");
347    abac_credential_t **credentials = NULL, *cur;
348    assert(ctx != NULL); assert(queryfor != NULL);
349    assert(with != NULL); assert(success != NULL);
350
351    abac_stack_t *result = abac_pl_query_with_structure(ctx->pl, queryfor, with);
352
353    int size = abac_stack_size(result);
354    if (size > 0) {
355        *success = 1;
356    } else {
357    // XXX NOT SURE YET..
358    // return partial proof
359        *success = 0;
360    }
361
362    // make the array (leave space to NULL terminate it)
363    //      n.b., even if the list is empty, we still return an array that
364    //            only contains the NULL terminator
365    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
366    int i = 0;
367    if(size) {
368        while(i<size) { 
369            cur=(abac_credential_t *) abac_stack_pop(result);
370            credentials[i++] = cur;
371        } 
372    }
373    credentials[i] = NULL;
374
375    if(result)
376        abac_stack_free(result);
377
378    return credentials;
379}
380
381/**
382 * A NULL-terminated array of all the credentials in the context.
383 */
384abac_credential_t **abac_context_credentials(abac_context_t *ctx) {
385    abac_credential_t **credentials = NULL, *cur;
386    assert(ctx != NULL);
387
388    abac_stack_t *result = abac_pl_credentials(ctx->pl);
389    int size = abac_stack_size(result);
390
391    // make the array (leave space to NULL terminate it)
392    //      n.b., even if the list is empty, we still return an array that
393    //            only contains the NULL terminator
394    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
395    int i = 0;
396    if(size) {
397        while(i<size) { 
398            cur=(abac_credential_t *) abac_stack_pop(result);
399            /* if not in there yet, add into it */
400            credentials[i++] = cur;
401        } 
402    }
403    credentials[i] = NULL;
404
405    if(result)
406        abac_stack_free(result);
407    return credentials;
408}
409
410/**
411 * Frees a NULL-terminated list of credentials.
412 */
413void abac_context_credentials_free(abac_credential_t **credentials) {
414    int i;
415
416    if (credentials == NULL)
417        return;
418
419    for (i = 0; credentials[i] != NULL; ++i)
420        abac_credential_free(credentials[i]);
421    free(credentials);
422}
423
424/**
425 * A NULL-terminated array of all the principals in the context.
426 */
427abac_id_credential_t **abac_context_principals(abac_context_t *ctx) {
428    abac_id_credential_t **principals = NULL, *cur;
429    assert(ctx != NULL);
430
431    abac_stack_t *result = abac_pl_principals(ctx->pl);
432
433    int size = abac_stack_size(result);
434
435    // make the array (leave space to NULL terminate it)
436    //      n.b., even if the list is empty, we still return an array that
437    //            only contains the NULL terminator
438    principals = abac_xmalloc(sizeof(abac_id_credential_t *) * (size + 1));
439    int i = 0;
440    if(size) {
441        while(i<size) { 
442            cur=(abac_id_credential_t *) abac_stack_pop(result);
443            /* if not in there yet, add into it */
444            principals[i++] = cur;
445        } 
446    }
447    principals[i] = NULL;
448
449    if(result)
450        abac_stack_free(result);
451    return principals;
452}
453
454/**
455 * Frees a NULL-terminated list of principals.
456 */
457void abac_context_principals_free(abac_id_credential_t **principals) {
458    int i;
459
460    if (principals == NULL)
461        return;
462
463    for (i = 0; principals[i] != NULL; ++i)
464        abac_id_credential_free(principals[i]);
465    free(principals);
466}
467
Note: See TracBrowser for help on using the repository browser.