1 /* $NetBSD: mech.h,v 1.4 2011/02/12 23:21:32 christos Exp $ */
2
3 /* Copyright (c) 2010 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Mateusz Kocielski.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #ifndef _MECH_H_
39 #define _MECH_H_
40
41 #include <sys/queue.h>
42
43 #include <assert.h>
44 #include <stdint.h>
45
46 #include "dict.h"
47 #include "list.h"
48
49 /** mechanism status */
50 enum {
51 STATUS_AUTHENTICATION, /**< authentication in progress */
52 STATUS_AUTHENTICATED /**< session authenticated. this value is used
53 * after last step of the authentication and
54 * means only that last step was performed. */
55 };
56
57 /* mechanism cont return values - used by _cont() functions */
58 enum {
59 MECH_ERROR = -1, /* error */
60 MECH_OK = 0, /* mechanism authenticated */
61 MECH_STEP = 1 /* mechanism needs one or more steps more */
62 };
63
64 /* qop enums and flags */
65 /* NB: used to index saslc__mech_qop_tbl[] */
66 typedef enum {
67 QOP_NONE = 0, /* no QOP layer */
68 QOP_INT = 1, /* integrity */
69 QOP_CONF = 2 /* confirmation */
70 } saslc__mech_sess_qop_t;
71
72 /* NB: These flags must match the security layer flags provided by the
73 * GSSAPI server. See RFC 2222 section 7.2.3 and RFC 4752 section 3.3. */
74 #define F_QOP_NONE (1 << QOP_NONE)
75 #define F_QOP_INT (1 << QOP_INT)
76 #define F_QOP_CONF (1 << QOP_CONF)
77
78 /* mechanism session */
79 typedef struct saslc__mech_sess_t {
80 uint32_t status; /**< status of authentication */
81 uint32_t step; /**< step counter */
82 saslc__mech_sess_qop_t qop; /**< quality of protection layer */
83 } saslc__mech_sess_t;
84
85 /* mechanism functions */
86 typedef int (*saslc__mech_create_t)(saslc_sess_t *);
87 typedef int (*saslc__mech_cont_t)(saslc_sess_t *, const void *, size_t,
88 void **, size_t *);
89 typedef ssize_t (*saslc__mech_xxcode_t)(saslc_sess_t *, const void *, size_t,
90 void **, size_t *);
91 typedef int (*saslc__mech_destroy_t)(saslc_sess_t *);
92
93 /** mechanism structure */
94 typedef struct saslc__mech_t {
95 const char *name; /**< mechanism name */
96 const uint32_t flags; /**< mechanism flags */
97 #define FLAG_NONE 0 /**< no flags */
98 #define FLAG_ANONYMOUS (1 << 0) /**< anonymous authentication */
99 #define FLAG_PLAINTEXT (1 << 1) /**< mechanism uses plaintext
100 for sharing secrets */
101 #define FLAG_DICTIONARY (1 << 2) /**< dictionary attack against
102 authentication is possible */
103 #define FLAG_ACTIVE (1 << 3) /**< nondictionary active attack
104 against authentication is
105 possible */
106 #define FLAG_MUTUAL (1 << 4) /**< mutual authentication */
107
108 /* see xsess.c:flags_OK() for REJ_FLAGS and REQ_FLAGS meaning */
109 #define REJ_FLAGS (FLAG_ANONYMOUS | FLAG_PLAINTEXT |\
110 FLAG_DICTIONARY | FLAG_ACTIVE)
111 #define REQ_FLAGS (FLAG_MUTUAL)
112
113 saslc__mech_create_t create; /**< create function - creates
114 mechanism instance */
115 saslc__mech_cont_t cont; /**< step function - performs
116 one step of authentication */
117 saslc__mech_xxcode_t encode; /**< encoding function - encodes input
118 according to negotiated security
119 layer */
120 saslc__mech_xxcode_t decode; /**< decoding function - decodes input
121 according to negotiated security
122 layer */
123 saslc__mech_destroy_t destroy; /**< destroy function - destroys
124 mechanism instance */
125 } saslc__mech_t;
126
127 /* mechanism list */
128
129 /** mechanisms list node */
130 typedef struct saslc__mech_list_node_t {
131 LIST_ENTRY(saslc__mech_list_node_t) nodes; /**< nodes */
132 const saslc__mech_t *mech; /**< mechanism */
133 saslc__dict_t *prop; /**< mechanism config */
134 } saslc__mech_list_node_t;
135
136 /* mechanisms list head */
137 typedef struct saslc__mech_list_t saslc__mech_list_t;
138 LIST_HEAD(saslc__mech_list_t, saslc__mech_list_node_t);
139
140 /* mechanism list functions */
141 saslc__mech_list_t *saslc__mech_list_create(saslc_t *);
142 void saslc__mech_list_destroy(saslc__mech_list_t *);
143 saslc__mech_list_node_t *saslc__mech_list_get(saslc__mech_list_t *,
144 const char *);
145
146 /* generic functions */
147 int saslc__mech_generic_create(saslc_sess_t *);
148 int saslc__mech_generic_destroy(saslc_sess_t *);
149
150 /* additional functions */
151 int saslc__mech_strdup(saslc_sess_t *, char **, size_t *, const char *,
152 const char *);
153
154 /* qop inline routines */
155 extern const named_flag_t saslc__mech_qop_tbl[4];
156
157 static inline const char *
saslc__mech_qop_name(saslc__mech_sess_qop_t qop)158 saslc__mech_qop_name(saslc__mech_sess_qop_t qop)
159 {
160
161 /* NULL terminated table */
162 assert(qop < __arraycount(saslc__mech_qop_tbl) - 1);
163 return saslc__mech_qop_tbl[qop].name;
164 }
165
166 static inline int
saslc__mech_qop_flag(saslc__mech_sess_qop_t qop)167 saslc__mech_qop_flag(saslc__mech_sess_qop_t qop)
168 {
169
170 /* NULL terminated table */
171 assert(qop < __arraycount(saslc__mech_qop_tbl) - 1);
172 return saslc__mech_qop_tbl[qop].flag;
173 }
174
175 static inline unsigned int
saslc__mech_qop_list_flags(list_t * list)176 saslc__mech_qop_list_flags(list_t *list)
177 {
178
179 return saslc__list_flags(list, saslc__mech_qop_tbl);
180 }
181
182 #endif /* ! _MECH_H_ */
183