source: doc/ABAC.hh

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

1) tweak according valgrind's leak report

  • Property mode set to 100644
File size: 11.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    class Context {
20        public:
21            Context() { m_ctx = abac_context_new(); }
22            Context(const Context &context) { m_ctx = abac_context_dup(context.m_ctx); }
23            ~Context() { abac_context_free(m_ctx); }
24
25            int load_id_file(char *filename) { return abac_context_load_id_file(m_ctx, filename); }
26            int load_id_chunk(abac_chunk_t cert) { return abac_context_load_id_chunk(m_ctx, cert); }
27            int load_id_id(ID& id); /* defined later in the class */
28            int load_attribute_file(char *filename) { return abac_context_load_attribute_file(m_ctx, filename); }
29            int load_attribute_chunk(abac_chunk_t cert) { return abac_context_load_attribute_chunk(m_ctx, cert); }
30
31            void load_directory(char *path) { abac_context_load_directory(m_ctx, path); }
32
33
34            /* abac query, returns a vector of credentials on success, NULL on fail */
35            std::vector<Credential> query(char *role, char *principal, bool &success) {
36                abac_credential_t **creds, **end;
37                int i, success_int;
38                creds = abac_context_query(m_ctx, role, principal, &success_int);
39                success = success_int;
40
41                for (i = 0; creds[i] != NULL; ++i)
42                    ;
43
44                end = &creds[i];
45                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
46                abac_context_credentials_free(creds);
47                return credentials;
48            }
49            std::vector<Credential> credentials() {
50                abac_credential_t **creds, **end;
51                int i;
52
53                creds = abac_context_credentials(m_ctx);
54                for (i = 0; creds[i] != NULL; ++i)
55                    ;
56
57                end = &creds[i];
58                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
59
60                abac_context_credentials_free(creds);
61                return credentials;
62            }
63        void set_nickname(char *key, char *nick) {
64            abac_context_set_nickname(m_ctx, key, nick);
65        }
66        private:
67            abac_context_t *m_ctx;
68        friend class Role;
69        friend class ID;
70        friend class Attribute;
71    };
72
73    class Role {
74        public:
75            Role() : m_role(NULL) { } // do not use: here for swig
76            Role(abac_role_t *role) { m_role = abac_role_dup(role); }
77            Role(char *role_name) { m_role = abac_role_from_string(role_name); }
78            Role(const Role &role) { m_role = abac_role_dup(role.m_role); }
79            ~Role() { abac_role_free(m_role); }
80            bool is_principal() const { return abac_role_is_principal(m_role); }
81            bool is_role() const { return abac_role_is_role(m_role); }
82            bool is_linking() const { return abac_role_is_linking(m_role); }
83
84            char *string() const { return abac_role_string(m_role); }
85            char *short_string(Context& c) const { 
86                return abac_role_short_string(m_role, c.m_ctx);
87            }
88            char *linked_role() const { return abac_role_linked_role(m_role); }
89            char *role_name() const { return abac_role_role_name(m_role); }
90            char *principal() const { return abac_role_principal(m_role); }
91
92        private:
93            abac_role_t *m_role;
94    };
95
96    class Credential {
97        public:
98            Credential() : m_cred(NULL) { } // do not use: here for swig
99            Credential(abac_credential_t *cred) :
100                m_head(abac_credential_head(cred)),
101                m_tail(abac_credential_tail(cred)),
102                m_cred(abac_credential_dup(cred))
103                    { }
104            Credential(const Credential &cred) :
105                m_head(cred.m_head),
106                m_tail(cred.m_tail),
107                m_cred(abac_credential_dup(cred.m_cred))
108                    { }
109            ~Credential() { abac_credential_free(m_cred); }
110            const Role &head() { return m_head; }
111            const Role &tail() { return m_tail; }
112            abac_chunk_t attribute_cert() { return abac_credential_attribute_cert(m_cred); }
113            abac_chunk_t issuer_cert() { return abac_credential_issuer_cert(m_cred); }
114       
115        private:
116            abac_credential_t *m_cred;
117            Role m_head, m_tail;
118    };
119
120
121    class ID {
122        public:
123            ID() : m_id(NULL) { } // do not use: required by swig
124            ID(const ID &id) { m_id = abac_id_dup(id.m_id); }
125            ~ID() { abac_id_free(m_id); }
126
127            ID(char *filename) : m_id(NULL) {
128                m_id = abac_id_from_file(filename);
129                if (m_id == NULL)
130                    throw std::invalid_argument("Could not load ID cert");
131            }
132
133            ID(abac_chunk_t chunk) : m_id(NULL) {
134                m_id = abac_id_from_chunk(chunk);
135                if (m_id == NULL)
136                    throw std::invalid_argument("Could not load ID certificate with a chunk");
137            }
138            ID(char *cn, int validity) : m_id(NULL) {
139                int ret = abac_id_generate(&m_id, cn, validity);
140                if (ret == ABAC_GENERATE_INVALID_CN)
141                    throw std::invalid_argument("CN must be alphanumeric and start with a letter");
142                if (ret == ABAC_GENERATE_INVALID_VALIDITY)
143                    throw std::invalid_argument("Validity must be > 0 days");
144            }
145            void load_privkey(char *filename) {
146                int ret = abac_id_privkey_from_file(m_id, filename);
147                if (ret != ABAC_SUCCESS)
148                    throw std::invalid_argument("Could not load private key");
149            }
150            void load_privkey_chunk(abac_chunk_t chunk) {
151                int ret = abac_id_privkey_from_chunk(m_id, chunk);
152                if (ret != ABAC_SUCCESS)
153                    throw std::invalid_argument("Could not load private key with a chunk");
154            }
155            int has_privkey() {
156                int ret= abac_id_has_privkey(m_id);
157                return ret;
158            }
159            char *keyid() { return abac_id_keyid(m_id); }
160            char *cn() { return abac_id_cn(m_id); }
161            char *cert_filename() { return abac_id_cert_filename(m_id); }
162            void write_cert(FILE *out) { abac_id_write_cert(m_id, out); }
163            void write_cert(const std::string &name) {
164                FILE *out = fopen(name.c_str(), "a+");
165                if (out == NULL)
166                    throw std::invalid_argument("Could not open certificate file for writing");
167                write_cert(out);
168                fclose(out);
169            }
170            // Simplifies access from swig
171            void write_cert_file(const char *n) {
172                write_cert(std::string(n));
173            }
174            void write_cert_name(const char *n) {
175                write_cert(std::string(n));
176                fprintf(stderr,"ABAC::ID::write_cert_name is deprecated, please use ABAC::ID::write_cert_name\n");
177            }
178            char *privkey_filename() { return abac_id_privkey_filename(m_id); }
179            void write_privkey(FILE *out) {
180                int ret = abac_id_write_privkey(m_id, out);
181                if (ret!=ABAC_SUCCESS) throw std::logic_error("No private key loaded");
182            }
183            void write_privkey(const std::string &name) {
184                FILE *out = fopen(name.c_str(), "a+");
185                if (out == NULL)
186                    throw std::invalid_argument("Could not open privkey file for writing");
187                write_privkey(out);
188                fclose(out);
189            }
190            // Simplifies access from swig
191            void write_privkey_file(const char *name) {
192                write_privkey(std::string(name));
193            }
194            void write_privkey_name(const char *name) {
195                write_privkey(std::string(name));
196                fprintf(stderr,"ABAC::ID::write_privkey_name is deprecated, please use ABAC::ID::write_privkey_file\n");
197            }
198            abac_chunk_t cert_chunk() { return abac_id_cert_chunk(m_id); }
199            abac_chunk_t privkey_chunk() { return abac_id_privkey_chunk(m_id); }
200
201            friend class Attribute;
202            friend class Context;
203
204        private:
205            abac_id_t *m_id;
206    };
207
208    class Attribute {
209        public:
210            Attribute() : m_attr(NULL) { } // do not use: required by swig
211            ~Attribute() { abac_attribute_free(m_attr); }
212
213            Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) {
214                int ret = abac_attribute_create(&m_attr, issuer.m_id, role, validity);
215                if (ret == ABAC_ATTRIBUTE_ISSUER_NOKEY)
216                    throw std::invalid_argument("Issuer has no private key");
217                if (ret == ABAC_ATTRIBUTE_INVALID_ROLE)
218                    throw std::invalid_argument("Role name must be alphanumeric");
219                if (ret == ABAC_ATTRIBUTE_INVALID_VALIDITY)
220                    throw std::invalid_argument("Validity must be > 0 days");
221                if (ret == ABAC_ATTRIBUTE_INVALID_ISSUER)
222                    throw std::invalid_argument("Issuer's validity expired");
223            }
224
225
226            bool principal(char *keyid) {
227                if (baked()) throw std::logic_error("Cert is already baked");
228                return abac_attribute_principal(m_attr, keyid);
229            }
230            bool role(char *keyid, char *role) {
231                if (baked()) throw std::logic_error("Cert is already baked");
232                return abac_attribute_role(m_attr, keyid, role);
233            }
234            bool linking_role(char *keyid, char *role, char *linked) {
235                if (baked()) throw std::logic_error("Cert is already baked");
236                return abac_attribute_linking_role(m_attr, keyid, role, linked);
237            }
238            bool bake() {
239                if (baked()) throw std::logic_error("Cert is already baked");
240                return abac_attribute_bake(m_attr);
241            }
242
243            bool bake(Context& c) {
244                if (baked()) throw std::logic_error("Cert is already baked");
245                return abac_attribute_bake_context(m_attr, c.m_ctx);
246            }
247
248            bool baked() { return abac_attribute_baked(m_attr); }
249
250            void set_output_format(char *fmt) {
251                abac_attribute_set_output_format(m_attr, fmt);
252            }
253
254            char *get_output_format() {
255                return abac_attribute_get_output_format(m_attr);
256            }
257
258            void write(FILE *out) {
259                int ret = abac_attribute_write(m_attr, out);
260                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
261            }
262            void write(const std::string &name) {
263                FILE *out = fopen(name.c_str(), "w");
264                if (out == NULL)
265                    throw std::invalid_argument("Could not open certificate file for writing");
266                write(out);
267                fclose(out);
268            }
269            void write_file(const char *name) {
270                int ret = abac_attribute_write_file(m_attr, name);
271                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
272            }
273            void write_name(const char *name) {
274                write_file(name);
275                fprintf(stderr,"ABAC::Attribute::write_name is deprecated, please use ABAC::Attribute::write_name\n");
276            }
277            abac_chunk_t cert_chunk() {
278                abac_chunk_t ret=abac_attribute_cert_chunk(m_attr);
279                if(ret.len == 0)
280                    throw std::logic_error("Cert is not baked");
281                return ret;
282            }
283
284        private:
285            abac_attribute_t *m_attr;
286    };
287
288    int Context::load_id_id(ID& id)
289    { return abac_context_load_id_id(m_ctx, id.m_id); }
290}
291
292#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.