1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
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 #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
xdr_gss_buffer_desc(XDR * xdrs,gss_buffer_desc * buf)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
xdr_gss_OID_desc(XDR * xdrs,gss_OID_desc * oid)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
xdr_gss_OID(XDR * xdrs,gss_OID * oidp)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
xdr_gss_OID_set_desc(XDR * xdrs,gss_OID_set_desc * set)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
xdr_gss_OID_set(XDR * xdrs,gss_OID_set * setp)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
xdr_gss_channel_bindings_t(XDR * xdrs,gss_channel_bindings_t * chp)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