source: libabac/abac.c @ 53e540d

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

1) adding appendL to do the credential list appending

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