source: libabac/abac_pl.c @ 9335cfa

mei_rt2mei_rt2_fix_1
Last change on this file since 9335cfa was 43ff309, checked in by Ted Faber <faber@…>, 12 years ago

Return the failure code

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