source: libabac/abac_pl.c @ 53e540d

mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2 yap_rt0
Last change on this file since 53e540d was e95d652, checked in by Mei <mei@…>, 13 years ago

1) added yap, flex, bison to bring in prolog backend

  • Property mode set to 100644
File size: 6.0 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.h"
11#include "abac_pl.h"
12#include "abac_pl_yap.h"
13
14#ifdef DEBUG_IT
15#include "abac_pl_yap_dbg.h"
16#endif
17
18#include "abac_util.h"
19#include "abac_verifier.h"
20
21static int debug = 1;
22
23struct _abac_context_t {
24    abac_pl_t *pl;
25#ifdef DEBUG_IT
26/* this is just for debugging */
27    abac_pl_yap_dbg_t *dpl;
28#endif
29};
30
31/**
32 * Init the library.
33 */
34void libabac_init(void) {
35    void libabac_deinit(void);
36    static int has_been_init = 0;
37
38    // called every time a context is created, so only do it once
39    if (!has_been_init) {
40        abac_verifier_init();
41        atexit(libabac_deinit);
42        has_been_init = 1;
43    }
44}
45
46/**
47 * Deinit the library.
48 */
49void libabac_deinit(void) {
50    abac_verifier_deinit();
51}
52
53/**
54 * Create a new abac context.
55 */
56abac_context_t *abac_context_new(void) {
57    libabac_init();
58
59    abac_context_t *ctx = abac_xmalloc(sizeof(abac_context_t));
60    ctx->pl = abac_pl_new();
61#ifdef DEBUG_IT
62    if (debug) {
63        ctx->dpl = abac_pl_yap_dbg_new();
64    } else ctx->dpl = NULL;
65#endif
66    return ctx;
67}
68
69
70/**
71 * Free an abac context.
72 */
73void abac_context_free(abac_context_t *ctx) {
74    assert(ctx != NULL);
75
76    abac_pl_free(ctx->pl);
77#ifdef DEBUG_IT
78    if (ctx->dpl)
79        abac_pl_yap_dbg_free(ctx->dpl);
80#endif
81    free(ctx);
82}
83
84/**
85 * Load an ID cert from a file.
86 */
87int abac_context_load_id_file(abac_context_t *ctx, char *filename) {
88    assert(ctx != NULL); assert(filename != NULL);
89    int ret = abac_verifier_load_id_file(filename);
90    if (ret == ABAC_CERT_SUCCESS) {
91        // add into yap
92    }
93    return ret;
94}
95
96/**
97 * Load an ID cert from a chunk.
98 */
99int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert) {
100    assert(ctx != NULL);
101    chunk_t cert_chunk = { cert.ptr, cert.len };
102    return abac_verifier_load_id_chunk(cert_chunk);
103}
104
105/**
106 * Load an attribute cert from a file.
107 */
108int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
109    int ret, add_ret;
110    abac_credential_t *cred;
111
112    assert(ctx != NULL); assert(filename != NULL);
113
114    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
115    if (ret == ABAC_CERT_SUCCESS) {
116        add_ret = abac_pl_add_credential(ctx->pl, cred);
117        assert(add_ret != ABAC_PL_CRED_INVALID);
118/* MEI, XXX this is weird..
119        abac_credential_free(cred);
120**/
121    }
122
123    return ret;
124}
125
126/**
127 * Load an attribute cert from a chunk.
128 */
129int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
130    int ret, add_ret;
131    abac_credential_t *cred;
132
133    assert(ctx != NULL);
134
135    chunk_t cert_chunk = { cert.ptr, cert.len };
136
137    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
138    if (ret == ABAC_CERT_SUCCESS) {
139        add_ret = abac_pl_add_credential(ctx->pl, cred);
140        assert(add_ret != ABAC_PL_CRED_INVALID);
141        abac_credential_free(cred);
142    }
143
144    return ret;
145}
146
147#define ID_PAT "/*_ID.{der,pem}"
148#define ATTR_PAT "/*_attr.der"
149
150/**
151 * Load a directory full of certs.
152 */
153void abac_context_load_directory(abac_context_t *ctx, char *path) {
154    char *glob_pat;
155    glob_t glob_buf;
156    int i, ret;
157
158    assert(ctx != NULL); assert(path != NULL);
159
160    int dirlen = strlen(path);
161    glob_pat = abac_xmalloc(dirlen + sizeof(ID_PAT));
162    memcpy(glob_pat, path, dirlen);
163
164    // first load ID certs
165    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
166    glob(glob_pat, GLOB_BRACE, NULL, &glob_buf); // TODO check for error
167    for (i = 0; i < glob_buf.gl_pathc; ++i) {
168        char *cert_file = glob_buf.gl_pathv[i];
169
170        printf("--> ID cert... %s\n", cert_file);
171        ret = abac_context_load_id_file(ctx, cert_file);
172        if (ret != ABAC_CERT_SUCCESS)
173            warnx("Couldn't load ID cert %s", cert_file);
174    }
175    globfree(&glob_buf);
176
177    // then load attr certs
178    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
179    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
180    for (i = 0; i < glob_buf.gl_pathc; ++i) {
181        char *cert_file = glob_buf.gl_pathv[i];
182
183        printf("--> attr cert... %s\n", cert_file);
184        ret = abac_context_load_attribute_file(ctx, cert_file);
185        if (ret != ABAC_CERT_SUCCESS)
186            warnx("Couldn't load attribute cert %s", cert_file);
187    }
188    globfree(&glob_buf);
189
190    free(glob_pat);
191}
192
193/**
194 * Run a query on the data in an abac context. Returns a NULL-terminated array
195 * of abac_credential_t. Success/failure in *success.
196 */
197abac_credential_t **abac_context_query(abac_context_t *ctx, char *role, char *principal, int *success) {
198    abac_credential_t **credentials = NULL, *cur;
199    int i = 0;
200
201    assert(ctx != NULL); assert(role != NULL); assert(principal != NULL); assert(success != NULL);
202
203    abac_list_t *result = abac_pl_query(ctx->pl, role, principal);
204
205    int size = abac_list_size(result);
206    if (size > 0)
207        *success = 1;
208
209    else {
210    // XXX NOT SURE YET..
211    // return partial proof
212    }
213
214    // make the array (leave space to NULL terminate it)
215    //      n.b., even if the list is empty, we still return an array that
216    //            only contains the NULL terminator
217    credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
218    if(size) {
219        abac_list_foreach(result, cur,
220            credentials[i++] = cur;
221        );
222    }
223    credentials[i] = NULL;
224
225    abac_list_free(result);
226
227    return credentials;
228}
229
230/**
231 * A NULL-terminated array of all the credentials in the context.
232 */
233abac_credential_t **abac_context_credentials(abac_context_t *ctx) {
234    assert(ctx != NULL);
235}
236
237/**
238 * Frees a NULL-terminated list of credentials.
239 */
240void abac_context_credentials_free(abac_credential_t **credentials) {
241    int i;
242
243    if (credentials == NULL)
244        return;
245
246    for (i = 0; credentials[i] != NULL; ++i)
247        abac_credential_free(credentials[i]);
248    free(credentials);
249}
250
251#ifdef DEBUG_IT
252// for debugging only
253void abac_context_debug_run(abac_context_t *ctx) {
254    if (ctx) {
255        abac_pl_yap_dbg_run_can(ctx->dpl);
256    }
257}
258#endif
Note: See TracBrowser for help on using the repository browser.