6a6dfe15f3187894ecf3a50ec76f2253f1e894ae
[mech_eap.git] / mech_eap / util_attr.h
1 /*
2  * Copyright (c) 2011, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 /*
34  * Attribute provider interface.
35  */
36
37 #ifndef _UTIL_ATTR_H_
38 #define _UTIL_ATTR_H_ 1
39
40 #ifdef __cplusplus
41 #include <string>
42 #include <new>
43
44 #include "gssapi_headerfix.h"
45
46 using namespace gss_eap_util;
47
48 struct gss_eap_attr_provider;
49 struct gss_eap_attr_ctx;
50
51 typedef bool
52 (*gss_eap_attr_enumeration_cb)(const gss_eap_attr_ctx *ctx,
53                                const gss_eap_attr_provider *source,
54                                const gss_buffer_t attribute,
55                                void *data);
56
57 #define ATTR_TYPE_RADIUS            0U                  /* RADIUS AVPs */
58 #ifdef HAVE_OPENSAML
59 #define ATTR_TYPE_SAML_ASSERTION    1U                  /* SAML assertion */
60 #define ATTR_TYPE_SAML              2U                  /* SAML attributes */
61 #endif
62 #define ATTR_TYPE_LOCAL             3U                  /* Local attributes */
63 #define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
64 #define ATTR_TYPE_MAX               ATTR_TYPE_LOCAL
65
66 #define ATTR_FLAG_DISABLE_LOCAL     0x00000001
67
68 /*
69  * Attribute provider: this represents a source of attributes derived
70  * from the security context.
71  */
72 struct gss_eap_attr_provider
73 {
74 public:
75     gss_eap_attr_provider(void) {}
76     virtual ~gss_eap_attr_provider(void) {}
77
78     bool initWithManager(const gss_eap_attr_ctx *manager)
79     {
80         m_manager = manager;
81         return true;
82     }
83
84     virtual bool initWithExistingContext(const gss_eap_attr_ctx *manager,
85                                          const gss_eap_attr_provider *ctx GSSEAP_UNUSED)
86     {
87         return initWithManager(manager);
88     }
89
90     virtual bool initWithGssContext(const gss_eap_attr_ctx *manager,
91                                     const gss_cred_id_t cred GSSEAP_UNUSED,
92                                     const gss_ctx_id_t ctx GSSEAP_UNUSED)
93     {
94         return initWithManager(manager);
95     }
96
97     virtual bool getAttributeTypes(gss_eap_attr_enumeration_cb GSSEAP_UNUSED,
98                                    void *data GSSEAP_UNUSED) const
99     {
100         return false;
101     }
102
103     virtual bool setAttribute(int complete GSSEAP_UNUSED,
104                               const gss_buffer_t attr GSSEAP_UNUSED,
105                               const gss_buffer_t value GSSEAP_UNUSED)
106     {
107         return false;
108     }
109
110     virtual bool deleteAttribute(const gss_buffer_t value GSSEAP_UNUSED)
111     {
112         return false;
113     }
114
115     virtual bool getAttribute(const gss_buffer_t attr GSSEAP_UNUSED,
116                               int *authenticated GSSEAP_UNUSED,
117                               int *complete GSSEAP_UNUSED,
118                               gss_buffer_t value GSSEAP_UNUSED,
119                               gss_buffer_t display_value GSSEAP_UNUSED,
120                               int *more GSSEAP_UNUSED) const
121     {
122         return false;
123     }
124
125     virtual gss_any_t mapToAny(int authenticated GSSEAP_UNUSED,
126                                gss_buffer_t type_id GSSEAP_UNUSED) const
127     {
128         return NULL;
129     }
130
131     virtual void releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED,
132                                        gss_any_t input GSSEAP_UNUSED) const
133     {
134     }
135
136     /* prefix to be prepended to attributes emitted by gss_get_name_attribute */
137     virtual const char *prefix(void) const
138     {
139         return NULL;
140     }
141
142     /* optional key for storing JSON dictionary */
143     virtual const char *name(void) const
144     {
145         return NULL;
146     }
147
148     virtual bool initWithJsonObject(const gss_eap_attr_ctx *manager,
149                                     JSONObject &object GSSEAP_UNUSED)
150     {
151         return initWithManager(manager);
152     }
153
154
155     virtual JSONObject jsonRepresentation(void) const
156     {
157         return JSONObject::null();
158     }
159
160     virtual time_t getExpiryTime(void) const { return 0; }
161
162     virtual OM_uint32 mapException(OM_uint32 *minor GSSEAP_UNUSED,
163                                    std::exception &e GSSEAP_UNUSED) const
164     {
165         return GSS_S_CONTINUE_NEEDED;
166     }
167
168     static bool init(void) { return true; }
169     static void finalize(void) {}
170
171     static gss_eap_attr_provider *createAttrContext(void) { return NULL; }
172
173 protected:
174     const gss_eap_attr_ctx *m_manager;
175
176 private:
177     /* make non-copyable */
178     gss_eap_attr_provider(const gss_eap_attr_provider&);
179     gss_eap_attr_provider& operator=(const gss_eap_attr_provider&);
180 };
181
182 typedef gss_eap_attr_provider *(*gss_eap_attr_create_provider)(void);
183
184 /*
185  * Attribute context: this manages a set of providers for a given
186  * security context.
187  */
188 struct gss_eap_attr_ctx
189 {
190 public:
191     gss_eap_attr_ctx(void);
192     ~gss_eap_attr_ctx(void);
193
194     bool initWithExistingContext(const gss_eap_attr_ctx *manager);
195     bool initWithGssContext(const gss_cred_id_t cred,
196                             const gss_ctx_id_t ctx);
197
198     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
199     bool getAttributeTypes(gss_buffer_set_t *attrs);
200
201     bool setAttribute(int complete,
202                       const gss_buffer_t attr,
203                       const gss_buffer_t value);
204     bool deleteAttribute(const gss_buffer_t value);
205     bool getAttribute(const gss_buffer_t attr,
206                       int *authenticated,
207                       int *complete,
208                       gss_buffer_t value,
209                       gss_buffer_t display_value,
210                       int *more) const;
211     gss_any_t mapToAny(int authenticated,
212                        gss_buffer_t type_id) const;
213     void releaseAnyNameMapping(gss_buffer_t type_id,
214                                gss_any_t input) const;
215
216     void exportToBuffer(gss_buffer_t buffer) const;
217     bool initWithBuffer(const gss_buffer_t buffer);
218
219     static std::string
220     composeAttributeName(const gss_buffer_t prefix,
221                          const gss_buffer_t suffix);
222     static void
223     decomposeAttributeName(const gss_buffer_t attribute,
224                            gss_buffer_t prefix,
225                            gss_buffer_t suffix);
226     static void
227     composeAttributeName(const gss_buffer_t prefix,
228                          const gss_buffer_t suffix,
229                          gss_buffer_t attribute);
230
231     std::string
232     composeAttributeName(unsigned int type,
233                          const gss_buffer_t suffix);
234     void
235     decomposeAttributeName(const gss_buffer_t attribute,
236                            unsigned int *type,
237                            gss_buffer_t suffix) const;
238     void
239     composeAttributeName(unsigned int type,
240                          const gss_buffer_t suffix,
241                          gss_buffer_t attribute) const;
242
243     gss_eap_attr_provider *getProvider(unsigned int type) const;
244
245     static void
246     registerProvider(unsigned int type,
247                      gss_eap_attr_create_provider factory);
248     static void
249     unregisterProvider(unsigned int type);
250
251     time_t getExpiryTime(void) const;
252     OM_uint32 mapException(OM_uint32 *minor, std::exception &e) const;
253
254 private:
255     bool providerEnabled(unsigned int type) const;
256     void releaseProvider(unsigned int type);
257
258     unsigned int attributePrefixToType(const gss_buffer_t prefix) const;
259     gss_buffer_desc attributeTypeToPrefix(unsigned int type) const;
260
261     bool initWithJsonObject(JSONObject &object);
262     JSONObject jsonRepresentation(void) const;
263
264     gss_eap_attr_provider *getPrimaryProvider(void) const;
265
266     /* make non-copyable */
267     gss_eap_attr_ctx(const gss_eap_attr_ctx&);
268     gss_eap_attr_ctx& operator=(const gss_eap_attr_ctx&);
269
270     uint32_t m_flags;
271     gss_eap_attr_provider *m_providers[ATTR_TYPE_MAX + 1];
272 };
273
274 #endif /* __cplusplus */
275
276 #include "util_radius.h"
277 #include "util_saml.h"
278 #include "util_shib.h"
279
280 #ifdef __cplusplus
281
282 static inline void
283 duplicateBuffer(gss_buffer_desc &src, gss_buffer_t dst)
284 {
285     OM_uint32 minor;
286
287     if (GSS_ERROR(duplicateBuffer(&minor, &src, dst)))
288         throw std::bad_alloc();
289 }
290
291 static inline void
292 duplicateBuffer(std::string &str, gss_buffer_t buffer)
293 {
294     gss_buffer_desc tmp;
295
296     tmp.length = str.length();
297     tmp.value = (char *)str.c_str();
298
299     duplicateBuffer(tmp, buffer);
300 }
301
302 #else
303 struct gss_eap_attr_ctx;
304 #endif
305
306 #ifdef __cplusplus
307 extern "C" {
308 #endif
309
310 /*
311  * C wrappers for attribute context functions. These match their
312  * GSS naming extension equivalents. The caller is required to
313  * obtain the name mutex.
314  */
315
316 OM_uint32
317 gssEapCreateAttrContext(OM_uint32 *minor,
318                         gss_cred_id_t acceptorCred,
319                         gss_ctx_id_t acceptorCtx,
320                         struct gss_eap_attr_ctx **pAttrCtx,
321                         time_t *pExpiryTime);
322
323 OM_uint32
324 gssEapInquireName(OM_uint32 *minor,
325                   gss_name_t name,
326                   int *name_is_MN,
327                   gss_OID *MN_mech,
328                   gss_buffer_set_t *attrs);
329
330 OM_uint32
331 gssEapGetNameAttribute(OM_uint32 *minor,
332                        gss_name_t name,
333                        gss_buffer_t attr,
334                        int *authenticated,
335                        int *complete,
336                        gss_buffer_t value,
337                        gss_buffer_t display_value,
338                        int *more);
339
340 OM_uint32
341 gssEapDeleteNameAttribute(OM_uint32 *minor,
342                           gss_name_t name,
343                           gss_buffer_t attr);
344
345 OM_uint32
346 gssEapSetNameAttribute(OM_uint32 *minor,
347                        gss_name_t name,
348                        int complete,
349                        gss_buffer_t attr,
350                        gss_buffer_t value);
351
352 OM_uint32
353 gssEapExportAttrContext(OM_uint32 *minor,
354                         gss_const_name_t name,
355                         gss_buffer_t buffer);
356
357 OM_uint32
358 gssEapImportAttrContext(OM_uint32 *minor,
359                         gss_buffer_t buffer,
360                         gss_name_t name);
361
362 OM_uint32
363 gssEapDuplicateAttrContext(OM_uint32 *minor,
364                            gss_const_name_t in,
365                            gss_name_t out);
366
367 OM_uint32
368 gssEapMapNameToAny(OM_uint32 *minor,
369                    gss_name_t name,
370                    int authenticated,
371                    gss_buffer_t type_id,
372                    gss_any_t *output);
373
374 OM_uint32
375 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
376                             gss_name_t name,
377                             gss_buffer_t type_id,
378                             gss_any_t *input);
379
380 OM_uint32
381 gssEapReleaseAttrContext(OM_uint32 *minor,
382                          gss_name_t name);
383
384 #ifdef __cplusplus
385 }
386 #endif
387
388 #endif /* _UTIL_ATTR_H_ */