Print this page
first pass
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/rpc/sec_gss/rpcsec_gss_misc.c
+++ new/usr/src/uts/common/rpc/sec_gss/rpcsec_gss_misc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 1996,1997,1999,2002-2003 Sun Microsystems, Inc.
24 24 * All rights reserved. Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
29 29 *
30 30 * $Header:
31 31 * /afs/gza.com/product/secure/rel-eng/src/1.1/rpc/RCS/auth_gssapi_misc.c,v 1.10
32 32 * 1994/10/27 12:39:23 jik Exp $
33 33 */
34 34
35 35 /*
36 36 * Copyright (c) 2013 by Delphix. All rights reserved.
37 37 */
38 38
39 39 #include <sys/param.h>
40 40 #include <sys/types.h>
41 41 #include <sys/stream.h>
42 42 #include <sys/strsubr.h>
43 43 #include <sys/cmn_err.h>
44 44 #include <gssapi/gssapi.h>
45 45 #include <rpc/rpc.h>
46 46 #include <rpc/rpcsec_defs.h>
47 47
48 48 /*
49 49 * The initial allocation size for dynamic allocation.
50 50 */
51 51 #define CKU_INITSIZE 2048
52 52
53 53 /*
54 54 * The size of additional allocations, if required. It is larger to
55 55 * reduce the number of actual allocations.
56 56 */
57 57 #define CKU_ALLOCSIZE 8192
58 58
59 59
60 60 /*
61 61 * Miscellaneous XDR routines.
62 62 */
63 63 bool_t
64 64 __xdr_gss_buf(xdrs, buf)
65 65 XDR *xdrs;
66 66 gss_buffer_t buf;
67 67 {
68 68 uint_t cast_len, bound_len;
69 69
70 70 /*
71 71 * We go through this contortion because size_t is a now a ulong,
72 72 * GSS-API uses ulongs.
73 73 */
74 74
75 75 if (xdrs->x_op != XDR_DECODE) {
76 76 bound_len = cast_len = (uint_t)buf->length;
77 77 } else {
78 78 bound_len = (uint_t)-1;
79 79 }
80 80
81 81 if (xdr_bytes(xdrs, (char **)&buf->value, &cast_len,
82 82 bound_len) == TRUE) {
83 83 if (xdrs->x_op == XDR_DECODE)
84 84 buf->length = cast_len;
85 85
86 86 return (TRUE);
87 87 }
88 88
89 89 return (FALSE);
90 90 }
91 91
92 92 bool_t
93 93 __xdr_rpc_gss_creds(xdrs, creds)
94 94 XDR *xdrs;
95 95 rpc_gss_creds *creds;
96 96 {
97 97 if (!xdr_u_int(xdrs, (uint_t *)&creds->version) ||
98 98 !xdr_u_int(xdrs, (uint_t *)&creds->gss_proc) ||
99 99 !xdr_u_int(xdrs, (uint_t *)&creds->seq_num) ||
100 100 !xdr_u_int(xdrs, (uint_t *)&creds->service) ||
101 101 !__xdr_gss_buf(xdrs, &creds->ctx_handle))
102 102 return (FALSE);
103 103 return (TRUE);
104 104 }
105 105
106 106 bool_t
107 107 __xdr_rpc_gss_init_arg(xdrs, init_arg)
108 108 XDR *xdrs;
109 109 rpc_gss_init_arg *init_arg;
110 110 {
111 111 if (!__xdr_gss_buf(xdrs, init_arg))
112 112 return (FALSE);
113 113 return (TRUE);
114 114 }
115 115
116 116 bool_t
117 117 __xdr_rpc_gss_init_res(xdrs, init_res)
118 118 XDR *xdrs;
119 119 rpc_gss_init_res *init_res;
120 120 {
121 121 if (!__xdr_gss_buf(xdrs, &init_res->ctx_handle) ||
122 122 !xdr_u_int(xdrs, (uint_t *)&init_res->gss_major) ||
123 123 !xdr_u_int(xdrs, (uint_t *)&init_res->gss_minor) ||
124 124 !xdr_u_int(xdrs, (uint_t *)&init_res->seq_window) ||
125 125 !__xdr_gss_buf(xdrs, &init_res->token))
126 126 return (FALSE);
127 127 return (TRUE);
128 128 }
129 129
130 130 /*
131 131 * Generic routine to wrap data used by client and server sides.
132 132 */
133 133 bool_t
134 134 __rpc_gss_wrap_data(service, qop, context, seq_num, out_xdrs,
135 135 xdr_func, xdr_ptr)
136 136 OM_uint32 qop;
137 137 rpc_gss_service_t service;
↓ open down ↓ |
137 lines elided |
↑ open up ↑ |
138 138 gss_ctx_id_t context;
139 139 uint_t seq_num;
140 140 XDR *out_xdrs;
141 141 bool_t (*xdr_func)();
142 142 caddr_t xdr_ptr;
143 143 {
144 144 OM_uint32 major, minor;
145 145 gss_buffer_desc in_buf, out_buf;
146 146 XDR temp_xdrs;
147 147 char *temp_data;
148 -/* EXPORT DELETE START */
149 148 bool_t conf_state;
150 -/* EXPORT DELETE END */
151 149 bool_t ret = FALSE;
152 150 int size;
153 151
154 152 /*
155 153 * Create a temporary XDR/buffer to hold the data to be wrapped.
156 154 * We need an extra bit for the sequence number serialized first.
157 155 */
158 156 size = xdr_sizeof(xdr_func, xdr_ptr) + BYTES_PER_XDR_UNIT;
159 157 temp_data = kmem_alloc(size, KM_SLEEP);
160 158 out_buf.length = 0;
161 159
162 160 xdrmem_create(&temp_xdrs, temp_data, size, XDR_ENCODE);
163 161
164 162 /*
165 163 * serialize the sequence number into tmp memory
166 164 */
167 165 if (!xdr_u_int(&temp_xdrs, &seq_num))
168 166 goto fail;
169 167
170 168 /*
171 169 * serialize the arguments into tmp memory
172 170 */
173 171 if (!(*xdr_func)(&temp_xdrs, xdr_ptr))
174 172 goto fail;
175 173
176 174 /*
177 175 * Data to be wrapped goes in in_buf. If privacy is used,
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
178 176 * out_buf will have wrapped data (in_buf will no longer be
179 177 * needed). If integrity is used, out_buf will have checksum
180 178 * which will follow the data in in_buf.
181 179 */
182 180 in_buf.length = xdr_getpos(&temp_xdrs);
183 181 in_buf.value = (char *)temp_xdrs.x_base;
184 182
185 183 switch (service) {
186 184 case rpc_gss_svc_privacy:
187 185
188 -/* EXPORT DELETE START */
189 186 if ((major = kgss_seal(&minor, context, TRUE, qop, &in_buf,
190 187 &conf_state, &out_buf)) != GSS_S_COMPLETE) {
191 188 RPCGSS_LOG1(1, "rpc_gss_wrap: kgss_seal failed."
192 189 "major = %x, minor = %x", major, minor);
193 190 goto fail;
194 191 }
195 192 in_buf.length = 0; /* in_buf not needed */
196 193 if (!conf_state)
197 -/* EXPORT DELETE END */
198 194 goto fail;
199 -/* EXPORT DELETE START */
200 195 break;
201 -/* EXPORT DELETE END */
202 196 case rpc_gss_svc_integrity:
203 197 if ((major = kgss_sign(&minor, context, qop, &in_buf,
204 198 &out_buf)) != GSS_S_COMPLETE) {
205 199 RPCGSS_LOG1(1, "rpc_gss_wrap: kgss_sign failed."
206 200 "major = %x, minor = %x", major, minor);
207 201 goto fail;
208 202 }
209 203 break;
210 204 default:
211 205 goto fail;
212 206 }
213 207
214 208 /*
215 209 * write out in_buf and out_buf as needed
216 210 */
217 211 if (in_buf.length != 0) {
218 212 if (!__xdr_gss_buf(out_xdrs, &in_buf))
219 213 goto fail;
220 214 }
221 215
222 216 if (!__xdr_gss_buf(out_xdrs, &out_buf))
223 217 goto fail;
224 218 ret = TRUE;
225 219 fail:
226 220 kmem_free(temp_data, size);
227 221 if (out_buf.length != 0)
228 222 (void) gss_release_buffer(&minor, &out_buf);
229 223 return (ret);
230 224 }
231 225
232 226 /*
233 227 * Generic routine to unwrap data used by client and server sides.
234 228 */
235 229 bool_t
236 230 __rpc_gss_unwrap_data(service, context, seq_num, qop_check, in_xdrs,
237 231 xdr_func, xdr_ptr)
238 232 rpc_gss_service_t service;
239 233 gss_ctx_id_t context;
240 234 uint_t seq_num;
241 235 OM_uint32 qop_check;
242 236 XDR *in_xdrs;
243 237 bool_t (*xdr_func)();
244 238 caddr_t xdr_ptr;
245 239 {
246 240 gss_buffer_desc in_buf, out_buf;
247 241 XDR temp_xdrs;
248 242 uint_t seq_num2;
249 243 bool_t conf = FALSE;
250 244 OM_uint32 major = GSS_S_COMPLETE, minor = 0;
251 245 int qop = 0;
252 246
253 247 in_buf.value = NULL;
254 248 out_buf.value = NULL;
255 249
256 250 /*
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
257 251 * Pull out wrapped data. For privacy service, this is the
258 252 * encrypted data. For integrity service, this is the data
259 253 * followed by a checksum.
260 254 */
261 255 if (!__xdr_gss_buf(in_xdrs, &in_buf)) {
262 256 return (FALSE);
263 257 }
264 258
265 259 if (service == rpc_gss_svc_privacy) {
266 260 major = GSS_S_FAILURE;
267 -/* EXPORT DELETE START */
268 261 major = kgss_unseal(&minor, context, &in_buf, &out_buf, &conf,
269 262 &qop);
270 -/* EXPORT DELETE END */
271 263 kmem_free(in_buf.value, in_buf.length);
272 264 if (major != GSS_S_COMPLETE) {
273 265 RPCGSS_LOG1(1, "rpc_gss_unwrap: kgss_unseal failed."
274 266 "major = %x, minor = %x", major, minor);
275 267 return (FALSE);
276 268 }
277 269 /*
278 270 * Keep the returned token (unencrypted data) in in_buf.
279 271 */
280 272 in_buf.length = out_buf.length;
281 273 in_buf.value = out_buf.value;
282 274
283 275 /*
284 276 * If privacy was not used, or if QOP is not what we are
285 277 * expecting, fail.
286 278 */
287 279 if (!conf || qop != qop_check)
288 280 goto fail;
289 281
290 282 } else if (service == rpc_gss_svc_integrity) {
291 283 if (!__xdr_gss_buf(in_xdrs, &out_buf)) {
292 284 return (FALSE);
293 285 }
294 286 major = kgss_verify(&minor, context, &in_buf, &out_buf,
295 287 &qop);
296 288 kmem_free(out_buf.value, out_buf.length);
297 289 if (major != GSS_S_COMPLETE) {
298 290 kmem_free(in_buf.value, in_buf.length);
299 291 RPCGSS_LOG1(1, "rpc_gss_unwrap: kgss_verify failed."
300 292 "major = %x, minor = %x", major, minor);
301 293 return (FALSE);
302 294 }
303 295
304 296 /*
305 297 * If QOP is not what we are expecting, fail.
306 298 */
307 299 if (qop != qop_check)
308 300 goto fail;
309 301 }
310 302
311 303 xdrmem_create(&temp_xdrs, in_buf.value, in_buf.length, XDR_DECODE);
312 304
313 305 /*
314 306 * The data consists of the sequence number followed by the
315 307 * arguments. Make sure sequence number is what we are
316 308 * expecting (i.e., the value in the header).
317 309 */
318 310 if (!xdr_u_int(&temp_xdrs, &seq_num2))
319 311 goto fail;
320 312 if (seq_num2 != seq_num)
321 313 goto fail;
322 314
323 315 /*
324 316 * Deserialize the arguments into xdr_ptr, and release in_buf.
325 317 */
326 318 if (!(*xdr_func)(&temp_xdrs, xdr_ptr)) {
327 319 goto fail;
328 320 }
329 321
330 322 if (service == rpc_gss_svc_privacy)
331 323 (void) gss_release_buffer(&minor, &in_buf);
332 324 else
333 325 kmem_free(in_buf.value, in_buf.length);
334 326 XDR_DESTROY(&temp_xdrs);
335 327 return (TRUE);
336 328 fail:
337 329 XDR_DESTROY(&temp_xdrs);
338 330 if (service == rpc_gss_svc_privacy)
339 331 (void) gss_release_buffer(&minor, &in_buf);
340 332 else
341 333 kmem_free(in_buf.value, in_buf.length);
342 334 return (FALSE);
343 335 }
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX