source: libabac/abac.hh @ ed3dc05

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

1) add more comments into abac.hh

  • Property mode set to 100644
File size: 36.3 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    static int debug=0;
12    class Role;
13    class Oset;
14/***
15ABAC::Constraint
16   This is a constraint on a data term. It holds a ptr to
17   a abac_condition_t structure
18***/
19    class Constraint {
20        public:
21/***
22   Constraint()
23     default constructor, do not use, for swig only
24   Constraint(const Constraint &)
25     copy constructor, used for cloning a constraint
26   ~Constraint()
27     default destructor
28***/
29            Constraint() : m_constraint(NULL) { }
30            Constraint(const Constraint &constraint) { 
31              m_constraint =abac_condition_dup(constraint.m_constraint);
32            }
33            ~Constraint() { 
34              if(m_constraint) abac_condition_free(m_constraint);
35            }
36/***
37   Constraint(Role &)
38     constructor that takes a constraining role
39       [role:?R[{role-constraint}]
40   Constraint(Oset &)
41     constructor that takes a constraining oset
42       [oset:?O[{oset-constraint}]
43       [urn:?F[keyid:$alpha_keyid].oset:documents([string:?P])]
44   Constraint(abac_condition_t *)
45     constructor that takes an abac_condition_t structure
46   Constraint(char *)
47     constructor that takes one of following string
48     as its vartype to set up a range constraint:
49       "integer"
50       "urn"
51       "float"
52       "boolean"
53       "time"
54       "string"
55     it should be followed with one or many of following utility
56     calls.
57***/
58            Constraint(Role& role);
59            Constraint(Oset& oset);
60            Constraint(abac_condition_t *constraint):
61              m_constraint(abac_condition_dup(constraint))
62            { }
63            Constraint(char *vartype) { 
64              m_constraint=abac_condition_create(vartype);
65            }
66/***
67   void add_constraint_integer_max(int)
68   void add_constraint_integer_min(int)
69     utility routines to setup a integer range constraint
70       [integer:?I[10 .. 20]]
71   void add_constraint_integer_target(int)
72     utility routine to setup a integer list constraint
73       [integer:?I[10,20]]
74***/
75            void add_constraint_integer_max(int val) {
76              abac_condition_add_range_integer_item(m_constraint,abac_max_item_type(),val);
77            }
78            void add_constraint_integer_min(int val) {
79              abac_condition_add_range_integer_item(m_constraint,abac_min_item_type(),val);
80            }
81            void add_constraint_integer_target(int val) {
82              abac_condition_add_range_integer_item(m_constraint,abac_target_item_type(),val);
83            }
84/***
85   void add_constraint_float_max(float)
86   void add_constraint_float_min(float)
87     utility routines to setup a float range constraint
88       [float:?F[1.0 .. 2.5]]
89   void add_constraint_float_target(float)
90     utility routine to setup a float list constraint
91       [float:?F[0.5, 2.5]]
92***/
93            void add_constraint_float_max(float val) {
94              abac_condition_add_range_float_item(m_constraint,abac_max_item_type(),val);
95            }
96            void add_constraint_float_min(float val) {
97              abac_condition_add_range_float_item(m_constraint,abac_min_item_type(),val);
98            }
99            void add_constraint_float_target(float val) {
100              abac_condition_add_range_float_item(m_constraint,abac_target_item_type(),val);
101            }
102/***
103   void add_constraint_time_max(char*)
104   void add_constraint_time_min(char*)
105     utility routines to setup a time range constraint,
106     takes quoted string values, beyond T is optional
107       [time:?M["20201101T182930"]]
108       [time:?M["20201101T"]]
109   void add_constraint_time_target(char*)
110     utility routine to setup a time list constraint
111       [time:?F["20120228T080000" .. "20120228T090000"]]
112***/
113            void add_constraint_time_max(char* val) {
114              abac_condition_add_range_time_item(m_constraint,abac_max_item_type(),val);
115            }
116            void add_constraint_time_min(char* val) {
117                abac_condition_add_range_time_item(m_constraint,abac_min_item_type(),val);
118            }
119            void add_constraint_time_target(char* val) {
120                abac_condition_add_range_time_item(m_constraint,abac_target_item_type(),val);
121            }
122/***
123   void add_constraint_urn_target(char*)
124     utility routine to setup a an urn list constraint
125       [urn:?U["fileA","http://fileB"]]
126   void add_constraint_string_target(char*)
127     utility routine to setup a a string list constraint
128       [string:?S["abc",'efg',"hij"]]
129   void add_constraint_boolean_target(char*)
130     utility routine to setup a a boolean list constraint
131       [boolean:?B['true']]
132***/
133            void add_constraint_urn_target(char* val) 
134            { abac_condition_add_range_urn_item(m_constraint,val); }
135            void add_constraint_string_target(char* val)
136            { abac_condition_add_range_string_item(m_constraint,val); }
137            void add_constraint_boolean_target(char* val)
138            { abac_condition_add_range_boolean_item(m_constraint,val); }
139/***
140   char *string() const
141     returns literal string of the constraint
142   char *typed_string() const
143     returns typed literal string of the constraint
144***/
145            char *string() const 
146            { return abac_condition_string(m_constraint); }
147            char *typed_string() const 
148            { return abac_condition_typed_string(m_constraint); }
149/***
150   abac_condition_t *constraint()
151     returns internal constraint structure
152***/
153            abac_condition_t *constraint()
154            { return m_constraint; }
155        private:
156            abac_condition_t *m_constraint;
157    };
158
159/***
160ABAC::DataTerm
161   A data term is associated with Role or Oset as a parameter that
162   maybe be instantiated, or uninstantiated but being constrained,
163   or as a principal oset term (standalone right handside of an oset
164   policy rule).  It holds a pointer to a abac_term_t structure and
165   an optional constraint that may be imposed on this data term if it
166   is indeed an unistantiated variable.
167***/
168    class DataTerm {
169        public:
170/***
171   DataTerm()
172     default constructor, do not use, for swig only
173   DataTerm(const DataTerm &)
174     copy constructor, used for cloning a data term
175   ~DataTerm()
176     default destructor
177***/
178            DataTerm() : m_term(NULL) { } // do not use: here for swig
179            DataTerm(const DataTerm &dterm) { 
180              m_term =abac_term_dup(dterm.m_term);
181              abac_condition_t *constraint=abac_term_constraint(m_term);
182              if(constraint) m_cond=new Constraint(constraint);
183                else m_cond=NULL;
184            }
185            ~DataTerm() { 
186              if(m_term) abac_term_free(m_term);
187              if(m_cond) free(m_cond);
188            }
189/*** ???
190   DataTerm(abac_term_t *)
191     constructor to make data term from abac_term_t structure
192***/
193            DataTerm(abac_term_t *term) { 
194              m_term=abac_term_dup(term);
195              abac_condition_t *constraint=abac_term_constraint(m_term);
196              if(constraint) m_cond=new Constraint(constraint);
197                else m_cond=NULL;
198            }
199/***
200   DataTerm(char*)
201     constructor to make named principal data term for the oset RHS
202   DataTerm(char*, char*, Constraint*)
203     constructor for making a variable data term or an instantiated
204     data term
205***/
206            DataTerm(char *sha) {
207              if(debug) printf("adding a Dataterm named principal(%s)\n",sha);
208              int isnamed=1;
209              int type=e_TERM_PRINCIPAL;
210              m_term=abac_term_named_create(type,sha);
211            }
212            DataTerm(char* typenm, char *name, Constraint *cond=NULL) {
213              int type=abac_verify_term_type(typenm);
214              if(debug) printf("adding a Dataterm (%s)\n",name);
215              if(type==ABAC_TERM_FAIL)
216                abac_errx(1, "DataTerm, fail to create the term");
217              if(cond) {
218                m_cond=cond;
219                m_term=abac_term_create(type,name,cond->constraint());
220                } else {
221                  m_cond=NULL;
222                  m_term=abac_term_create(type,name,NULL);
223              }
224            }
225/***
226   char *string() const
227     returns literal string of the data term
228   char *typed_string() const
229     returns typed literal string of the data term
230***/
231            char *string() const
232            { return abac_term_string(m_term); }
233            char *typed_string() const
234            { return abac_term_typed_string(m_term); }
235/***
236   bool is_time() const
237   bool is_string() const
238   bool is_urn() const
239   bool is_integer() const
240     returns true if data term is of certain type
241***/
242            bool is_time() const 
243            { return abac_term_is_time_type(m_term); }
244            bool is_string() const
245            { return abac_term_is_string_type(m_term); }
246            bool is_urn() const
247            { return abac_term_is_urn_type(m_term); }
248            bool is_integer() const 
249            { return abac_term_is_integer_type(m_term); }
250/***
251   int add_constraint(const Contraint&)
252     utiltiy routine to add a constraint to this data term
253***/
254            int add_constraint(const Constraint& cond) {
255              m_cond=new Constraint(cond);
256              abac_term_add_constraint(m_term, m_cond->constraint());
257            }
258/***
259   int type() const
260     returns subtype of the data term
261   char *name() const
262     returns the name of the data term
263***/
264            int type() const 
265            { abac_term_type(m_term); }
266            char *name() const 
267            { return abac_term_name(m_term); }
268/*** ??? value
269   char *value() const
270     Not implemented
271***/
272            char *value() const { }
273/***
274   abac_term_t *term()
275     returns internal data term structure
276   Constraint *constraint()
277     returns internal constraint structure to the data term
278***/
279            abac_term_t *term() 
280            { return m_term; }
281            Constraint *constraint()
282            { return m_cond; }
283        private:
284            abac_term_t *m_term;
285            Constraint *m_cond;
286    };
287
288
289/***
290ABAC::Role
291   A Role is role specification of a set of entitities for a principal.
292***/
293    class Role {
294        public:
295/***
296   Role()
297     default constructor, do not use, for swig only
298   Role(const Role &)
299     copy constructor, used for cloning a role
300   ~Role()
301     default destructor
302***/
303            Role() : m_role(NULL) { } // do not use: here for swig
304            Role(const Role &role) { 
305              m_role = abac_aspect_dup(role.m_role);
306            }
307            ~Role() { 
308              if (m_role) abac_aspect_free(m_role);
309            }
310/***
311   Role(abac_aspect_t*)
312     constructor that takes an abac_aspect_t structure
313   Role(char*)
314     constructor that builds a bare bone role with just principal's name
315   Role(char*, char*)
316     constructor that builds a bare bone role with just principal's name
317     and a role name
318***/
319            Role(abac_aspect_t *role): m_role(abac_aspect_dup(role))
320            { }
321            Role(char *principal_name) : 
322               m_role(abac_aspect_role_principal_create(principal_name)) 
323            { }
324            Role(char *principal_name, char *role_name) : 
325               m_role(abac_aspect_role_create(principal_name, role_name)) 
326            { }
327/***
328   bool is_principal() const
329     return true if the role is a principal object(made from
330     a data term), the right hand side of,
331       [keyid:A].role:r <- [keyid:B]
332***/
333            bool is_principal() const
334            { return abac_aspect_is_principal(m_role); }
335/***
336   bool is_linking() const
337     returns true if the role is a linking role like
338     the right hand side of,
339       [keyid:A].role:r1 <- [keyid:B].role:r2.role:r3
340***/
341            bool is_linking() const
342            { return abac_aspect_is_linking(m_role); }
343/***
344   char *string() const
345     returns literal string of the role
346   char *typed_string() const
347     returns typed literal string of the role
348***/
349            char *string() const
350            { return abac_aspect_string(m_role); }
351            char *typed_string()
352            { return abac_aspect_typed_string(m_role); }
353/***
354   char *linked_role() const
355     returns linked part of a linking role, for
356     [keyid:A].role:r1.role:r2, it returns r1
357***/
358            char *linked_role() const 
359            { return abac_aspect_linked_role_name(m_role); }
360/***
361   char *role_name() const
362     returns the role name of any role (the part after the last dot)
363     [keyid:A].role.r1.role:r2, it returns r2
364     [keyid:A].role.r1, it returns r1
365***/
366            char *role_name() const
367            { return abac_aspect_aspect_name(m_role); }
368            char *principal() const
369            { return abac_aspect_principal_name(m_role); }
370
371/***
372   int add_data_term(DataTerm&)
373     add a data term to the role
374***/
375            int add_data_term(DataTerm& d) {
376              abac_aspect_add_param(m_role, d.term());
377              return 1;
378            }
379/***
380   std::vector<DataTerm> get_data_terms(bool &)
381     return the data terms bound to this role.
382     ??? If the role is returned in a proof, these will all have values.
383***/
384            std::vector<DataTerm> get_data_terms(bool &success) {
385              abac_term_t **terms, **end;
386              int i;
387              terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_role));
388              for (i = 0; terms[i] != NULL; ++i)
389                  ;
390              end = &terms[i];
391              std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
392              abac_terms_free(terms);
393              success=1;
394              return dataterms;
395            }
396            int add_linking_data_term(DataTerm& d) {
397              abac_aspect_add_linked_param(m_role, d.term());
398              return 1;
399            }
400/***
401   std::vector<DataTerm> get_linked_data_terms(bool &)
402     return the data terms bound to this role's linking role.
403     ??? If the role is returned in a proof, these will all have values.
404***/
405            std::vector<DataTerm> get_linked_data_terms(bool &success) {
406              abac_term_t **terms, **end;
407              int i;
408              terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_role));
409              for (i = 0; terms[i] != NULL; ++i)
410                  ;
411              end = &terms[i];
412              std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
413              abac_terms_free(terms);
414              success=1;
415              return dataterms;
416            }
417/***
418   abac_aspect_t *role()
419     returns the interal libabac representation of this role
420***/
421            abac_aspect_t *role() {return m_role;}
422        private:
423            abac_aspect_t *m_role;
424    };
425
426/***
427ABAC::Oset
428   An Oset is oset specification of a set of entitities for a principal.
429***/
430    class Oset {
431        public:
432/***
433   Oset()
434     default constructor, do not use, for swig only
435   Oset(const Oset &)
436     copy constructor, used for cloning an oset
437   ~Oset()
438     default destructor
439***/
440            Oset() : m_oset(NULL) { } // do not use: here for swig
441            Oset(const Oset &oset)
442            { m_oset =abac_aspect_dup(oset.m_oset); }
443            ~Oset()
444            { if(m_oset) abac_aspect_free(m_oset); }
445/***
446   Oset(abac_aspect_t *)
447     constructor that takes abac_aspect_t structure
448   Oset(char *)
449     constructor that makes a principal oset, ie [keyid:B]
450   Oset(char *, char *)
451     constructor that makes a regular oset, ie. [keyid:B].oset:o
452   Oset(DataTerm&)
453     constructor that makes an object oset, ie. [urn:'file/fileA']
454***/
455            Oset(abac_aspect_t *oset): m_oset(abac_aspect_dup(oset)) 
456            { }
457            Oset(char *oset_name) : m_oset(abac_aspect_oset_principal_create(oset_name)) 
458            { }
459            Oset(char *principal_name, char *oset_name) : 
460               m_oset(abac_aspect_oset_create(principal_name, oset_name)) 
461            { }
462            Oset(DataTerm& d) :
463               m_oset(abac_aspect_oset_object_create(d.term())) 
464            { }
465
466/***
467   bool is_object(), ie <- [integer:10]
468     return ture if this oset is an object oset
469***/
470            bool is_object() const
471            { return abac_aspect_is_object(m_oset); }
472/***
473   bool is_principal() const
474     return true if the oset is a principal object(made from
475     a data term), the right hand side of,
476       [keyid:A].oset:o <- [keyid:B]
477***/
478            bool is_principal() const 
479            { return abac_aspect_is_principal(m_oset); }
480/***
481   bool is_linking() const
482     returns true if the oset is a linking oset like
483     the right hand side of,
484       [keyid:A].oset:o1 <- [keyid:B].role:r1.oset:o2
485***/
486            bool is_linking() const 
487            { return abac_aspect_is_linking(m_oset); }
488/***
489   char *string() const
490     returns literal string of the oset
491   char *typed_string() const
492     returns typed literal string of the oset
493***/
494            char *string() const
495            { return abac_aspect_string(m_oset); }
496            char *typed_string()
497            { return abac_aspect_typed_string(m_oset); }
498/***
499   char *linked_role() const
500     returns linked part of a linking oset, for
501     [keyid:A].role:r1.oset:o1, it returns r1
502***/
503            char *linked_role() const 
504            { return abac_aspect_linked_role_name(m_oset); }
505/***
506   char *oset_name() const
507     returns oset name,
508     [keyid:A].role:r1.oset:o1, it returns o1
509     [keyid:A].oset:o1, it returns o1
510***/
511            char *oset_name() const
512            { return abac_aspect_aspect_name(m_oset); }
513/***
514   char *principal() const
515     returns principal name,
516     [keyid:A].role:r1.oset:o1, it returns A
517***/
518            char *principal() const
519            { return abac_aspect_principal_name(m_oset); }
520/***
521   char *object() const
522     returns object's name when the oset is a principal object
523     [keyid:A].oset:values <- [integer:10], it returns 10
524***/
525            char *object() const 
526            { return abac_aspect_object_name(m_oset); }
527/***
528   int add_data_term(DataTerm&)
529     add a data term to this oset's parameter set
530     always returns 1
531***/
532            int add_data_term(DataTerm& d) {
533              abac_aspect_add_param(m_oset, d.term()); 
534              return 1;
535            }
536/***
537   std::vector<DataTerm> get_data_terms(bool &)
538     returns the data terms bound to this oset. 
539     ??? If the oset is returned in a proof, these will all have values.
540***/
541            std::vector<DataTerm> get_data_terms(bool &success) {
542              abac_term_t **terms, **end;
543              int i;
544              terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_oset));
545              for (i = 0; terms[i] != NULL; ++i)
546                  ;
547              end = &terms[i];
548              std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
549              abac_terms_free(terms);
550              success=1;
551              return dataterms;
552            }
553/***
554   int add_linking_data_term(DataTerm&)
555     add a data term to this oset's linking role's parameter set.
556     always returns 1
557***/
558            int add_linking_data_term(DataTerm& d) {
559              abac_aspect_add_linked_param(m_oset, d.term());
560              return 1;
561            }
562/***
563   std::vector<DataTerm> get_linked_data_terms(bool &)
564     returns the data terms bound to this oset's linking role. 
565     ??? If the oset is returned in a proof, these will all have values.
566***/
567            std::vector<DataTerm> get_linked_data_terms(bool &success) {
568              abac_term_t **terms, **end;
569              int i;
570              terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_oset));
571              for (i = 0; terms[i] != NULL; ++i)
572                  ;
573              end = &terms[i];
574              std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
575              abac_terms_free(terms);
576              success=1;
577              return dataterms;
578            }
579/***
580   abac_aspect_t *oset()
581     returns the internal libabac representation of the oset
582***/
583            abac_aspect_t *oset() {return m_oset;}
584        private:
585            abac_aspect_t *m_oset;
586    };
587
588
589    class ID {
590        public:
591            ID() : m_id(NULL) { } // do not use: here for swig
592            ID(abac_id_t *id): m_id(abac_id_dup(id)) 
593              { }
594            ID(abac_id_credential_t *idcred) {
595                if(idcred)
596                  m_id=abac_id_dup(abac_id_credential_id(idcred));
597                else m_id=NULL;
598              }
599            ID(const ID &id) { m_id =abac_id_dup(id.m_id); }
600            ~ID() { if(m_id) abac_id_free(m_id); }
601
602/* load an ID cert from a file
603Will throw an exception if the cert cannot be loaded */
604            ID(char *filename) {
605                m_id=abac_id_from_file(filename); 
606                if(m_id==NULL)
607                  abac_errx(1, "Id creation from filename failed");
608              }
609/* generates a new ID with the supplied CN and validity period
610   - CN must be alphanumeric and begin with a letter
611   - validity must be at least one second
612   Will throw an exception if either of the above is violated */
613            ID(char *cn, int validity) {
614                int rt=abac_id_generate(&m_id, cn, validity);
615                if(rt != ABAC_ID_SUCCESS) 
616                  abac_errx(1, "Id creation failed");
617              }
618/* loads the private key associated with the cert
619   will throw an exception if the key cannot be loaded */
620            void load_privkey(char *filename) {
621                int rt=abac_id_load_privkey_file(m_id, filename);
622                if(rt != 1) 
623                  abac_errx(1, "Failed to load private key");
624              }
625            abac_id_t *id() { return m_id; }
626
627/* returns the SHA1 keyid of the cert */
628            char *keyid() { return abac_id_keyid(m_id); }
629/* returns the CN */
630            char *name() { return abac_id_cn(m_id); }
631/* returns true if the ID has an associated private key */
632            bool has_privkey() {
633                return abac_id_has_privkey(m_id);
634              }
635/* writes a PEM-encoded cert to the file handle */
636            void write_cert(FILE *out) {
637                abac_id_write_cert(m_id, out); 
638              }
639/* writes a PEM-encoded cert to a file named out */
640            void write_cert(char *filename) {
641                FILE *out = fopen(filename, "a");
642                write_cert(out);
643                fclose(out);
644              }
645/* writes a PEM-encoded private key to the file handle
646   throws an exception if no private key is loaded */
647            void write_privkey(FILE *out) {
648                if(!has_privkey())
649                    abac_errx(1, "No privkey to write");
650                abac_id_write_privkey(m_id, out);
651              }
652/* writes a PEM-encoded private key a file named out
653   throws an exception if no private key is loaded */
654            void write_privkey(char *filename) {
655                FILE *out = fopen(filename, "a");
656                write_privkey(out);
657                fclose(out);
658              }
659/* returns a DER-encoded binary representation of the X.509 ID cert
660   associated with this ID.
661   can be passed to libabac's Context::load_id_chunk() */
662            abac_chunk_t cert_chunk() {
663                return abac_id_cert_chunk(m_id);
664              }
665            char *string() {
666                char *tmp=NULL;
667                if(has_privkey())
668                  asprintf(&tmp,"(%s,%s,y)",abac_id_name(m_id),abac_id_idtype_string(m_id));
669                  else asprintf(&tmp,"(%s,%s,n)",abac_id_name(m_id),abac_id_idtype_string(m_id));
670                return tmp;
671              }
672        public:
673            abac_id_t *m_id;
674    };
675
676
677/* N.B., The way you use this class is by instantiating the object, adding
678   subjects to it, and then baking it. Only once it's baked can you access the
679   X.509 cert. Once it's been baked you can no longer add subjects to it. */
680    class Attribute {
681        public:
682            Attribute() : m_attr(NULL) { } // do not use: here for swig
683            Attribute(abac_attribute_t *attr): m_attr(abac_attribute_dup(attr)) 
684              { }
685            Attribute(abac_credential_t *cred) {
686                m_attr=abac_attribute_dup(abac_credential_attribute(cred));
687              }
688            Attribute(const Attribute &id) { 
689                m_attr =abac_attribute_dup(id.m_attr);
690              }
691            ~Attribute() { 
692                if(m_attr) abac_attribute_free(m_attr);
693              }
694/* Create an object to be signed by the given issuer with the given role
695   and validity period
696   An exception will be thrown if:
697     - the issuer has no private key
698     - the Head is invalid
699     - the validity period is invalid (must be >= 1 second) */
700            Attribute(Role& head, int validity) {
701                int rt=abac_attribute_create(&m_attr, head.role(), NULL, validity);
702                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
703                    abac_errx(1, "attribute(role), unable to make an attribute");
704              }
705            Attribute(Oset& head, int validity) {
706                int rt=abac_attribute_create(&m_attr, head.oset(), NULL, validity);
707                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
708                    abac_errx(1, "attribute(oset), unable to make an attribute");
709              }
710            bool add_tail(Role& tail) {
711                if(abac_attribute_add_tail(m_attr, tail.role()))
712                    return 1;
713                    else return 0;
714              }
715            bool add_tail(Oset& tail) {
716                if(abac_attribute_add_tail(m_attr, tail.oset()))
717                    return 1;
718                    else return 0;
719              }
720            char *head_string() {
721                abac_aspect_t *head=abac_attribute_head(m_attr);
722                char *string=abac_aspect_string(head);
723                return string;
724              }
725            char *tail_string() {
726                abac_aspect_t *tail=abac_attribute_tail(m_attr);
727                char *string=abac_aspect_string(tail);
728                return string;
729              }
730            char *head_typed_string() {
731                abac_aspect_t *head=abac_attribute_head(m_attr);
732                char *string=abac_aspect_typed_string(head);
733                return string;
734              }
735            char *tail_typed_string() {
736                abac_aspect_t *tail=abac_attribute_tail(m_attr);
737                char *string=abac_aspect_typed_string(tail);
738                return string;
739              }
740            char *string() {
741                char *head=head_string();
742                char *tail=tail_string();
743                if(head==NULL || tail==NULL)
744                    abac_errx(1, "attribute string, head and tail can not be NULL");
745                char *tmp=NULL;
746                asprintf(&tmp,"%s<-%s",head,tail);
747                return tmp;
748              }
749            char *typed_string() {
750                char *head=head_typed_string();
751                char *tail=tail_typed_string();
752                if(head==NULL || tail==NULL)
753                    abac_errx(1, "attribute string, head and tail can not be NULL");
754                char *tmp=NULL;
755                asprintf(&tmp,"%s<-%s",head,tail);
756                return tmp;
757              }
758            const Role &role_head() {
759                abac_aspect_t *head=abac_attribute_head(m_attr);
760                static Role role=Role(head);
761                return role;
762              }
763            const Oset &oset_head() {
764                abac_aspect_t *head=abac_attribute_tail(m_attr);
765                static Oset oset=Oset(head);
766                return oset;
767              }
768            std::vector<Role> role_tails(bool &success) {
769                abac_aspect_t **tails, **end;
770                int i;
771                tails = abac_attribute_tail_vectorized(m_attr);
772                for (i = 0; tails[i] != NULL; ++i)
773                    ;
774                end = &tails[i];
775                std::vector<Role> roles = std::vector<Role>(tails, end);
776                abac_aspects_free(tails);
777                success=1;
778                return roles;
779              }
780            std::vector<Oset> oset_tails(bool &success) {
781                abac_aspect_t **tails, **end;
782                int i;
783                tails = abac_attribute_tail_vectorized(m_attr);
784                for (i = 0; tails[i] != NULL; ++i)
785                    ;
786                end = &tails[i];
787                std::vector<Oset> osets = std::vector<Oset>(tails, end);
788                success=1;
789                abac_aspects_free(tails);
790                return osets;
791              }
792            abac_attribute_t *attribute() { return m_attr; }
793
794/* Generate the cert. Call this after you've added subjects to your cert.
795   This returns false if there are no subjects
796   This will throw an exception if the cert's already been baked. */
797            bool bake() {
798                /* can not bake in ABAC_CN mode */
799                if(USE("ABAC_CN"))
800                    abac_errx(1, "bake, can not bake the cert with env(ABAC_CN) set");
801                int rt=abac_attribute_bake(m_attr);
802                if(rt!=1)
803                    abac_errx(1, "bake, can not bake the cert");
804              }
805/* Returns true iff the cert has been baked. */
806            bool baked() {
807                return abac_attribute_baked(m_attr);
808              }
809/* Write the DER-encoded X.509 attribute cert to the open file handle
810   Throws an exception if the cert isn't baked */
811            void write_cert(FILE *out) {
812                int rt= abac_attribute_write(m_attr,out);
813                if(!rt)
814                    abac_errx(1, "write, cert is not baked");
815              }
816/* Write the DER-encoded X.509 attribute cert to a file named out
817   Throws an exception if the cert isn't baked */
818            void write_cert(char *filename) {
819                FILE *out = fopen(filename, "w");
820                printf("writing to %s\n", filename);
821                write_cert(out);
822                printf("done writing to %s\n", filename);
823                fclose(out);
824              }
825/* returns a DER-encoded binary representation of the X.509 attribute
826   cert associated with this cert
827   Throws an exception if the cert isn't baked
828   the chunk can be passed to libabac's Context::load_attribute_chunk() */
829            abac_chunk_t cert_chunk() {
830                return abac_attribute_cert_chunk(m_attr);
831              }
832/* generate yap clauses and injected into db */
833            int consume() {
834              /* attribute needs to be baked */ 
835                if(!baked()) {
836                    return ABAC_ATTRIBUTE_FAIL;
837                }
838              }
839      private:
840            abac_attribute_t *m_attr;
841     };
842
843
844    class Context {
845        public:
846            Context() { m_ctx = abac_context_new(); m_abac_version=strdup("1.0"); }
847            Context(const Context &context) { 
848                m_ctx = abac_context_dup(context.m_ctx);
849                m_abac_version=strdup(context.m_abac_version);
850              }
851            ~Context() { 
852                abac_context_free(m_ctx);
853                if(m_abac_version) free(m_abac_version);
854              }
855
856/* load an identity certificate, returns:
857      ABAC_CERT_SUCCESS   successfully loaded
858      ABAC_CERT_INVALID   invalid certificate (or file not found)
859      ABAC_CERT_BAD_SIG   invalid signature */
860            void dump_yap() {
861                show_yap_db("dump_yap");
862              }
863            int load_id(ABAC::ID& id) {
864                return abac_context_load_id_id(m_ctx, id.id());
865              }
866            int load_id_file(char *filename) {
867                return abac_context_load_id_idkey_file(m_ctx, filename);
868              }
869            int load_id_file(char *filename, char *keyfilename) {
870                return abac_context_load_id_id_file_key_file(m_ctx, filename, keyfilename);
871              }
872            int load_id_chunk(abac_chunk_t cert) { 
873                return abac_context_load_id_chunk(m_ctx, cert);
874              }
875/* load an attribute certificate, returns the same values as above
876   * additionally can return ABAC_CERT_MISSING_ISSUER if the issuer
877   certificate has not been loaded */
878            int load_attribute(ABAC::Attribute& a) {
879                return abac_context_load_attribute_attribute(m_ctx, a.attribute());
880              }
881            int load_attribute_file(char *filename) { 
882                return abac_context_load_attribute_file(m_ctx, filename);
883              }
884            int load_attribute_chunk(abac_chunk_t cert) {
885                return abac_context_load_attribute_chunk(m_ctx, cert);
886              }
887/* load a directory full of certificates:
888   first: ${path}/*_ID.{der,pem} as identity certificates
889   then: ${path}/*_attr.der as attribute certificates */
890            void load_directory(char *path) {
891                abac_context_load_directory(m_ctx, path);
892              }
893/* run the query:
894       role <-?- principal
895   returns true/false in success
896   returns a proof upon success, partial proof on failure */
897/* the string version is for query that is composed by hand with SHA or
898   in non ABAC_CN mode  */
899            std::vector<Attribute> query(char *role, char *principal, bool &success) {
900                 abac_credential_t **creds, **end;
901                 int i, success_int;
902
903                 creds = abac_context_query(m_ctx, role, principal, &success_int);
904                 success = success_int;
905
906                 for (i = 0; creds[i] != NULL; ++i)
907                    ;
908
909                 end = &creds[i];
910                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
911                 if(debug) printf("query, got rules(%d)\n", i);
912
913                 abac_context_credentials_free(creds);
914
915                 return attributes;
916              }
917
918/* another way */
919            std::vector<Attribute> query(Role &role, Role &p_role, bool &success) {
920                 abac_credential_t **creds, **end;
921                 int i, success_int;
922
923                 creds = abac_context_query_with_structure(m_ctx, role.role(), p_role.role(), &success_int);
924                 success = success_int;
925
926                 for (i = 0; creds[i] != NULL; ++i)
927                    ;
928
929                 end = &creds[i];
930                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
931
932                 abac_context_credentials_free(creds);
933
934                 return attributes;
935              }
936
937            std::vector<Attribute> query(Oset &oset, Oset &p_oset, bool &success) {
938                 abac_credential_t **creds, **end;
939                 int i, success_int;
940             
941                 creds = abac_context_query_with_structure(m_ctx, oset.oset(), p_oset.oset(), &success_int);
942                 success = success_int;
943
944                 for (i = 0; creds[i] != NULL; ++i)
945                    ;
946
947                 end = &creds[i];
948                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
949                 if(debug) printf("query, returning rules(%d)\n", i);
950
951                 abac_context_credentials_free(creds);
952
953                 return attributes;
954              }
955
956/* returns a vector of all the credentials loaded in the context */
957            std::vector<Attribute> context_credentials(bool &success) {
958                abac_credential_t **creds, **end;
959                int i;
960                success = 1;
961
962                creds = abac_context_credentials(m_ctx);
963                for (i = 0; creds[i] != NULL; ++i)
964                    ;
965
966                end = &creds[i];
967                std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
968                if(debug) printf("credentials, got (%d)\n", i);
969
970                abac_context_credentials_free(creds);
971                if(debug) show_yap_db("calling from context_credentials");
972                return attributes;
973              }
974
975/* returns a vector of all the principals loaded in the context */
976            std::vector<ID> context_principals(bool &success) {
977                abac_id_credential_t **ids, **end;
978                int i;
979                success = 1;
980
981                ids = abac_context_principals(m_ctx);
982                for (i = 0; ids[i] != NULL; ++i)
983                    ;
984
985                end = &ids[i];
986                std::vector<ID> principals = std::vector<ID>(ids, end);
987                if(debug) printf("principals, got (%d)\n", i);
988
989                abac_context_principals_free(ids);
990                return principals;
991              }
992           
993            char *version() const { return m_abac_version; }
994
995        private:
996            abac_context_t *m_ctx;
997            char *m_abac_version;
998    };
999
1000    Constraint::Constraint(Role& role)
1001    { m_constraint=abac_condition_create_from_aspect(role.role()); }
1002    Constraint::Constraint(Oset &oset)
1003    { m_constraint=abac_condition_create_from_aspect(oset.oset()); }
1004}
1005
1006#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.