source: libabac/abac.c @ 137b55f

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

1) upgraded to use strongswan-4.6.4

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