source: libabac/abac.c @ 314869f

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 314869f was 314869f, checked in by Mike Ryan <mikeryan@…>, 14 years ago

detect duplicate credential being added to the graph

  • Property mode set to 100644
File size: 5.2 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) {
[43e3b71]20    abac_verifier_init();
[90d20f0]21}
22
23/**
24 * Deinit the library.
25 */
26void libabac_deinit(void) {
[43e3b71]27    abac_verifier_deinit();
[90d20f0]28}
29
30/**
31 * Create a new abac context.
32 */
[390f749]33abac_context_t *abac_context_new(void) {
34    abac_context_t *ctx = abac_xmalloc(sizeof(abac_context_t));
35    ctx->graph = abac_graph_new();
36    return ctx;
[90d20f0]37}
38
39/**
40 * Deep copy an abac context.
41 */
[390f749]42abac_context_t *abac_context_dup(abac_context_t *ctx) {
43    assert(ctx != NULL);
[90d20f0]44
[390f749]45    abac_context_t *dup = abac_xmalloc(sizeof(abac_context_t));
46    dup->graph = abac_graph_dup(ctx->graph);
[90d20f0]47
48    return dup;
49}
50
51/**
52 * Free an abac context.
53 */
[390f749]54void abac_context_free(abac_context_t *ctx) {
55    assert(ctx != NULL);
[90d20f0]56
[390f749]57    abac_graph_free(ctx->graph);
58    free(ctx);
[90d20f0]59}
60
61/**
62 * Load an ID cert from a file.
63 */
[390f749]64int abac_context_load_id_file(abac_context_t *ctx, char *filename) {
65    assert(ctx != NULL); assert(filename != NULL);
[43e3b71]66    return abac_verifier_load_id_file(filename);
[90d20f0]67}
68
69/**
70 * Load an ID cert from a chunk.
71 */
[390f749]72int abac_context_load_id_chunk(abac_context_t *ctx, abac_chunk_t cert) {
73    assert(ctx != NULL);
[9efbfbf]74    chunk_t cert_chunk = { cert.ptr, cert.len };
[43e3b71]75    return abac_verifier_load_id_chunk(cert_chunk);
[90d20f0]76}
77
78/**
79 * Load an attribute cert from a file.
80 */
[390f749]81int abac_context_load_attribute_file(abac_context_t *ctx, char *filename) {
[0779c99]82    int ret, add_ret;
83    abac_credential_t *cred;
[6dd2d1a]84
[390f749]85    assert(ctx != NULL); assert(filename != NULL);
[90d20f0]86
[0779c99]87    ret = abac_verifier_load_attribute_cert_file(filename, &cred);
88    if (ret == ABAC_CERT_SUCCESS) {
89        add_ret = abac_graph_add_credential(ctx->graph, cred);
[314869f]90        assert(add_ret != ABAC_GRAPH_CRED_INVALID);
[401a054]91        abac_credential_free(cred);
[6dd2d1a]92    }
93
94    return ret;
[90d20f0]95}
96
97/**
98 * Load an attribute cert from a chunk.
99 */
[390f749]100int abac_context_load_attribute_chunk(abac_context_t *ctx, abac_chunk_t cert) {
[0779c99]101    int ret, add_ret;
102    abac_credential_t *cred;
103
[390f749]104    assert(ctx != NULL);
[90d20f0]105
[9efbfbf]106    chunk_t cert_chunk = { cert.ptr, cert.len };
[0779c99]107
108    ret = abac_verifier_load_attribute_cert_chunk(cert_chunk, &cred);
109    if (ret == ABAC_CERT_SUCCESS) {
110        add_ret = abac_graph_add_credential(ctx->graph, cred);
[314869f]111        assert(add_ret != ABAC_GRAPH_CRED_INVALID);
[0779c99]112        abac_credential_free(cred);
113    }
114
115    return ret;
[90d20f0]116}
117
[03b3293]118#define ID_PAT "/*_ID.der"
119#define ATTR_PAT "/*_attr.der"
120
121/**
122 * Load a directory full of certs.
123 */
[390f749]124void abac_context_load_directory(abac_context_t *ctx, char *path) {
[03b3293]125    char *glob_pat;
126    glob_t glob_buf;
127    int i, ret;
128
[390f749]129    assert(ctx != NULL); assert(path != NULL);
[03b3293]130
131    int dirlen = strlen(path);
[3c251d0]132    glob_pat = abac_xmalloc(dirlen + sizeof(ATTR_PAT));
[03b3293]133    memcpy(glob_pat, path, dirlen);
134
135    // first load ID certs
136    memcpy(glob_pat + dirlen, ID_PAT, sizeof(ID_PAT));
137    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
138    for (i = 0; i < glob_buf.gl_pathc; ++i) {
139        char *cert_file = glob_buf.gl_pathv[i];
140
[390f749]141        ret = abac_context_load_id_file(ctx, cert_file);
[0779c99]142        if (ret != ABAC_CERT_SUCCESS)
[03b3293]143            warnx("Couldn't load ID cert %s\n", cert_file);
144    }
145    globfree(&glob_buf);
146
147    // then load attr certs
148    memcpy(glob_pat + dirlen, ATTR_PAT, sizeof(ATTR_PAT));
149    glob(glob_pat, 0, NULL, &glob_buf); // TODO check for error
150    for (i = 0; i < glob_buf.gl_pathc; ++i) {
151        char *cert_file = glob_buf.gl_pathv[i];
152
[390f749]153        ret = abac_context_load_attribute_file(ctx, cert_file);
[0779c99]154        if (ret != ABAC_CERT_SUCCESS)
[03b3293]155            warnx("Couldn't load attribute cert %s\n", cert_file);
156    }
157    globfree(&glob_buf);
158
159    free(glob_pat);
160}
161
[90d20f0]162/**
[dc62c68]163 * Run a query on the data in an abac context. Returns a NULL-terminated array
[401a054]164 * of abac_credential_t.
[90d20f0]165 */
[4e426c9]166abac_credential_t **abac_context_query(abac_context_t *ctx, char *role, char *principal, int *success) {
[401a054]167    abac_credential_t **credentials = NULL, *cur;
[dc62c68]168    int i = 0;
169
[4e426c9]170    assert(ctx != NULL); assert(role != NULL); assert(principal != NULL); assert(success != NULL);
[90d20f0]171
[390f749]172    abac_graph_t *result_graph = abac_graph_query(ctx->graph, role, principal);
[401a054]173    abac_list_t *result = abac_graph_credentials(result_graph);
[90d20f0]174
[06293d1]175    abac_graph_free(result_graph);
[90d20f0]176
[6d5623e]177    int size = abac_list_size(result);
[4e426c9]178    if (size > 0)
179        *success = 1;
180
181    // if there is no actual path, return everything that can reach the role
182    else {
183        *success = 0;
184        abac_list_free(result);
185
186        result = abac_graph_postorder_credentials(ctx->graph, role);
187        size = abac_list_size(result);
188    }
189
[dc62c68]190    if (size > 0) {
191        // make the array (leave space to NULL terminate it)
[401a054]192        credentials = abac_xmalloc(sizeof(abac_credential_t *) * (size + 1));
[6d5623e]193        abac_list_foreach(result, cur,
[401a054]194            credentials[i++] = cur;
[dc62c68]195        );
[401a054]196        credentials[i] = NULL;
[90d20f0]197    }
[dc62c68]198
[6d5623e]199    abac_list_free(result);
[dc62c68]200
[401a054]201    return credentials;
[90d20f0]202}
203
204/**
205 * Frees the result of an abac query.
206 */
[401a054]207void abac_context_query_free(abac_credential_t **credentials) {
[dc62c68]208    int i;
[90d20f0]209
[401a054]210    if (credentials == NULL)
[90d20f0]211        return;
212
[401a054]213    for (i = 0; credentials[i] != NULL; ++i)
214        abac_credential_free(credentials[i]);
215    free(credentials);
[90d20f0]216}
Note: See TracBrowser for help on using the repository browser.