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 return (FALSE); 106 *oidp = oid; 107 } 108 break; 109 110 case XDR_FREE: 111 oid = *oidp; 112 if (oid) { 113 xdr_gss_OID_desc(xdrs, oid); 114 mem_free(oid, sizeof(gss_OID_desc)); 115 } 116 } 117 118 return (TRUE); 119 } 120 121 bool_t 122 xdr_gss_OID_set_desc(XDR *xdrs, gss_OID_set_desc *set) 123 { 124 caddr_t addr; 125 u_int len; 126 127 len = set->count; 128 addr = (caddr_t) set->elements; 129 if (!xdr_array(xdrs, &addr, &len, ~0, sizeof(gss_OID_desc), 130 (xdrproc_t) xdr_gss_OID_desc)) 131 return (FALSE); 132 set->count = len; 133 set->elements = (gss_OID) addr; 134 135 return (TRUE); 136 } 137 138 bool_t 139 xdr_gss_OID_set(XDR *xdrs, gss_OID_set *setp) 140 { 141 gss_OID_set set; 142 bool_t is_null; 143 144 switch (xdrs->x_op) { 145 case XDR_ENCODE: 146 set = *setp; 147 if (set) { 148 is_null = FALSE; 149 if (!xdr_bool(xdrs, &is_null) 150 || !xdr_gss_OID_set_desc(xdrs, set)) 151 return (FALSE); 152 } else { 153 is_null = TRUE; 154 if (!xdr_bool(xdrs, &is_null)) 155 return (FALSE); 156 } 157 break; 158 159 case XDR_DECODE: 160 if (!xdr_bool(xdrs, &is_null)) 161 return (FALSE); 162 if (is_null) { 163 *setp = GSS_C_NO_OID_SET; 164 } else { 165 set = mem_alloc(sizeof(gss_OID_set_desc)); 166 memset(set, 0, sizeof(*set)); 167 if (!xdr_gss_OID_set_desc(xdrs, set)) 168 return (FALSE); 169 *setp = set; 170 } 171 break; 172 173 case XDR_FREE: 174 set = *setp; 175 if (set) { 176 xdr_gss_OID_set_desc(xdrs, set); 177 mem_free(set, sizeof(gss_OID_set_desc)); 178 } 179 } 180 181 return (TRUE); 182 } 183 184 bool_t 185 xdr_gss_channel_bindings_t(XDR *xdrs, gss_channel_bindings_t *chp) 186 { 187 gss_channel_bindings_t ch; 188 bool_t is_null; 189 190 switch (xdrs->x_op) { 191 case XDR_ENCODE: 192 ch = *chp; 193 if (ch) { 194 is_null = FALSE; 195 if (!xdr_bool(xdrs, &is_null) 196 || !xdr_uint32_t(xdrs, &ch->initiator_addrtype) 197 || !xdr_gss_buffer_desc(xdrs, 198 &ch->initiator_address) 199 || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 200 || !xdr_gss_buffer_desc(xdrs, 201 &ch->acceptor_address) 202 || !xdr_gss_buffer_desc(xdrs, 203 &ch->application_data)) 204 return (FALSE); 205 } else { 206 is_null = TRUE; 207 if (!xdr_bool(xdrs, &is_null)) 208 return (FALSE); 209 } 210 break; 211 212 case XDR_DECODE: 213 if (!xdr_bool(xdrs, &is_null)) 214 return (FALSE); 215 if (is_null) { 216 *chp = GSS_C_NO_CHANNEL_BINDINGS; 217 } else { 218 ch = mem_alloc(sizeof(*ch)); 219 memset(ch, 0, sizeof(*ch)); 220 if (!xdr_uint32_t(xdrs, &ch->initiator_addrtype) 221 || !xdr_gss_buffer_desc(xdrs, 222 &ch->initiator_address) 223 || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 224 || !xdr_gss_buffer_desc(xdrs, 225 &ch->acceptor_address) 226 || !xdr_gss_buffer_desc(xdrs, 227 &ch->application_data)) 228 return (FALSE); 229 *chp = ch; 230 } 231 break; 232 233 case XDR_FREE: 234 ch = *chp; 235 if (ch) { 236 xdr_gss_buffer_desc(xdrs, &ch->initiator_address); 237 xdr_gss_buffer_desc(xdrs, &ch->acceptor_address); 238 xdr_gss_buffer_desc(xdrs, &ch->application_data); 239 mem_free(ch, sizeof(*ch)); 240 } 241 } 242 243 return (TRUE); 244 } 245