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 * 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 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 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