#ifndef __ABAC_HH__ #define __ABAC_HH__ #include #include namespace ABAC { extern "C" { #include "abac.h" } static int debug=0; class Role; class Oset; class ID; /*** ABAC::dump_yap_db() Dump the complete yap prolog database (C:show_yap_db) ABAC::dump_debug_info() Dump debug info on whole session (C:show_debug_info) ***/ void dump_yap_db() { show_yap_db("dump_yap"); } void dump_debug_info(const char *msg) { show_debug_info(msg); } /*** ABAC::Constraint Constraint on a data term. There are 3 types: - Role constraint on a principal - Oset constraint on a principal, or a data object - Range/List constraint on a data object It holds a ptr to a abac_condition_t structure ***/ class Constraint { public: /*** f Constraint() default constructor, do not use, for swig only f Constraint(const Constraint &) copy constructor, used for cloning a constraint (C:abac_condition_dup) f ~Constraint() default destructor (C:abac_condition_free) ***/ Constraint() : m_constraint(NULL) { } Constraint(const Constraint &constraint) { m_constraint=abac_condition_dup(constraint.m_constraint); } ~Constraint() { if(m_constraint) abac_condition_free(m_constraint); } /*** f Constraint(Role &) constructor that takes a constraining role [role:?R[{role-constraint}] (C:abac_constraint_from_role) f Constraint(Oset &) constructor that takes a constraining oset [oset:?O[{oset-constraint}] [urn:?F[keyid:$alpha_keyid].oset:documents([string:?P])] (C:abac_constraint_from_oset) f Constraint(char *) constructor that takes one of following string as its vartype to set up a range constraint: "integer" "urn" "float" "boolean" "time" "string" it should be followed with one or many of following utility calls. (C:abac_constraint_create) ***/ Constraint(Role& role); /* defined later in the class */ Constraint(Oset& oset); /* defined later in the class */ Constraint(char *vartype) { m_constraint=abac_constraint_create(vartype); } /*ii** f Constraint(abac_condition_t *) internal constructor that takes an abac_condition_t structure (C:abac_condition_dup) **ii*/ Constraint(abac_condition_t *constraint): m_constraint(abac_condition_dup(constraint)) { } /*** f void constraint_add_integer_max(int) (C:abac_constraint_add_integer_max) void constraint_add_integer_min(int) utility routines to setup a integer range constraint [integer:?I[10 .. 20]] (C:abac_constraint_add_integer_min) f void constraint_add_integer_target(int) utility routine to setup a integer list constraint [integer:?I[10,20]] (C:abac_constraint_add_integer_target) ***/ void constraint_add_integer_max(int val) { abac_constraint_add_integer_max(m_constraint,val); } void constraint_add_integer_min(int val) { abac_constraint_add_integer_min(m_constraint,val); } void constraint_add_integer_target(int val) { abac_constraint_add_integer_target(m_constraint,val); } /*** f void constraint_add_float_max(float) (C:abac_constraint_add_float_max) void constraint_add_float_min(float) utility routines to setup a float range constraint [float:?F[1.0 .. 2.5]] (C:abac_constraint_add_float_min) f void constraint_add_float_target(float) utility routine to setup a float list constraint [float:?F[0.5, 2.5]] (C:abac_constraint_add_float_target) ***/ void constraint_add_float_max(float val) { abac_constraint_add_float_max(m_constraint,val); } void constraint_add_float_min(float val) { abac_constraint_add_float_min(m_constraint,val); } void constraint_add_float_target(float val) { abac_constraint_add_float_target(m_constraint,val); } /*** f void constraint_add_time_max(char*) (C:abac_constraint_add_time_max) void constraint_add_time_min(char*) utility routines to setup a time range constraint, takes quoted string values, beyond T is optional [time:?F["20120228T" .. "20120228T090000"]] (C:abac_constraint_add_time_min) f void constraint_add_time_target(char*) utility routine to setup a time list constraint [time:?M["20201101T182930","20201101T"]] (C:abac_constraint_add_time_target) ***/ void constraint_add_time_max(char* val) { abac_constraint_add_time_max(m_constraint,val); } void constraint_add_time_min(char* val) { abac_constraint_add_time_min(m_constraint,val); } void constraint_add_time_target(char* val) { abac_constraint_add_time_target(m_constraint,val); } /*** f void constraint_add_urn_target(char*) utility routine to setup a an urn list constraint [urn:?U["fileA","http://fileB"]] (C:abac_constraint_add_urn_target) f void constraint_add_string_target(char*) utility routine to setup a a string list constraint [string:?S["abc",'efg',"hij"]] (C:abac_constraint_add_string_target) f void constraint_add_boolean_target(char*) utility routine to setup a a boolean list constraint [boolean:?B['true']] (C:abac_constraint_add_boolean_target) ***/ void constraint_add_urn_target(char* val) { abac_constraint_add_urn_target(m_constraint,val); } void constraint_add_string_target(char* val) { abac_constraint_add_string_target(m_constraint,val); } void constraint_add_boolean_target(char* val) { abac_constraint_add_boolean_target(m_constraint,val); } /*** f char *string() const returns literal string of the constraint (C:abac_constraint_string) f char *typed_string() const returns typed literal string of the constraint (C:abac_constraint_typed_string) ***/ char *string() const { return abac_constraint_string(m_constraint); } char *typed_string() const { return abac_constraint_typed_string(m_constraint); } /*ii** f abac_condition_t *constraint() internal returns internal constraint structure (S:abac_condition_t) **ii*/ abac_condition_t *constraint() { return m_constraint; } private: abac_condition_t *m_constraint; }; /*** ABAC::DataTerm A data term is associated with Role or Oset as a parameter that maybe be instantiated, or uninstantiated but being constrained, or as a principal oset term (standalone right handside of an oset policy rule). It holds a pointer to a abac_term_t structure. Types of data terms are: "integer" "urn" "float" "boolean" "string" "time" "principal" "anonymous" "this" ***/ class DataTerm { public: /*** f DataTerm() default constructor, do not use, for swig only f DataTerm(const DataTerm &) copy constructor, used for cloning a data term (C:abac_term_dup) f ~DataTerm() default destructor (C:abac_term_free) ***/ DataTerm() : m_term(NULL) { } // do not use: here for swig DataTerm(const DataTerm &dterm) { m_term=abac_term_dup(dterm.m_term); } ~DataTerm() { if(m_term) abac_term_free(m_term); } /*ii** f DataTerm(abac_term_t *) internal constructor to make data term from abac_term_t structure (C:abac_term_dup) **ii*/ DataTerm(abac_term_t *term) { m_term=abac_term_dup(term); } /*** f DataTerm(char*) constructor to make named principal data term for the oset RHS if "this" is supplied, a term with tyep=e_TERM_THIS is created if "anonymous" is supplied, a term with type=e_TERM_ANONYMOUS is created (C:abac_term_named_create) f DataTerm(const ID&) constructor to make named principal data term for parameter term (C:abac_term_id_create) f DataTerm(char*, char*, Constraint*) constructor for making a variable data term (C:abac_term_create) f DataTerm(char*, char*) constructor for making an instantiated data term (C:abac_term_create) ***/ DataTerm(char *name) { if(debug) printf("adding a Dataterm named principal(%s)\n",name); m_term=abac_term_named_create(name); } DataTerm(ID& id); /* defined later in the class */ DataTerm(char* typenm, char *name, Constraint *cond) { if(debug) printf("adding a Dataterm (%s)\n",name); m_term=abac_term_create(typenm,name,cond->constraint()); } DataTerm(char* typenm, char *name) { if(debug) printf("adding a Dataterm (%s)\n",name); m_term=abac_term_create(typenm,name,NULL); } /*** f char *string() const returns literal string of the data term (C:abac_term_string) f char *typed_string() const returns typed literal string of the data term (C:abac_term_typed_string) ***/ char *string() const { return abac_term_string(m_term); } char *typed_string() const { return abac_term_typed_string(m_term); } /*** f bool term_is_time() const (C:abac_term_is_time) bool term_is_string() const (C:abac_term_is_string) bool term_is_urn() const (C:abac_term_is_urn) bool term_is_integer() const (C:abac_term_is_integer) returns true if data term is of certain type ***/ bool term_is_time() const { return abac_term_is_time(m_term); } bool term_is_string() const { return abac_term_is_string(m_term); } bool term_is_urn() const { return abac_term_is_urn(m_term); } bool term_is_integer() const { return abac_term_is_integer(m_term); } /*** f int term_add_constraint(Contraint&) utiltiy routine to add a constraint to this data term (C:abac_term_add_constraint) ***/ int term_add_constraint(Constraint& cond) { abac_term_add_constraint(m_term, cond.constraint()); return 1; } /*** f int term_type() const returns subtype of the data term (C:abac_term_type) f char *term_name() const returns the name of the data term (C:abac_term_name) ***/ int term_type() const { abac_term_type(m_term); } char *term_name() const { return abac_term_name(m_term); } /*ii** f abac_term_t *term() returns abac_term_t term structure (S:abac_term_t) **ii*/ abac_term_t *term() { return m_term; } private: abac_term_t *m_term; }; /*** ABAC::Role A Role is role specification of a set of entitities for a principal ***/ class Role { public: /*** f Role() default constructor, do not use, for swig only f Role(const Role &) copy constructor, used for cloning a role (C:abac_aspect_dup) f ~Role() default destructor (C:abac_aspect_free) ***/ Role() : m_role(NULL) { } // do not use: here for swig Role(const Role &role) { m_role = abac_aspect_dup(role.m_role); } ~Role() { if (m_role) abac_aspect_free(m_role); } /*ii** f Role(abac_aspect_t*) constructor that takes an abac_aspect_t structure (C:abac_aspect_dup) **ii*/ Role(abac_aspect_t *role): m_role(abac_aspect_dup(role)) { } /*** f Role(char*) constructor that builds a bare bone role with just principal's name (C:abac_role_principal_create) f Role(char*, char*) constructor that builds a bare bone role with just principal's name and a role name (C:abac_role_create) f Role(char*, char*, char*) constructor that builds a bare bone role with just principal's name and a linking role name and a role name (C:abac_role_linked_create) ***/ Role(char *principal_name) : m_role(abac_role_principal_create(principal_name)) { } Role(char *principal_name, char *role_name) : m_role(abac_role_create(principal_name, role_name)) { } Role(char *principal_name, char *linked_role_name, char *role_name) : m_role(abac_role_linked_create(principal_name, linked_role_name,role_name)) { } /*** f bool role_is_principal() const return true if the role is a principal object(made from a data term), the right hand side of, [keyid:A].role:r <- [keyid:B] (C:abac_role_is_principal) ***/ bool role_is_principal() const { return abac_role_is_principal(m_role); } /*** f bool role_is_linking() const returns true if the role is a linking role like the right hand side of, [keyid:A].role:r1 <- [keyid:B].role:r2.role:r3 (C:abac_role_is_linking) ***/ bool is_linking() const { return abac_role_is_linking(m_role); } /*** f char *string() const returns literal string of the role (C:abac_role_string) f char *typed_string() const returns typed literal string of the role (C:abac_role_typed_string) ***/ char *string() const { return abac_role_string(m_role); } char *typed_string() { return abac_role_typed_string(m_role); } /*** f char *role_linked_role() const returns linked part of a linking role, for [keyid:A].role:r1.role:r2, it returns r1 (C:abac_role_linked_role) ***/ char *role_linked_role() const { return abac_role_linked_role(m_role); } /*** f char *role_name() const returns the role name of any role (the part after the last dot) [keyid:A].role.r1.role:r2, it returns r2 [keyid:A].role.r1, it returns r1 (C:abac_role_name) f char *role_principal() const returns the principal of role (the part before the first dot) [keyid:A].role.r1, it returns A (C:abac_role_principal) ***/ char *role_name() const { return abac_role_name(m_role); } char *role_principal() const { return abac_role_principal(m_role); } /*** f void role_add_data_term(DataTerm&) add a data term to the role (C:abac_role_add_data_term) ***/ void role_add_data_term(DataTerm& d) { abac_role_add_data_term(m_role, d.term()); } /*** f std::vector get_data_terms(bool &) return the data terms bound to this role. (C:abac_role_get_data_terms) ***/ std::vector get_data_terms(bool &success) { abac_term_t **terms, **end; int i; terms = abac_role_get_data_terms(m_role); for (i = 0; terms[i] != NULL; ++i) ; end = &terms[i]; std::vector dataterms = std::vector(terms, end); abac_terms_free(terms); success=1; return dataterms; } /*** f void role_add_linked_data_term(DataTerm&) add a data term to the linking role (C:abac_role_add_linked_data_term) ***/ void role_add_linked_data_term(DataTerm& d) { abac_role_add_linked_data_term(m_role, d.term()); } /*** f std::vector get_linked_data_terms(bool &) return the data terms bound to this role's linking role. (C:abac_role_get_linked_data_terms) (C::abac_terms_free) ***/ std::vector get_linked_data_terms(bool &success) { abac_term_t **terms, **end; int i; terms = abac_role_get_linked_data_terms(m_role); for (i = 0; terms[i] != NULL; ++i) ; end = &terms[i]; std::vector dataterms = std::vector(terms, end); abac_terms_free(terms); success=1; return dataterms; } /*ii** f abac_aspect_t *role() returns the interal libabac representation of this role (S:abac_aspect_t) **ii*/ abac_aspect_t *role() {return m_role;} private: abac_aspect_t *m_role; }; /*** ABAC::Oset An Oset is oset specification of a set of entitities for a principal ***/ class Oset { public: /*** f Oset() default constructor, do not use, for swig only f Oset(const Oset &) copy constructor, used for cloning an oset (C:abac_aspect_dup) f ~Oset() default destructor (C:abac_aspect_free) ***/ Oset() : m_oset(NULL) { } // do not use: here for swig Oset(const Oset &oset) { m_oset =abac_aspect_dup(oset.m_oset); } ~Oset() { if(m_oset) abac_aspect_free(m_oset); } /*ii** f Oset(abac_aspect_t *) constructor that takes abac_aspect_t structure (C:abac_aspect_dup) **ii*/ Oset(abac_aspect_t *oset): m_oset(abac_aspect_dup(oset)) { } /*** f Oset(char *) constructor that makes a principal oset, ie [keyid:B] (C:abac_oset_principal_create) f Oset(char *, char *) constructor that makes a regular oset, ie. [keyid:B].oset:o (C:abac_oset_create) f Oset(char *, char*, char *) constructor that makes a linked oset, ie. [keyid:B].role:r.oset:o (C:abac_oset_linked_create) f Oset(DataTerm&) constructor that makes an object oset, ie. [urn:'file/fileA'] (C:abac_oset_object_create) ***/ Oset(char *oset_name) : m_oset(abac_oset_principal_create(oset_name)) { } Oset(char *principal_name, char *oset_name) : m_oset(abac_oset_create(principal_name, oset_name)) { } Oset(char *principal_name, char *linked_role_name,char *oset_name) : m_oset(abac_oset_linked_create(principal_name, linked_role_name, oset_name)) { } Oset(DataTerm& d) : m_oset(abac_oset_object_create(d.term())) { } /*** f bool oset_is_object(), ie <- [integer:10] return ture if this oset is an object oset (C:abac_oset_is_object) ***/ bool oset_is_object() const { return abac_oset_is_object(m_oset); } /*** f bool oset_is_principal() const return true if the oset is a principal object(made from a data term), the right hand side of, [keyid:A].oset:o <- [keyid:B] (C:abac_oset_is_principal) ***/ bool oset_is_principal() const { return abac_oset_is_principal(m_oset); } /*** f bool oset_is_linking() const returns true if the oset is a linking oset like the right hand side of, [keyid:A].oset:o1 <- [keyid:B].role:r1.oset:o2 (C:abac_oset_is_linking) ***/ bool oset_is_linking() const { return abac_oset_is_linking(m_oset); } /*** f char *string() const returns literal string of the oset (C:abac_oset_string) f char *typed_string() const returns typed literal string of the oset (C:abac_oset_typed_string) ***/ char *string() const { return abac_oset_string(m_oset); } char *typed_string() { return abac_oset_typed_string(m_oset); } /*** f char *oset_linked_role() const returns linked part of a linking oset, for [keyid:A].role:r1.oset:o1, it returns r1 (C:abac_oset_linked_role) ***/ char *oset_linked_role() const { return abac_oset_linked_role(m_oset); } /*** f char *oset_name() const returns oset name, [keyid:A].role:r1.oset:o1, it returns o1 [keyid:A].oset:o1, it returns o1 (C:abac_oset_name) ***/ char *oset_name() const { return abac_oset_name(m_oset); } /*** f char *oset_principal() const returns principal name, [keyid:A].role:r1.oset:o1, it returns A (C:abac_oset_principal) ***/ char *oset_principal() const { return abac_oset_principal(m_oset); } /*** f char *oset_object() const returns object's name when the oset is a principal object [keyid:A].oset:values <- [integer:10], it returns 10 (C:abac_oset_object) ***/ char *oset_object() const { return abac_oset_object(m_oset); } /*** f void add_data_term(DataTerm&) add a data term to this oset's parameter set (C:abac_oset_add_data_term) ***/ void oset_add_data_term(DataTerm& d) { abac_oset_add_data_term(m_oset, d.term()); } /*** f std::vector get_data_terms(bool &) returns the data terms bound to this oset. (C:abac_oset_get_data_terms) (C::abac_terms_free) ***/ std::vector get_data_terms(bool &success) { abac_term_t **terms, **end; int i; terms = abac_oset_get_data_terms(m_oset); for (i = 0; terms[i] != NULL; ++i) ; end = &terms[i]; std::vector dataterms = std::vector(terms, end); abac_terms_free(terms); success=1; return dataterms; } /*** f void oset_add_linked_data_term(DataTerm&) add a data term to this oset's linking role's parameter set. (C:abac_oset_add_linked_data_term) ***/ void oset_add_linked_data_term(DataTerm& d) { abac_oset_add_linked_data_term(m_oset, d.term()); } /*** f std::vector get_linked_data_terms(bool &) returns the data terms bound to this oset's linking role. (C:abac_oset_get_linked_data_terms) (C::abac_terms_free) ***/ std::vector get_linked_data_terms(bool &success) { abac_term_t **terms, **end; int i; terms = abac_oset_get_linked_data_terms(m_oset); for (i = 0; terms[i] != NULL; ++i) ; end = &terms[i]; std::vector dataterms = std::vector(terms, end); abac_terms_free(terms); success=1; return dataterms; } /*ii** f abac_aspect_t *oset() internal returns the internal libabac representation of the oset (S:abac_aspect_t) **ii*/ abac_aspect_t *oset() {return m_oset;} private: abac_aspect_t *m_oset; }; /*** ABAC::ID An ID holds a principal credential. It maybe imported from an existing ID credential via external files, constructed from a streaming chunk, or instantiated on the fly ***/ class ID { public: /*** f ID() default constructor, do not use, for swig only f ID(const ID &) copy constructor, used for cloning an ID (C:abac_id_dup) f ~ID() default destructor (C:abac_id_free) ***/ ID() : m_id(NULL) { } // do not use: here for swig ID(const ID &id) { m_id =abac_id_dup(id.m_id); } ~ID() { if(m_id) abac_id_free(m_id); } /*ii** f ID(abac_id_t *) constructor from abac_id_t (C:abac_id_dup) f ID(abac_id_credential_t *) constructor from abac_id_credential_t (C:abac_id_credential_id) (S::abac_id_credential_t) **ii*/ ID(abac_id_t *id): m_id(abac_id_dup(id)) { } ID(abac_id_credential_t *idcred) { if(idcred) m_id=abac_id_dup(abac_id_credential_id(idcred)); else m_id=NULL; } /*** f ID(char *) load an ID cert from a file, will throw an exception if the cert cannot be loaded (C:abac_id_from_file) ***/ ID(char *filename) { if(debug) printf("calling ID with a filename\n"); m_id=abac_id_from_file(filename); if(m_id==NULL) { printf("trying.. %s\n",filename); abac_errx(1, "Id creation from filename failed"); } } /*** f ID_chunk(abac_chunk_t chunk) create an ID cert from an cert chunk, will throw an exception if the cert cannot be loaded (C:abac_id_from_chunk) ***/ ID(abac_chunk_t chunk) { /* had to renamed to ID_chunk(chunk) to make it to work with swig */ if(debug) printf("calling ID with chunk\n"); m_id=abac_id_from_chunk(chunk); if(m_id==NULL) abac_errx(1, "Id creation from chunk failed"); } /*** f ID(char *,int) generates a new ID(cert&key) with the supplied CN and validity period - CN must be alphanumeric and begin with a letter - validity must be at least one second will throw an exception if either of the above is violated (C:abac_id_generate) ***/ ID(char *cn, int validity) { int rt=abac_id_generate(&m_id, cn, validity); if(rt != ABAC_ID_SUCCESS) abac_errx(1, "Id generation failed"); } /*** f ID(char *,int, char*, char*) generates a new ID from a supplied CN, keyfile, passphrase(optional) file and validity period - CN must be alphanumeric and begin with a letter - validity must be at least one second - optional passphrase is when the keyfile is encrypted will throw an exception if either of the above is violated (C:abac_id_generate_with_key) ***/ ID(char *cn, int validity, char *kfile, char* pfile) { int rt=abac_id_generate_with_key(&m_id, cn, validity, kfile, pfile); if(rt != ABAC_ID_SUCCESS) abac_errx(1, "Id (with key) creation failed"); } /*** f void id_load_privkey_file(char *) loads the private key associated with the ID credential, will throw an exception if the key cannot be loaded (C:abac_id_load_privkey_file) ***/ void id_load_privkey_file(char *filename) { int rt=abac_id_load_privkey_file(m_id, filename); if(rt != 1) abac_errx(1, "Failed to load private key"); } /*** f void id_load_encrypted_privkey_file(char *, char*) loads an encrypted private key and pfile associated with the ID credential, will throw an exception if the key cannot be loaded (C:abac_id_load_enc_privkey_file) ***/ void id_load_encrypted_privkey_file(char *filename, char* pfile) { int rt=abac_id_load_enc_privkey_file(m_id, filename, pfile); if(rt != 1) abac_errx(1, "Failed to load private key"); } /*** f char *id_keyid() returns the SHA1 keyid of the id cert (C:abac_id_keyid) f char *id_name() returns the CN (the parameter passed to the constructor or the CN of the cert). (C:abac_id_cn) ***/ char *id_keyid() { return abac_id_keyid(m_id); } char *id_name() { return abac_id_cn(m_id); } /*** f bool id_has_privkey() returns true if the ID has an associated private key (C:abac_id_has_privkey) ***/ bool id_has_privkey() { return abac_id_has_privkey(m_id); } /*** f void id_write_cert(FILE *) writes a PEM-encoded cert to the file handle (C:abac_id_write_cert) f void id_write_cert(char *) writes a PEM-encoded cert to a file named out (C:abac_id_write_cert_fname) ***/ void id_write_cert(FILE *out) { abac_id_write_cert(m_id, out); } void id_write_cert(char *filename) { abac_id_write_cert_fname(m_id, filename); } /*** f void id_write_privkey(FILE *) writes a PEM-encoded private key to the file handle throws an exception if no private key is loaded (C:abac_id_write_privkey) f void id_write_privkey(char *) writes a PEM-encoded private key a file named out throws an exception if no private key is loaded (C:abac_id_write_privkey_fname) ***/ void id_write_privkey(FILE *out) { if(!id_has_privkey()) abac_errx(1, "No privkey to write"); abac_id_write_privkey(m_id, out); } void id_write_privkey(char *filename) { abac_id_write_privkey_fname(m_id, filename); } /*** f abac_chunk_t id_cert_chunk() returns a DER-encoded binary representation of the X.509 ID cert associated with this ID. can be passed to libabac's Context::load_id_chunk() (C:abac_id_cert_chunk) f abac_chunk_t id_privkey_chunk() returns a PEM-encoded binary representation of the private key associated with this ID. can be passed to libabac's Context::load_id_chunks() (C:abac_id_privkey_chunk) ***/ abac_chunk_t id_cert_chunk() { return abac_id_cert_chunk(m_id); } abac_chunk_t id_privkey_chunk() { return abac_id_privkey_chunk(m_id); } /*** f char *string() returns literal string of the id credential (C:abac_id_string) ***/ char *string() { return abac_id_string(m_id); } /*ii** f abac_id_t *id() returns the interal libabac representation of this id (S:abac_id_t) **ii*/ abac_id_t *id() { return m_id; } private: abac_id_t *m_id; }; /*** ABAC::Attribute This is the attribute representation for the access policy rule LHS <- RHS The sequence of generation is to first, instantiate the object, ie, LHS (head) second, adding subject(s) to it, ie, RHS (tail) and then baking it. Only once it's baked can you access the X.509 cert. Once it's been baked you can no longer add subjects to it ***/ class Attribute { public: /*** f Attribute() default constructor, do not use, for swig only f Attribute(const Attribute &) copy constructor, used for cloning an attribute (C:abac_attribute_dup) f ~Attribute() default destructor (C:abac_attribute_free) ***/ Attribute() : m_attr(NULL) { } Attribute(const Attribute &id) { m_attr =abac_attribute_dup(id.m_attr); } ~Attribute() { if(m_attr) abac_attribute_free(m_attr); } /*ii** f Attribute(abac_attribute_t *) constructor that takes abac_attribute_t, locally used (C:abac_attribute_dup) f Attribute(abac_credential_t *) constructor that takes abac_credential_t, locally used (C:abac_attribute_dup) (C::abac_credential_attribute) (S::abac_credential_t) **ii*/ Attribute(abac_attribute_t *attr): m_attr(abac_attribute_dup(attr)) { } Attribute(abac_credential_t *cred) { m_attr=abac_attribute_dup(abac_credential_attribute(cred)); } /*** f Attribute(Role&, int) constructor that creates an attribute policy to be signed by the issuer with the given role with a specified validity period An exception will be thrown if: - the issuer has no private key - the Head role is invalid - the validity period is invalid (must be >= 1 second) (C:abac_attribute_create) ***/ Attribute(Role& head, int validity) { int rt=abac_attribute_create(&m_attr, head.role(), NULL, validity); if(rt!=ABAC_ATTRIBUTE_SUCCESS) abac_errx(1, "attribute(role), unable to make an attribute"); } /*** f Attribute(Oset&, int) constructor that creates an attribute policy to be signed by the issuer with the given oset with a specified validity period An exception will be thrown if: - the issuer has no private key - the Head oset is invalid - the validity period is invalid (must be >= 1 second) (C:abac_attribute_create) ***/ Attribute(Oset& head, int validity) { int rt=abac_attribute_create(&m_attr, head.oset(), NULL, validity); if(rt!=ABAC_ATTRIBUTE_SUCCESS) abac_errx(1, "attribute(oset), unable to make an attribute"); } /*** f Attribute_chunk(abac_chunk_t chunk) constructor that creates an attribute policy to be signed by the issuer with a given cert chunk. (C:abac_attribute_from_chunk) ***/ Attribute(abac_chunk_t chunk) { /* had to renamed to Attribute_chunk(chunk) to make it to work with swig */ m_attr=abac_attribute_from_chunk(chunk); if(m_attr==NULL) abac_errx(1, "attribute(chunk), unable to make an attribute"); } /*** f bool attribute_add_tail(Role&) Add a role tail. Call multiple times for intersection (C:abac_attribute_add_tail) f bool attribute_add_tail(Oset&) Add an oset tail. Call multiple times for intersection (C:abac_attribute_add_tail) f void attribute_set_using_this() Allow user set whether this attribute has '?This' in its attribute rule (C:abac_attribute_set_using_this) ***/ bool attribute_add_tail(Role& tail) { if(abac_attribute_add_tail(m_attr, tail.role())) return 1; else return 0; } bool attribute_add_tail(Oset& tail) { if(abac_attribute_add_tail(m_attr, tail.oset())) return 1; else return 0; } void attribute_set_using_this() { abac_attribute_set_using_this(m_attr,1); } /*** /*** f char *head_string() returns literal string of head of the attribute (C:abac_head_string) f char *tail_string() returns literal string of tail of the attribute (C:abac_tail_string) ***/ char *head_string() { return abac_head_string(m_attr); } char *tail_string() { return abac_tail_string(m_attr); } /*** f char *head_typed_string() returns typed literal string of head of the attribute (C:abac_head_typed_string) f char *tail_typed_string() returns typed literal string of tail of the attribute (C:abac_tail_typed_string) ***/ char *head_typed_string() { return abac_head_typed_string(m_attr); } char *tail_typed_string() { return abac_tail_typed_string(m_attr); } /*** f char *string() returns literal string of the attribute (C:abac_attribute_string) f char *typed_string() returns typed literal string of the attribute (C:abac_attribute_typed_string) ***/ char *string() { return abac_attribute_string(m_attr); } char *typed_string() { return abac_attribute_typed_string(m_attr); } /*** ??? not sure about implmentation f const Role &role_head() returns the head role (C:abac_attribute_head) f const Oset &oset_head() returns the oset head (C:abac_attribute_head) ***/ const Role &role_head() { abac_aspect_t *head=abac_attribute_head(m_attr); static Role role=Role(head); return role; } const Oset &oset_head() { abac_aspect_t *head=abac_attribute_head(m_attr); static Oset oset=Oset(head); return oset; } /*** f std::vector role_tails(bool &) retrieve tail role which maybe more than 1 if intersecting (C:abac_attribute_role_tails) (C::abac_attribute_is_role) (C::abac_aspects_free) f std::vector oset_tails(bool &) retrieve tail oset which maybe more than 1 if intersecting (C:abac_attribute_oset_tails) (C::abac_attribute_is_role) (C::abac_aspects_free) ***/ std::vector role_tails(bool &success) { abac_aspect_t **tails, **end; int i; /* make sure it is role */ if(!abac_attribute_is_role(m_attr)) { success=0; abac_errx(1, "role_tails, attribute is not a role"); } tails = abac_attribute_role_tails(m_attr); for (i = 0; tails[i] != NULL; ++i) ; end = &tails[i]; std::vector roles = std::vector(tails, end); abac_aspects_free(tails); success=1; return roles; } std::vector oset_tails(bool &success) { abac_aspect_t **tails, **end; int i; /* make sure that tail is not role */ if(abac_attribute_is_role(m_attr)) { success=0; abac_errx(1, "oset_tails, attribute is not an oset"); } tails = abac_attribute_oset_tails(m_attr); for (i = 0; tails[i] != NULL; ++i) ; end = &tails[i]; std::vector osets = std::vector(tails, end); success=1; abac_aspects_free(tails); return osets; } /*** f bool attribute_bake() Generate the cert. Call this after you've added subjects to your cert. This returns false if there are no subjects This will throw an exception if the cert's already been baked. (C:abac_attribute_bake) ***/ bool attribute_bake() { /* can not bake in ABAC_CN mode */ if(USE("ABAC_CN")) abac_errx(1, "bake, can not bake the cert with env(ABAC_CN) set"); int rt=abac_attribute_bake(m_attr); if(rt!=1) abac_errx(1, "bake, can not bake the cert"); } /*** f bool attribute_baked() returns true iff the cert has been baked. (C:abac_attribute_baked) ***/ bool attribute_baked() { return abac_attribute_baked(m_attr); } /*** f void attribute_write_cert(FILE *) write the DER-encoded X.509 attribute cert to the open file handle Throws an exception if the cert isn't baked (C:abac_attribute_write_cert) ***/ void attribute_write_cert(FILE *out) { int rt= abac_attribute_write_cert(m_attr,out); if(!rt) abac_errx(1, "write, cert is not baked"); } /*** f void attribute_write_cert(char *) write the DER-encoded X.509 attribute cert to a file named out Throws an exception if the cert isn't baked (C:abac_attribute_write_cert_fname) ***/ void attribute_write_cert(char *filename) { abac_attribute_write_cert_fname(m_attr,filename); } /*** f abac_chunk_t cert_chunk() returns a DER-encoded binary representation of the X.509 attribute cert associated with this cert Throws an exception if the cert isn't baked the chunk can be passed to libabac's Context::load_attribute_chunk() (C:abac_attribute_cert_chunk) ***/ abac_chunk_t cert_chunk() { return abac_attribute_cert_chunk(m_attr); } /*ii** f abac_attribute_t *attribute() return libabac structure for attribute (S:abac_attribute_t) **ii*/ abac_attribute_t *attribute() { return m_attr; } private: abac_attribute_t *m_attr; }; /*** ABAC::Context An ABAC Context ***/ class Context { public: /*** f Context() default constructor (C:abac_context_new) f Context(const Context &) copy constructor, used for cloning the context (C:abac_context_dup) f ~Context() default destructor (C:abac_context_free) ***/ Context() { m_ctx = abac_context_new(); m_abac_version=abac_xstrdup(abac_version()); } Context(const Context &context) { m_ctx = abac_context_dup(context.m_ctx); m_abac_version=abac_xstrdup(context.m_abac_version); } ~Context() { if(m_abac_version!=NULL) free(m_abac_version); if(m_ctx!=NULL) abac_context_free(m_ctx); } /*** f int load_id(ABAC::ID&) load id cert from ID (C:abac_context_load_id) f int load_id_file(char *) load id cert from an idkey combo file. key retrieval will be attempted but won't fail if not found (C:abac_context_load_id_idkey_file) f int load_id_encrypted_file(char *, char *) load id cert from an idkey combo file and a pfile. Encrypted key retrieval will be attempted but won't fail if not found (C:abac_context_load_encrypted_id_file) f int load_id_files(char *, char *) load id cert from an id file and a key file (C:abac_context_load_id_files) f int load_id_encrypted_files(char *, char *, char *) load id cert from an id file, an encrypted key file, and a pfile (C:abac_context_load_encrypted_id_files) f int load_id_chunk(abac_chunk_t) load id cert from a chunk structure (C:abac_context_load_id_chunk) f int load_id_chunks(abac_chunk_t, abac_chunk_t) load id & privkey from chunk structures (C:abac_context_load_id_privkey_chunk) f int load_id_encrypted_chunks(abac_chunk_t, abac_chunk_t,char *pfile) load id & encrypted privkey from chunk structures (C:abac_context_load_id_enc_privkey_chunk) returns: ABAC_CERT_SUCCESS successfully loaded ABAC_CERT_INVALID invalid certificate (or file not found) ABAC_CERT_BAD_SIG invalid signature ***/ int load_id(ABAC::ID& id) { return abac_context_load_id(m_ctx, id.id()); } int load_id_file(char *filename) { return abac_context_load_id_idkey_file(m_ctx, filename); } int load_id_encrypted_file(char *filename, char *pfile) { return abac_context_load_encrypted_id_file(m_ctx, filename, pfile); } int load_id_files(char *filename, char *keyfilename) { return abac_context_load_id_files(m_ctx, filename, keyfilename); } int load_id_encrypted_files(char *filename, char *keyfilename, char *pfile) { return abac_context_load_encrypted_id_files(m_ctx, filename, keyfilename, pfile); } int load_id_chunk(abac_chunk_t cert) { return abac_context_load_id_chunk(m_ctx, cert); } int load_id_chunks(abac_chunk_t cert, abac_chunk_t privkey) { if(debug) printf("load_id_chunks, FUNNY privkey ptr, loc(%p)\n", privkey.ptr); return abac_context_load_id_privkey_chunk(m_ctx, cert, privkey); } int load_id_encrypted_chunks(abac_chunk_t cert, abac_chunk_t privkey, char *pfile) { if(debug) printf("load_id_encrypted_chunks, FUNNY privkey ptr, loc(%p)\n", privkey.ptr); return abac_context_load_id_enc_privkey_chunk(m_ctx, cert, privkey, pfile); } /*** f int load_attribute(ABAC::Attribute&) load attribute credential from attribute structure (C:abac_context_load_attribute) f int load_attribute_file(char *) load attribute credential from a file (C:abac_context_load_attribute_file) f int load_attribute_chunk(abac_chunk_t) load attribute credential from a chunk (C:abac_context_load_attribute_chunk) f returns the same values as above, additionally returns ABAC_CERT_MISSING_ISSUER if the issuer certificate has not been loaded ***/ int load_attribute(ABAC::Attribute& a) { return abac_context_load_attribute(m_ctx, a.attribute()); } int load_attribute_file(char *filename) { return abac_context_load_attribute_file(m_ctx, filename); } int load_attribute_chunk(abac_chunk_t cert) { return abac_context_load_attribute_chunk(m_ctx, cert); } /*** f void load_principals(char *) load a directory full of principals only: f first: ${path}/*_ID.{der,pem} as identity certificates implicitly looking for ${path}/*_private.{der,pem} as the private key file then: ${path}/*_IDKEY.{der,pem} as id/key combo certificate (C:abac_context_load_principals) f void load_directory(char *) load a directory full of certificates: f first: ${path}/*_ID.{der,pem} as identity certificates implicitly looking for ${path}/*_private.{der,pem} as the private key file then: ${path}/*_IDKEY.{der,pem} as id/key combo certificate last: ${path}/*_attr.der as attribute certificates (C:abac_context_load_directory) ***/ void load_principals(char *path) { abac_context_load_principals(m_ctx, path); } void load_directory(char *path) { abac_context_load_directory(m_ctx, path); } /*** f void set_no_partial_proof() (C:abac_context_set_no_partial_proof) void set_want_partial_proof() enable and disable the partial proof on query proof failure (C:abac_context_set_want_partial_proof) ***/ void set_no_partial_proof() { abac_context_set_no_partial_proof(m_ctx); } void set_want_partial_proof() { abac_context_set_want_partial_proof(m_ctx); } /*** f std::vector query(char *, char *, bool &) the string version is for query that is composed by hand with SHA or in non ABAC_CN mode (C:abac_context_query) (C::abac_free_credentials) f std::vector query(Role &, Role &, bool &) (C:abac_context_query_with_structure) (C::abac_free_credentials) std::vector query(Oset &, Oset &, bool &) (C:abac_context_query_with_structure) (C::abac_free_credentials) runs the query: role <-?- principal oset <-?- principal/obj returns true/false in success returns a proof upon success, a partial proof on failure by default ***/ std::vector query(char *role, char *principal, bool &success) { abac_credential_t **creds, **end; int i, success_int; creds = abac_context_query(m_ctx, role, principal, &success_int); success = success_int; if(debug) printf("query, returning success(%d)\n", success_int); for (i = 0; creds[i] != NULL; ++i) ; end = &creds[i]; std::vector attributes = std::vector(creds, end); if(debug) printf("query, got rules(%d)\n", i); abac_free_credentials(creds); return attributes; } std::vector query(Role &role, Role &p_role, bool &success) { abac_credential_t **creds, **end; int i, success_int; creds = abac_context_query_with_structure(m_ctx, role.role(), p_role.role(), &success_int); success = success_int; if(debug) printf("query, returning success(%d)\n", success_int); for (i = 0; creds[i] != NULL; ++i) ; end = &creds[i]; std::vector attributes = std::vector(creds, end); abac_free_credentials(creds); return attributes; } std::vector query(Oset &oset, Oset &p_oset, bool &success) { abac_credential_t **creds, **end; int i, success_int; creds = abac_context_query_with_structure(m_ctx, oset.oset(), p_oset.oset(), &success_int); success = success_int; if(debug) printf("query, returning success(%d)\n", success_int); for (i = 0; creds[i] != NULL; ++i) ; end = &creds[i]; std::vector attributes = std::vector(creds, end); if(debug) printf("query, returning rules(%d)\n", i); abac_free_credentials(creds); return attributes; } /*** f std::vector next_proof(bool &) (C:abac_context_query_again) (C::abac_free_credentials) force backtrack and try to get next solution proof: returns true/false in success returns a proof upon success, ***/ std::vector next_proof(bool &success) { abac_credential_t **creds, **end; int i, success_int; creds = abac_context_query_again(m_ctx, &success_int); success = success_int; for (i = 0; creds[i] != NULL; ++i) ; end = &creds[i]; std::vector attributes = std::vector(creds, end); if(debug) printf("repeat query, got rules(%d)\n", i); abac_free_credentials(creds); return attributes; } /*** f std::vector context_credentials(bool &) returns a vector of all the credentials loaded in the context extracted from the internal data structure (C:abac_context_credentials) (C::abac_free_credentials) f int credential_count() returns the number of credentials loaded in the context currently (C:abac_context_credential_count() ***/ std::vector context_credentials(bool &success) { abac_credential_t **creds, **end; int i; success = 1; creds = abac_context_credentials(m_ctx); for (i = 0; creds[i] != NULL; ++i) ; end = &creds[i]; std::vector attributes = std::vector(creds, end); if(debug) printf("credentials, got (%d)\n", i); abac_free_credentials(creds); if(debug) show_yap_db("calling from context_credentials"); return attributes; } int credential_count() const { return abac_context_credential_count(m_ctx); } /*** f std::vector context_principals(bool &) returns a vector of all the principals loaded in the context extracted from the internal data structure (C:abac_context_principals) (C::abac_free_principals) f int principal_count() returns the number of principals loaded in the context currently (C:abac_context_principal_count() ***/ std::vector context_principals(bool &success) { abac_id_credential_t **ids, **end; int i; success = 1; ids = abac_context_principals(m_ctx); for (i = 0; ids[i] != NULL; ++i) ; end = &ids[i]; std::vector principals = std::vector(ids, end); if(debug) printf("principals, got (%d)\n", i); abac_free_principals(ids); return principals; } int principal_count() const { return abac_context_principal_count(m_ctx); } /*** f ID lookup_principal(char *) find a particular principal from the context (C:abac_context_principal_lookup) ***/ ID lookup_principal(char *name) const { abac_id_credential_t *principal=abac_context_principal_lookup(m_ctx,name); if(principal==NULL) { if(debug) printf("did not find the principal(%s)\n", name); abac_errx(1, "lookup principal failed"); } return principal; } /*** f char *version() return the version of this interface ***/ char *version() const { return m_abac_version; } /*ii** f abac_context_t *context() return libabac structure for context (S:abac_context_t) **ii*/ abac_context_t *context() { return m_ctx; } private: abac_context_t *m_ctx; char *m_abac_version; }; Constraint::Constraint(Role& role) { m_constraint=abac_constraint_from_role(role.role()); } Constraint::Constraint(Oset &oset) { m_constraint=abac_constraint_from_oset(oset.oset()); } DataTerm::DataTerm(ID& id) { m_term=abac_term_id_create(id.id()); } } #endif /* __ABAC_HH__ */