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