1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 5 * Authors: Doug Rabson <dfr@rabson.org> 6 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #ifdef _KERNEL 34 #include <sys/malloc.h> 35 #else 36 #include <stdlib.h> 37 #include <string.h> 38 #endif 39 40 #include <rpc/rpc.h> 41 #include <rpc/rpc_com.h> 42 43 #include "gssd.h" 44 45 bool_t 46 xdr_gss_buffer_desc(XDR *xdrs, gss_buffer_desc *buf) 47 { 48 char *val; 49 u_int len; 50 51 len = buf->length; 52 val = buf->value; 53 if (!xdr_bytes(xdrs, &val, &len, ~0)) 54 return (FALSE); 55 buf->length = len; 56 buf->value = val; 57 58 return (TRUE); 59 } 60 61 bool_t 62 xdr_gss_OID_desc(XDR *xdrs, gss_OID_desc *oid) 63 { 64 char *val; 65 u_int len; 66 67 len = oid->length; 68 val = oid->elements; 69 if (!xdr_bytes(xdrs, &val, &len, ~0)) 70 return (FALSE); 71 oid->length = len; 72 oid->elements = val; 73 74 return (TRUE); 75 } 76 77 bool_t 78 xdr_gss_OID(XDR *xdrs, gss_OID *oidp) 79 { 80 gss_OID oid; 81 bool_t is_null; 82 83 switch (xdrs->x_op) { 84 case XDR_ENCODE: 85 oid = *oidp; 86 if (oid) { 87 is_null = FALSE; 88 if (!xdr_bool(xdrs, &is_null) 89 || !xdr_gss_OID_desc(xdrs, oid)) 90 return (FALSE); 91 } else { 92 is_null = TRUE; 93 if (!xdr_bool(xdrs, &is_null)) 94 return (FALSE); 95 } 96 break; 97 98 case XDR_DECODE: 99 if (!xdr_bool(xdrs, &is_null)) 100 return (FALSE); 101 if (is_null) { 102 *oidp = GSS_C_NO_OID; 103 } else { 104 oid = mem_alloc(sizeof(gss_OID_desc)); 105 memset(oid, 0, sizeof(*oid)); 106 if (!xdr_gss_OID_desc(xdrs, oid)) { 107 mem_free(oid, sizeof(gss_OID_desc)); 108 return (FALSE); 109 } 110 *oidp = oid; 111 } 112 break; 113 114 case XDR_FREE: 115 oid = *oidp; 116 if (oid) { 117 xdr_gss_OID_desc(xdrs, oid); 118 mem_free(oid, sizeof(gss_OID_desc)); 119 } 120 } 121 122 return (TRUE); 123 } 124 125 bool_t 126 xdr_gss_OID_set_desc(XDR *xdrs, gss_OID_set_desc *set) 127 { 128 caddr_t addr; 129 u_int len; 130 131 len = set->count; 132 addr = (caddr_t) set->elements; 133 if (!xdr_array(xdrs, &addr, &len, ~0, sizeof(gss_OID_desc), 134 (xdrproc_t) xdr_gss_OID_desc)) 135 return (FALSE); 136 set->count = len; 137 set->elements = (gss_OID) addr; 138 139 return (TRUE); 140 } 141 142 bool_t 143 xdr_gss_OID_set(XDR *xdrs, gss_OID_set *setp) 144 { 145 gss_OID_set set; 146 bool_t is_null; 147 148 switch (xdrs->x_op) { 149 case XDR_ENCODE: 150 set = *setp; 151 if (set) { 152 is_null = FALSE; 153 if (!xdr_bool(xdrs, &is_null) 154 || !xdr_gss_OID_set_desc(xdrs, set)) 155 return (FALSE); 156 } else { 157 is_null = TRUE; 158 if (!xdr_bool(xdrs, &is_null)) 159 return (FALSE); 160 } 161 break; 162 163 case XDR_DECODE: 164 if (!xdr_bool(xdrs, &is_null)) 165 return (FALSE); 166 if (is_null) { 167 *setp = GSS_C_NO_OID_SET; 168 } else { 169 set = mem_alloc(sizeof(gss_OID_set_desc)); 170 memset(set, 0, sizeof(*set)); 171 if (!xdr_gss_OID_set_desc(xdrs, set)) { 172 mem_free(set, sizeof(gss_OID_set_desc)); 173 return (FALSE); 174 } 175 *setp = set; 176 } 177 break; 178 179 case XDR_FREE: 180 set = *setp; 181 if (set) { 182 xdr_gss_OID_set_desc(xdrs, set); 183 mem_free(set, sizeof(gss_OID_set_desc)); 184 } 185 } 186 187 return (TRUE); 188 } 189 190 bool_t 191 xdr_gss_channel_bindings_t(XDR *xdrs, gss_channel_bindings_t *chp) 192 { 193 gss_channel_bindings_t ch; 194 bool_t is_null; 195 196 switch (xdrs->x_op) { 197 case XDR_ENCODE: 198 ch = *chp; 199 if (ch) { 200 is_null = FALSE; 201 if (!xdr_bool(xdrs, &is_null) 202 || !xdr_uint32_t(xdrs, &ch->initiator_addrtype) 203 || !xdr_gss_buffer_desc(xdrs, 204 &ch->initiator_address) 205 || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 206 || !xdr_gss_buffer_desc(xdrs, 207 &ch->acceptor_address) 208 || !xdr_gss_buffer_desc(xdrs, 209 &ch->application_data)) 210 return (FALSE); 211 } else { 212 is_null = TRUE; 213 if (!xdr_bool(xdrs, &is_null)) 214 return (FALSE); 215 } 216 break; 217 218 case XDR_DECODE: 219 if (!xdr_bool(xdrs, &is_null)) 220 return (FALSE); 221 if (is_null) { 222 *chp = GSS_C_NO_CHANNEL_BINDINGS; 223 } else { 224 ch = mem_alloc(sizeof(*ch)); 225 memset(ch, 0, sizeof(*ch)); 226 if (!xdr_uint32_t(xdrs, &ch->initiator_addrtype) 227 || !xdr_gss_buffer_desc(xdrs, 228 &ch->initiator_address) 229 || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 230 || !xdr_gss_buffer_desc(xdrs, 231 &ch->acceptor_address) 232 || !xdr_gss_buffer_desc(xdrs, 233 &ch->application_data)) { 234 mem_free(ch, sizeof(*ch)); 235 return (FALSE); 236 } 237 *chp = ch; 238 } 239 break; 240 241 case XDR_FREE: 242 ch = *chp; 243 if (ch) { 244 xdr_gss_buffer_desc(xdrs, &ch->initiator_address); 245 xdr_gss_buffer_desc(xdrs, &ch->acceptor_address); 246 xdr_gss_buffer_desc(xdrs, &ch->application_data); 247 mem_free(ch, sizeof(*ch)); 248 } 249 } 250 251 return (TRUE); 252 } 253