1184588Sdfr/*- 2184588Sdfr * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 3184588Sdfr * Authors: Doug Rabson <dfr@rabson.org> 4184588Sdfr * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 5184588Sdfr * 6184588Sdfr * Redistribution and use in source and binary forms, with or without 7184588Sdfr * modification, are permitted provided that the following conditions 8184588Sdfr * are met: 9184588Sdfr * 1. Redistributions of source code must retain the above copyright 10184588Sdfr * notice, this list of conditions and the following disclaimer. 11184588Sdfr * 2. Redistributions in binary form must reproduce the above copyright 12184588Sdfr * notice, this list of conditions and the following disclaimer in the 13184588Sdfr * documentation and/or other materials provided with the distribution. 14184588Sdfr * 15184588Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16184588Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17184588Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18184588Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19184588Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20184588Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21184588Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22184588Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23184588Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24184588Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25184588Sdfr * SUCH DAMAGE. 26184588Sdfr */ 27184588Sdfr 28184588Sdfr#include <sys/cdefs.h> 29184588Sdfr__FBSDID("$FreeBSD$"); 30184588Sdfr 31184588Sdfr#ifdef _KERNEL 32184588Sdfr#include <sys/malloc.h> 33184588Sdfr#else 34184588Sdfr#include <stdlib.h> 35184588Sdfr#include <string.h> 36184588Sdfr#endif 37184588Sdfr 38184588Sdfr#include <rpc/rpc.h> 39184588Sdfr#include <rpc/rpc_com.h> 40184588Sdfr 41184588Sdfr#include "gssd.h" 42184588Sdfr 43184588Sdfrbool_t 44184588Sdfrxdr_gss_buffer_desc(XDR *xdrs, gss_buffer_desc *buf) 45184588Sdfr{ 46184588Sdfr char *val; 47184588Sdfr u_int len; 48184588Sdfr 49184588Sdfr len = buf->length; 50184588Sdfr val = buf->value; 51184588Sdfr if (!xdr_bytes(xdrs, &val, &len, ~0)) 52184588Sdfr return (FALSE); 53184588Sdfr buf->length = len; 54184588Sdfr buf->value = val; 55184588Sdfr 56184588Sdfr return (TRUE); 57184588Sdfr} 58184588Sdfr 59184588Sdfrbool_t 60184588Sdfrxdr_gss_OID_desc(XDR *xdrs, gss_OID_desc *oid) 61184588Sdfr{ 62184588Sdfr char *val; 63184588Sdfr u_int len; 64184588Sdfr 65184588Sdfr len = oid->length; 66184588Sdfr val = oid->elements; 67184588Sdfr if (!xdr_bytes(xdrs, &val, &len, ~0)) 68184588Sdfr return (FALSE); 69184588Sdfr oid->length = len; 70184588Sdfr oid->elements = val; 71184588Sdfr 72184588Sdfr return (TRUE); 73184588Sdfr} 74184588Sdfr 75184588Sdfrbool_t 76184588Sdfrxdr_gss_OID(XDR *xdrs, gss_OID *oidp) 77184588Sdfr{ 78184588Sdfr gss_OID oid; 79184588Sdfr bool_t is_null; 80184588Sdfr 81184588Sdfr switch (xdrs->x_op) { 82184588Sdfr case XDR_ENCODE: 83184588Sdfr oid = *oidp; 84184588Sdfr if (oid) { 85184588Sdfr is_null = FALSE; 86184588Sdfr if (!xdr_bool(xdrs, &is_null) 87184588Sdfr || !xdr_gss_OID_desc(xdrs, oid)) 88184588Sdfr return (FALSE); 89184588Sdfr } else { 90184588Sdfr is_null = TRUE; 91184588Sdfr if (!xdr_bool(xdrs, &is_null)) 92184588Sdfr return (FALSE); 93184588Sdfr } 94184588Sdfr break; 95184588Sdfr 96184588Sdfr case XDR_DECODE: 97184588Sdfr if (!xdr_bool(xdrs, &is_null)) 98184588Sdfr return (FALSE); 99184588Sdfr if (is_null) { 100184588Sdfr *oidp = GSS_C_NO_OID; 101184588Sdfr } else { 102184588Sdfr oid = mem_alloc(sizeof(gss_OID_desc)); 103184588Sdfr memset(oid, 0, sizeof(*oid)); 104298655Scem if (!xdr_gss_OID_desc(xdrs, oid)) { 105298655Scem mem_free(oid, sizeof(gss_OID_desc)); 106184588Sdfr return (FALSE); 107298655Scem } 108184588Sdfr *oidp = oid; 109184588Sdfr } 110184588Sdfr break; 111184588Sdfr 112184588Sdfr case XDR_FREE: 113184588Sdfr oid = *oidp; 114184588Sdfr if (oid) { 115184588Sdfr xdr_gss_OID_desc(xdrs, oid); 116184588Sdfr mem_free(oid, sizeof(gss_OID_desc)); 117184588Sdfr } 118184588Sdfr } 119184588Sdfr 120184588Sdfr return (TRUE); 121184588Sdfr} 122184588Sdfr 123184588Sdfrbool_t 124184588Sdfrxdr_gss_OID_set_desc(XDR *xdrs, gss_OID_set_desc *set) 125184588Sdfr{ 126184588Sdfr caddr_t addr; 127184588Sdfr u_int len; 128184588Sdfr 129184588Sdfr len = set->count; 130184588Sdfr addr = (caddr_t) set->elements; 131184588Sdfr if (!xdr_array(xdrs, &addr, &len, ~0, sizeof(gss_OID_desc), 132184588Sdfr (xdrproc_t) xdr_gss_OID_desc)) 133184588Sdfr return (FALSE); 134184588Sdfr set->count = len; 135184588Sdfr set->elements = (gss_OID) addr; 136184588Sdfr 137184588Sdfr return (TRUE); 138184588Sdfr} 139184588Sdfr 140184588Sdfrbool_t 141184588Sdfrxdr_gss_OID_set(XDR *xdrs, gss_OID_set *setp) 142184588Sdfr{ 143184588Sdfr gss_OID_set set; 144184588Sdfr bool_t is_null; 145184588Sdfr 146184588Sdfr switch (xdrs->x_op) { 147184588Sdfr case XDR_ENCODE: 148184588Sdfr set = *setp; 149184588Sdfr if (set) { 150184588Sdfr is_null = FALSE; 151184588Sdfr if (!xdr_bool(xdrs, &is_null) 152184588Sdfr || !xdr_gss_OID_set_desc(xdrs, set)) 153184588Sdfr return (FALSE); 154184588Sdfr } else { 155184588Sdfr is_null = TRUE; 156184588Sdfr if (!xdr_bool(xdrs, &is_null)) 157184588Sdfr return (FALSE); 158184588Sdfr } 159184588Sdfr break; 160184588Sdfr 161184588Sdfr case XDR_DECODE: 162184588Sdfr if (!xdr_bool(xdrs, &is_null)) 163184588Sdfr return (FALSE); 164184588Sdfr if (is_null) { 165184588Sdfr *setp = GSS_C_NO_OID_SET; 166184588Sdfr } else { 167184588Sdfr set = mem_alloc(sizeof(gss_OID_set_desc)); 168184588Sdfr memset(set, 0, sizeof(*set)); 169298655Scem if (!xdr_gss_OID_set_desc(xdrs, set)) { 170298655Scem mem_free(set, sizeof(gss_OID_set_desc)); 171184588Sdfr return (FALSE); 172298655Scem } 173184588Sdfr *setp = set; 174184588Sdfr } 175184588Sdfr break; 176184588Sdfr 177184588Sdfr case XDR_FREE: 178184588Sdfr set = *setp; 179184588Sdfr if (set) { 180184588Sdfr xdr_gss_OID_set_desc(xdrs, set); 181184588Sdfr mem_free(set, sizeof(gss_OID_set_desc)); 182184588Sdfr } 183184588Sdfr } 184184588Sdfr 185184588Sdfr return (TRUE); 186184588Sdfr} 187184588Sdfr 188184588Sdfrbool_t 189184588Sdfrxdr_gss_channel_bindings_t(XDR *xdrs, gss_channel_bindings_t *chp) 190184588Sdfr{ 191184588Sdfr gss_channel_bindings_t ch; 192184588Sdfr bool_t is_null; 193184588Sdfr 194184588Sdfr switch (xdrs->x_op) { 195184588Sdfr case XDR_ENCODE: 196184588Sdfr ch = *chp; 197184588Sdfr if (ch) { 198184588Sdfr is_null = FALSE; 199184588Sdfr if (!xdr_bool(xdrs, &is_null) 200184588Sdfr || !xdr_uint32_t(xdrs, &ch->initiator_addrtype) 201184588Sdfr || !xdr_gss_buffer_desc(xdrs, 202184588Sdfr &ch->initiator_address) 203184588Sdfr || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 204184588Sdfr || !xdr_gss_buffer_desc(xdrs, 205184588Sdfr &ch->acceptor_address) 206184588Sdfr || !xdr_gss_buffer_desc(xdrs, 207184588Sdfr &ch->application_data)) 208184588Sdfr return (FALSE); 209184588Sdfr } else { 210184588Sdfr is_null = TRUE; 211184588Sdfr if (!xdr_bool(xdrs, &is_null)) 212184588Sdfr return (FALSE); 213184588Sdfr } 214184588Sdfr break; 215184588Sdfr 216184588Sdfr case XDR_DECODE: 217184588Sdfr if (!xdr_bool(xdrs, &is_null)) 218184588Sdfr return (FALSE); 219184588Sdfr if (is_null) { 220184588Sdfr *chp = GSS_C_NO_CHANNEL_BINDINGS; 221184588Sdfr } else { 222184588Sdfr ch = mem_alloc(sizeof(*ch)); 223184588Sdfr memset(ch, 0, sizeof(*ch)); 224184588Sdfr if (!xdr_uint32_t(xdrs, &ch->initiator_addrtype) 225184588Sdfr || !xdr_gss_buffer_desc(xdrs, 226184588Sdfr &ch->initiator_address) 227184588Sdfr || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 228184588Sdfr || !xdr_gss_buffer_desc(xdrs, 229184588Sdfr &ch->acceptor_address) 230184588Sdfr || !xdr_gss_buffer_desc(xdrs, 231298655Scem &ch->application_data)) { 232298655Scem mem_free(ch, sizeof(*ch)); 233184588Sdfr return (FALSE); 234298655Scem } 235184588Sdfr *chp = ch; 236184588Sdfr } 237184588Sdfr break; 238184588Sdfr 239184588Sdfr case XDR_FREE: 240184588Sdfr ch = *chp; 241184588Sdfr if (ch) { 242184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->initiator_address); 243184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->acceptor_address); 244184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->application_data); 245184588Sdfr mem_free(ch, sizeof(*ch)); 246184588Sdfr } 247184588Sdfr } 248184588Sdfr 249184588Sdfr return (TRUE); 250184588Sdfr} 251