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