1 /* context.c --- Implementation of GSS-API Context functions.
2  * Copyright (C) 2003-2014 Simon Josefsson
3  *
4  * This file is part of the Generic Security Service (GSS).
5  *
6  * GSS is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS; if not, see http://www.gnu.org/licenses or write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19  * Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "internal.h"
24 
25 /* _gss_find_mech */
26 #include "meta.h"
27 
28 /**
29  * gss_init_sec_context:
30  * @minor_status: (integer, modify) Mechanism specific status code.
31  * @initiator_cred_handle: (gss_cred_id_t, read, optional) Handle for
32  *   credentials claimed.  Supply GSS_C_NO_CREDENTIAL to act as a
33  *   default initiator principal.  If no default initiator is defined,
34  *   the function will return GSS_S_NO_CRED.
35  * @context_handle: (gss_ctx_id_t, read/modify) Context handle for new
36  *   context.  Supply GSS_C_NO_CONTEXT for first call; use value
37  *   returned by first call in continuation calls.  Resources
38  *   associated with this context-handle must be released by the
39  *   application after use with a call to gss_delete_sec_context().
40  * @target_name: (gss_name_t, read) Name of target.
41  * @mech_type: (OID, read, optional) Object ID of desired
42  *   mechanism. Supply GSS_C_NO_OID to obtain an implementation
43  *   specific default.
44  * @req_flags: (bit-mask, read) Contains various independent flags,
45  *   each of which requests that the context support a specific
46  *   service option.  Symbolic names are provided for each flag, and
47  *   the symbolic names corresponding to the required flags should be
48  *   logically-ORed together to form the bit-mask value.  See below
49  *   for the flags.
50  * @time_req: (Integer, read, optional) Desired number of seconds for
51  *   which context should remain valid.  Supply 0 to request a default
52  *   validity period.
53  * @input_chan_bindings: (channel bindings, read, optional)
54  *   Application-specified bindings.  Allows application to securely
55  *   bind channel identification information to the security context.
56  *   Specify GSS_C_NO_CHANNEL_BINDINGS if channel bindings are not
57  *   used.
58  * @input_token: (buffer, opaque, read, optional) Token received from
59  *   peer application.  Supply GSS_C_NO_BUFFER, or a pointer to a
60  *   buffer containing the value GSS_C_EMPTY_BUFFER on initial call.
61  * @actual_mech_type: (OID, modify, optional) Actual mechanism used.
62  *   The OID returned via this parameter will be a pointer to static
63  *   storage that should be treated as read-only; In particular the
64  *   application should not attempt to free it.  Specify NULL if not
65  *   required.
66  * @output_token: (buffer, opaque, modify) Token to be sent to peer
67  *   application.  If the length field of the returned buffer is zero,
68  *   no token need be sent to the peer application.  Storage
69  *   associated with this buffer must be freed by the application
70  *   after use with a call to gss_release_buffer().
71  * @ret_flags: (bit-mask, modify, optional) Contains various
72  *   independent flags, each of which indicates that the context
73  *   supports a specific service option.  Specify NULL if not
74  *   required.  Symbolic names are provided for each flag, and the
75  *   symbolic names corresponding to the required flags should be
76  *   logically-ANDed with the ret_flags value to test whether a given
77  *   option is supported by the context.  See below for the flags.
78  * @time_rec: (Integer, modify, optional) Number of seconds for which
79  *   the context will remain valid. If the implementation does not
80  *   support context expiration, the value GSS_C_INDEFINITE will be
81  *   returned.  Specify NULL if not required.
82  *
83  * Initiates the establishment of a security context between the
84  * application and a remote peer.  Initially, the input_token
85  * parameter should be specified either as GSS_C_NO_BUFFER, or as a
86  * pointer to a gss_buffer_desc object whose length field contains the
87  * value zero.  The routine may return a output_token which should be
88  * transferred to the peer application, where the peer application
89  * will present it to gss_accept_sec_context.  If no token need be
90  * sent, gss_init_sec_context will indicate this by setting the length
91  * field of the output_token argument to zero. To complete the context
92  * establishment, one or more reply tokens may be required from the
93  * peer application; if so, gss_init_sec_context will return a status
94  * containing the supplementary information bit GSS_S_CONTINUE_NEEDED.
95  * In this case, gss_init_sec_context should be called again when the
96  * reply token is received from the peer application, passing the
97  * reply token to gss_init_sec_context via the input_token parameters.
98  *
99  * Portable applications should be constructed to use the token length
100  * and return status to determine whether a token needs to be sent or
101  * waited for.  Thus a typical portable caller should always invoke
102  * gss_init_sec_context within a loop:
103  *
104  * ---------------------------------------------------
105  * int context_established = 0;
106  * gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
107  *        ...
108  * input_token->length = 0;
109  *
110  * while (!context_established) {
111  *   maj_stat = gss_init_sec_context(&min_stat,
112  *                                   cred_hdl,
113  *                                   &context_hdl,
114  *                                   target_name,
115  *                                   desired_mech,
116  *                                   desired_services,
117  *                                   desired_time,
118  *                                   input_bindings,
119  *                                   input_token,
120  *                                   &actual_mech,
121  *                                   output_token,
122  *                                   &actual_services,
123  *                                   &actual_time);
124  *   if (GSS_ERROR(maj_stat)) {
125  *     report_error(maj_stat, min_stat);
126  *   };
127  *
128  *   if (output_token->length != 0) {
129  *     send_token_to_peer(output_token);
130  *     gss_release_buffer(&min_stat, output_token)
131  *   };
132  *   if (GSS_ERROR(maj_stat)) {
133  *
134  *     if (context_hdl != GSS_C_NO_CONTEXT)
135  *       gss_delete_sec_context(&min_stat,
136  *                              &context_hdl,
137  *                              GSS_C_NO_BUFFER);
138  *     break;
139  *   };
140  *
141  *   if (maj_stat & GSS_S_CONTINUE_NEEDED) {
142  *     receive_token_from_peer(input_token);
143  *   } else {
144  *     context_established = 1;
145  *   };
146  * };
147  * ---------------------------------------------------
148  *
149  * Whenever the routine returns a major status that includes the value
150  * GSS_S_CONTINUE_NEEDED, the context is not fully established and the
151  * following restrictions apply to the output parameters:
152  *
153  * - The value returned via the time_rec parameter is undefined unless
154  * the accompanying ret_flags parameter contains the bit
155  * GSS_C_PROT_READY_FLAG, indicating that per-message services may be
156  * applied in advance of a successful completion status, the value
157  * returned via the actual_mech_type parameter is undefined until the
158  * routine returns a major status value of GSS_S_COMPLETE.
159  *
160  * - The values of the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
161  * GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG,
162  * GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned via the
163  * ret_flags parameter should contain the values that the
164  * implementation expects would be valid if context establishment were
165  * to succeed.  In particular, if the application has requested a
166  * service such as delegation or anonymous authentication via the
167  * req_flags argument, and such a service is unavailable from the
168  * underlying mechanism, gss_init_sec_context should generate a token
169  * that will not provide the service, and indicate via the ret_flags
170  * argument that the service will not be supported.  The application
171  * may choose to abort the context establishment by calling
172  * gss_delete_sec_context (if it cannot continue in the absence of the
173  * service), or it may choose to transmit the token and continue
174  * context establishment (if the service was merely desired but not
175  * mandatory).
176  *
177  * - The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
178  * within ret_flags should indicate the actual state at the time
179  * gss_init_sec_context returns, whether or not the context is fully
180  * established.
181  *
182  * - GSS-API implementations that support per-message protection are
183  * encouraged to set the GSS_C_PROT_READY_FLAG in the final ret_flags
184  * returned to a caller (i.e. when accompanied by a GSS_S_COMPLETE
185  * status code).  However, applications should not rely on this
186  * behavior as the flag was not defined in Version 1 of the GSS-API.
187  * Instead, applications should determine what per-message services
188  * are available after a successful context establishment according to
189  * the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
190  *
191  * - All other bits within the ret_flags argument should be set to
192  * zero.
193  *
194  * If the initial call of gss_init_sec_context() fails, the
195  * implementation should not create a context object, and should leave
196  * the value of the context_handle parameter set to GSS_C_NO_CONTEXT
197  * to indicate this.  In the event of a failure on a subsequent call,
198  * the implementation is permitted to delete the "half-built" security
199  * context (in which case it should set the context_handle parameter
200  * to GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
201  * security context untouched for the application to delete (using
202  * gss_delete_sec_context).
203  *
204  * During context establishment, the informational status bits
205  * GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors,
206  * and GSS-API mechanisms should always return them in association
207  * with a routine error of GSS_S_FAILURE.  This requirement for
208  * pairing did not exist in version 1 of the GSS-API specification, so
209  * applications that wish to run over version 1 implementations must
210  * special-case these codes.
211  *
212  * The `req_flags` values:
213  *
214  * `GSS_C_DELEG_FLAG`::
215  * - True - Delegate credentials to remote peer.
216  * - False - Don't delegate.
217  *
218  * `GSS_C_MUTUAL_FLAG`::
219  * - True - Request that remote peer authenticate itself.
220  * - False - Authenticate self to remote peer only.
221  *
222  * `GSS_C_REPLAY_FLAG`::
223  * - True - Enable replay detection for messages protected with
224  * gss_wrap or gss_get_mic.
225  * - False - Don't attempt to detect replayed messages.
226  *
227  * `GSS_C_SEQUENCE_FLAG`::
228  * - True - Enable detection of out-of-sequence protected messages.
229  * - False - Don't attempt to detect out-of-sequence messages.
230  *
231  * `GSS_C_CONF_FLAG`::
232  * - True - Request that confidentiality service be made available
233  * (via gss_wrap).
234  * - False - No per-message confidentiality service is required.
235  *
236  * `GSS_C_INTEG_FLAG`::
237  * - True - Request that integrity service be made available (via
238  * gss_wrap or gss_get_mic).
239  * - False - No per-message integrity service is required.
240  *
241  * `GSS_C_ANON_FLAG`::
242  * - True - Do not reveal the initiator's identity to the acceptor.
243  * - False - Authenticate normally.
244  *
245  * The `ret_flags` values:
246  *
247  * `GSS_C_DELEG_FLAG`::
248  * - True - Credentials were delegated to the remote peer.
249  * - False - No credentials were delegated.
250  *
251  * `GSS_C_MUTUAL_FLAG`::
252  * - True - The remote peer has authenticated itself.
253  * - False - Remote peer has not authenticated itself.
254  *
255  * `GSS_C_REPLAY_FLAG`::
256  * - True - replay of protected messages will be detected.
257  * - False - replayed messages will not be detected.
258  *
259  * `GSS_C_SEQUENCE_FLAG`::
260  * - True - out-of-sequence protected messages will be detected.
261  * - False - out-of-sequence messages will not be detected.
262  *
263  * `GSS_C_CONF_FLAG`::
264  * - True - Confidentiality service may be invoked by calling gss_wrap
265  * routine.
266  * - False - No confidentiality service (via gss_wrap)
267  * available. gss_wrap will provide message encapsulation, data-origin
268  * authentication and integrity services only.
269  *
270  * `GSS_C_INTEG_FLAG`::
271  * - True - Integrity service may be invoked by calling either
272  * gss_get_mic or gss_wrap routines.
273  * - False - Per-message integrity service unavailable.
274  *
275  * `GSS_C_ANON_FLAG`::
276  * - True - The initiator's identity has not been revealed, and will
277  * not be revealed if any emitted token is passed to the acceptor.
278  * - False - The initiator's identity has been or will be
279  * authenticated normally.
280  *
281  * `GSS_C_PROT_READY_FLAG`::
282  * - True - Protection services (as specified by the states of the
283  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available for use if the
284  * accompanying major status return value is either GSS_S_COMPLETE or
285  * GSS_S_CONTINUE_NEEDED.
286  * - False - Protection services (as specified by the states of the
287  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
288  * accompanying major status return value is GSS_S_COMPLETE.
289  *
290  * `GSS_C_TRANS_FLAG`::
291  * - True - The resultant security context may be transferred to other
292  * processes via a call to gss_export_sec_context().
293  * - False - The security context is not transferable.
294  *
295  * All other bits should be set to zero.
296  *
297  * Return value:
298  *
299  * `GSS_S_COMPLETE`: Successful completion.
300  *
301  * `GSS_S_CONTINUE_NEEDED`: Indicates that a token from the peer
302  * application is required to complete the context, and that
303  * gss_init_sec_context must be called again with that token.
304  *
305  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
306  * performed on the input_token failed.
307  *
308  * `GSS_S_DEFECTIVE_CREDENTIAL`: Indicates that consistency checks
309  * performed on the credential failed.
310  *
311  * `GSS_S_NO_CRED`: The supplied credentials were not valid for
312  * context initiation, or the credential handle did not reference any
313  * credentials.
314  *
315  * `GSS_S_CREDENTIALS_EXPIRED`: The referenced credentials have
316  * expired.
317  *
318  * `GSS_S_BAD_BINDINGS`: The input_token contains different channel
319  * bindings to those specified via the input_chan_bindings parameter.
320  *
321  * `GSS_S_BAD_SIG`: The input_token contains an invalid MIC, or a MIC
322  * that could not be verified.
323  *
324  * `GSS_S_OLD_TOKEN`: The input_token was too old.  This is a fatal
325  * error during context establishment.
326  *
327  * `GSS_S_DUPLICATE_TOKEN`: The input_token is valid, but is a
328  * duplicate of a token already processed.  This is a fatal error
329  * during context establishment.
330  *
331  * `GSS_S_NO_CONTEXT`: Indicates that the supplied context handle did
332  * not refer to a valid context.
333  *
334  * `GSS_S_BAD_NAMETYPE`: The provided target_name parameter contained
335  * an invalid or unsupported type of name.
336  *
337  * `GSS_S_BAD_NAME`: The provided target_name parameter was
338  * ill-formed.
339  *
340  * `GSS_S_BAD_MECH`: The specified mechanism is not supported by the
341  * provided credential, or is unrecognized by the implementation.
342  **/
343 OM_uint32
gss_init_sec_context(OM_uint32 * minor_status,const gss_cred_id_t initiator_cred_handle,gss_ctx_id_t * context_handle,const gss_name_t target_name,const gss_OID mech_type,OM_uint32 req_flags,OM_uint32 time_req,const gss_channel_bindings_t input_chan_bindings,const gss_buffer_t input_token,gss_OID * actual_mech_type,gss_buffer_t output_token,OM_uint32 * ret_flags,OM_uint32 * time_rec)344 gss_init_sec_context (OM_uint32 * minor_status,
345 		      const gss_cred_id_t initiator_cred_handle,
346 		      gss_ctx_id_t * context_handle,
347 		      const gss_name_t target_name,
348 		      const gss_OID mech_type,
349 		      OM_uint32 req_flags,
350 		      OM_uint32 time_req,
351 		      const gss_channel_bindings_t input_chan_bindings,
352 		      const gss_buffer_t input_token,
353 		      gss_OID * actual_mech_type,
354 		      gss_buffer_t output_token,
355 		      OM_uint32 * ret_flags, OM_uint32 * time_rec)
356 {
357   OM_uint32 maj_stat;
358   _gss_mech_api_t mech;
359   int freecontext = 0;
360 
361   if (output_token)
362     {
363       output_token->length = 0;
364       output_token->value = NULL;
365     }
366 
367   if (ret_flags)
368     *ret_flags = 0;
369 
370   if (!context_handle)
371     {
372       if (minor_status)
373 	*minor_status = 0;
374       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
375     }
376 
377   if (output_token == GSS_C_NO_BUFFER)
378     {
379       if (minor_status)
380 	*minor_status = 0;
381       return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
382     }
383 
384   if (*context_handle == GSS_C_NO_CONTEXT)
385     mech = _gss_find_mech (mech_type);
386   else
387     mech = _gss_find_mech ((*context_handle)->mech);
388   if (mech == NULL)
389     {
390       if (minor_status)
391 	*minor_status = 0;
392       return GSS_S_BAD_MECH;
393     }
394 
395   if (actual_mech_type)
396     *actual_mech_type = mech->mech;
397 
398   if (*context_handle == GSS_C_NO_CONTEXT)
399     {
400       *context_handle = calloc (sizeof (**context_handle), 1);
401       if (!*context_handle)
402 	{
403 	  if (minor_status)
404 	    *minor_status = ENOMEM;
405 	  return GSS_S_FAILURE;
406 	}
407       (*context_handle)->mech = mech->mech;
408       freecontext = 1;
409     }
410 
411   maj_stat = mech->init_sec_context (minor_status,
412 				     initiator_cred_handle,
413 				     context_handle,
414 				     target_name,
415 				     mech_type,
416 				     req_flags,
417 				     time_req,
418 				     input_chan_bindings,
419 				     input_token,
420 				     actual_mech_type,
421 				     output_token, ret_flags, time_rec);
422 
423   if (GSS_ERROR (maj_stat) && freecontext)
424     {
425       free (*context_handle);
426       *context_handle = GSS_C_NO_CONTEXT;
427     }
428 
429   return maj_stat;
430 }
431 
432 /**
433  * gss_accept_sec_context:
434  * @minor_status: (Integer, modify) Mechanism specific status code.
435  * @context_handle: (gss_ctx_id_t, read/modify) Context handle for new
436  *   context.  Supply GSS_C_NO_CONTEXT for first call; use value
437  *   returned in subsequent calls.  Once gss_accept_sec_context() has
438  *   returned a value via this parameter, resources have been assigned
439  *   to the corresponding context, and must be freed by the
440  *   application after use with a call to gss_delete_sec_context().
441  * @acceptor_cred_handle: (gss_cred_id_t, read) Credential handle
442  *   claimed by context acceptor. Specify GSS_C_NO_CREDENTIAL to
443  *   accept the context as a default principal.  If
444  *   GSS_C_NO_CREDENTIAL is specified, but no default acceptor
445  *   principal is defined, GSS_S_NO_CRED will be returned.
446  * @input_token_buffer: (buffer, opaque, read) Token obtained from
447  *   remote application.
448  * @input_chan_bindings: (channel bindings, read, optional)
449  *   Application- specified bindings.  Allows application to securely
450  *   bind channel identification information to the security context.
451  *   If channel bindings are not used, specify
452  *   GSS_C_NO_CHANNEL_BINDINGS.
453  * @src_name: (gss_name_t, modify, optional) Authenticated name of
454  *   context initiator.  After use, this name should be deallocated by
455  *   passing it to gss_release_name().  If not required, specify NULL.
456  * @mech_type: (Object ID, modify, optional) Security mechanism used.
457  *   The returned OID value will be a pointer into static storage, and
458  *   should be treated as read-only by the caller (in particular, it
459  *   does not need to be freed).  If not required, specify NULL.
460  * @output_token: (buffer, opaque, modify) Token to be passed to peer
461  *   application.  If the length field of the returned token buffer is
462  *   0, then no token need be passed to the peer application.  If a
463  *   non- zero length field is returned, the associated storage must
464  *   be freed after use by the application with a call to
465  *   gss_release_buffer().
466  * @ret_flags: (bit-mask, modify, optional) Contains various
467  *   independent flags, each of which indicates that the context
468  *   supports a specific service option.  If not needed, specify NULL.
469  *   Symbolic names are provided for each flag, and the symbolic names
470  *   corresponding to the required flags should be logically-ANDed
471  *   with the ret_flags value to test whether a given option is
472  *   supported by the context.  See below for the flags.
473  * @time_rec: (Integer, modify, optional) Number of seconds for which
474  *   the context will remain valid. Specify NULL if not required.
475  * @delegated_cred_handle: (gss_cred_id_t, modify, optional
476  *   credential) Handle for credentials received from context
477  *   initiator.  Only valid if deleg_flag in ret_flags is true, in
478  *   which case an explicit credential handle (i.e. not
479  *   GSS_C_NO_CREDENTIAL) will be returned; if deleg_flag is false,
480  *   gss_accept_sec_context() will set this parameter to
481  *   GSS_C_NO_CREDENTIAL.  If a credential handle is returned, the
482  *   associated resources must be released by the application after
483  *   use with a call to gss_release_cred().  Specify NULL if not
484  *   required.
485  *
486  * Allows a remotely initiated security context between the
487  * application and a remote peer to be established.  The routine may
488  * return a output_token which should be transferred to the peer
489  * application, where the peer application will present it to
490  * gss_init_sec_context.  If no token need be sent,
491  * gss_accept_sec_context will indicate this by setting the length
492  * field of the output_token argument to zero.  To complete the
493  * context establishment, one or more reply tokens may be required
494  * from the peer application; if so, gss_accept_sec_context will
495  * return a status flag of GSS_S_CONTINUE_NEEDED, in which case it
496  * should be called again when the reply token is received from the
497  * peer application, passing the token to gss_accept_sec_context via
498  * the input_token parameters.
499  *
500  * Portable applications should be constructed to use the token length
501  * and return status to determine whether a token needs to be sent or
502  * waited for.  Thus a typical portable caller should always invoke
503  * gss_accept_sec_context within a loop:
504  *
505  * ---------------------------------------------------
506  * gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
507  *
508  * do {
509  *   receive_token_from_peer(input_token);
510  *   maj_stat = gss_accept_sec_context(&min_stat,
511  *                                     &context_hdl,
512  *                                     cred_hdl,
513  *                                     input_token,
514  *                                     input_bindings,
515  *                                     &client_name,
516  *                                     &mech_type,
517  *                                     output_token,
518  *                                     &ret_flags,
519  *                                     &time_rec,
520  *                                     &deleg_cred);
521  *   if (GSS_ERROR(maj_stat)) {
522  *     report_error(maj_stat, min_stat);
523  *   };
524  *   if (output_token->length != 0) {
525  *     send_token_to_peer(output_token);
526  *
527  *     gss_release_buffer(&min_stat, output_token);
528  *   };
529  *   if (GSS_ERROR(maj_stat)) {
530  *     if (context_hdl != GSS_C_NO_CONTEXT)
531  *       gss_delete_sec_context(&min_stat,
532  *                              &context_hdl,
533  *                              GSS_C_NO_BUFFER);
534  *     break;
535  *   };
536  * } while (maj_stat & GSS_S_CONTINUE_NEEDED);
537  * ---------------------------------------------------
538  *
539  *
540  * Whenever the routine returns a major status that includes the value
541  * GSS_S_CONTINUE_NEEDED, the context is not fully established and the
542  * following restrictions apply to the output parameters:
543  *
544  * The value returned via the time_rec parameter is undefined Unless the
545  * accompanying ret_flags parameter contains the bit
546  * GSS_C_PROT_READY_FLAG, indicating that per-message services may be
547  * applied in advance of a successful completion status, the value
548  * returned via the mech_type parameter may be undefined until the
549  * routine returns a major status value of GSS_S_COMPLETE.
550  *
551  * The values of the GSS_C_DELEG_FLAG,
552  * GSS_C_MUTUAL_FLAG,GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG,
553  * GSS_C_CONF_FLAG,GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned
554  * via the ret_flags parameter should contain the values that the
555  * implementation expects would be valid if context establishment were
556  * to succeed.
557  *
558  * The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
559  * within ret_flags should indicate the actual state at the time
560  * gss_accept_sec_context returns, whether or not the context is fully
561  * established.
562  *
563  * Although this requires that GSS-API implementations set the
564  * GSS_C_PROT_READY_FLAG in the final ret_flags returned to a caller
565  * (i.e. when accompanied by a GSS_S_COMPLETE status code), applications
566  * should not rely on this behavior as the flag was not defined in
567  * Version 1 of the GSS-API. Instead, applications should be prepared to
568  * use per-message services after a successful context establishment,
569  * according to the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
570  *
571  * All other bits within the ret_flags argument should be set to zero.
572  * While the routine returns GSS_S_CONTINUE_NEEDED, the values returned
573  * via the ret_flags argument indicate the services that the
574  * implementation expects to be available from the established context.
575  *
576  * If the initial call of gss_accept_sec_context() fails, the
577  * implementation should not create a context object, and should leave
578  * the value of the context_handle parameter set to GSS_C_NO_CONTEXT to
579  * indicate this.  In the event of a failure on a subsequent call, the
580  * implementation is permitted to delete the "half-built" security
581  * context (in which case it should set the context_handle parameter to
582  * GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
583  * security context (and the context_handle parameter) untouched for the
584  * application to delete (using gss_delete_sec_context).
585  *
586  * During context establishment, the informational status bits
587  * GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors, and
588  * GSS-API mechanisms should always return them in association with a
589  * routine error of GSS_S_FAILURE.  This requirement for pairing did not
590  * exist in version 1 of the GSS-API specification, so applications that
591  * wish to run over version 1 implementations must special-case these
592  * codes.
593  *
594  * The `ret_flags` values:
595  *
596  * `GSS_C_DELEG_FLAG`::
597  * - True - Delegated credentials are available via the
598  * delegated_cred_handle parameter.
599  * - False - No credentials were delegated.
600  *
601  * `GSS_C_MUTUAL_FLAG`::
602  * - True - Remote peer asked for mutual authentication.
603  * - False - Remote peer did not ask for mutual authentication.
604  *
605  * `GSS_C_REPLAY_FLAG`::
606  * - True - replay of protected messages will be detected.
607  * - False - replayed messages will not be detected.
608  *
609  * `GSS_C_SEQUENCE_FLAG`::
610  * - True - out-of-sequence protected messages will be detected.
611  * - False - out-of-sequence messages will not be detected.
612  *
613  * `GSS_C_CONF_FLAG`::
614  * - True - Confidentiality service may be invoked by calling the
615  * gss_wrap routine.
616  * - False - No confidentiality service (via gss_wrap)
617  * available. gss_wrap will provide message encapsulation, data-origin
618  * authentication and integrity services only.
619  *
620  * `GSS_C_INTEG_FLAG`::
621  * - True - Integrity service may be invoked by calling either
622  * gss_get_mic or gss_wrap routines.
623  * - False - Per-message integrity service unavailable.
624  *
625  * `GSS_C_ANON_FLAG`::
626  * - True - The initiator does not wish to be authenticated; the
627  * src_name parameter (if requested) contains an anonymous internal
628  * name.
629  * - False - The initiator has been authenticated normally.
630  *
631  * `GSS_C_PROT_READY_FLAG`::
632  * - True - Protection services (as specified by the states of the
633  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available if the
634  * accompanying major status return value is either GSS_S_COMPLETE or
635  * GSS_S_CONTINUE_NEEDED.
636  * - False - Protection services (as specified by the states of the
637  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
638  * accompanying major status return value is GSS_S_COMPLETE.
639  *
640  * `GSS_C_TRANS_FLAG`::
641  * - True - The resultant security context may be transferred to other
642  * processes via a call to gss_export_sec_context().
643  * - False - The security context is not transferable.
644  *
645  * All other bits should be set to zero.
646  *
647  * Return value:
648  *
649  * `GSS_S_CONTINUE_NEEDED`: Indicates that a token from the peer
650  * application is required to complete the context, and that
651  * gss_accept_sec_context must be called again with that token.
652  *
653  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
654  * performed on the input_token failed.
655  *
656  * `GSS_S_DEFECTIVE_CREDENTIAL`: Indicates that consistency checks
657  * performed on the credential failed.
658  *
659  * `GSS_S_NO_CRED`: The supplied credentials were not valid for
660  * context acceptance, or the credential handle did not reference any
661  * credentials.
662  *
663  * `GSS_S_CREDENTIALS_EXPIRED`: The referenced credentials have
664  * expired.
665  *
666  * `GSS_S_BAD_BINDINGS`: The input_token contains different channel
667  * bindings to those specified via the input_chan_bindings parameter.
668  *
669  * `GSS_S_NO_CONTEXT`: Indicates that the supplied context handle did
670  * not refer to a valid context.
671  *
672  * `GSS_S_BAD_SIG`: The input_token contains an invalid MIC.
673  *
674  * `GSS_S_OLD_TOKEN`: The input_token was too old.  This is a fatal
675  * error during context establishment.
676  *
677  * `GSS_S_DUPLICATE_TOKEN`: The input_token is valid, but is a
678  * duplicate of a token already processed.  This is a fatal error
679  * during context establishment.
680  *
681  * `GSS_S_BAD_MECH`: The received token specified a mechanism that is
682  * not supported by the implementation or the provided credential.
683  **/
684 OM_uint32
gss_accept_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,const gss_cred_id_t acceptor_cred_handle,const gss_buffer_t input_token_buffer,const gss_channel_bindings_t input_chan_bindings,gss_name_t * src_name,gss_OID * mech_type,gss_buffer_t output_token,OM_uint32 * ret_flags,OM_uint32 * time_rec,gss_cred_id_t * delegated_cred_handle)685 gss_accept_sec_context (OM_uint32 * minor_status,
686 			gss_ctx_id_t * context_handle,
687 			const gss_cred_id_t acceptor_cred_handle,
688 			const gss_buffer_t input_token_buffer,
689 			const gss_channel_bindings_t input_chan_bindings,
690 			gss_name_t * src_name,
691 			gss_OID * mech_type,
692 			gss_buffer_t output_token,
693 			OM_uint32 * ret_flags,
694 			OM_uint32 * time_rec,
695 			gss_cred_id_t * delegated_cred_handle)
696 {
697   _gss_mech_api_t mech;
698 
699   if (!context_handle)
700     {
701       if (minor_status)
702 	*minor_status = 0;
703       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
704     }
705 
706   if (*context_handle == GSS_C_NO_CONTEXT)
707     {
708       char *oid;
709       size_t oidlen;
710       gss_OID_desc oidbuf;
711       int rc;
712 
713       rc = _gss_decapsulate_token (input_token_buffer->value,
714 				   input_token_buffer->length,
715 				   &oid, &oidlen, NULL, NULL);
716       if (rc != 0)
717 	{
718 	  if (minor_status)
719 	    *minor_status = 0;
720 	  return GSS_S_DEFECTIVE_TOKEN;
721 	}
722 
723       oidbuf.elements = oid;
724       oidbuf.length = oidlen;
725 
726       mech = _gss_find_mech_no_default (&oidbuf);
727     }
728   else
729     mech = _gss_find_mech_no_default ((*context_handle)->mech);
730   if (mech == NULL)
731     {
732       if (minor_status)
733 	*minor_status = 0;
734       return GSS_S_BAD_MECH;
735     }
736 
737   if (mech_type)
738     *mech_type = mech->mech;
739 
740   return mech->accept_sec_context (minor_status,
741 				   context_handle,
742 				   acceptor_cred_handle,
743 				   input_token_buffer,
744 				   input_chan_bindings,
745 				   src_name,
746 				   mech_type,
747 				   output_token,
748 				   ret_flags,
749 				   time_rec, delegated_cred_handle);
750 }
751 
752 /**
753  * gss_delete_sec_context:
754  * @minor_status: (Integer, modify) Mechanism specific status code.
755  * @context_handle: (gss_ctx_id_t, modify) Context handle identifying
756  *   context to delete.  After deleting the context, the GSS-API will
757  *   set this context handle to GSS_C_NO_CONTEXT.
758  * @output_token: (buffer, opaque, modify, optional) Token to be sent
759  *   to remote application to instruct it to also delete the context.
760  *   It is recommended that applications specify GSS_C_NO_BUFFER for
761  *   this parameter, requesting local deletion only.  If a buffer
762  *   parameter is provided by the application, the mechanism may
763  *   return a token in it; mechanisms that implement only local
764  *   deletion should set the length field of this token to zero to
765  *   indicate to the application that no token is to be sent to the
766  *   peer.
767  *
768  * Delete a security context.  gss_delete_sec_context will delete the
769  * local data structures associated with the specified security
770  * context, and may generate an output_token, which when passed to the
771  * peer gss_process_context_token will instruct it to do likewise.  If
772  * no token is required by the mechanism, the GSS-API should set the
773  * length field of the output_token (if provided) to zero.  No further
774  * security services may be obtained using the context specified by
775  * context_handle.
776  *
777  * In addition to deleting established security contexts,
778  * gss_delete_sec_context must also be able to delete "half-built"
779  * security contexts resulting from an incomplete sequence of
780  * gss_init_sec_context()/gss_accept_sec_context() calls.
781  *
782  * The output_token parameter is retained for compatibility with
783  * version 1 of the GSS-API.  It is recommended that both peer
784  * applications invoke gss_delete_sec_context passing the value
785  * GSS_C_NO_BUFFER for the output_token parameter, indicating that no
786  * token is required, and that gss_delete_sec_context should simply
787  * delete local context data structures.  If the application does pass
788  * a valid buffer to gss_delete_sec_context, mechanisms are encouraged
789  * to return a zero-length token, indicating that no peer action is
790  * necessary, and that no token should be transferred by the
791  * application.
792  *
793  * Return value:
794  *
795  * `GSS_S_COMPLETE`: Successful completion.
796  *
797  * `GSS_S_NO_CONTEXT`: No valid context was supplied.
798  **/
799 OM_uint32
gss_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)800 gss_delete_sec_context (OM_uint32 * minor_status,
801 			gss_ctx_id_t * context_handle,
802 			gss_buffer_t output_token)
803 {
804   _gss_mech_api_t mech;
805   OM_uint32 ret;
806 
807   if (!context_handle)
808     {
809       if (minor_status)
810 	*minor_status = 0;
811       return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
812     }
813 
814   if (*context_handle == GSS_C_NO_CONTEXT)
815     {
816       if (minor_status)
817 	*minor_status = 0;
818       return GSS_S_NO_CONTEXT | GSS_S_CALL_BAD_STRUCTURE;
819     }
820 
821   if (output_token != GSS_C_NO_BUFFER)
822     {
823       output_token->length = 0;
824       output_token->value = NULL;
825     }
826 
827   mech = _gss_find_mech ((*context_handle)->mech);
828   if (mech == NULL)
829     {
830       if (minor_status)
831 	*minor_status = 0;
832       return GSS_S_BAD_MECH;
833     }
834 
835   ret = mech->delete_sec_context (NULL, context_handle, output_token);
836 
837   free (*context_handle);
838   *context_handle = GSS_C_NO_CONTEXT;
839 
840   return ret;
841 }
842 
843 /**
844  * gss_process_context_token:
845  * @minor_status: (Integer, modify) Implementation specific status code.
846  * @context_handle: (gss_ctx_id_t, read) Context handle of context on
847  *   which token is to be processed
848  * @token_buffer: (buffer, opaque, read) Token to process.
849  *
850  * Provides a way to pass an asynchronous token to the security
851  * service.  Most context-level tokens are emitted and processed
852  * synchronously by gss_init_sec_context and gss_accept_sec_context,
853  * and the application is informed as to whether further tokens are
854  * expected by the GSS_C_CONTINUE_NEEDED major status bit.
855  * Occasionally, a mechanism may need to emit a context-level token at
856  * a point when the peer entity is not expecting a token.  For
857  * example, the initiator's final call to gss_init_sec_context may
858  * emit a token and return a status of GSS_S_COMPLETE, but the
859  * acceptor's call to gss_accept_sec_context may fail.  The acceptor's
860  * mechanism may wish to send a token containing an error indication
861  * to the initiator, but the initiator is not expecting a token at
862  * this point, believing that the context is fully established.
863  * Gss_process_context_token provides a way to pass such a token to
864  * the mechanism at any time.
865  *
866  * Return value:
867  *
868  * `GSS_S_COMPLETE`: Successful completion.
869  *
870  * `GSS_S_DEFECTIVE_TOKEN`: Indicates that consistency checks
871  * performed on the token failed.
872  *
873  * `GSS_S_NO_CONTEXT`: The context_handle did not refer to a valid
874  * context.
875  **/
876 OM_uint32
gss_process_context_token(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t token_buffer)877 gss_process_context_token (OM_uint32 * minor_status,
878 			   const gss_ctx_id_t context_handle,
879 			   const gss_buffer_t token_buffer)
880 {
881   return GSS_S_FAILURE;
882 }
883 
884 /**
885  * gss_context_time:
886  * @minor_status: (Integer, modify) Implementation specific status
887  *   code.
888  * @context_handle: (gss_ctx_id_t, read) Identifies the context to be
889  *   interrogated.
890  * @time_rec: (Integer, modify) Number of seconds that the context
891  *   will remain valid.  If the context has already expired, zero will
892  *   be returned.
893  *
894  * Determines the number of seconds for which the specified context
895  * will remain valid.
896  *
897  * Return value:
898  *
899  * `GSS_S_COMPLETE`: Successful completion.
900  *
901  * `GSS_S_CONTEXT_EXPIRED`: The context has already expired.
902  *
903  * `GSS_S_NO_CONTEXT`: The context_handle parameter did not identify a
904  * valid context
905  **/
906 OM_uint32
gss_context_time(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,OM_uint32 * time_rec)907 gss_context_time (OM_uint32 * minor_status,
908 		  const gss_ctx_id_t context_handle, OM_uint32 * time_rec)
909 {
910   _gss_mech_api_t mech;
911 
912   if (context_handle == GSS_C_NO_CONTEXT)
913     {
914       if (minor_status)
915 	*minor_status = 0;
916       return GSS_S_NO_CONTEXT | GSS_S_CALL_BAD_STRUCTURE;
917     }
918 
919   mech = _gss_find_mech (context_handle->mech);
920   if (mech == NULL)
921     {
922       if (minor_status)
923 	*minor_status = 0;
924       return GSS_S_BAD_MECH;
925     }
926 
927   return mech->context_time (minor_status, context_handle, time_rec);
928 }
929 
930 /**
931  * gss_inquire_context:
932  * @minor_status: (Integer, modify) Mechanism specific status code.
933  * @context_handle: (gss_ctx_id_t, read) A handle that refers to the
934  *   security context.
935  * @src_name: (gss_name_t, modify, optional) The name of the context
936  *   initiator.  If the context was established using anonymous
937  *   authentication, and if the application invoking
938  *   gss_inquire_context is the context acceptor, an anonymous name
939  *   will be returned.  Storage associated with this name must be
940  *   freed by the application after use with a call to
941  *   gss_release_name().  Specify NULL if not required.
942  * @targ_name: (gss_name_t, modify, optional) The name of the context
943  *   acceptor.  Storage associated with this name must be freed by the
944  *   application after use with a call to gss_release_name().  If the
945  *   context acceptor did not authenticate itself, and if the
946  *   initiator did not specify a target name in its call to
947  *   gss_init_sec_context(), the value GSS_C_NO_NAME will be returned.
948  *   Specify NULL if not required.
949  * @lifetime_rec: (Integer, modify, optional) The number of seconds
950  *   for which the context will remain valid.  If the context has
951  *   expired, this parameter will be set to zero.  If the
952  *   implementation does not support context expiration, the value
953  *   GSS_C_INDEFINITE will be returned.  Specify NULL if not required.
954  * @mech_type: (gss_OID, modify, optional) The security mechanism
955  *   providing the context.  The returned OID will be a pointer to
956  *   static storage that should be treated as read-only by the
957  *   application; in particular the application should not attempt to
958  *   free it.  Specify NULL if not required.
959  * @ctx_flags: (bit-mask, modify, optional) Contains various
960  *   independent flags, each of which indicates that the context
961  *   supports (or is expected to support, if ctx_open is false) a
962  *   specific service option.  If not needed, specify NULL.  Symbolic
963  *   names are provided for each flag, and the symbolic names
964  *   corresponding to the required flags should be logically-ANDed
965  *   with the ret_flags value to test whether a given option is
966  *   supported by the context.  See below for the flags.
967  * @locally_initiated: (Boolean, modify) Non-zero if the invoking
968  *   application is the context initiator.  Specify NULL if not
969  *   required.
970  * @open: (Boolean, modify) Non-zero if the context is fully
971  *   established; Zero if a context-establishment token is expected
972  *   from the peer application.  Specify NULL if not required.
973  *
974  * Obtains information about a security context.  The caller must
975  * already have obtained a handle that refers to the context, although
976  * the context need not be fully established.
977  *
978  * The `ctx_flags` values:
979  *
980  * `GSS_C_DELEG_FLAG`::
981  * - True - Credentials were delegated from the initiator to the
982  * acceptor.
983  * - False - No credentials were delegated.
984  *
985  * `GSS_C_MUTUAL_FLAG`::
986  * - True - The acceptor was authenticated to the initiator.
987  * - False - The acceptor did not authenticate itself.
988  *
989  * `GSS_C_REPLAY_FLAG`::
990  * - True - replay of protected messages will be detected.
991  * - False - replayed messages will not be detected.
992  *
993  * `GSS_C_SEQUENCE_FLAG`::
994  * - True - out-of-sequence protected messages will be detected.
995  * - False - out-of-sequence messages will not be detected.
996  *
997  * `GSS_C_CONF_FLAG`::
998  * - True - Confidentiality service may be invoked by calling gss_wrap
999  * routine.
1000  * - False - No confidentiality service (via gss_wrap)
1001  * available. gss_wrap will provide message encapsulation, data-origin
1002  * authentication and integrity services only.
1003  *
1004  * `GSS_C_INTEG_FLAG`::
1005  * - True - Integrity service may be invoked by calling either
1006  * gss_get_mic or gss_wrap routines.
1007  * - False - Per-message integrity service unavailable.
1008  *
1009  * `GSS_C_ANON_FLAG`::
1010  * - True - The initiator's identity will not be revealed to the
1011  * acceptor.  The src_name parameter (if requested) contains an
1012  * anonymous internal name.
1013  * - False - The initiator has been authenticated normally.
1014  *
1015  * `GSS_C_PROT_READY_FLAG`::
1016  * - True - Protection services (as specified by the states of the
1017  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available for use.
1018  * - False - Protection services (as specified by the states of the
1019  * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
1020  * context is fully established (i.e. if the open parameter is
1021  * non-zero).
1022  *
1023  * `GSS_C_TRANS_FLAG`::
1024  * - True - The resultant security context may be transferred to other
1025  * processes via a call to gss_export_sec_context().
1026  * - False - The security context is not transferable.
1027  *
1028  * Return value:
1029  *
1030  * `GSS_S_COMPLETE`: Successful completion.
1031  *
1032  * `GSS_S_NO_CONTEXT`: The referenced context could not be accessed.
1033  **/
1034 OM_uint32
gss_inquire_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,gss_name_t * src_name,gss_name_t * targ_name,OM_uint32 * lifetime_rec,gss_OID * mech_type,OM_uint32 * ctx_flags,int * locally_initiated,int * open)1035 gss_inquire_context (OM_uint32 * minor_status,
1036 		     const gss_ctx_id_t context_handle,
1037 		     gss_name_t * src_name,
1038 		     gss_name_t * targ_name,
1039 		     OM_uint32 * lifetime_rec,
1040 		     gss_OID * mech_type,
1041 		     OM_uint32 * ctx_flags, int *locally_initiated, int *open)
1042 {
1043   return GSS_S_FAILURE;
1044 }
1045 
1046 /**
1047  * gss_wrap_size_limit:
1048  * @minor_status: (Integer, modify) Mechanism specific status code.
1049  * @context_handle: (gss_ctx_id_t, read) A handle that refers to the
1050  *   security over which the messages will be sent.
1051  * @conf_req_flag: (Boolean, read) Indicates whether gss_wrap will be
1052  *   asked to apply confidentiality protection in addition to
1053  *   integrity protection.  See the routine description for gss_wrap
1054  *   for more details.
1055  * @qop_req: (gss_qop_t, read) Indicates the level of protection that
1056  *   gss_wrap will be asked to provide.  See the routine description
1057  *   for gss_wrap for more details.
1058  * @req_output_size: (Integer, read) The desired maximum size for
1059  *   tokens emitted by gss_wrap.
1060  * @max_input_size: (Integer, modify) The maximum input message size
1061  *   that may be presented to gss_wrap in order to guarantee that the
1062  *   emitted token shall be no larger than req_output_size bytes.
1063  *
1064  * Allows an application to determine the maximum message size that,
1065  * if presented to gss_wrap with the same conf_req_flag and qop_req
1066  * parameters, will result in an output token containing no more than
1067  * req_output_size bytes.
1068  *
1069  * This call is intended for use by applications that communicate over
1070  * protocols that impose a maximum message size.  It enables the
1071  * application to fragment messages prior to applying protection.
1072  *
1073  * GSS-API implementations are recommended but not required to detect
1074  * invalid QOP values when gss_wrap_size_limit() is called. This
1075  * routine guarantees only a maximum message size, not the
1076  * availability of specific QOP values for message protection.
1077  *
1078  * Successful completion of this call does not guarantee that gss_wrap
1079  * will be able to protect a message of length max_input_size bytes,
1080  * since this ability may depend on the availability of system
1081  * resources at the time that gss_wrap is called.  However, if the
1082  * implementation itself imposes an upper limit on the length of
1083  * messages that may be processed by gss_wrap, the implementation
1084  * should not return a value via max_input_bytes that is greater than
1085  * this length.
1086  *
1087  * Return value:
1088  *
1089  * `GSS_S_COMPLETE`: Successful completion.
1090  *
1091  * `GSS_S_NO_CONTEXT`: The referenced context could not be accessed.
1092  *
1093  * `GSS_S_CONTEXT_EXPIRED`: The context has expired.
1094  *
1095  * `GSS_S_BAD_QOP`: The specified QOP is not supported by the
1096  * mechanism.
1097  **/
1098 OM_uint32
gss_wrap_size_limit(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,int conf_req_flag,gss_qop_t qop_req,OM_uint32 req_output_size,OM_uint32 * max_input_size)1099 gss_wrap_size_limit (OM_uint32 * minor_status,
1100 		     const gss_ctx_id_t context_handle,
1101 		     int conf_req_flag,
1102 		     gss_qop_t qop_req,
1103 		     OM_uint32 req_output_size, OM_uint32 * max_input_size)
1104 {
1105   return GSS_S_FAILURE;
1106 }
1107 
1108 /**
1109  * gss_export_sec_context:
1110  * @minor_status: (Integer, modify) Mechanism specific status code.
1111  * @context_handle: (gss_ctx_id_t, modify) Context handle identifying
1112  *   the context to transfer.
1113  * @interprocess_token: (buffer, opaque, modify) Token to be
1114  *   transferred to target process.  Storage associated with this
1115  *   token must be freed by the application after use with a call to
1116  *   gss_release_buffer().
1117  *
1118  * Provided to support the sharing of work between multiple processes.
1119  * This routine will typically be used by the context-acceptor, in an
1120  * application where a single process receives incoming connection
1121  * requests and accepts security contexts over them, then passes the
1122  * established context to one or more other processes for message
1123  * exchange. gss_export_sec_context() deactivates the security context
1124  * for the calling process and creates an interprocess token which,
1125  * when passed to gss_import_sec_context in another process, will
1126  * re-activate the context in the second process. Only a single
1127  * instantiation of a given context may be active at any one time; a
1128  * subsequent attempt by a context exporter to access the exported
1129  * security context will fail.
1130  *
1131  * The implementation may constrain the set of processes by which the
1132  * interprocess token may be imported, either as a function of local
1133  * security policy, or as a result of implementation decisions.  For
1134  * example, some implementations may constrain contexts to be passed
1135  * only between processes that run under the same account, or which
1136  * are part of the same process group.
1137  *
1138  * The interprocess token may contain security-sensitive information
1139  * (for example cryptographic keys).  While mechanisms are encouraged
1140  * to either avoid placing such sensitive information within
1141  * interprocess tokens, or to encrypt the token before returning it to
1142  * the application, in a typical object-library GSS-API implementation
1143  * this may not be possible. Thus the application must take care to
1144  * protect the interprocess token, and ensure that any process to
1145  * which the token is transferred is trustworthy.
1146  *
1147  * If creation of the interprocess token is successful, the
1148  * implementation shall deallocate all process-wide resources
1149  * associated with the security context, and set the context_handle to
1150  * GSS_C_NO_CONTEXT.  In the event of an error that makes it
1151  * impossible to complete the export of the security context, the
1152  * implementation must not return an interprocess token, and should
1153  * strive to leave the security context referenced by the
1154  * context_handle parameter untouched.  If this is impossible, it is
1155  * permissible for the implementation to delete the security context,
1156  * providing it also sets the context_handle parameter to
1157  * GSS_C_NO_CONTEXT.
1158  *
1159  * Return value:
1160  *
1161  * `GSS_S_COMPLETE`: Successful completion.
1162  *
1163  * `GSS_S_CONTEXT_EXPIRED`: The context has expired.
1164  *
1165  * `GSS_S_NO_CONTEXT`: The context was invalid.
1166  *
1167  * `GSS_S_UNAVAILABLE`: The operation is not supported.
1168  **/
1169 OM_uint32
gss_export_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t interprocess_token)1170 gss_export_sec_context (OM_uint32 * minor_status,
1171 			gss_ctx_id_t * context_handle,
1172 			gss_buffer_t interprocess_token)
1173 {
1174   return GSS_S_UNAVAILABLE;
1175 }
1176 
1177 /**
1178  * gss_import_sec_context:
1179  * @minor_status: (Integer, modify) Mechanism specific status code.
1180  * @interprocess_token: (buffer, opaque, modify) Token received from
1181  *   exporting process
1182  * @context_handle: (gss_ctx_id_t, modify) Context handle of newly
1183  *   reactivated context.  Resources associated with this context
1184  *   handle must be released by the application after use with a call
1185  *   to gss_delete_sec_context().
1186  *
1187  * Allows a process to import a security context established by
1188  * another process.  A given interprocess token may be imported only
1189  * once.  See gss_export_sec_context.
1190  *
1191  * Return value:
1192  *
1193  * `GSS_S_COMPLETE`: Successful completion.
1194  *
1195  * `GSS_S_NO_CONTEXT`: The token did not contain a valid context
1196  * reference.
1197  *
1198  * `GSS_S_DEFECTIVE_TOKEN`: The token was invalid.
1199  *
1200  * `GSS_S_UNAVAILABLE`: The operation is unavailable.
1201  *
1202  * `GSS_S_UNAUTHORIZED`: Local policy prevents the import of this
1203  *  context by the current process.
1204  **/
1205 OM_uint32
gss_import_sec_context(OM_uint32 * minor_status,const gss_buffer_t interprocess_token,gss_ctx_id_t * context_handle)1206 gss_import_sec_context (OM_uint32 * minor_status,
1207 			const gss_buffer_t interprocess_token,
1208 			gss_ctx_id_t * context_handle)
1209 {
1210   return GSS_S_UNAVAILABLE;
1211 }
1212