source: libabac/abac.hh @ 461541a

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

1) updated original rt0 to remove libstrongswan dependency

a) identity credential being made/accessed with openssl api calls

(X509/EVP_PKEY pem)

b) attribute credential being made/access via xmlsec1 (custom XML

structure)

2) refactored libcreddy into libabac and now one ABAC namespace for

libabac

3) added attribute_rule suboption to creddy's attribute as another way

to insert access rule

4) added some regression tests into example directory
5) updated some docs.

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