source: libabac/abac.c @ 97a6a36

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

1) added java to libabac using swig
2) added java examples (setup/prover) into regression test suites
(note. still have that libstrongswan/src/threading/threads.c/thread_deinit()
problem when using using libabac with java)

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