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)); 104184588Sdfr if (!xdr_gss_OID_desc(xdrs, oid)) 105184588Sdfr return (FALSE); 106184588Sdfr *oidp = oid; 107184588Sdfr } 108184588Sdfr break; 109184588Sdfr 110184588Sdfr case XDR_FREE: 111184588Sdfr oid = *oidp; 112184588Sdfr if (oid) { 113184588Sdfr xdr_gss_OID_desc(xdrs, oid); 114184588Sdfr mem_free(oid, sizeof(gss_OID_desc)); 115184588Sdfr } 116184588Sdfr } 117184588Sdfr 118184588Sdfr return (TRUE); 119184588Sdfr} 120184588Sdfr 121184588Sdfrbool_t 122184588Sdfrxdr_gss_OID_set_desc(XDR *xdrs, gss_OID_set_desc *set) 123184588Sdfr{ 124184588Sdfr caddr_t addr; 125184588Sdfr u_int len; 126184588Sdfr 127184588Sdfr len = set->count; 128184588Sdfr addr = (caddr_t) set->elements; 129184588Sdfr if (!xdr_array(xdrs, &addr, &len, ~0, sizeof(gss_OID_desc), 130184588Sdfr (xdrproc_t) xdr_gss_OID_desc)) 131184588Sdfr return (FALSE); 132184588Sdfr set->count = len; 133184588Sdfr set->elements = (gss_OID) addr; 134184588Sdfr 135184588Sdfr return (TRUE); 136184588Sdfr} 137184588Sdfr 138184588Sdfrbool_t 139184588Sdfrxdr_gss_OID_set(XDR *xdrs, gss_OID_set *setp) 140184588Sdfr{ 141184588Sdfr gss_OID_set set; 142184588Sdfr bool_t is_null; 143184588Sdfr 144184588Sdfr switch (xdrs->x_op) { 145184588Sdfr case XDR_ENCODE: 146184588Sdfr set = *setp; 147184588Sdfr if (set) { 148184588Sdfr is_null = FALSE; 149184588Sdfr if (!xdr_bool(xdrs, &is_null) 150184588Sdfr || !xdr_gss_OID_set_desc(xdrs, set)) 151184588Sdfr return (FALSE); 152184588Sdfr } else { 153184588Sdfr is_null = TRUE; 154184588Sdfr if (!xdr_bool(xdrs, &is_null)) 155184588Sdfr return (FALSE); 156184588Sdfr } 157184588Sdfr break; 158184588Sdfr 159184588Sdfr case XDR_DECODE: 160184588Sdfr if (!xdr_bool(xdrs, &is_null)) 161184588Sdfr return (FALSE); 162184588Sdfr if (is_null) { 163184588Sdfr *setp = GSS_C_NO_OID_SET; 164184588Sdfr } else { 165184588Sdfr set = mem_alloc(sizeof(gss_OID_set_desc)); 166184588Sdfr memset(set, 0, sizeof(*set)); 167184588Sdfr if (!xdr_gss_OID_set_desc(xdrs, set)) 168184588Sdfr return (FALSE); 169184588Sdfr *setp = set; 170184588Sdfr } 171184588Sdfr break; 172184588Sdfr 173184588Sdfr case XDR_FREE: 174184588Sdfr set = *setp; 175184588Sdfr if (set) { 176184588Sdfr xdr_gss_OID_set_desc(xdrs, set); 177184588Sdfr mem_free(set, sizeof(gss_OID_set_desc)); 178184588Sdfr } 179184588Sdfr } 180184588Sdfr 181184588Sdfr return (TRUE); 182184588Sdfr} 183184588Sdfr 184184588Sdfrbool_t 185184588Sdfrxdr_gss_channel_bindings_t(XDR *xdrs, gss_channel_bindings_t *chp) 186184588Sdfr{ 187184588Sdfr gss_channel_bindings_t ch; 188184588Sdfr bool_t is_null; 189184588Sdfr 190184588Sdfr switch (xdrs->x_op) { 191184588Sdfr case XDR_ENCODE: 192184588Sdfr ch = *chp; 193184588Sdfr if (ch) { 194184588Sdfr is_null = FALSE; 195184588Sdfr if (!xdr_bool(xdrs, &is_null) 196184588Sdfr || !xdr_uint32_t(xdrs, &ch->initiator_addrtype) 197184588Sdfr || !xdr_gss_buffer_desc(xdrs, 198184588Sdfr &ch->initiator_address) 199184588Sdfr || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 200184588Sdfr || !xdr_gss_buffer_desc(xdrs, 201184588Sdfr &ch->acceptor_address) 202184588Sdfr || !xdr_gss_buffer_desc(xdrs, 203184588Sdfr &ch->application_data)) 204184588Sdfr return (FALSE); 205184588Sdfr } else { 206184588Sdfr is_null = TRUE; 207184588Sdfr if (!xdr_bool(xdrs, &is_null)) 208184588Sdfr return (FALSE); 209184588Sdfr } 210184588Sdfr break; 211184588Sdfr 212184588Sdfr case XDR_DECODE: 213184588Sdfr if (!xdr_bool(xdrs, &is_null)) 214184588Sdfr return (FALSE); 215184588Sdfr if (is_null) { 216184588Sdfr *chp = GSS_C_NO_CHANNEL_BINDINGS; 217184588Sdfr } else { 218184588Sdfr ch = mem_alloc(sizeof(*ch)); 219184588Sdfr memset(ch, 0, sizeof(*ch)); 220184588Sdfr if (!xdr_uint32_t(xdrs, &ch->initiator_addrtype) 221184588Sdfr || !xdr_gss_buffer_desc(xdrs, 222184588Sdfr &ch->initiator_address) 223184588Sdfr || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) 224184588Sdfr || !xdr_gss_buffer_desc(xdrs, 225184588Sdfr &ch->acceptor_address) 226184588Sdfr || !xdr_gss_buffer_desc(xdrs, 227184588Sdfr &ch->application_data)) 228184588Sdfr return (FALSE); 229184588Sdfr *chp = ch; 230184588Sdfr } 231184588Sdfr break; 232184588Sdfr 233184588Sdfr case XDR_FREE: 234184588Sdfr ch = *chp; 235184588Sdfr if (ch) { 236184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->initiator_address); 237184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->acceptor_address); 238184588Sdfr xdr_gss_buffer_desc(xdrs, &ch->application_data); 239184588Sdfr mem_free(ch, sizeof(*ch)); 240184588Sdfr } 241184588Sdfr } 242184588Sdfr 243184588Sdfr return (TRUE); 244184588Sdfr} 245