source: libabac/abac.hh @ 8bd77b5

mei_rt2mei_rt2_fix_1
Last change on this file since 8bd77b5 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: 23.4 KB
Line 
1#ifndef __ABAC_HH__
2#define __ABAC_HH__
3
4#include <string>
5#include <vector>
6
7namespace ABAC {
8    extern "C" {
9        #include "abac.h"
10    }
11
12    static int debug=0;
13
14    class Role;
15    class Oset;
16
17    class Constraint {
18        public:
19            Constraint() : m_constraint(NULL) { } // do not use: here for swig
20            Constraint(abac_condition_t *constraint): 
21              m_constraint(abac_condition_dup(constraint))
22              { }
23            Constraint(const Constraint &constraint) { 
24                m_constraint =abac_condition_dup(constraint.m_constraint);
25              }
26            ~Constraint() { 
27                if(m_constraint) abac_condition_free(m_constraint);
28              }
29            /* range constraint */
30            Constraint(char *constraint) {
31                m_constraint=abac_condition_from_string(constraint); 
32              }
33            /* role constraint */
34            Constraint(Role *role);
35            /* oset constraint */
36            Constraint(Oset *oset);
37            char *string() const { 
38                return abac_condition_string(m_constraint);
39              }
40            char *typed_string() const { 
41                return abac_condition_typed_string(m_constraint);
42              }
43            abac_condition_t *constraint()
44              { return m_constraint; }
45        private:
46            abac_condition_t *m_constraint;
47    };
48
49    /* XXX need to track the principal [keyid:alice] so can generate
50       the id_type_clause within attribute clause */
51    class DataTerm {
52        public:
53            DataTerm() : m_term(NULL) { } // do not use: here for swig
54            DataTerm(abac_term_t *term) { 
55                m_term=abac_term_dup(term);
56                abac_condition_t *constraint=abac_term_constraint(m_term);
57                if(constraint) m_cond=new Constraint(constraint);
58                  else m_cond=NULL;
59              }
60            DataTerm(const DataTerm &term) { 
61                m_term =abac_term_dup(term.m_term);
62                abac_condition_t *constraint=abac_term_constraint(m_term);
63                if(constraint) m_cond=new Constraint(constraint);
64                  else m_cond=NULL;
65              }
66            ~DataTerm() { 
67                if(m_term) abac_term_free(m_term);
68                if(m_cond) free(m_cond);
69              }
70
71            DataTerm(int type, char *name, Constraint *cond=NULL) {
72                if(debug) printf("adding a Dataterm (%s)\n",name);
73                if(cond) {
74                  m_cond=cond;
75                  m_term=abac_term_create(type,name,cond->constraint());
76                  } else {
77                      m_cond=NULL;
78                      m_term=abac_term_create(type,name,NULL);
79                }
80              }
81            char *string() const { 
82                return abac_term_string(m_term);
83              }
84            char *typed_string() const { 
85                return abac_term_typed_string(m_term);
86              }
87            bool is_time() const {
88                return abac_term_is_time_type(m_term);
89              }
90            bool is_string() const {
91                return abac_term_is_string_type(m_term);
92              }
93            bool is_urn() const {
94                return abac_term_is_urn_type(m_term);
95              }
96            bool is_integer() const {
97                return abac_term_is_integer_type(m_term);
98              }
99/* Add a constraint to this term. */
100            int add_constraint(Constraint& cond) {
101                m_cond=new Constraint(cond);
102                abac_term_add_constraint(m_term, m_cond->constraint());
103              }
104            int type() {
105                abac_term_type(m_term);
106              }
107            char *name() {
108                return abac_term_name(m_term);
109              }
110            char *value() {
111/* ??? value XXX */
112              }
113            Constraint *constraint() {
114                return m_cond;
115              }
116            abac_term_t *term() {
117                return m_term;
118              }
119
120        private:
121            abac_term_t *m_term;
122            Constraint *m_cond;
123    };
124
125
126    class Role {
127        public:
128            Role() : m_role(NULL) { } // do not use: here for swig
129            Role(abac_aspect_t *role): m_role(abac_aspect_dup(role))
130              { }
131            Role(char *principal_name) : 
132               m_role(abac_aspect_role_principal_create(principal_name)) 
133              { }
134            Role(char *principal_name, char *role_name) : 
135               m_role(abac_aspect_role_create(principal_name, role_name)) 
136              { }
137            Role(const Role &role) { 
138                m_role = abac_aspect_dup(role.m_role);
139              }
140            ~Role() { 
141                if (m_role) abac_aspect_free(m_role);
142              }
143            bool is_principal() const { 
144                return abac_aspect_is_principal(m_role); 
145              }
146            bool is_linking() const { 
147                return abac_aspect_is_linking(m_role); 
148              }
149            char *string() const { 
150                return abac_aspect_string(m_role);
151              }
152            char *typed_string() {
153                char* string=abac_aspect_typed_string(m_role);
154                return string;
155              }
156            char *linked_role() const { 
157                return abac_aspect_linked_role_name(m_role);
158              }
159            char *role_name() const { 
160                return abac_aspect_aspect_name(m_role);
161              }
162            char *principal() const { 
163                return abac_aspect_principal_name(m_role);
164              }
165/* Add a data term to this name. */
166            int add_data_term(DataTerm& d) {
167                abac_aspect_add_param(m_role, d.term());
168                return 1;
169              }
170/* Return the DataTerms bound to this name.  If the name is returned
171   in a proof, these will all have values. */
172            std::vector<DataTerm> get_data_terms() {
173                abac_term_t **terms, **end;
174                int i, success_int;
175                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_role));
176                for (i = 0; terms[i] != NULL; ++i)
177                    ;
178                end = &terms[i];
179                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
180                abac_terms_free(terms);
181                return dataterms;
182              }
183            int add_linking_data_term(DataTerm& d) {
184                abac_aspect_add_linked_param(m_role, d.term());
185                return 1;
186              }
187            std::vector<DataTerm> get_linked_data_terms() {
188                abac_term_t **terms, **end;
189                int i, success_int;
190                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_role));
191                for (i = 0; terms[i] != NULL; ++i)
192                    ;
193                end = &terms[i];
194                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
195                abac_terms_free(terms);
196                return dataterms;
197              }
198            abac_aspect_t *role() {return m_role;}
199        private:
200            abac_aspect_t *m_role;
201    };
202
203    class Oset {
204        public:
205            Oset() : m_oset(NULL) { } // do not use: here for swig
206            Oset(abac_aspect_t *oset): m_oset(abac_aspect_dup(oset)) 
207              { }
208            Oset(char *oset_name) : m_oset(abac_aspect_role_principal_create(oset_name)) 
209              { }
210            Oset(char *principal_name, char *oset_name) : 
211               m_oset(abac_aspect_oset_create(principal_name, oset_name)) 
212              { }
213            Oset(const Oset &oset) { 
214                m_oset =abac_aspect_dup(oset.m_oset);
215              }
216            ~Oset() { 
217                if(m_oset) abac_aspect_free(m_oset);
218              }
219            bool is_object() const { 
220                return abac_aspect_is_object(m_oset); 
221              }
222            bool is_principal() const { 
223                return abac_aspect_is_principal(m_oset); 
224              }
225            bool is_linking() const { 
226                return abac_aspect_is_linking(m_oset); 
227              }
228            char *string() const { 
229                return abac_aspect_string(m_oset);
230              }
231            char *typed_string() {
232                char* string=abac_aspect_typed_string(m_oset);
233                return string;
234              }
235            char *linked_role() const { 
236                return abac_aspect_linked_role_name(m_oset);
237              }
238            char *oset_name() const { 
239                return abac_aspect_aspect_name(m_oset);
240              }
241            char *principal() const { 
242                return abac_aspect_principal_name(m_oset);
243              }
244            char *object() const { 
245                return abac_aspect_object_name(m_oset);
246              }
247/* Add a data term to this name. */
248            int add_data_term(DataTerm& d) {
249                abac_aspect_add_param(m_oset, d.term()); 
250                return 1;
251              }
252/* Return the DataTerms bound to this name.  If the name is returned
253   in a proof, these will all have values. */
254            std::vector<DataTerm> get_data_terms() {
255                abac_term_t **terms, **end;
256                int i, success_int;
257                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_oset));
258                for (i = 0; terms[i] != NULL; ++i)
259                    ;
260                end = &terms[i];
261                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
262                abac_terms_free(terms);
263                return dataterms;
264              }
265            int add_linking_data_term(DataTerm& d) {
266                abac_aspect_add_linked_param(m_oset, d.term());
267                return 1;
268              }
269            std::vector<DataTerm> get_linked_data_terms() {
270                abac_term_t **terms, **end;
271                int i, success_int;
272                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_oset));
273                for (i = 0; terms[i] != NULL; ++i)
274                    ;
275                end = &terms[i];
276                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
277                abac_terms_free(terms);
278                return dataterms;
279              }
280            abac_aspect_t *oset() {return m_oset;}
281        private:
282            abac_aspect_t *m_oset;
283    };
284
285
286    class ID {
287        public:
288            ID() : m_id(NULL) { } // do not use: here for swig
289            ID(abac_id_t *id): m_id(abac_id_dup(id)) 
290              { }
291            ID(const ID &id) { m_id =abac_id_dup(id.m_id); }
292            ~ID() { if(m_id) abac_id_free(m_id); }
293
294/* load an ID cert from a file
295Will throw an exception if the cert cannot be loaded */
296            ID(char *filename) {
297                m_id=abac_id_from_file(filename); 
298                if(m_id==NULL)
299                  abac_errx(1, "Id creation from filename failed");
300              }
301/* generates a new ID with the supplied CN and validity period
302   - CN must be alphanumeric and begin with a letter
303   - validity must be at least one second
304   Will throw an exception if either of the above is violated */
305            ID(char *cn, int validity) {
306                int rt=abac_id_generate(&m_id, cn, validity);
307                if(rt != ABAC_ID_SUCCESS) 
308                  abac_errx(1, "Id creation failed");
309              }
310/* loads the private key associated with the cert
311   will throw an exception if the key cannot be loaded */
312            void load_privkey(char *filename) {
313                int rt=abac_id_load_privkey(m_id, filename);
314                if(rt != 1) 
315                  abac_errx(1, "Failed to load private key");
316              }
317            abac_id_t *id() { return m_id; }
318
319/* returns the SHA1 keyid of the cert */
320            char *keyid() { return abac_id_keyid(m_id); }
321/* returns the CN (the parameter passed to the constructor or the
322   CN of the cert). */
323            char *name() { return abac_id_cn(m_id); }
324/* returns true if the ID has an associated private key */
325            bool has_privkey() {
326                return abac_id_has_privkey(m_id);
327              }
328/* writes a PEM-encoded cert to the file handle */
329            void write_cert(FILE *out) {
330                abac_id_write_cert(m_id, out); 
331              }
332/* writes a PEM-encoded cert to a file named out */
333            void write_cert(char *filename) {
334                FILE *out = fopen(filename, "w");
335                write_cert(out);
336                fclose(out);
337              }
338/* writes a PEM-encoded private key to the file handle
339   throws an exception if no private key is loaded */
340            void write_privkey(FILE *out) {
341                if(!has_privkey())
342                    abac_errx(1, "No privkey to write");
343                abac_id_write_privkey(m_id, out);
344              }
345/* writes a PEM-encoded private key a file named out
346   throws an exception if no private key is loaded */
347            void write_privkey(char *filename) {
348                FILE *out = fopen(filename, "w");
349                write_privkey(out);
350                fclose(out);
351              }
352/* returns a DER-encoded binary representation of the X.509 ID cert
353   associated with this ID.
354   can be passed to libabac's Context::load_id_chunk() */
355            abac_chunk_t cert_chunk() {
356                return abac_id_cert_chunk(m_id);
357              }
358        public:
359            abac_id_t *m_id;
360    };
361
362
363/* N.B., The way you use this class is by instantiating the object, adding
364   subjects to it, and then baking it. Only once it's baked can you access the
365   X.509 cert. Once it's been baked you can no longer add subjects to it. */
366    class Attribute {
367        public:
368            Attribute() : m_attr(NULL) { } // do not use: here for swig
369            Attribute(abac_attribute_t *attr): m_attr(abac_attribute_dup(attr)) 
370              { }
371            Attribute(abac_credential_t *cred) {
372                m_attr=abac_attribute_dup(abac_credential_attribute(cred));
373              }
374            Attribute(const Attribute &id) { 
375                m_attr =abac_attribute_dup(id.m_attr);
376              }
377            ~Attribute() { 
378                if(m_attr) abac_attribute_free(m_attr);
379              }
380/* Create an object to be signed by the given issuer with the given role
381   and validity period
382   An exception will be thrown if:
383     - the issuer has no private key
384     - the Head is invalid
385     - the validity period is invalid (must be >= 1 second) */
386            Attribute(Role& head, int validity) {
387                int rt=abac_attribute_create(&m_attr, head.role(), NULL, validity);
388                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
389                    abac_errx(1, "attribute(role), unable to make an attribute");
390              }
391            Attribute(Oset& head, int validity) {
392                int rt=abac_attribute_create(&m_attr, head.oset(), NULL, validity);
393                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
394                    abac_errx(1, "attribute(oset), unable to make an attribute");
395              }
396            bool add_tail(Role& tail) {
397                if(abac_attribute_add_tail(m_attr, tail.role()))
398                    return 1;
399                    else return 0;
400              }
401            bool add_tail(Oset& tail) {
402                if(abac_attribute_add_tail(m_attr, tail.oset()))
403                    return 1;
404                    else return 0;
405              }
406            char *head_string() {
407                abac_aspect_t *head=abac_attribute_head(m_attr);
408                char *string=abac_aspect_string(head);
409                return string;
410              }
411            char *tail_string() {
412                abac_aspect_t *tail=abac_attribute_tail(m_attr);
413                char *string=abac_aspect_string(tail);
414                return string;
415              }
416            char *head_typed_string() {
417                abac_aspect_t *head=abac_attribute_head(m_attr);
418                char *string=abac_aspect_typed_string(head);
419                return string;
420              }
421            char *tail_typed_string() {
422                abac_aspect_t *tail=abac_attribute_tail(m_attr);
423                char *string=abac_aspect_typed_string(tail);
424                return string;
425              }
426            char *string() {
427                char *head=head_string();
428                char *tail=tail_string();
429                if(head==NULL || tail==NULL)
430                    abac_errx(1, "attribute string, head and tail can not be NULL");
431                char *tmp=NULL;
432                asprintf(&tmp,"%s<-%s",head,tail);
433                return tmp;
434              }
435            char *typed_string() {
436                char *head=head_typed_string();
437                char *tail=tail_typed_string();
438                if(head==NULL || tail==NULL)
439                    abac_errx(1, "attribute string, head and tail can not be NULL");
440                char *tmp=NULL;
441                asprintf(&tmp,"%s<-%s",head,tail);
442                return tmp;
443              }
444            const Role &role_head() {
445                abac_aspect_t *head=abac_attribute_head(m_attr);
446                static Role role=Role(head);
447                return role;
448              }
449            const Oset &oset_head() {
450                abac_aspect_t *head=abac_attribute_tail(m_attr);
451                static Oset oset=Oset(head);
452                return oset;
453              }
454            std::vector<Role> role_tails() {
455                abac_aspect_t **tails, **end;
456                int i, success_int;
457                char * string=abac_aspect_string(abac_attribute_tail(m_attr));
458                printf("XXX %s XXX\n",string);
459                tails = abac_attribute_tail_vectorized(m_attr);
460                for (i = 0; tails[i] != NULL; ++i)
461                    ;
462                end = &tails[i];
463                std::vector<Role> roles = std::vector<Role>(tails, end);
464                abac_aspects_free(tails);
465                return roles;
466              }
467            std::vector<Oset> oset_tails() {
468                abac_aspect_t **tails, **end;
469                int i, success_int;
470                tails = abac_attribute_tail_vectorized(m_attr);
471                for (i = 0; tails[i] != NULL; ++i)
472                    ;
473                end = &tails[i];
474                std::vector<Oset> osets = std::vector<Oset>(tails, end);
475                abac_aspects_free(tails);
476                return osets;
477              }
478            abac_attribute_t *attribute() { return m_attr; }
479
480/* Generate the cert. Call this after you've added subjects to your cert.
481   This returns false if there are no subjects
482   This will throw an exception if the cert's already been baked. */
483            bool bake() {
484                int rt=abac_attribute_bake(m_attr);
485                if(rt!=1)
486                    abac_errx(1, "bake, can not bake the cert");
487              }
488/* Returns true iff the cert has been baked. */
489            bool baked() {
490                return abac_attribute_baked(m_attr);
491              }
492/* Write the DER-encoded X.509 attribute cert to the open file handle
493   Throws an exception if the cert isn't baked */
494            void write_cert(FILE *out) {
495                int rt= abac_attribute_write(m_attr,out);
496                if(!rt)
497                    abac_errx(1, "write, cert is not baked");
498              }
499/* Write the DER-encoded X.509 attribute cert to a file named out
500   Throws an exception if the cert isn't baked */
501            void write_cert(char *filename) {
502                FILE *out = fopen(filename, "w");
503                write_cert(out);
504                fclose(out);
505              }
506/* returns a DER-encoded binary representation of the X.509 attribute
507   cert associated with this cert
508   Throws an exception if the cert isn't baked
509   the chunk can be passed to libabac's Context::load_attribute_chunk() */
510            abac_chunk_t cert_chunk() {
511                return abac_attribute_cert_chunk(m_attr);
512              }
513      private:
514            abac_attribute_t *m_attr;
515     };
516
517
518    class Context {
519        public:
520            Context() { m_ctx = abac_context_new(); m_abac_version=strdup("1.0"); }
521            Context(const Context &context) { 
522                m_ctx = abac_context_dup(context.m_ctx);
523                m_abac_version=strdup(context.m_abac_version);
524              }
525            ~Context() { 
526                abac_context_free(m_ctx);
527                if(m_abac_version) free(m_abac_version);
528              }
529
530/* load an identity certificate, returns:
531      ABAC_CERT_SUCCESS   successfully loaded
532      ABAC_CERT_INVALID   invalid certificate (or file not found)
533      ABAC_CERT_BAD_SIG   invalid signature */
534            int load_id(ABAC::ID& id) {
535                return abac_context_load_id_id(m_ctx, id.id());
536              }
537            int load_id_file(char *filename) {
538                return abac_context_load_id_file(m_ctx, filename);
539              }
540            int load_id_chunk(abac_chunk_t cert) { 
541                return abac_context_load_id_chunk(m_ctx, cert);
542              }
543/* load an attribute certificate, returns the same values as above
544   * additionally can return ABAC_CERT_MISSING_ISSUER if the issuer
545   certificate has not been loaded */
546            int load_attribute(ABAC::Attribute& a) {
547                return abac_context_load_attribute_attribute(m_ctx, a.attribute());
548              }
549            int load_attribute_file(char *filename) { 
550                return abac_context_load_attribute_file(m_ctx, filename);
551              }
552            int load_attribute_chunk(abac_chunk_t cert) {
553                return abac_context_load_attribute_chunk(m_ctx, cert);
554              }
555/* load a directory full of certificates:
556   first: ${path}/*_ID.{der,pem} as identity certificates
557   then: ${path}/*_attr.der as attribute certificates */
558            void load_directory(char *path) {
559                abac_context_load_directory(m_ctx, path);
560              }
561/* run the query:
562       role <-?- principal
563   returns true/false in success
564   returns a proof upon success, partial proof on failure */
565            std::vector<Attribute> query(char *role, char *principal, bool &success) {
566                 abac_credential_t **creds, **end;
567                 int i, success_int;
568
569                 creds = abac_context_query(m_ctx, role, principal, &success_int);
570                 success = success_int;
571
572                 for (i = 0; creds[i] != NULL; ++i)
573                    ;
574
575                 end = &creds[i];
576                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
577                 if(debug) printf("rules, got (%d)\n", i);
578
579                 abac_context_credentials_free(creds);
580
581                 return attributes;
582              }
583
584/* returns a vector of all the credentials loaded in the context */
585            std::vector<Attribute> context_credentials(bool &success) {
586                abac_credential_t **creds, **end;
587                int i;
588                success = 1;
589
590                creds = abac_context_credentials(m_ctx);
591                for (i = 0; creds[i] != NULL; ++i)
592                    ;
593
594                end = &creds[i];
595                std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
596                if(debug) printf("credentials, got (%d)\n", i);
597
598                abac_context_credentials_free(creds);
599                return attributes;
600              }
601           
602            char *version() const { return m_abac_version; }
603
604        private:
605            abac_context_t *m_ctx;
606            char *m_abac_version;
607    };
608
609    Constraint::Constraint(Role *role)
610    { m_constraint=abac_condition_from_aspect(role->role()); }
611    Constraint::Constraint(Oset *oset)
612    { m_constraint=abac_condition_from_aspect(oset->oset()); }
613}
614
615#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.