source: libabac/abac.hh @ 4423f47

abac0-leakabac0-meimei-idtvf-new-xml
Last change on this file since 4423f47 was 4423f47, checked in by Mei <mei@…>, 11 years ago

Merge branch 'master' of git://abac.deterlab.net/abac

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