Fixes for Heimdal (macOS) builds from Stefan.
[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 #ifndef HAVE_HEIMDAL_VERSION
45 #include "gssapi_headerfix.h"
46 #endif
47
48 using namespace gss_eap_util;
49
50 struct gss_eap_attr_provider;
51 struct gss_eap_attr_ctx;
52
53 typedef bool
54 (*gss_eap_attr_enumeration_cb)(const gss_eap_attr_ctx *ctx,
55                                const gss_eap_attr_provider *source,
56                                const gss_buffer_t attribute,
57                                void *data);
58
59 #define ATTR_TYPE_RADIUS            0U                  /* RADIUS AVPs */
60 #ifdef HAVE_OPENSAML
61 #define ATTR_TYPE_SAML_ASSERTION    1U                  /* SAML assertion */
62 #define ATTR_TYPE_SAML              2U                  /* SAML attributes */
63 #endif
64 #define ATTR_TYPE_LOCAL             3U                  /* Local attributes */
65 #define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
66 #define ATTR_TYPE_MAX               ATTR_TYPE_LOCAL
67
68 #define ATTR_FLAG_DISABLE_LOCAL     0x00000001
69
70 /*
71  * Attribute provider: this represents a source of attributes derived
72  * from the security context.
73  */
74 struct gss_eap_attr_provider
75 {
76 public:
77     gss_eap_attr_provider(void) {}
78     virtual ~gss_eap_attr_provider(void) {}
79
80     bool initWithManager(const gss_eap_attr_ctx *manager)
81     {
82         m_manager = manager;
83         return true;
84     }
85
86     virtual bool initWithExistingContext(const gss_eap_attr_ctx *manager,
87                                          const gss_eap_attr_provider *ctx GSSEAP_UNUSED)
88     {
89         return initWithManager(manager);
90     }
91
92     virtual bool initWithGssContext(const gss_eap_attr_ctx *manager,
93                                     const gss_cred_id_t cred GSSEAP_UNUSED,
94                                     const gss_ctx_id_t ctx GSSEAP_UNUSED)
95     {
96         return initWithManager(manager);
97     }
98
99     virtual bool getAttributeTypes(gss_eap_attr_enumeration_cb GSSEAP_UNUSED,
100                                    void *data GSSEAP_UNUSED) const
101     {
102         return false;
103     }
104
105     virtual bool setAttribute(int complete GSSEAP_UNUSED,
106                               const gss_buffer_t attr GSSEAP_UNUSED,
107                               const gss_buffer_t value GSSEAP_UNUSED)
108     {
109         return false;
110     }
111
112     virtual bool deleteAttribute(const gss_buffer_t value GSSEAP_UNUSED)
113     {
114         return false;
115     }
116
117     virtual bool getAttribute(const gss_buffer_t attr GSSEAP_UNUSED,
118                               int *authenticated GSSEAP_UNUSED,
119                               int *complete GSSEAP_UNUSED,
120                               gss_buffer_t value GSSEAP_UNUSED,
121                               gss_buffer_t display_value GSSEAP_UNUSED,
122                               int *more GSSEAP_UNUSED) const
123     {
124         return false;
125     }
126
127     virtual gss_any_t mapToAny(int authenticated GSSEAP_UNUSED,
128                                gss_buffer_t type_id GSSEAP_UNUSED) const
129     {
130         return NULL;
131     }
132
133     virtual void releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED,
134                                        gss_any_t input GSSEAP_UNUSED) const
135     {
136     }
137
138     /* prefix to be prepended to attributes emitted by gss_get_name_attribute */
139     virtual const char *prefix(void) const
140     {
141         return NULL;
142     }
143
144     /* optional key for storing JSON dictionary */
145     virtual const char *name(void) const
146     {
147         return NULL;
148     }
149
150     virtual bool initWithJsonObject(const gss_eap_attr_ctx *manager,
151                                     JSONObject &object GSSEAP_UNUSED)
152     {
153         return initWithManager(manager);
154     }
155
156
157     virtual JSONObject jsonRepresentation(void) const
158     {
159         return JSONObject::null();
160     }
161
162     virtual time_t getExpiryTime(void) const { return 0; }
163
164     virtual OM_uint32 mapException(OM_uint32 *minor GSSEAP_UNUSED,
165                                    std::exception &e GSSEAP_UNUSED) const
166     {
167         return GSS_S_CONTINUE_NEEDED;
168     }
169
170     static bool init(void) { return true; }
171     static void finalize(void) {}
172
173     static gss_eap_attr_provider *createAttrContext(void) { return NULL; }
174
175 protected:
176     const gss_eap_attr_ctx *m_manager;
177
178 private:
179     /* make non-copyable */
180     gss_eap_attr_provider(const gss_eap_attr_provider&);
181     gss_eap_attr_provider& operator=(const gss_eap_attr_provider&);
182 };
183
184 typedef gss_eap_attr_provider *(*gss_eap_attr_create_provider)(void);
185
186 /*
187  * Attribute context: this manages a set of providers for a given
188  * security context.
189  */
190 struct gss_eap_attr_ctx
191 {
192 public:
193     gss_eap_attr_ctx(void);
194     ~gss_eap_attr_ctx(void);
195
196     bool initWithExistingContext(const gss_eap_attr_ctx *manager);
197     bool initWithGssContext(const gss_cred_id_t cred,
198                             const gss_ctx_id_t ctx);
199
200     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
201     bool getAttributeTypes(gss_buffer_set_t *attrs);
202
203     bool setAttribute(int complete,
204                       const gss_buffer_t attr,
205                       const gss_buffer_t value);
206     bool deleteAttribute(const gss_buffer_t value);
207     bool getAttribute(const gss_buffer_t attr,
208                       int *authenticated,
209                       int *complete,
210                       gss_buffer_t value,
211                       gss_buffer_t display_value,
212                       int *more) const;
213     gss_any_t mapToAny(int authenticated,
214                        gss_buffer_t type_id) const;
215     void releaseAnyNameMapping(gss_buffer_t type_id,
216                                gss_any_t input) const;
217
218     void exportToBuffer(gss_buffer_t buffer) const;
219     bool initWithBuffer(const gss_buffer_t buffer);
220
221     static std::string
222     composeAttributeName(const gss_buffer_t prefix,
223                          const gss_buffer_t suffix);
224     static void
225     decomposeAttributeName(const gss_buffer_t attribute,
226                            gss_buffer_t prefix,
227                            gss_buffer_t suffix);
228     static void
229     composeAttributeName(const gss_buffer_t prefix,
230                          const gss_buffer_t suffix,
231                          gss_buffer_t attribute);
232
233     std::string
234     composeAttributeName(unsigned int type,
235                          const gss_buffer_t suffix);
236     void
237     decomposeAttributeName(const gss_buffer_t attribute,
238                            unsigned int *type,
239                            gss_buffer_t suffix) const;
240     void
241     composeAttributeName(unsigned int type,
242                          const gss_buffer_t suffix,
243                          gss_buffer_t attribute) const;
244
245     gss_eap_attr_provider *getProvider(unsigned int type) const;
246
247     static void
248     registerProvider(unsigned int type,
249                      gss_eap_attr_create_provider factory);
250     static void
251     unregisterProvider(unsigned int type);
252
253     time_t getExpiryTime(void) const;
254     OM_uint32 mapException(OM_uint32 *minor, std::exception &e) const;
255
256 private:
257     bool providerEnabled(unsigned int type) const;
258     void releaseProvider(unsigned int type);
259
260     unsigned int attributePrefixToType(const gss_buffer_t prefix) const;
261     gss_buffer_desc attributeTypeToPrefix(unsigned int type) const;
262
263     bool initWithJsonObject(JSONObject &object);
264     JSONObject jsonRepresentation(void) const;
265
266     gss_eap_attr_provider *getPrimaryProvider(void) const;
267
268     /* make non-copyable */
269     gss_eap_attr_ctx(const gss_eap_attr_ctx&);
270     gss_eap_attr_ctx& operator=(const gss_eap_attr_ctx&);
271
272     uint32_t m_flags;
273     gss_eap_attr_provider *m_providers[ATTR_TYPE_MAX + 1];
274 };
275
276 #endif /* __cplusplus */
277
278 #include "util_radius.h"
279 #include "util_saml.h"
280 #include "util_shib.h"
281
282 #ifdef __cplusplus
283
284 static inline void
285 duplicateBuffer(gss_buffer_desc &src, gss_buffer_t dst)
286 {
287     OM_uint32 minor;
288
289     if (GSS_ERROR(duplicateBuffer(&minor, &src, dst)))
290         throw std::bad_alloc();
291 }
292
293 static inline void
294 duplicateBuffer(std::string &str, gss_buffer_t buffer)
295 {
296     gss_buffer_desc tmp;
297
298     tmp.length = str.length();
299     tmp.value = (char *)str.c_str();
300
301     duplicateBuffer(tmp, buffer);
302 }
303
304 #else
305 struct gss_eap_attr_ctx;
306 #endif
307
308 #ifdef __cplusplus
309 extern "C" {
310 #endif
311
312 /*
313  * C wrappers for attribute context functions. These match their
314  * GSS naming extension equivalents. The caller is required to
315  * obtain the name mutex.
316  */
317
318 OM_uint32
319 gssEapCreateAttrContext(OM_uint32 *minor,
320                         gss_cred_id_t acceptorCred,
321                         gss_ctx_id_t acceptorCtx,
322                         struct gss_eap_attr_ctx **pAttrCtx,
323                         time_t *pExpiryTime);
324
325 OM_uint32
326 gssEapInquireName(OM_uint32 *minor,
327                   gss_name_t name,
328                   int *name_is_MN,
329                   gss_OID *MN_mech,
330                   gss_buffer_set_t *attrs);
331
332 OM_uint32
333 gssEapGetNameAttribute(OM_uint32 *minor,
334                        gss_name_t name,
335                        gss_buffer_t attr,
336                        int *authenticated,
337                        int *complete,
338                        gss_buffer_t value,
339                        gss_buffer_t display_value,
340                        int *more);
341
342 OM_uint32
343 gssEapDeleteNameAttribute(OM_uint32 *minor,
344                           gss_name_t name,
345                           gss_buffer_t attr);
346
347 OM_uint32
348 gssEapSetNameAttribute(OM_uint32 *minor,
349                        gss_name_t name,
350                        int complete,
351                        gss_buffer_t attr,
352                        gss_buffer_t value);
353
354 OM_uint32
355 gssEapExportAttrContext(OM_uint32 *minor,
356                         gss_const_name_t name,
357                         gss_buffer_t buffer);
358
359 OM_uint32
360 gssEapImportAttrContext(OM_uint32 *minor,
361                         gss_buffer_t buffer,
362                         gss_name_t name);
363
364 OM_uint32
365 gssEapDuplicateAttrContext(OM_uint32 *minor,
366                            gss_const_name_t in,
367                            gss_name_t out);
368
369 OM_uint32
370 gssEapMapNameToAny(OM_uint32 *minor,
371                    gss_name_t name,
372                    int authenticated,
373                    gss_buffer_t type_id,
374                    gss_any_t *output);
375
376 OM_uint32
377 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
378                             gss_name_t name,
379                             gss_buffer_t type_id,
380                             gss_any_t *input);
381
382 OM_uint32
383 gssEapReleaseAttrContext(OM_uint32 *minor,
384                          gss_name_t name);
385
386 #ifdef __cplusplus
387 }
388 #endif
389
390 #endif /* _UTIL_ATTR_H_ */