source: libabac/abac.c @ b8a6fd2a

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

1) add new tests for attribute creation also for Attribute_chunk,

ID_chunk

  • Property mode set to 100644
File size: 16.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        } else {
35           if(debug) fprintf(stderr, "libabac_init, can only be called once\n");
36    }
37}
38
39/**
40 * Deinit the library.
41 */
42void libabac_deinit(void) {
43    abac_verifier_deinit();
44}
45
46/**
47 * Create a new abac context.
48 */
49abac_context_t *abac_context_new(void) {
50    libabac_init();
51
52    abac_context_t *ctx = abac_xmalloc(sizeof(abac_context_t));
53    ctx->pl = abac_pl_new();
54    return ctx;
55}
56
57/**
58 * Deep copy an abac context. -- XXX dummy stub
59 */
60abac_context_t *abac_context_dup(abac_context_t *ctx) {
61    assert(ctx != NULL);
62    abac_context_t *dup = abac_xmalloc(sizeof(abac_context_t));
63    return dup;
64}
65
66
67/**
68 * Free an abac context.
69 */
70void abac_context_free(abac_context_t *ctx) {
71    assert(ctx != NULL);
72
73    abac_pl_free(ctx->pl);
74    free(ctx);
75}
76
77/**
78 * Load an ID cert from an abac_id_t.
79 */
80int abac_context_load_id_id(abac_context_t *ctx, abac_id_t *id) {
81    assert(ctx != NULL); assert(id);
82    abac_id_credential_t *id_cert=NULL;
83    int ret = abac_verifier_load_id_id(id,&id_cert);
84    if(id_cert) {
85        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
86    }
87    return ret;
88}
89
90/**
91 * Load an ID cert from a file.
92 */
93int abac_context_load_id_id_file_key_file(abac_context_t *ctx, char *filename,
94char *keyfilename)
95{
96    assert(ctx != NULL); assert(filename != NULL); assert(keyfilename!=NULL);
97    abac_id_credential_t *id_cert=NULL;
98    int ret = abac_verifier_load_id_file_key_file(filename,keyfilename,&id_cert);
99    if(id_cert) {
100        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
101    }
102    return ret;
103}
104
105int abac_context_load_id_enc_id_file_key_file(abac_context_t *ctx, char *filename,
106char *keyfilename, char *pfile)
107{
108    assert(ctx != NULL); assert(filename != NULL); assert(keyfilename!=NULL);
109    abac_id_credential_t *id_cert=NULL;
110    int ret = abac_verifier_load_enc_id_file_key_file(filename,keyfilename, pfile, &id_cert);
111    if(id_cert) {
112        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
113    }
114    return ret;
115}
116
117/**
118 * Load an ID cert from a file, it may contain key part but not necessary.
119 */
120int abac_context_load_id_idkey_file(abac_context_t *ctx, char *filename) {
121    assert(ctx != NULL); assert(filename != NULL); 
122    abac_id_credential_t *id_cert=NULL;
123    int ret = abac_verifier_load_idkey_file(filename,&id_cert);
124    if(id_cert) {
125        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
126    }
127    return ret;
128}
129
130/**
131 * Load an ID cert from a file, it may contain encrypted key part but not necessary.
132 */
133int abac_context_load_id_enc_idkey_file(abac_context_t *ctx, char *filename, char *pfile) {
134    assert(ctx != NULL); assert(filename != NULL); 
135    abac_id_credential_t *id_cert=NULL;
136    int ret = abac_verifier_load_enc_idkey_file(filename, pfile,&id_cert);
137    if(id_cert) {
138        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
139    }
140    return ret;
141}
142
143/**
144 * Load an ID cert from a chunk.
145 */
146int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert) {
147    assert(ctx != NULL);
148    abac_id_credential_t *id_cert=NULL;
149    chunk_t cert_chunk = { cert.ptr, cert.len };
150    int ret=abac_verifier_load_id_chunk(cert_chunk,&id_cert);
151    if(id_cert) {
152        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
153    }
154    return ret;
155}
156
157
158/**
159 * Load an ID cert and privkey from chunks.
160 */
161int abac_context_load_id_privkey_chunk(abac_context_t *ctx, abac_chunk_t cert, abac_chunk_t privkey) {
162    assert(ctx != NULL);
163    abac_id_credential_t *id_cert=NULL;
164    chunk_t cert_chunk = { cert.ptr, cert.len };
165/*A HACK/SWIG, this is to work around the swig's stub that seems to
166  mess up the transformation from abac_chunk_t to chunk_t and calling of
167  load_id_chunks to here */
168/* BAD,  chunk_t privkey_chunk = { privkey.ptr, privkey.len }; */
169    chunk_t privkey_chunk = { strndup(privkey.ptr,privkey.len), privkey.len };
170/* another way,
171    chunk_t tmp = { privkey.ptr, privkey.len };
172    char *ptr = abac_xmalloc(sizeof(unsigned char) * privkey.len);
173    chunk_t privkey_chunk = chunk_create_clone(ptr,tmp);
174*/
175    if(debug) {
176        fprintf(stderr, "abac_context_load_id_privkey_chunk, privkey ptr, loc(%d)\n",
177                                                           (int)privkey.ptr);
178        fprintf(stderr, "abac_context_load_id_privkey_chunk, privkey_chunk ptr, loc(%d)\n",
179                                                           (int)privkey_chunk.ptr);
180    }
181    int ret=abac_verifier_load_id_privkey_chunk(cert_chunk, privkey_chunk, &id_cert);
182    if(id_cert) {
183        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
184    }
185    return ret;
186}
187
188/**
189 * Load an ID cert and privkey from chunks.
190 */
191int abac_context_load_id_enc_privkey_chunk(abac_context_t *ctx,
192abac_chunk_t cert, abac_chunk_t privkey, char *pfile) {
193    assert(ctx != NULL);
194    abac_id_credential_t *id_cert=NULL;
195    chunk_t cert_chunk = { cert.ptr, cert.len };
196/*A HACK/SWIG, this is to work around the swig's stub that seems to
197  mess up the transformation from abac_chunk_t to chunk_t and calling of
198  load_id_chunks to here */
199/* BAD,  chunk_t privkey_chunk = { privkey.ptr, privkey.len }; */
200    chunk_t privkey_chunk = { strndup(privkey.ptr,privkey.len), privkey.len };
201    int ret=abac_verifier_load_id_enc_privkey_chunk(cert_chunk, privkey_chunk, pfile, &id_cert);
202
203    if(id_cert) {
204        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
205    }
206    return ret;
207}
208
209
210
211/**
212 * Load an attribute cert from an abac_attribute_t.
213 */
214int abac_context_load_attribute_attribute(abac_context_t *ctx, abac_attribute_t *ptr)
215{
216    int ret, add_ret;
217    abac_credential_t *cred=NULL;
218
219    assert(ctx != NULL);
220
221    ret = abac_verifier_load_attribute_cert_attribute(ptr, &cred);
222    if (ret == ABAC_CERT_SUCCESS) {
223        add_ret = abac_pl_add_credential(ctx->pl, cred);
224        assert(add_ret != ABAC_PL_CRED_INVALID);
225    }
226
227    return ret;
228
229}
230
231/**
232 * Load an attribute cert from a file.
233 */
234int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
235    int ret, add_ret;
236    abac_credential_t *cred=NULL;
237
238    assert(ctx != NULL); assert(filename != NULL);
239
240    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
241    if (ret == ABAC_CERT_SUCCESS) {
242        add_ret = abac_pl_add_credential(ctx->pl, cred);
243        assert(add_ret != ABAC_PL_CRED_INVALID);
244    }
245
246    return ret;
247}
248
249/**
250 * Load an attribute cert from a chunk.
251 */
252int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
253    int ret, add_ret;
254    abac_credential_t *cred=NULL;
255
256    assert(ctx != NULL);
257
258    chunk_t cert_chunk = { cert.ptr, cert.len };
259
260    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
261    if (ret == ABAC_CERT_SUCCESS) {
262        add_ret = abac_pl_add_credential(ctx->pl, cred);
263        assert(add_ret != ABAC_PL_CRED_INVALID);
264    }
265
266    return ret;
267}
268
269#define KEY_PAT "/*_private.{der,pem}"
270#define ID_PAT "/*_ID.{der,pem}"
271#define ATTR_PAT "/*_attr.der"
272#define IDKEY_PAT "/*_IDKEY.{der,pem}"
273
274char *_make_key_filename(char *cert_file)
275{
276    char *p=strstr(cert_file,"_ID.");
277    char *head=strndup(cert_file,p-cert_file);
278    char *tail=p+4;
279    char *keyfile=NULL;
280    asprintf(&keyfile,"%s_private.%s",head,tail);
281    free(head);
282    return keyfile;
283}
284
285/**
286 * Load a directory full of principal certs.
287 */
288void abac_context_load_principals(abac_context_t *ctx, char *path) {
289    char *glob_pat, *key_pat;
290    glob_t glob_buf;
291    int i, ret;
292
293    assert(ctx != NULL); assert(path != NULL);
294
295    int dirlen = strlen(path);
296
297    /* make sure pick the larger one */
298    glob_pat = abac_xmalloc(dirlen + sizeof(IDKEY_PAT));
299    memcpy(glob_pat, path, dirlen);
300
301    // load ID certs
302    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
303    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
304    for (i = 0; i < glob_buf.gl_pathc; ++i) {
305        /* blah_ID.pem */
306        char *cert_file = glob_buf.gl_pathv[i];
307        /* blah_private.pem */
308        char *key_file=_make_key_filename(cert_file);
309        if(debug) {
310            fprintf(stderr,"--> ID cert... %s\n", cert_file);
311            fprintf(stderr,"--> KEY cert... %s\n", key_file);
312        }
313        ret = abac_context_load_id_id_file_key_file(ctx, cert_file, key_file);
314        if (ret != ABAC_CERT_SUCCESS)
315            warnx("Couldn't load ID cert %s", cert_file);
316    }
317    globfree(&glob_buf);
318
319    // next load IDKEY certs
320    memcpy(glob_pat + dirlen, IDKEY_PAT, sizeof(IDKEY_PAT));
321    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
322    for (i = 0; i < glob_buf.gl_pathc; ++i) {
323        /* blah_IDKEY.pem */
324        char *certkey_file = glob_buf.gl_pathv[i];
325        if(debug) fprintf(stderr, "--> IDKEY certkey... %s\n", certkey_file);
326        ret = abac_context_load_id_idkey_file(ctx, certkey_file);
327        if (ret != ABAC_CERT_SUCCESS)
328            warnx("Couldn't load ID/KEY IDKEY cert %s", certkey_file);
329    }
330    globfree(&glob_buf);
331
332    free(glob_pat);
333}
334
335/**
336 * Load a directory full of certs.
337 */
338void abac_context_load_directory(abac_context_t *ctx, char *path) {
339    char *glob_pat, *key_pat;
340    glob_t glob_buf;
341    int i, ret;
342
343    abac_context_load_principals(ctx,path);
344    int dirlen = strlen(path);
345
346    /* make sure pick the larger one */
347    glob_pat = abac_xmalloc(dirlen + sizeof(IDKEY_PAT));
348    memcpy(glob_pat, path, dirlen);
349
350    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
351    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
352    for (i = 0; i < glob_buf.gl_pathc; ++i) {
353        char *cert_file = glob_buf.gl_pathv[i];
354
355        if(debug) fprintf(stderr,"--> attr file... (%s)\n", cert_file);
356        ret = abac_context_load_attribute_file(ctx, cert_file);
357        if (ret != ABAC_CERT_SUCCESS)
358            warnx("Couldn't load attribute cert --%s", cert_file);
359        if(debug) fprintf(stderr,"Loaded.. (%s)\n", cert_file);
360    }
361    globfree(&glob_buf);
362
363    free(glob_pat);
364}
365
366/**
367 * Run a query on the data in an abac context. Returns a NULL-terminated array
368 * of abac_credential_t. Success/failure in *success.
369 * queryfor(either role or oset), with(either keyid or object type)
370 */
371abac_credential_t **abac_context_query(abac_context_t *ctx, char *queryfor, char *with, int *success) {
372    if(debug) fprintf(stderr,"abac_context_query about(%s) with(%s)\n", queryfor, with);
373    abac_credential_t **credentials = NULL, *cur;
374    assert(ctx != NULL); assert(queryfor != NULL);
375    assert(with != NULL); assert(success != NULL);
376
377    abac_stack_t *result = abac_pl_query(ctx->pl, queryfor, with);
378
379    int size = abac_stack_size(result);
380    if (size > 0) {
381        *success = 1;
382    } else {
383    // XXX NOT SURE YET..
384    // return partial proof
385        *success = 0;
386    }
387
388    // make the array (leave space to NULL terminate it)
389    //      n.b., even if the list is empty, we still return an array that
390    //            only contains the NULL terminator
391    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
392    int i = 0;
393    if(size) {
394        while(i<size) { 
395            cur=(abac_credential_t *) abac_stack_pop(result);
396            credentials[i++] = cur;
397        } 
398    }
399    credentials[i] = NULL;
400
401    if(result)
402        abac_stack_free(result);
403
404    return credentials;
405}
406
407/**
408 * Run a repeated query on the data in an abac context to get the next
409 * solution proof. Returns a NULL-terminated array
410 * of abac_credential_t. Success/failure in *success.
411 */
412abac_credential_t **abac_context_query_again(abac_context_t *ctx, int *success)
413{
414    if(debug) fprintf(stderr,"abac_context_query_again\n");
415    abac_credential_t **credentials = NULL, *cur;
416    assert(ctx != NULL);
417    assert(success != NULL);
418
419    abac_stack_t *result = abac_pl_query_again(ctx->pl);
420
421    int size = abac_stack_size(result);
422    if (size > 0) {
423        *success = 1;
424        } else {
425            *success = 0;
426    }
427
428    // make the array (leave space to NULL terminate it)
429    //      n.b., even if the list is empty, we still return an array that
430    //            only contains the NULL terminator
431    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
432    int i = 0;
433    if(size) {
434        while(i<size) { 
435            cur=(abac_credential_t *) abac_stack_pop(result);
436            credentials[i++] = cur;
437        } 
438    }
439    credentials[i] = NULL;
440
441    if(result)
442        abac_stack_free(result);
443
444    return credentials;
445}
446
447
448abac_credential_t **abac_context_query_with_structure(abac_context_t *ctx,
449abac_aspect_t *queryfor, abac_aspect_t *with, int *success)
450{
451    if(debug) fprintf(stderr,"abac_context_query_with_structure\n");
452    abac_credential_t **credentials = NULL, *cur;
453    assert(ctx != NULL); assert(queryfor != NULL);
454    assert(with != NULL); assert(success != NULL);
455
456    abac_stack_t *result = abac_pl_query_with_structure(ctx->pl, queryfor, with);
457
458    int size = abac_stack_size(result);
459    if (size > 0) {
460        *success = 1;
461    } else {
462    // XXX NOT SURE YET..
463    // return partial proof
464        *success = 0;
465    }
466
467    // make the array (leave space to NULL terminate it)
468    //      n.b., even if the list is empty, we still return an array that
469    //            only contains the NULL terminator
470    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
471    int i = 0;
472    if(size) {
473        while(i<size) { 
474            cur=(abac_credential_t *) abac_stack_pop(result);
475            credentials[i++] = cur;
476        } 
477    }
478    credentials[i] = NULL;
479
480    if(result)
481        abac_stack_free(result);
482
483    return credentials;
484}
485
486/**
487 * A NULL-terminated array of all the credentials in the context.
488 */
489abac_credential_t **abac_context_credentials(abac_context_t *ctx) {
490    abac_credential_t **credentials = NULL, *cur;
491    assert(ctx != NULL);
492
493    abac_stack_t *result = abac_pl_credentials(ctx->pl);
494    int size = abac_stack_size(result);
495
496    // make the array (leave space to NULL terminate it)
497    //      n.b., even if the list is empty, we still return an array that
498    //            only contains the NULL terminator
499    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
500    int i = 0;
501    if(size) {
502        while(i<size) { 
503            cur=(abac_credential_t *) abac_stack_pop(result);
504            /* if not in there yet, add into it */
505            credentials[i++] = cur;
506        } 
507    }
508    credentials[i] = NULL;
509
510    if(result)
511        abac_stack_free(result);
512    return credentials;
513}
514
515/**
516 * Frees a NULL-terminated list of credentials.
517 */
518void abac_context_credentials_free(abac_credential_t **credentials) {
519    int i;
520
521    if (credentials == NULL)
522        return;
523
524    for (i = 0; credentials[i] != NULL; ++i)
525        abac_credential_free(credentials[i]);
526    free(credentials);
527}
528
529/**
530 * A NULL-terminated array of all the principals in the context.
531 */
532abac_id_credential_t **abac_context_principals(abac_context_t *ctx) {
533    abac_id_credential_t **principals = NULL, *cur;
534    assert(ctx != NULL);
535
536    abac_stack_t *result = abac_pl_principals(ctx->pl);
537
538    int size = abac_stack_size(result);
539
540    // make the array (leave space to NULL terminate it)
541    //      n.b., even if the list is empty, we still return an array that
542    //            only contains the NULL terminator
543    principals = abac_xmalloc(sizeof(abac_id_credential_t *) * (size + 1));
544    int i = 0;
545    if(size) {
546        while(i<size) { 
547            cur=(abac_id_credential_t *) abac_stack_pop(result);
548            /* if not in there yet, add into it */
549            principals[i++] = cur;
550        } 
551    }
552    principals[i] = NULL;
553
554    if(result)
555        abac_stack_free(result);
556    return principals;
557}
558
559/**
560 * Frees a NULL-terminated list of principals.
561 */
562void abac_context_principals_free(abac_id_credential_t **principals) {
563    int i;
564
565    if (principals == NULL)
566        return;
567
568    for (i = 0; principals[i] != NULL; ++i)
569        abac_id_credential_free(principals[i]);
570    free(principals);
571}
572
573/**
574 *
575 */
576abac_id_credential_t *abac_context_principal_lookup(abac_context_t *ctx, char *name)
577{
578    assert(ctx != NULL);
579    abac_id_credential_t *principal=abac_id_credential_lookup(name);
580    return principal;
581}
Note: See TracBrowser for help on using the repository browser.