source: libabac/abac.hh @ 7764378

abac0-leak
Last change on this file since 7764378 was 7764378, checked in by Mei <mei@…>, 6 years ago

1) tweak according valgrind's leak report

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