1 /*
2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3  */
4 #ifndef	_GSSAPIP_SPNEGO_H_
5 #define	_GSSAPIP_SPNEGO_H_
6 
7 #ifdef	__cplusplus
8 extern "C" {
9 #endif
10 
11 #include <gssapi/gssapi.h>
12 #include <gssapi/gssapi_ext.h>
13 #include <syslog.h>
14 
15 #define	SEC_CONTEXT_TOKEN 1
16 #define	SPNEGO_SIZE_OF_INT 4
17 
18 #define	ACCEPT_COMPLETE 0
19 #define	ACCEPT_INCOMPLETE 1
20 #define	REJECT 2
21 #define REQUEST_MIC 3
22 #define	ACCEPT_DEFECTIVE_TOKEN 0xffffffffUL
23 
24 /*
25  * constants for der encoding/decoding routines.
26  */
27 
28 #define	MECH_OID		0x06
29 #define	OCTET_STRING		0x04
30 #define	CONTEXT			0xa0
31 #define	SEQUENCE		0x30
32 #define	SEQUENCE_OF		0x30
33 #define	BIT_STRING		0x03
34 #define	BIT_STRING_LENGTH	0x02
35 #define	BIT_STRING_PADDING	0x01
36 #define	ENUMERATED		0x0a
37 #define	ENUMERATION_LENGTH	1
38 #define	HEADER_ID		0x60
39 #define GENERAL_STRING		0x1b
40 
41 /*
42  * SPNEGO specific error codes (minor status codes)
43  */
44 #define	ERR_SPNEGO_NO_MECHS_AVAILABLE		0x20000001
45 #define	ERR_SPNEGO_NO_CREDS_ACQUIRED		0x20000002
46 #define	ERR_SPNEGO_NO_MECH_FROM_ACCEPTOR	0x20000003
47 #define	ERR_SPNEGO_NEGOTIATION_FAILED		0x20000004
48 #define	ERR_SPNEGO_NO_TOKEN_FROM_ACCEPTOR	0x20000005
49 
50 /*
51  * send_token_flag is used to indicate in later steps what type
52  * of token, if any should be sent or processed.
53  * NO_TOKEN_SEND = no token should be sent
54  * INIT_TOKEN_SEND = initial token will be sent
55  * CONT_TOKEN_SEND = continuing tokens to be sent
56  * CHECK_MIC = no token to be sent, but have a MIC to check.
57  * ERROR_TOKEN_SEND = error token from peer needs to be sent.
58  */
59 
60 typedef	enum {NO_TOKEN_SEND, INIT_TOKEN_SEND, CONT_TOKEN_SEND,
61 		CHECK_MIC, ERROR_TOKEN_SEND} send_token_flag;
62 
63 /*
64  * The Mech OID:
65  * { iso(1) org(3) dod(6) internet(1) security(5)
66  *  mechanism(5) spnego(2) }
67  */
68 
69 #define	SPNEGO_OID_LENGTH 6
70 #define	SPNEGO_OID "\053\006\001\005\005\002"
71 
72 typedef void *spnego_token_t;
73 
74 /* spnego name structure for internal representation. */
75 typedef struct {
76 	gss_OID type;
77 	gss_buffer_t buffer;
78 	gss_OID	mech_type;
79 	gss_name_t	mech_name;
80 } spnego_name_desc, *spnego_name_t;
81 
82 /* Structure for context handle */
83 typedef struct {
84 	OM_uint32	magic_num;
85 	gss_buffer_desc DER_mechTypes;
86 	gss_OID internal_mech;
87 	gss_ctx_id_t ctx_handle;
88 	char  *optionStr;
89 	gss_cred_id_t default_cred;
90 	int mic_reqd;
91 	int mic_sent;
92 	int mic_rcvd;
93 	int firstpass;
94 	int mech_complete;
95 	int nego_done;
96 	OM_uint32 ctx_flags;
97 	gss_name_t internal_name;
98 	gss_OID actual_mech;
99         struct errinfo err;
100 } spnego_gss_ctx_id_rec, *spnego_gss_ctx_id_t;
101 
102 /*
103  * The magic number must be less than a standard pagesize
104  * to avoid a possible collision with a real address.
105  */
106 #define	SPNEGO_MAGIC_ID  0x00000fed
107 
108 /* SPNEGO oid declarations */
109 extern const gss_OID_desc * const gss_mech_spnego;
110 extern const gss_OID_set_desc * const gss_mech_set_spnego;
111 
112 
113 #ifdef DEBUG
114 #define	dsyslog(a) syslog(LOG_DEBUG, a)
115 #else
116 #define	dsyslog(a)
117 #define	SPNEGO_STATIC
118 #endif	/* DEBUG */
119 
120 /*
121  * declarations of internal name mechanism functions
122  */
123 
124 OM_uint32 spnego_gss_acquire_cred
125 (
126 	OM_uint32 *,		/* minor_status */
127 	gss_name_t,		/* desired_name */
128 	OM_uint32,		/* time_req */
129 	gss_OID_set,		/* desired_mechs */
130 	gss_cred_usage_t,	/* cred_usage */
131 	gss_cred_id_t *,	/* output_cred_handle */
132 	gss_OID_set *,		/* actual_mechs */
133 	OM_uint32 *		/* time_rec */
134 );
135 
136 OM_uint32 glue_spnego_gss_acquire_cred
137 (
138 	void *,
139 	OM_uint32 *,		/* minor_status */
140 	gss_name_t,		/* desired_name */
141 	OM_uint32,		/* time_req */
142 	gss_OID_set,		/* desired_mechs */
143 	gss_cred_usage_t,	/* cred_usage */
144 	gss_cred_id_t *,	/* output_cred_handle */
145 	gss_OID_set *,		/* actual_mechs */
146 	OM_uint32 *		/* time_rec */
147 );
148 
149 OM_uint32 spnego_gss_release_cred
150 (
151 	OM_uint32 *,		/* minor_status */
152 	/* CSTYLED */
153 	gss_cred_id_t	*	/* cred_handle */
154 );
155 
156 OM_uint32 glue_spnego_gss_release_cred
157 (
158 	void *,
159 	OM_uint32 *,		/* minor_status */
160 	/* CSTYLED */
161 	gss_cred_id_t	*	/* cred_handle */
162 );
163 
164 OM_uint32 spnego_gss_init_sec_context
165 (
166 	OM_uint32 *,		/* minor_status */
167 	gss_cred_id_t,		/* claimant_cred_handle */
168 	gss_ctx_id_t *,		/* context_handle */
169 	gss_name_t,		/* target_name */
170 	gss_OID,		/* mech_type */
171 	OM_uint32,		/* req_flags */
172 	OM_uint32,		/* time_req */
173 	gss_channel_bindings_t, /* input_chan_bindings */
174 	gss_buffer_t,		/* input_token */
175 	gss_OID *,		/* actual_mech_type */
176 	gss_buffer_t,		/* output_token */
177 	OM_uint32 *,		/* ret_flags */
178 	OM_uint32 *		/* time_rec */
179 );
180 
181 OM_uint32 glue_spnego_gss_init_sec_context
182 (
183 	void *,
184 	OM_uint32 *,		/* minor_status */
185 	gss_cred_id_t,		/* claimant_cred_handle */
186 	gss_ctx_id_t *,		/* context_handle */
187 	gss_name_t,		/* target_name */
188 	gss_OID,		/* mech_type */
189 	OM_uint32,		/* req_flags */
190 	OM_uint32,		/* time_req */
191 	gss_channel_bindings_t, /* input_chan_bindings */
192 	gss_buffer_t,		/* input_token */
193 	gss_OID *,		/* actual_mech_type */
194 	gss_buffer_t,		/* output_token */
195 	OM_uint32 *,		/* ret_flags */
196 	OM_uint32 *		/* time_rec */
197 );
198 
199 #ifndef LEAN_CLIENT
200 OM_uint32 spnego_gss_accept_sec_context
201 (
202 	OM_uint32 *,		/* minor_status */
203 	gss_ctx_id_t *,		/* context_handle */
204 	gss_cred_id_t,		/* verifier_cred_handle */
205 	gss_buffer_t,		/* input_token_buffer */
206 	gss_channel_bindings_t, /* input_chan_bindings */
207 	gss_name_t *,		/* src_name */
208 	gss_OID *,		/* mech_type */
209 	gss_buffer_t,		/* output_token */
210 	OM_uint32 *,		/* ret_flags */
211 	OM_uint32 *,		/* time_rec */
212 	/* CSTYLED */
213 	gss_cred_id_t *		/* delegated_cred_handle */
214 );
215 OM_uint32 glue_spnego_gss_accept_sec_context
216 (
217 	void *,
218 	OM_uint32 *,		/* minor_status */
219 	gss_ctx_id_t *,		/* context_handle */
220 	gss_cred_id_t,		/* verifier_cred_handle */
221 	gss_buffer_t,		/* input_token_buffer */
222 	gss_channel_bindings_t, /* input_chan_bindings */
223 	gss_name_t *,		/* src_name */
224 	gss_OID *,		/* mech_type */
225 	gss_buffer_t,		/* output_token */
226 	OM_uint32 *,		/* ret_flags */
227 	OM_uint32 *,		/* time_rec */
228 	/* CSTYLED */
229 	gss_cred_id_t *		/* delegated_cred_handle */
230 );
231 
232 #endif /* LEAN_CLIENT */
233 
234 OM_uint32 spnego_gss_compare_name
235 (
236 	OM_uint32 *,		/* minor_status */
237 	const gss_name_t,	/* name1 */
238 	const gss_name_t,	/* name2 */
239 	int *			/* name_equal */
240 );
241 
242 OM_uint32 glue_spnego_gss_compare_name
243 (
244 	void *,
245 	OM_uint32 *,		/* minor_status */
246 	const gss_name_t,	/* name1 */
247 	const gss_name_t,	/* name2 */
248 	int *			/* name_equal */
249 );
250 
251 OM_uint32 spnego_gss_display_name
252 (
253 	OM_uint32 *,		/* minor_status */
254 	gss_name_t,		/*  input_name */
255 	gss_buffer_t,		/*  output_name_buffer */
256 	gss_OID *		/* output_name_type */
257 );
258 
259 OM_uint32 glue_spnego_gss_display_name
260 (
261 	void *,
262 	OM_uint32 *,		/* minor_status */
263 	gss_name_t,		/*  input_name */
264 	gss_buffer_t,		/*  output_name_buffer */
265 	gss_OID *		/* output_name_type */
266 );
267 
268 OM_uint32 spnego_gss_display_status
269 (
270 	OM_uint32 *,		/* minor_status */
271 	OM_uint32,		/* status_value */
272 	int,			/* status_type */
273 	gss_OID,		/* mech_type */
274 	OM_uint32 *,		/* message_context */
275 	gss_buffer_t		/* status_string */
276 );
277 
278 OM_uint32 spnego_gss_display_status2
279 (
280 	OM_uint32 *,		/* minor_status */
281 	OM_uint32,		/* status_value */
282 	int,			/* status_type */
283 	gss_OID,		/* mech_type */
284 	OM_uint32 *,		/* message_context */
285 	gss_buffer_t		/* status_string */
286 );
287 
288 OM_uint32 glue_spnego_gss_display_status
289 (
290 	void *,
291 	OM_uint32 *,		/* minor_status */
292 	OM_uint32,		/* status_value */
293 	int,			/* status_type */
294 	gss_OID,		/* mech_type */
295 	OM_uint32 *,		/* message_context */
296 	gss_buffer_t		/* status_string */
297 );
298 
299 OM_uint32 spnego_gss_import_name
300 (
301 	OM_uint32 *,		/* minor_status */
302 	gss_buffer_t,		/* input_name_buffer */
303 	gss_OID,		/* input_name_type */
304 	/* CSTYLED */
305 	gss_name_t *		/* output_name */
306 );
307 
308 OM_uint32 glue_spnego_gss_import_name
309 (
310 	void *,
311 	OM_uint32 *,		/* minor_status */
312 	gss_buffer_t,		/* input_name_buffer */
313 	gss_OID,		/* input_name_type */
314 	/* CSTYLED */
315 	gss_name_t *		/* output_name */
316 );
317 OM_uint32 spnego_gss_release_name
318 (
319 	OM_uint32 *,		/* minor_status */
320 	/* CSTYLED */
321 	gss_name_t *		/* input_name */
322 );
323 
324 OM_uint32 glue_spnego_gss_release_name
325 (
326 	void *,
327 
328 	OM_uint32 *,		/* minor_status */
329 	/* CSTYLED */
330 	gss_name_t *		/* input_name */
331 );
332 
333 OM_uint32 spnego_gss_inquire_names_for_mech
334 (
335 	OM_uint32 *,		/* minor_status */
336 	gss_OID,		/* mechanism */
337 	gss_OID_set *		/* name_types */
338 );
339 
340 OM_uint32 glue_spnego_gss_inquire_names_for_mech
341 (
342 	void *,
343 	OM_uint32 *,		/* minor_status */
344 	gss_OID,		/* mechanism */
345 	gss_OID_set *		/* name_types */
346 );
347 
348 OM_uint32 spnego_gss_unwrap
349 (
350 	OM_uint32 *minor_status,
351 	gss_ctx_id_t context_handle,
352 	gss_buffer_t input_message_buffer,
353 	gss_buffer_t output_message_buffer,
354 	int *conf_state,
355 	gss_qop_t *qop_state
356 );
357 
358 OM_uint32 spnego_gss_wrap
359 (
360 	OM_uint32 *minor_status,
361 	gss_ctx_id_t context_handle,
362 	int conf_req_flag,
363 	gss_qop_t qop_req,
364 	gss_buffer_t input_message_buffer,
365 	int *conf_state,
366 	gss_buffer_t output_message_buffer
367 );
368 
369 OM_uint32 spnego_gss_process_context_token
370 (
371 	OM_uint32	*minor_status,
372 	const gss_ctx_id_t context_handle,
373 	const gss_buffer_t token_buffer
374 );
375 
376 OM_uint32 spnego_gss_delete_sec_context
377 (
378 	OM_uint32 *minor_status,
379 	gss_ctx_id_t *context_handle,
380 	gss_buffer_t output_token
381 );
382 
383 OM_uint32 glue_spnego_gss_delete_sec_context
384 (
385 	void *,
386 
387 	OM_uint32 *minor_status,
388 	gss_ctx_id_t *context_handle,
389 	gss_buffer_t output_token
390 );
391 
392 OM_uint32 spnego_gss_context_time
393 (
394 	OM_uint32	*minor_status,
395 	const gss_ctx_id_t context_handle,
396 	OM_uint32	*time_rec
397 );
398 OM_uint32 glue_spnego_gss_context_time
399 (
400 	void *,
401 	OM_uint32	*minor_status,
402 	const gss_ctx_id_t context_handle,
403 	OM_uint32	*time_rec
404 );
405 
406 #ifndef LEAN_CLIENT
407 OM_uint32 spnego_gss_export_sec_context
408 (
409 	OM_uint32	*minor_status,
410 	gss_ctx_id_t	*context_handle,
411 	gss_buffer_t	interprocess_token
412 );
413 
414 OM_uint32 glue_spnego_gss_export_sec_context
415 (
416 	void *,
417 	OM_uint32	*minor_status,
418 	gss_ctx_id_t	*context_handle,
419 	gss_buffer_t	interprocess_token
420 );
421 
422 OM_uint32 spnego_gss_import_sec_context
423 (
424 	OM_uint32		*minor_status,
425 	const gss_buffer_t	interprocess_token,
426 	gss_ctx_id_t		*context_handle
427 );
428 OM_uint32 glue_spnego_gss_import_sec_context
429 (
430 	void *,
431 	OM_uint32		*minor_status,
432 	const gss_buffer_t	interprocess_token,
433 	gss_ctx_id_t		*context_handle
434 );
435 #endif /* LEAN_CLIENT */
436 
437 OM_uint32 glue_spnego_gss_inquire_context
438 (
439 	void *,
440 	OM_uint32	*minor_status,
441 	const gss_ctx_id_t context_handle,
442 	gss_name_t	*src_name,
443 	gss_name_t	*targ_name,
444 	OM_uint32	*lifetime_rec,
445 	gss_OID		*mech_type,
446 	OM_uint32	*ctx_flags,
447 	int		*locally_initiated,
448 	int		*opened
449 );
450 
451 OM_uint32 spnego_gss_inquire_context
452 (
453 	OM_uint32	*minor_status,
454 	const gss_ctx_id_t context_handle,
455 	gss_name_t	*src_name,
456 	gss_name_t	*targ_name,
457 	OM_uint32	*lifetime_rec,
458 	gss_OID		*mech_type,
459 	OM_uint32	*ctx_flags,
460 	int		*locally_initiated,
461 	int		*opened
462 );
463 
464 OM_uint32 spnego_gss_wrap_size_limit
465 (
466 	OM_uint32	*minor_status,
467 	const gss_ctx_id_t context_handle,
468 	int		conf_req_flag,
469 	gss_qop_t	qop_req,
470 	OM_uint32	req_output_size,
471 	OM_uint32	*max_input_size
472 );
473 
474 OM_uint32 glue_spnego_gss_wrap_size_limit
475 (
476 	void *,
477 	OM_uint32	*minor_status,
478 	const gss_ctx_id_t context_handle,
479 	int		conf_req_flag,
480 	gss_qop_t	qop_req,
481 	OM_uint32	req_output_size,
482 	OM_uint32	*max_input_size
483 );
484 
485 OM_uint32 spnego_gss_get_mic
486 (
487 	OM_uint32 *minor_status,
488 	const gss_ctx_id_t context_handle,
489 	gss_qop_t qop_req,
490 	const gss_buffer_t message_buffer,
491 	gss_buffer_t message_token
492 );
493 
494 OM_uint32 spnego_gss_verify_mic
495 (
496 	OM_uint32 *minor_status,
497 	const gss_ctx_id_t context_handle,
498 	const gss_buffer_t msg_buffer,
499 	const gss_buffer_t token_buffer,
500 	gss_qop_t *qop_state
501 );
502 
503 OM_uint32
504 spnego_gss_inquire_sec_context_by_oid
505 (
506 	OM_uint32 *minor_status,
507 	const gss_ctx_id_t context_handle,
508 	const gss_OID desired_object,
509 	gss_buffer_set_t *data_set
510 );
511 
512 
513 #if 0 /* SUNW17PACresync - will be needed for full MIT 1.7 resync */
514 OM_uint32 spnego_gss_wrap_aead
515 (
516 	OM_uint32 *minor_status,
517 	gss_ctx_id_t context_handle,
518 	int conf_req_flag,
519 	gss_qop_t qop_req,
520 	gss_buffer_t input_assoc_buffer,
521 	gss_buffer_t input_payload_buffer,
522 	int *conf_state,
523 	gss_buffer_t output_message_buffer
524 );
525 
526 OM_uint32 spnego_gss_unwrap_aead
527 (
528 	OM_uint32 *minor_status,
529 	gss_ctx_id_t context_handle,
530 	gss_buffer_t input_message_buffer,
531 	gss_buffer_t input_assoc_buffer,
532 	gss_buffer_t output_payload_buffer,
533 	int *conf_state,
534 	gss_qop_t *qop_state
535 );
536 
537 OM_uint32 spnego_gss_wrap_iov
538 (
539 	OM_uint32 *minor_status,
540 	gss_ctx_id_t context_handle,
541 	int conf_req_flag,
542 	gss_qop_t qop_req,
543 	int *conf_state,
544 	gss_iov_buffer_desc *iov,
545 	int iov_count
546 );
547 
548 OM_uint32 spnego_gss_unwrap_iov
549 (
550 	OM_uint32 *minor_status,
551 	gss_ctx_id_t context_handle,
552 	int *conf_state,
553 	gss_qop_t *qop_state,
554 	gss_iov_buffer_desc *iov,
555 	int iov_count
556 );
557 
558 OM_uint32 spnego_gss_wrap_iov_length
559 (
560 	OM_uint32 *minor_status,
561 	gss_ctx_id_t context_handle,
562 	int conf_req_flag,
563 	gss_qop_t qop_req,
564 	int *conf_state,
565 	gss_iov_buffer_desc *iov,
566 	int iov_count
567 );
568 
569 OM_uint32
570 spnego_gss_complete_auth_token
571 (
572 	OM_uint32 *minor_status,
573 	const gss_ctx_id_t context_handle,
574 	gss_buffer_t input_message_buffer
575 );
576 #endif /* 0 */
577 
578 /*
579  * Solaris SPNEGO
580  * Cloned the krb5_*_error_message and krb5_gss_*_error_info APIs
581  * to give similar functionality to SPNEGO mech.
582  * See new files in this dir:
583  *     spnego_disp_status.c
584  *     spnego_kerrs.c
585  *     error_map.h
586  */
587 typedef int spnego_error_code;
588 void spnego_set_error_message (spnego_gss_ctx_id_t, spnego_error_code, const char *, ...);
589 const char * spnego_get_error_message (spnego_gss_ctx_id_t, spnego_error_code);
590 void spnego_free_error_message (spnego_gss_ctx_id_t, const char *);
591 void spnego_clear_error_message (spnego_gss_ctx_id_t);
592 
593 void spnego_gss_save_error_info(OM_uint32 minor_code, spnego_gss_ctx_id_t ctx);
594 char *spnego_gss_get_error_message(OM_uint32 minor_code);
595 void spnego_gss_delete_error_info(void *p);
596 
597 OM_uint32 krb5_gss_display_status2();
598 #ifdef	__cplusplus
599 }
600 #endif
601 
602 #endif /* _GSSAPIP_SPNEGO_H_ */
603