source: libabac/abac.c @ ca72963

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

1) able to programmatially build structure, bake attribute credential

write it out to a .der file and use prover to bring it back and
process just like other .der files.
-- tested with rt1 like policy without constraint.

2) changed abac_term structure alittle to ready it for 2 pass code

gen.

  • Property mode set to 100644
File size: 7.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    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_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(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/**
102 * Load an ID cert from a chunk.
103 */
104int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert) {
105    assert(ctx != NULL);
106    abac_id_credential_t *id_cert=NULL;
107    chunk_t cert_chunk = { cert.ptr, cert.len };
108    int ret=abac_verifier_load_id_chunk(cert_chunk,&id_cert);
109    if(id_cert) {
110        int add_ret = abac_pl_add_type_credential(ctx->pl, id_cert);
111    }
112    return ret;
113}
114
115/**
116 * Load an attribute cert from an abac_attribute_t.
117 */
118int abac_context_load_attribute_attribute(abac_context_t *ctx, abac_attribute_t *ptr)
119{
120/* XXX */
121    int ret=0;
122    return ret;
123}
124
125/**
126 * Load an attribute cert from a file.
127 */
128int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
129    int ret, add_ret;
130    abac_credential_t *cred;
131
132    assert(ctx != NULL); assert(filename != NULL);
133
134    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
135    if (ret == ABAC_CERT_SUCCESS) {
136        add_ret = abac_pl_add_credential(ctx->pl, cred);
137        assert(add_ret != ABAC_PL_CRED_INVALID);
138    }
139
140    return ret;
141}
142
143/**
144 * Load an attribute cert from a chunk.
145 */
146int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
147    int ret, add_ret;
148    abac_credential_t *cred;
149
150    assert(ctx != NULL);
151
152    chunk_t cert_chunk = { cert.ptr, cert.len };
153
154    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
155    if (ret == ABAC_CERT_SUCCESS) {
156        add_ret = abac_pl_add_credential(ctx->pl, cred);
157        assert(add_ret != ABAC_PL_CRED_INVALID);
158        abac_credential_free(cred);
159    }
160
161    return ret;
162}
163
164#define KEY_PAT "/*_private.{der,pem}"
165#define ID_PAT "/*_ID.{der,pem}"
166#define ATTR_PAT "/*_attr.der"
167
168char *_make_key_filename(char *cert_file)
169{
170    char *p=strstr(cert_file,"_ID.");
171    char *head=strndup(cert_file,p-cert_file);
172    char *tail=p+4;
173    char *keyfile=NULL;
174    asprintf(&keyfile,"%s_private.%s",head,tail);
175    free(head);
176    return keyfile;
177}
178/**
179 * Load a directory full of certs.
180 */
181void abac_context_load_directory(abac_context_t *ctx, char *path) {
182    char *glob_pat, *key_pat;
183    glob_t glob_buf;
184    int i, ret;
185
186    assert(ctx != NULL); assert(path != NULL);
187
188    int dirlen = strlen(path);
189    glob_pat = abac_xmalloc(dirlen + sizeof(ID_PAT));
190    memcpy(glob_pat, path, dirlen);
191
192    // first load ID certs
193    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
194    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
195    for (i = 0; i < glob_buf.gl_pathc; ++i) {
196        /* blah_ID.pem */
197        char *cert_file = glob_buf.gl_pathv[i];
198        /* blah_private.pem */
199        char *key_file=_make_key_filename(cert_file);
200        if(debug) {
201            printf("--> ID cert... %s\n", cert_file);
202            printf("--> KEY cert... %s\n", key_file);
203        }
204        ret = abac_context_load_id_file(ctx, cert_file, key_file);
205        if (ret != ABAC_CERT_SUCCESS)
206            warnx("Couldn't load ID cert %s", cert_file);
207    }
208    globfree(&glob_buf);
209
210    // then load attr certs
211    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
212    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
213    for (i = 0; i < glob_buf.gl_pathc; ++i) {
214        char *cert_file = glob_buf.gl_pathv[i];
215
216        if(debug) printf("--> attr file... %s\n", cert_file);
217        ret = abac_context_load_attribute_file(ctx, cert_file);
218        if (ret != ABAC_CERT_SUCCESS)
219            warnx("Couldn't load attribute cert %s", cert_file);
220    }
221    globfree(&glob_buf);
222
223    free(glob_pat);
224}
225
226/**
227 * Run a query on the data in an abac context. Returns a NULL-terminated array
228 * of abac_credential_t. Success/failure in *success.
229 * queryfor(either role or oset), with(either keyid or object type)
230 */
231abac_credential_t **abac_context_query(abac_context_t *ctx, char *queryfor, char *with, int *success) {
232    if(debug) {
233         printf("abac_context_query about(%s) with(%s)\n", queryfor, with);
234    }
235    abac_credential_t **credentials = NULL, *cur;
236    assert(ctx != NULL); assert(queryfor != NULL);
237    assert(with != NULL); assert(success != NULL);
238
239    abac_stack_t *result = abac_pl_query(ctx->pl, queryfor, with);
240
241    int size = abac_stack_size(result);
242    if (size > 0) {
243        *success = 1;
244    } else {
245    // XXX NOT SURE YET..
246    // return partial proof
247        *success = 0;
248    }
249
250    // make the array (leave space to NULL terminate it)
251    //      n.b., even if the list is empty, we still return an array that
252    //            only contains the NULL terminator
253    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
254    int i = 0;
255    if(size) {
256        while(i<size) { 
257            cur=(abac_credential_t *) abac_stack_pop(result);
258            credentials[i++] = cur;
259        } 
260    }
261    credentials[i] = NULL;
262
263    if(result)
264        abac_stack_free(result);
265
266    return credentials;
267}
268
269/**
270 * A NULL-terminated array of all the credentials in the context.
271 */
272abac_credential_t **abac_context_credentials(abac_context_t *ctx) {
273    abac_credential_t **credentials = NULL, *cur;
274    assert(ctx != NULL);
275
276    abac_stack_t *result = abac_pl_credentials(ctx->pl);
277    int size = abac_stack_size(result);
278
279    // make the array (leave space to NULL terminate it)
280    //      n.b., even if the list is empty, we still return an array that
281    //            only contains the NULL terminator
282    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
283    int i = 0;
284    if(size) {
285        while(i<size) { 
286            cur=(abac_credential_t *) abac_stack_pop(result);
287            /* if not in there yet, add into it */
288            credentials[i++] = cur;
289        } 
290    }
291    credentials[i] = NULL;
292
293    if(result)
294        abac_stack_free(result);
295    return credentials;
296}
297
298/**
299 * Frees a NULL-terminated list of credentials.
300 */
301void abac_context_credentials_free(abac_credential_t **credentials) {
302    int i;
303
304    if (credentials == NULL)
305        return;
306
307    for (i = 0; credentials[i] != NULL; ++i)
308        abac_credential_free(credentials[i]);
309    free(credentials);
310}
311
Note: See TracBrowser for help on using the repository browser.