source: libabac/abac.hh @ 92661b4

abac0-leakabac0-meimei-idmei-rt0-nmei_rt0tvf-new-xml
Last change on this file since 92661b4 was 92661b4, checked in by Mei <mei@…>, 11 years ago

1) add some doc
2) fix the version in abac_xml

  • Property mode set to 100644
File size: 19.9 KB
Line 
1#ifndef __ABAC_HH__
2#define __ABAC_HH__
3
4#include <cstdio>
5#include <stdexcept>
6#include <string>
7#include <vector>
8
9namespace ABAC {
10    extern "C" {
11        #include "abac.h"
12    }
13
14    class Attribute;
15    class ID;
16
17/***
18ABAC::Role
19   A Role, most calls are rarely used outside the library
20***/
21    class Role {
22        public:
23/***
24f  Role()
25     default constructor, do not use, for swig only
26f  Role(abac_role_t*)
27     copy constructor, used for cloning an Role
28     (C:abac_role_dup)
29f  Role(char *)
30     instantiate a role from a string
31     (C:abac_role_from_string)
32f  Role(const Role &)
33     copy constructor, used for cloning an Role
34     (C:abac_role_dup)
35f  ~Role()
36     default destructor
37     (C:abac_role_free)
38***/
39            Role() : m_role(NULL) { } // do not use: here for swig
40            Role(abac_role_t *role) { m_role = abac_role_dup(role); }
41            Role(char *role_name) { m_role = abac_role_from_string(role_name); }
42            Role(const Role &role) { m_role = abac_role_dup(role.m_role); }
43            ~Role() { abac_role_free(m_role); }
44/***
45f  bool is_principal()
46     (C:abac_role_is_principal)
47f  bool is_role()
48     (C:abac_role_is_role)
49f  bool is_linking()
50     (C:abac_role_is_linking)
51     indicates the type of role encoded
52***/
53            bool is_principal() const { return abac_role_is_principal(m_role); }
54            bool is_role() const { return abac_role_is_role(m_role); }
55            bool is_linking() const { return abac_role_is_linking(m_role); }
56
57/***
58f  char* string()
59     string representation of the role
60     (C:abac_role_string)
61***/
62            char *string() const { return abac_role_string(m_role); }
63/***
64f  char* linked_role()
65     the linked role of a linking role
66     i.e., A.r1.r2, linked_role() returns A.r1
67     (C:abac_role_linked_role)
68f  char* role_name()
69     the role name of any role (the part after the last dot)
70     (C:abac_role_role_name)
71f  char* principal()
72     the principal part of any role
73     (C:abac_role_principal)
74***/
75            char *linked_role() const { return abac_role_linked_role(m_role); }
76            char *role_name() const { return abac_role_role_name(m_role); }
77            char *principal() const { return abac_role_principal(m_role); }
78
79        private:
80            abac_role_t *m_role;
81    };
82
83/***
84ABAC::Credential
85   This is never instantiated directly. These will only ever be
86   returned as a result of calls to Context::query or
87   Context::credentials.
88***/
89    class Credential {
90        public:
91/***
92f  Credential()
93     default constructor, do not use, for swig only
94f  Credential(abac_credential_t*)
95     copy constructor, used for cloning a credential
96     (C:abac_credential_head)
97     (C:abac_credential_tail)
98     (C:abac_credential_dup)
99f  Credential(const Credential&)
100     copy constructor, used for cloning a credential
101     (C:abac_credential_head)
102     (C:abac_credential_tail)
103     (C:abac_credential_dup)
104f  ~Credential()
105     default destructor
106     (C:abac_credential_free)
107***/
108            Credential() : m_cred(NULL) { } // do not use: here for swig
109            Credential(abac_credential_t *cred) :
110                m_head(abac_credential_head(cred)),
111                m_tail(abac_credential_tail(cred)),
112                m_cred(abac_credential_dup(cred))
113                    { }
114            Credential(const Credential &cred) :
115                m_head(cred.m_head),
116                m_tail(cred.m_tail),
117                m_cred(abac_credential_dup(cred.m_cred))
118                    { }
119            ~Credential() { abac_credential_free(m_cred); }
120/***
121f  Role &head()
122     returns the head of the credential
123f  Role &tail()
124     returns the tail of the credential
125***/
126            const Role &head() { return m_head; }
127            const Role &tail() { return m_tail; }
128/***
129f  abac_chunk_t attribute_cert()
130     returns the attribute certificate in chunk, suitable for
131     transmission over the network or storage in a file
132     (C:abac_credential_attribute_cert)
133f  abac_chunk_t issuer_cert()
134     returns the issuer certificate in chunk, again suitable for
135     network transmission or file storage
136     (C:abac_credential_issuer_cert)
137***/
138            abac_chunk_t attribute_cert() { return abac_credential_attribute_cert(m_cred); }
139            abac_chunk_t issuer_cert() { return abac_credential_issuer_cert(m_cred); }
140       
141        private:
142            abac_credential_t *m_cred;
143            Role m_head, m_tail;
144    };
145
146/***
147ABAC::Context
148    An ABAC Context
149***/
150    class Context {
151        public:
152/***
153f  Context()
154     default constructor
155     (C:abac_context_new)
156f  Context(const Context &)
157     copy constructor, used for cloning the context
158     (C:abac_context_dup)
159f  ~Context()
160     default destructor
161     (C:abac_context_free)
162***/
163            Context() { m_ctx = abac_context_new(); }
164            Context(const Context &context) { m_ctx = abac_context_dup(context.m_ctx); }
165            ~Context() { abac_context_free(m_ctx); }
166
167/***
168f  int load_id_file(char *)
169     load identity certificate from an id file
170     (C:abac_context_load_id_file)
171f  int load_id_chunk(abac_chunk_t)
172     load id certificate from an chunk
173     (C:abac_context_load_id_chunk)
174f  int load_attribute_file(char *)
175     load attribute certificate from an id file.
176     (C:abac_context_load_attribute_file)
177f  int load_attribute_chunk(abac_chunk_t)
178     load attribute certificate from an chunk
179     (C:abac_context_load_attribute_chunk)
180f  returns :
181        ABAC_CERT_SUCCESS   successfully loaded
182        ABAC_CERT_INVALID   invalid certificate (or file not found)
183        ABAC_CERT_BAD_SIG   invalid signature
184***/
185            int load_id_file(char *filename) { return abac_context_load_id_file(m_ctx, filename); }
186            int load_id_chunk(abac_chunk_t cert) { return abac_context_load_id_chunk(m_ctx, cert); }
187            int load_attribute_file(char *filename) { return abac_context_load_attribute_file(m_ctx, filename); }
188            int load_attribute_chunk(abac_chunk_t cert) { return abac_context_load_attribute_chunk(m_ctx, cert); }
189
190/***
191f  void load_directory(char *)
192     load a directory full of certificates:
193f       first: ${path}/*_ID.{der,pem} as identity certificates
194               implicitly looking for ${path}/*_private.{der,pem} as
195               the private key file
196        last: ${path}/*_attr.xml as attribute certificates
197      (C:abac_context_load_directory)
198***/
199            void load_directory(char *path) { abac_context_load_directory(m_ctx, path); }
200
201/***
202f  std::vector<Attribute> query(char *, char *, bool &)
203     run the query:
204        role <-?- principal
205     returns true/false in success
206     returns a proof upon success, partial proof on failure
207     (C:abac_context_query)
208     (C::abac_free_credentials_free)
209***/
210
211            /* abac query, returns a vector of credentials on success, NULL on fail */
212            std::vector<Credential> query(char *role, char *principal, bool &success) {
213                abac_credential_t **creds, **end;
214                int i, success_int;
215                creds = abac_context_query(m_ctx, role, principal, &success_int);
216                success = success_int;
217
218                for (i = 0; creds[i] != NULL; ++i)
219                    ;
220
221                end = &creds[i];
222                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
223                abac_context_credentials_free(creds);
224                return credentials;
225            }
226/***
227f  std::vector<Attribute> credentials(bool &)
228     returns a vector of all the credentials loaded in the context
229     (C:abac_context_credentials)
230     (C::abac_context_credentials_free)
231***/
232            std::vector<Credential> credentials() {
233                abac_credential_t **creds, **end;
234                int i;
235
236                creds = abac_context_credentials(m_ctx);
237                for (i = 0; creds[i] != NULL; ++i)
238                    ;
239
240                end = &creds[i];
241                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
242
243                abac_context_credentials_free(creds);
244                return credentials;
245            }
246
247        private:
248            abac_context_t *m_ctx;
249    };
250
251/***
252ABAC::ID
253   An ID holds a principal credential. It maybe imported from an existing
254   ID credential via external files, constructed from a streaming chunk,
255   or instantiated on the fly
256***/
257    class ID {
258        public:
259/***
260f  ID()
261     default constructor, do not use, for swig only
262f  ID(const ID &)
263     copy constructor, used for cloning an ID
264     (C:abac_id_dup)
265f  ~ID()
266     default destructor
267     (C:abac_id_free)
268***/
269            ID() : m_id(NULL) { } // do not use: required by swig
270            ID(const ID &id) { m_id = abac_id_dup(id.m_id); }
271            ~ID() { abac_id_free(m_id); }
272
273/***
274f  ID(char *)
275     load an ID certificate from a file, will throw an exception
276     if the certificate cannot be loaded
277     (C:abac_id_from_file)
278***/
279            ID(char *filename) : m_id(NULL) {
280                m_id = abac_id_from_file(filename);
281                if (m_id == NULL)
282                    throw std::invalid_argument("Could not load ID cert");
283            }
284
285/***
286f  ID_chunk(abac_chunk_t chunk)
287     create an ID certificate from an certificate chunk, will
288     throw an exception if the certificate cannot be loaded
289     (C:abac_id_from_chunk)
290***/
291            ID(abac_chunk_t chunk) : m_id(NULL) {
292                m_id = abac_id_from_chunk(chunk);
293                if (m_id == NULL)
294                    throw std::invalid_argument("Could not load ID certificate with abac_chunk_t");
295            }
296/***
297f  ID(char *,int)
298     generates a new ID(cert&key) with the supplied CN and validity period
299     - CN must be alphanumeric and begin with a letter
300     - validity must be at least one second
301     will throw an exception if either of the above is violated
302     (C:abac_id_generate)
303***/
304            ID(char *cn, int validity) : m_id(NULL) {
305                int ret = abac_id_generate(&m_id, cn, validity);
306                if (ret == ABAC_GENERATE_INVALID_CN)
307                    throw std::invalid_argument("CN must be alphanumeric and start with a letter");
308                if (ret == ABAC_GENERATE_INVALID_VALIDITY)
309                    throw std::invalid_argument("Validity must be > 0 days");
310            }
311/***
312f  void id_load_privkey_file(char *)
313     loads the private key associated with the ID credential,
314     will throw an exception if the key cannot be loaded
315     (C:abac_id_privkey_from_file)
316***/
317            void load_privkey(char *filename) {
318                int ret = abac_id_privkey_from_file(m_id, filename);
319                if (ret != ABAC_SUCCESS)
320                    throw std::invalid_argument("Could not load private key");
321            }
322
323/***
324f  char *keyid()
325     returns the SHA1 keyid of the id cert
326     (C:abac_id_keyid)
327f  char *cert_filename()
328     returns the default libabac filename for the cert.
329     value must be freed by caller.
330     (C:abac_id_cert_filename)
331***/
332            char *keyid() { return abac_id_keyid(m_id); }
333            char *cert_filename() { return abac_id_cert_filename(m_id); }
334/***
335f  void write_cert(FILE *)
336     writes a PEM-encoded certificate to a file handle
337     (C:abac_id_write_cert)
338f  void write_cert(string &)
339     writes a PEM-encoded certificate to a file named in string
340f  void write_cert_file(string &)
341     writes a PEM-encoded certificate to a file
342f  void write_cert_name(string &)
343     writes a PEM-encoded certificate to a file
344     (added to support original libcreddy users)
345***/
346            void write_cert(FILE *out) { abac_id_write_cert(m_id, out); }
347            void write_cert(const std::string &name) {
348                FILE *out = fopen(name.c_str(), "w");
349                if (out == NULL)
350                    throw std::invalid_argument("Could not open certificate file for writing");
351                write_cert(out);
352                fclose(out);
353            }
354            // Simplifies access from swig
355            void write_cert_file(const char *n) {
356                write_cert(std::string(n));
357            }
358            void write_cert_name(const char *n) {
359                write_cert(std::string(n));
360                fprintf(stderr,"ABAC::ID::write_cert_name is deprecated, please use ABAC::ID::write_cert_name\n");
361            }
362/***
363f  char *privkey_filename()
364     returns the default libabac filename for the private key.
365     value must be freed by caller.
366     (C:abac_id_privkey_filename)
367***/
368            char *privkey_filename() { return abac_id_privkey_filename(m_id); }
369/***
370f  void write_privkey(FILE *)
371     write the private key to a file handle
372     throws a std::logic_error if no private key is loaded
373     (C:abac_id_write_privkey)
374f  void write_privkey(string &)
375     writes a private key to file named in string
376f  void write_privkey_file(string &)
377     writes a private key to a file
378f  void write_privkey_name(string &)
379     writes a private key to a file
380     (added to support original libcreddy users)
381***/
382            void write_privkey(FILE *out) {
383                int ret = abac_id_write_privkey(m_id, out);
384                if (ret!=ABAC_SUCCESS) throw std::logic_error("No private key loaded");
385            }
386            void write_privkey(const std::string &name) {
387                FILE *out = fopen(name.c_str(), "w");
388                if (out == NULL)
389                    throw std::invalid_argument("Could not open privkey file for writing");
390                write_privkey(out);
391                fclose(out);
392            }
393            // Simplifies access from swig
394            void write_privkey_file(const char *name) {
395                write_privkey(std::string(name));
396            }
397            void write_privkey_name(const char *name) {
398                write_privkey(std::string(name));
399                fprintf(stderr,"ABAC::ID::write_privkey_name is deprecated, please use ABAC::ID::write_privkey_file\n");
400            }
401/***
402f  abac_chunk_t cert_chunk()
403     returns a DER-encoded binary representation of the X.509 ID cert
404     associated with this ID.
405     can be passed to libabac's Context::load_id_chunk()
406     (C:abac_id_cert_chunk)
407f  abac_chunk_t privkey_chunk()
408     returns a PEM-encoded binary representation of the private key
409     associated with this ID.
410     (C:abac_id_privkey_chunk)
411***/
412            abac_chunk_t cert_chunk() { return abac_id_cert_chunk(m_id); }
413            abac_chunk_t privkey_chunk() { return abac_id_privkey_chunk(m_id); }
414
415            friend class Attribute;
416
417        private:
418            abac_id_t *m_id;
419    };
420
421/***
422ABAC::Attribute
423   This is the attribute representation for the access policy rule
424       LHS <- RHS
425   The sequence of generation is to
426       first, instantiate the object, ie, LHS (head)
427       second, adding subject(s) to it, ie, RHS (tail)
428       and then baking it.
429   Only once it's baked can you access the X.509 cert.
430   Once it's been baked you can no longer add subjects to it
431***/
432    class Attribute {
433        public:
434/***
435f  Attribute()
436     default constructor, do not use, for swig only
437f  ~Attribute()
438     default destructor
439     (C:abac_attribute_free)
440***/
441            Attribute() : m_attr(NULL) { } // do not use: required by swig
442            ~Attribute() { abac_attribute_free(m_attr); }
443
444/***
445f  Attribute(ID&, char*,int)
446     constructor that creates an attribute policy to be signed by the issuer
447     with the given role with a specified validity period
448     An exception will be thrown if:
449       - the issuer has no private key
450       - the Head role is invalid
451       - the validity period is invalid (must be >= 0 second)
452       - The issuer is invalid
453     (C:abac_attribute_create)
454***/
455            Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) {
456                int ret = abac_attribute_create(&m_attr, issuer.m_id, role, validity);
457                if (ret == ABAC_ATTRIBUTE_ISSUER_NOKEY)
458                    throw std::invalid_argument("Issuer has no private key");
459                if (ret == ABAC_ATTRIBUTE_INVALID_ROLE)
460                    throw std::invalid_argument("Role name must be alphanumeric");
461                if (ret == ABAC_ATTRIBUTE_INVALID_VALIDITY)
462                    throw std::invalid_argument("Validity must be > 0 days");
463                if (ret == ABAC_ATTRIBUTE_INVALID_ISSUER)
464                    throw std::invalid_argument("Issuer's validity expired");
465            }
466
467
468/***
469f  bool principal(char *)
470     validate the principal and insert into the attribute
471     throw a std::logic_error if the cert's been baked and keyid bad
472     (C:abac_attribute_principal)
473f bool role(char *, char *)
474     validate the principal and role and insert into the attribute
475     throw a std::logic_error if the cert's been baked and keyid bad
476     (C:abac_attribute_role)
477f bool linkig_role(char *, char *)
478     validate the role and linking role and insert into the attribute
479     throw a std::logic_error if the cert's been baked and keyid bad
480     (C:abac_attribute_linking_role)
481***/
482            bool principal(char *keyid) {
483                if (baked()) throw std::logic_error("Cert is already baked");
484                return abac_attribute_principal(m_attr, keyid);
485            }
486            bool role(char *keyid, char *role) {
487                if (baked()) throw std::logic_error("Cert is already baked");
488                return abac_attribute_role(m_attr, keyid, role);
489            }
490            bool linking_role(char *keyid, char *role, char *linked) {
491                if (baked()) throw std::logic_error("Cert is already baked");
492                return abac_attribute_linking_role(m_attr, keyid, role, linked);
493            }
494/***
495f  bool bake()
496     Generate the cert. Call this after you've added subjects to your cert.
497     This returns false if there are no subjects
498     This will throw an exception if the cert's already been baked.
499     (C:abac_attribute_bake)
500***/
501            bool bake() {
502                if (baked()) throw std::logic_error("Cert is already baked");
503                return abac_attribute_bake(m_attr);
504            }
505
506/***
507f  bool baked()
508     returns true iff the certificate has been baked.
509     (C:abac_attribute_baked)
510***/
511            bool baked() { return abac_attribute_baked(m_attr); }
512
513/***
514f  void write(FILE *)
515     write an attribute certificate in XML to an open file handle
516     Throws an exception if the certificate isn't baked
517     (C:abac_attribute_write)
518f  void write(const string&)
519     write an attribute certificate in XML to file named in string
520f  void write_file(const char *)
521     write an attribute certificate in XML to file
522f  void write_name(const char *)
523     write an attribute certificate in XML to file
524     (added to support original libcreddy users)
525***/
526            void write(FILE *out) {
527                int ret = abac_attribute_write(m_attr, out);
528                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
529            }
530            void write(const std::string &name) {
531                FILE *out = fopen(name.c_str(), "w");
532                if (out == NULL)
533                    throw std::invalid_argument("Could not open certificate file for writing");
534                write(out);
535                fclose(out);
536            }
537            void write_file(const char *name) {
538                int ret = abac_attribute_write_file(m_attr, name);
539                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
540            }
541            void write_name(const char *name) {
542                write_file(name);
543                fprintf(stderr,"ABAC::Attribute::write_name is deprecated, please use ABAC::Attribute::write_name\n");
544            }
545/***
546f  abac_chunk_t cert_chunk()
547     returns a XML structure of the attribute certificate in a abac_chunk_t
548     Throws an exception if the certificate isn't baked
549     the chunk can be passed to libabac's Context::load_attribute_chunk()
550     (C:abac_attribute_cert_chunk)
551***/
552            abac_chunk_t cert_chunk() {
553                abac_chunk_t ret=abac_attribute_cert_chunk(m_attr);
554                if(ret.len == 0)
555                    throw std::logic_error("Cert is not baked");
556                return ret;
557            }
558
559        private:
560            abac_attribute_t *m_attr;
561    };
562}
563
564#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.