source: libabac/abac_attribute.c @ 13c9479

mei_rt2mei_rt2_fix_1
Last change on this file since 13c9479 was 8bd77b5, checked in by Mei <mei@…>, 12 years ago

1) convert parser and libabac to use id cred and attr cred like

creddy (move those 2 files to libabac).

2) fix up abac.hh to work with expanded libabac. can now build

structure from python script

3) redid the credential dump using the internal credential table

instead of depending on a search in db.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1
2/**
3**  abac_attribute.c
4**/
5
6#include <assert.h>
7#include <ctype.h>
8#include <string.h>
9#include <time.h>
10#include <err.h>
11
12#include "abac_internal.h"
13#include "abac_util.h"
14
15#define SHA1_LENGTH 40
16
17extern char* abac_encode_string(char*);
18
19static int debug=0;
20
21struct _abac_attribute_t {
22    abac_id_t *issuer_id; 
23    abac_aspect_t *head;
24    abac_aspect_t *tail;
25    int validity;
26    certificate_t *cert; // NULL until baked
27    certificate_t *issuer_cert;
28
29    int refcount;
30};
31
32/********************************************************************/
33static char *_get_cred_encoding(abac_attribute_t *ptr)
34{
35    char *encoding=NULL;
36 
37    /* must have a head aspect and tail aspect */
38    assert(ptr->head != NULL);
39    assert(ptr->tail != NULL);
40
41    char *head_string=abac_aspect_typed_string_with_condition(ptr->head);
42    char *tail_string=abac_aspect_typed_string_with_condition(ptr->tail);
43
44    asprintf(&encoding,"%s<-%s", head_string,tail_string);
45    char* base64_encoding=abac_encode_string(encoding);
46
47    if(debug) printf("XXX abac_attribute_bake (%s)\n", encoding);
48
49    free(encoding);
50    free(head_string);
51    free(tail_string);
52    return base64_encoding;
53}
54
55/********************************************************************/
56abac_attribute_t *abac_attribute_new(abac_id_t *issuer, certificate_t *cert,
57certificate_t *issuer_cert)
58{
59    abac_attribute_t *ptr = abac_xmalloc(sizeof(abac_attribute_t));
60    ptr->issuer_id = abac_id_dup(issuer);
61    ptr->head = NULL;
62    ptr->tail = NULL;
63    ptr->validity= 365 * 86400; // default
64    ptr->cert=cert; // already baked..
65    ptr->issuer_cert=issuer_cert;
66    ptr->refcount=1;
67
68    return ptr;
69}
70
71// validity is measured in seconds (as of 0.2.0)
72int abac_attribute_create(abac_attribute_t **ret, 
73abac_aspect_t *head, abac_aspect_t *tail, int validity)
74{
75    abac_id_t *issuer_id=abac_aspect_get_issuer_id(head);
76    char *name=abac_aspect_aspect_name(head);
77
78/* XXX ????
79    if (abac_id_privkey(issuer_id) == NULL)
80        return ABAC_ATTRIBUTE_ISSUER_NOKEY;
81*/
82    if (!abac_validate_clean_aspect_name(name))
83        return ABAC_ATTRIBUTE_INVALID_ROLE;
84    if (validity < 0)
85        return ABAC_ATTRIBUTE_INVALID_VALIDITY;
86
87    abac_attribute_t *ptr = abac_xmalloc(sizeof(abac_attribute_t));
88    ptr->issuer_id = abac_id_dup(issuer_id);
89    ptr->head = abac_aspect_dup(head);
90    ptr->tail = (tail!=NULL) ? abac_aspect_dup(tail):NULL;
91    ptr->validity=(validity==0?(365 * 86400):validity);
92
93    // NULL until baked
94    ptr->cert=NULL;
95    ptr->issuer_cert=NULL;
96    ptr->refcount=1;
97    *ret = ptr;
98    return ABAC_ATTRIBUTE_SUCCESS;
99}
100
101// validity is measured in seconds (as of 0.2.0)
102int abac_attribute_create_creddy(abac_attribute_t **ret, abac_id_t *issuer, 
103abac_aspect_t *head_aspect, abac_aspect_t *tail_aspect, char *name, int validity)
104{
105    if (abac_id_privkey(issuer) == NULL)
106        return ABAC_ATTRIBUTE_ISSUER_NOKEY;
107    if (!abac_validate_clean_aspect_name(name))
108        return ABAC_ATTRIBUTE_INVALID_ROLE;
109    if (validity < 0)
110        return ABAC_ATTRIBUTE_INVALID_VALIDITY;
111
112    abac_attribute_t *ptr = abac_xmalloc(sizeof(abac_attribute_t));
113    ptr->issuer_id = abac_id_dup(issuer);
114
115    ptr->head=head_aspect;
116    ptr->tail=tail_aspect;
117    ptr->validity = validity;
118
119    // NULL until baked
120    ptr->cert = NULL;
121    ptr->issuer_cert = NULL;
122    *ret = ptr;
123    return ABAC_ATTRIBUTE_SUCCESS;
124}
125
126int abac_attribute_bake(abac_attribute_t *ptr) {
127    assert(ptr);
128
129    char *cred_encoding = _get_cred_encoding(ptr);
130
131    // create attribute cert
132    time_t not_before = time(NULL);
133    time_t not_after = not_before + ptr->validity;
134    chunk_t serial = abac_generate_serial();
135
136    certificate_t *attr_cert = lib->creds->create(lib->creds,
137        CRED_CERTIFICATE, CERT_X509_AC,
138        BUILD_CERT, abac_id_cert(ptr->issuer_id),
139        BUILD_NOT_BEFORE_TIME, not_before,
140        BUILD_NOT_AFTER_TIME, not_after,
141        BUILD_SERIAL, serial,
142        BUILD_IETF_GROUP_ATTR, cred_encoding,
143        BUILD_SIGNING_CERT, abac_id_cert(ptr->issuer_id),
144        BUILD_SIGNING_KEY, abac_id_privkey(ptr->issuer_id),
145        BUILD_END
146    );
147    if (attr_cert == NULL)
148        return 0;
149
150    ptr->cert = attr_cert;
151    ptr->issuer_cert= attr_cert->get_ref(attr_cert);
152 
153    free(cred_encoding);
154    free(serial.ptr);
155    return 1;
156}
157
158abac_chunk_t abac_attribute_cert_chunk(abac_attribute_t *ptr) {
159    assert(ptr->cert);
160    chunk_t encoding = ptr->cert->get_encoding(ptr->cert);
161    abac_chunk_t ret = { encoding.ptr, encoding.len };
162    return ret;
163}
164
165int abac_attribute_baked(abac_attribute_t *ptr) {
166    return ptr->cert != NULL;
167}
168
169// returns 0 if the cert hasn't been baked
170int abac_attribute_write(abac_attribute_t *ptr, FILE *out) {
171    assert(ptr != NULL);
172
173    if (ptr->cert == NULL)
174        return 0;
175
176    // write to file
177    chunk_t encoding = ptr->cert->get_encoding(ptr->cert);
178    fwrite(encoding.ptr, encoding.len, 1, out);
179    free(encoding.ptr);
180
181    return 1;
182}
183
184abac_attribute_t *abac_attribute_dup(abac_attribute_t *ptr)
185{
186    assert(ptr);
187    ++ptr->refcount;
188    return ptr;
189}
190
191void abac_attribute_free(abac_attribute_t *ptr) {
192    int i;
193
194    if (ptr == NULL)
195        return;
196
197    --ptr->refcount;
198    if (ptr->refcount > 0)
199        return;
200
201    if(ptr->issuer_id) abac_id_free(ptr->issuer_id);
202    if(ptr->head) abac_aspect_free(ptr->head);
203    if(ptr->tail) abac_aspect_free(ptr->tail);
204
205    if(ptr->cert) DESTROY_IF(ptr->cert);
206    if(ptr->issuer_cert) DESTROY_IF(ptr->issuer_cert);
207
208    free(ptr);
209}
210
211/********************************************************************/
212certificate_t *abac_attribute_issuer_cert(abac_attribute_t *ptr)
213{
214   assert(ptr);
215   return ptr->issuer_cert;
216}
217
218abac_aspect_t *abac_attribute_head(abac_attribute_t *ptr)
219{
220    assert(ptr);
221    return ptr->head;
222}
223
224abac_attribute_t *abac_attribute_set_head(abac_attribute_t *ptr, abac_aspect_t *head)
225{
226    assert(ptr);
227    ptr->head=head;
228    return ptr;
229}
230
231abac_aspect_t *abac_attribute_tail(abac_attribute_t *ptr)
232{
233    assert(ptr);
234    return ptr->tail;
235}
236
237abac_attribute_t *abac_attribute_add_tail(abac_attribute_t *ptr, abac_aspect_t *tail)
238{
239    assert(ptr);
240    assert(tail);
241
242    /* type of head and tail has to match */
243    abac_aspect_t *head=abac_attribute_head(ptr);
244    if(abac_aspect_is_intersecting(tail)) {
245        if(debug) {
246            printf("tail is intersection \n");
247            printf("tail is (%s)\n", abac_aspect_string_with_condition(tail));
248        }
249        if(abac_aspect_intersecting_aspect_type(tail) != abac_aspect_aspect_type(head))
250            errx(1, "head and tail's aspect type does not match");
251        } else {
252            if(abac_aspect_aspect_type(head) != abac_aspect_aspect_type(tail)) {
253                if(debug) {
254                    printf("head->(%s)\n",abac_aspect_type_string(head));
255                    printf("tail->(%s)\n",abac_aspect_type_string(tail));
256                    printf("tail is (%s)\n", abac_aspect_string_with_condition(tail));
257                }
258                errx(1, "head and tail's aspect type does not match");
259            }
260    }
261
262    /* special case.. if there is a tail there already and it is not an intersecting
263       tail, need to turn this into an intersecting tails */
264    if(ptr->tail == NULL) {
265        ptr->tail=abac_aspect_dup(tail);
266        } else {
267            if(abac_aspect_is_intersecting(ptr->tail)) {
268                abac_aspect_add_intersecting_aspect(ptr->tail, tail);
269                } else {
270    /* special case.. if there is a tail there already and it is not an intersecting
271       tail, need to turn this into an intersecting tails */
272                    abac_aspect_t *nptr=abac_aspect_intersection_new(ptr->tail);
273                    abac_aspect_add_intersecting_aspect(nptr, tail);
274                    ptr->tail=nptr;
275            }
276    }
277    return ptr;
278}
279
280certificate_t *abac_attribute_cert(abac_attribute_t *ptr)
281{
282    assert(ptr);
283    return ptr->cert;
284}
285
286int abac_attribute_lastone(abac_attribute_t *ptr)
287{
288    assert(ptr);
289    if(ptr->refcount == 1)
290        return 1;
291    return 0;
292}
293
294
295abac_aspect_t **abac_attribute_tail_vectorized(abac_attribute_t *ptr)
296{
297    abac_aspect_t **tails=NULL;
298    abac_aspect_t *tail=ptr->tail;
299    abac_list_t *list=NULL;
300    int cnt=0;
301    if(tail != NULL) {
302        if(!abac_aspect_is_intersecting(tail)) {
303            tails = abac_xmalloc(sizeof(abac_aspect_t *) * 2);
304            tails[0] = abac_aspect_dup(tail);
305            tails[1] = NULL;
306            if(debug) {
307               printf("abac_attribute_tail_vectorized, only 1 tail\n");
308            }
309            return tails;
310            } else {
311                abac_list_t *list=abac_aspect_prereqs(tail);
312                cnt=abac_list_size(list);
313        }
314    }
315    // make the array (leave space to NULL terminate it)
316    //      n.b., even if the list is empty, we still return an array that
317    //            only contains the NULL terminator
318    tails = abac_xmalloc(sizeof(abac_aspect_t *) * (cnt + 1));
319    abac_aspect_t  *cur;
320    int i = 0;
321    if(i<cnt) {
322        abac_list_foreach(list, cur,
323            tails[i++] = abac_aspect_dup(cur);
324        );
325    }
326    tails[i] = NULL;
327    if(debug)
328        printf("abac_attribute_tail_vectorized, %d tails\n", cnt);
329    return tails;
330}
331
332void abac_aspects_free(abac_aspect_t **aspects)
333{
334    /* always null terminating */
335    assert(aspects);
336    int i;
337    for (i = 0; aspects[i] != NULL; ++i) {
338        abac_aspect_free(aspects[i]);
339    }
340    free(aspects);
341}
Note: See TracBrowser for help on using the repository browser.