Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/gssapi/mechs/dummy/dmech.c
+++ new/usr/src/uts/common/gssapi/mechs/dummy/dmech.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 2004 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
26 26 */
27 27
28 28 /*
29 29 * A module that implements a dummy security mechanism.
30 30 * It's mainly used to test GSS-API application. Multiple tokens
31 31 * exchanged during security context establishment can be
32 32 * specified through dummy_mech.conf located in /etc.
33 33 */
34 34
35 35 #include <sys/types.h>
36 36 #include <sys/modctl.h>
37 37 #include <sys/errno.h>
38 38 #include <gssapiP_dummy.h>
39 39 #include <gssapi_err_generic.h>
40 40 #include <mechglueP.h>
41 41 #include <gssapi/kgssapi_defs.h>
42 42 #include <sys/debug.h>
43 43
44 44 #ifdef DUMMY_MECH_DEBUG
45 45 /*
46 46 * Kernel kgssd module debugging aid. The global variable "dummy_mech_log"
47 47 * is a bit mask which allows various types of debugging messages
48 48 * to be printed out.
49 49 *
50 50 * dummy_mech_log & 1 will cause actual failures to be printed.
51 51 * dummy_mech_log & 2 will cause informational messages to be
52 52 * printed on the client side of kgssd.
53 53 * dummy_mech_log & 4 will cause informational messages to be
54 54 * printed on the server side of kgssd.
55 55 * dummy_mech_log & 8 will cause informational messages to be
56 56 * printed on both client and server side of kgssd.
57 57 */
58 58
59 59 uint_t dummy_mech_log = 1;
60 60 #endif
61 61
62 62 /* Local defines */
63 63 #define MAGIC_TOKEN_NUMBER 12345
64 64 /* private routines for dummy_mechanism */
65 65 static gss_buffer_desc make_dummy_token_msg(void *data, int datalen);
66 66
67 67 static int der_length_size(int);
68 68
69 69 static void der_write_length(unsigned char **, int);
70 70 static int der_read_length(unsigned char **, int *);
71 71 static int g_token_size(gss_OID mech, unsigned int body_size);
72 72 static void g_make_token_header(gss_OID mech, int body_size,
73 73 unsigned char **buf, int tok_type);
74 74 static int g_verify_token_header(gss_OID mech, int *body_size,
75 75 unsigned char **buf_in, int tok_type,
76 76 int toksize);
77 77
78 78 /* private global variables */
79 79 static int dummy_token_nums;
80 80
81 81 /*
82 82 * This OID:
83 83 * { iso(1) org(3) internet(6) dod(1) private(4) enterprises(1) sun(42)
84 84 * products(2) gssapi(26) mechtypes(1) dummy(2) }
85 85 */
86 86
87 87 static struct gss_config dummy_mechanism =
88 88 {{10, "\053\006\001\004\001\052\002\032\001\002"},
89 89 NULL, /* context */
90 90 NULL, /* next */
91 91 TRUE, /* uses_kmod */
92 92 dummy_gss_unseal,
93 93 dummy_gss_delete_sec_context,
94 94 dummy_gss_seal,
95 95 dummy_gss_import_sec_context,
96 96 dummy_gss_sign,
97 97 dummy_gss_verify
98 98 };
99 99
100 100 static gss_mechanism
101 101 gss_mech_initialize()
102 102 {
103 103 dprintf("Entering gss_mech_initialize\n");
104 104
105 105 if (dummy_token_nums == 0)
106 106 dummy_token_nums = 1;
107 107
108 108 dprintf("Leaving gss_mech_initialize\n");
109 109 return (&dummy_mechanism);
110 110 }
111 111
112 112 /*
113 113 * Clean up after a failed mod_install()
114 114 */
115 115 static void
116 116 gss_mech_fini()
117 117 {
118 118 /* Nothing to do */
119 119 }
120 120
121 121
122 122 /*
↓ open down ↓ |
122 lines elided |
↑ open up ↑ |
123 123 * Module linkage information for the kernel.
124 124 */
125 125 extern struct mod_ops mod_miscops;
126 126
127 127 static struct modlmisc modlmisc = {
128 128 &mod_miscops, "in-kernel dummy GSS mechanism"
129 129 };
130 130
131 131 static struct modlinkage modlinkage = {
132 132 MODREV_1,
133 - (void *)&modlmisc,
134 - NULL
133 + { (void *)&modlmisc, NULL }
135 134 };
136 135
137 136 static int dummy_fini_code = EBUSY;
138 137
139 138 int
140 139 _init()
141 140 {
142 141 int retval;
143 142 gss_mechanism mech, tmp;
144 143
145 144 mech = gss_mech_initialize();
146 145
147 146 mutex_enter(&__kgss_mech_lock);
148 147 tmp = __kgss_get_mechanism(&mech->mech_type);
149 148 if (tmp != NULL) {
150 149 DUMMY_MECH_LOG0(8,
151 150 "dummy GSS mechanism: mechanism already in table.\n");
152 151 if (tmp->uses_kmod == TRUE) {
153 152 DUMMY_MECH_LOG0(8, "dummy GSS mechanism: mechanism "
154 153 "table supports kernel operations!\n");
155 154 }
156 155 /*
157 156 * keep us loaded, but let us be unloadable. This
158 157 * will give the developer time to trouble shoot
159 158 */
160 159 dummy_fini_code = 0;
161 160 } else {
162 161 __kgss_add_mechanism(mech);
163 162 ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
164 163 }
165 164 mutex_exit(&__kgss_mech_lock);
166 165
167 166 if ((retval = mod_install(&modlinkage)) != 0)
168 167 gss_mech_fini(); /* clean up */
169 168
170 169 return (retval);
171 170 }
172 171
173 172 int
174 173 _fini()
175 174 {
176 175 int ret = dummy_fini_code;
177 176
178 177 if (ret == 0) {
179 178 ret = (mod_remove(&modlinkage));
180 179 }
181 180 return (ret);
182 181 }
183 182
184 183 int
185 184 _info(struct modinfo *modinfop)
186 185 {
187 186 return (mod_info(&modlinkage, modinfop));
188 187 }
189 188
190 189
191 190 /*ARGSUSED*/
192 191 static OM_uint32
193 192 dummy_gss_sign(context, minor_status, context_handle,
194 193 qop_req, message_buffer, message_token,
195 194 gssd_ctx_verifier)
196 195 void *context;
197 196 OM_uint32 *minor_status;
198 197 gss_ctx_id_t context_handle;
199 198 int qop_req;
200 199 gss_buffer_t message_buffer;
201 200 gss_buffer_t message_token;
202 201 OM_uint32 gssd_ctx_verifier;
203 202 {
204 203 dummy_gss_ctx_id_rec *ctx;
205 204 char token_string[] = "dummy_gss_sign";
206 205
207 206 dprintf("Entering gss_sign\n");
208 207
209 208 if (context_handle == GSS_C_NO_CONTEXT)
210 209 return (GSS_S_NO_CONTEXT);
211 210 ctx = (dummy_gss_ctx_id_rec *) context_handle;
212 211 ASSERT(ctx->established == 1);
213 212 ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
214 213
215 214 *message_token = make_dummy_token_msg(
216 215 token_string, strlen(token_string));
217 216
218 217 dprintf("Leaving gss_sign\n");
219 218 return (GSS_S_COMPLETE);
220 219 }
221 220
222 221 /*ARGSUSED*/
223 222 static OM_uint32
224 223 dummy_gss_verify(context, minor_status, context_handle,
225 224 message_buffer, token_buffer, qop_state,
226 225 gssd_ctx_verifier)
227 226 void *context;
228 227 OM_uint32 *minor_status;
229 228 gss_ctx_id_t context_handle;
230 229 gss_buffer_t message_buffer;
231 230 gss_buffer_t token_buffer;
232 231 int *qop_state;
233 232 OM_uint32 gssd_ctx_verifier;
234 233 {
235 234 unsigned char *ptr;
236 235 int bodysize;
237 236 int err;
238 237 dummy_gss_ctx_id_rec *ctx;
239 238
240 239 dprintf("Entering gss_verify\n");
241 240
242 241 if (context_handle == GSS_C_NO_CONTEXT)
243 242 return (GSS_S_NO_CONTEXT);
244 243
245 244 ctx = (dummy_gss_ctx_id_rec *) context_handle;
246 245 ASSERT(ctx->established == 1);
247 246 ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
248 247 /* Check for defective input token. */
249 248
250 249 ptr = (unsigned char *) token_buffer->value;
251 250 if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
252 251 &ptr, 0,
253 252 token_buffer->length)) {
254 253 *minor_status = err;
255 254 return (GSS_S_DEFECTIVE_TOKEN);
256 255 }
257 256
258 257 *qop_state = GSS_C_QOP_DEFAULT;
259 258
260 259 dprintf("Leaving gss_verify\n");
261 260 return (GSS_S_COMPLETE);
262 261 }
263 262
264 263 /*ARGSUSED*/
265 264 static OM_uint32
266 265 dummy_gss_seal(context, minor_status, context_handle, conf_req_flag,
267 266 qop_req, input_message_buffer, conf_state,
268 267 output_message_buffer, gssd_ctx_verifier)
269 268 void *context;
270 269 OM_uint32 *minor_status;
271 270 gss_ctx_id_t context_handle;
272 271 int conf_req_flag;
273 272 int qop_req;
274 273 gss_buffer_t input_message_buffer;
275 274 int *conf_state;
276 275 gss_buffer_t output_message_buffer;
277 276 OM_uint32 gssd_ctx_verifier;
278 277 {
279 278 gss_buffer_desc output;
280 279 dummy_gss_ctx_id_rec *ctx;
281 280 dprintf("Entering gss_seal\n");
282 281
283 282 if (context_handle == GSS_C_NO_CONTEXT)
284 283 return (GSS_S_NO_CONTEXT);
285 284 ctx = (dummy_gss_ctx_id_rec *) context_handle;
286 285 ASSERT(ctx->established == 1);
287 286 ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
288 287 /* Copy the input message to output message */
289 288 output = make_dummy_token_msg(
290 289 input_message_buffer->value, input_message_buffer->length);
291 290
292 291 if (conf_state)
293 292 *conf_state = 1;
294 293
295 294 *output_message_buffer = output;
296 295
297 296 dprintf("Leaving gss_seal\n");
298 297 return (GSS_S_COMPLETE);
299 298 }
300 299
301 300 /*ARGSUSED*/
302 301 static OM_uint32
303 302 dummy_gss_unseal(context, minor_status, context_handle,
304 303 input_message_buffer, output_message_buffer,
305 304 conf_state, qop_state, gssd_ctx_verifier)
306 305 void *context;
307 306 OM_uint32 *minor_status;
308 307 gss_ctx_id_t context_handle;
309 308 gss_buffer_t input_message_buffer;
310 309 gss_buffer_t output_message_buffer;
311 310 int *conf_state;
312 311 int *qop_state;
313 312 OM_uint32 gssd_ctx_verifier;
314 313 {
315 314 gss_buffer_desc output;
316 315 dummy_gss_ctx_id_rec *ctx;
317 316 unsigned char *ptr;
318 317 int bodysize;
319 318 int err;
320 319
321 320 dprintf("Entering gss_unseal\n");
322 321
323 322 if (context_handle == GSS_C_NO_CONTEXT)
324 323 return (GSS_S_NO_CONTEXT);
325 324
326 325 ctx = (dummy_gss_ctx_id_rec *) context_handle;
327 326 ASSERT(ctx->established == 1);
328 327 ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
329 328
330 329 ptr = (unsigned char *) input_message_buffer->value;
331 330 if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
332 331 &ptr, 0,
333 332 input_message_buffer->length)) {
334 333 *minor_status = err;
335 334 return (GSS_S_DEFECTIVE_TOKEN);
336 335 }
337 336 output.length = bodysize;
338 337 output.value = (void *)MALLOC(output.length);
339 338 (void) memcpy(output.value, ptr, output.length);
340 339
341 340 *output_message_buffer = output;
342 341 *qop_state = GSS_C_QOP_DEFAULT;
343 342
344 343 if (conf_state)
345 344 *conf_state = 1;
346 345
347 346 dprintf("Leaving gss_unseal\n");
348 347 return (GSS_S_COMPLETE);
349 348 }
350 349
351 350 /*ARGSUSED*/
352 351 OM_uint32
353 352 dummy_gss_import_sec_context(ct, minor_status, interprocess_token,
354 353 context_handle)
355 354 void *ct;
356 355 OM_uint32 *minor_status;
357 356 gss_buffer_t interprocess_token;
358 357 gss_ctx_id_t *context_handle;
359 358 {
360 359 unsigned char *ptr;
361 360 int bodysize;
362 361 int err;
363 362
364 363 /* Assume that we got ctx from the interprocess token. */
365 364 dummy_gss_ctx_id_t ctx;
366 365
367 366 dprintf("Entering import_sec_context\n");
368 367 ptr = (unsigned char *) interprocess_token->value;
369 368 if (err = g_verify_token_header((gss_OID)gss_mech_dummy, &bodysize,
370 369 &ptr, 0,
371 370 interprocess_token->length)) {
372 371 *minor_status = err;
373 372 return (GSS_S_DEFECTIVE_TOKEN);
374 373 }
375 374 ctx = (dummy_gss_ctx_id_t)MALLOC(sizeof (dummy_gss_ctx_id_rec));
376 375 ctx->token_number = MAGIC_TOKEN_NUMBER;
377 376 ctx->established = 1;
378 377
379 378 *context_handle = (gss_ctx_id_t)ctx;
380 379
381 380 dprintf("Leaving import_sec_context\n");
382 381 return (GSS_S_COMPLETE);
383 382 }
384 383
385 384 /*ARGSUSED*/
386 385 static OM_uint32
387 386 dummy_gss_delete_sec_context(ct, minor_status,
388 387 context_handle, output_token,
389 388 gssd_ctx_verifier)
390 389 void *ct;
391 390 OM_uint32 *minor_status;
392 391 gss_ctx_id_t *context_handle;
393 392 gss_buffer_t output_token;
394 393 OM_uint32 gssd_ctx_verifier;
395 394 {
396 395 dummy_gss_ctx_id_t ctx;
397 396
398 397 dprintf("Entering delete_sec_context\n");
399 398
400 399 /* Make the length to 0, so the output token is not sent to peer */
401 400 if (output_token) {
402 401 output_token->length = 0;
403 402 output_token->value = NULL;
404 403 }
405 404
406 405 if (*context_handle == GSS_C_NO_CONTEXT) {
407 406 *minor_status = 0;
408 407 return (GSS_S_COMPLETE);
409 408 }
410 409
411 410 ctx = (dummy_gss_ctx_id_rec *) *context_handle;
412 411 ASSERT(ctx->established == 1);
413 412 ASSERT(ctx->token_number == MAGIC_TOKEN_NUMBER);
414 413
415 414 FREE(ctx, sizeof (dummy_gss_ctx_id_rec));
416 415 *context_handle = GSS_C_NO_CONTEXT;
417 416
418 417 dprintf("Leaving delete_sec_context\n");
419 418 return (GSS_S_COMPLETE);
420 419 }
421 420
422 421 static int
423 422 der_length_size(int length)
424 423 {
425 424 if (length < (1<<7))
426 425 return (1);
427 426 else if (length < (1<<8))
428 427 return (2);
429 428 else if (length < (1<<16))
430 429 return (3);
431 430 else if (length < (1<<24))
432 431 return (4);
433 432 else
434 433 return (5);
435 434 }
436 435
437 436 static void
438 437 der_write_length(unsigned char ** buf, int length)
439 438 {
440 439 if (length < (1<<7)) {
441 440 *(*buf)++ = (unsigned char) length;
442 441 } else {
443 442 *(*buf)++ = (unsigned char) (der_length_size(length)+127);
444 443 if (length >= (1<<24))
445 444 *(*buf)++ = (unsigned char) (length>>24);
446 445 if (length >= (1<<16))
447 446 *(*buf)++ = (unsigned char) ((length>>16)&0xff);
448 447 if (length >= (1<<8))
449 448 *(*buf)++ = (unsigned char) ((length>>8)&0xff);
450 449 *(*buf)++ = (unsigned char) (length&0xff);
451 450 }
452 451 }
453 452
454 453 static int
455 454 der_read_length(buf, bufsize)
456 455 unsigned char **buf;
457 456 int *bufsize;
458 457 {
459 458 unsigned char sf;
460 459 int ret;
461 460
462 461 if (*bufsize < 1)
463 462 return (-1);
464 463 sf = *(*buf)++;
465 464 (*bufsize)--;
466 465 if (sf & 0x80) {
467 466 if ((sf &= 0x7f) > ((*bufsize)-1))
468 467 return (-1);
469 468 if (sf > DUMMY_SIZE_OF_INT)
470 469 return (-1);
471 470 ret = 0;
472 471 for (; sf; sf--) {
473 472 ret = (ret<<8) + (*(*buf)++);
474 473 (*bufsize)--;
475 474 }
476 475 } else {
477 476 ret = sf;
478 477 }
479 478
480 479 return (ret);
481 480 }
482 481
483 482 static int
484 483 g_token_size(mech, body_size)
485 484 gss_OID mech;
486 485 unsigned int body_size;
487 486 {
488 487 /* set body_size to sequence contents size */
489 488 body_size += 4 + (int)mech->length; /* NEED overflow check */
490 489 return (1 + der_length_size(body_size) + body_size);
491 490 }
492 491
493 492 static void
494 493 g_make_token_header(mech, body_size, buf, tok_type)
495 494 gss_OID mech;
496 495 int body_size;
497 496 unsigned char **buf;
498 497 int tok_type;
499 498 {
500 499 *(*buf)++ = 0x60;
501 500 der_write_length(buf, 4 + mech->length + body_size);
502 501 *(*buf)++ = 0x06;
503 502 *(*buf)++ = (unsigned char) mech->length;
504 503 TWRITE_STR(*buf, mech->elements, ((int)mech->length));
505 504 *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
506 505 *(*buf)++ = (unsigned char) (tok_type&0xff);
507 506 }
508 507
509 508 static int
510 509 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize)
511 510 gss_OID mech;
512 511 int *body_size;
513 512 unsigned char **buf_in;
514 513 int tok_type;
515 514 int toksize;
516 515 {
517 516 unsigned char *buf = *buf_in;
518 517 int seqsize;
519 518 gss_OID_desc toid;
520 519 int ret = 0;
521 520
522 521 if ((toksize -= 1) < 0)
523 522 return (G_BAD_TOK_HEADER);
524 523 if (*buf++ != 0x60)
525 524 return (G_BAD_TOK_HEADER);
526 525
527 526 if ((seqsize = der_read_length(&buf, &toksize)) < 0)
528 527 return (G_BAD_TOK_HEADER);
529 528
530 529 if (seqsize != toksize)
531 530 return (G_BAD_TOK_HEADER);
532 531
533 532 if ((toksize -= 1) < 0)
534 533 return (G_BAD_TOK_HEADER);
535 534 if (*buf++ != 0x06)
536 535 return (G_BAD_TOK_HEADER);
537 536
538 537 if ((toksize -= 1) < 0)
539 538 return (G_BAD_TOK_HEADER);
540 539 toid.length = *buf++;
541 540
542 541 if ((toksize -= toid.length) < 0)
543 542 return (G_BAD_TOK_HEADER);
544 543 toid.elements = buf;
545 544 buf += toid.length;
546 545
547 546 if (! g_OID_equal(&toid, mech))
548 547 ret = G_WRONG_MECH;
549 548
550 549 /*
551 550 * G_WRONG_MECH is not returned immediately because it's more important
552 551 * to return G_BAD_TOK_HEADER if the token header is in fact bad
553 552 */
554 553
555 554 if ((toksize -= 2) < 0)
556 555 return (G_BAD_TOK_HEADER);
557 556
558 557 if ((*buf++ != ((tok_type>>8)&0xff)) ||
559 558 (*buf++ != (tok_type&0xff)))
560 559 return (G_BAD_TOK_HEADER);
561 560
562 561 if (!ret) {
563 562 *buf_in = buf;
564 563 *body_size = toksize;
565 564 }
566 565
567 566 return (ret);
568 567 }
569 568
570 569 static gss_buffer_desc
571 570 make_dummy_token_msg(void *data, int dataLen)
572 571 {
573 572 gss_buffer_desc buffer;
574 573 int tlen;
575 574 unsigned char *t;
576 575 unsigned char *ptr;
577 576
578 577 if (data == NULL) {
579 578 buffer.length = 0;
580 579 buffer.value = NULL;
581 580 return (buffer);
582 581 }
583 582
584 583 tlen = g_token_size((gss_OID)gss_mech_dummy, dataLen);
585 584 t = (unsigned char *) MALLOC(tlen);
586 585 ptr = t;
587 586
588 587 g_make_token_header((gss_OID)gss_mech_dummy, dataLen, &ptr, 0);
589 588 (void) memcpy(ptr, data, dataLen);
590 589
591 590 buffer.length = tlen;
592 591 buffer.value = (void *) t;
593 592 return (buffer);
594 593 }
↓ open down ↓ |
450 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX