Add.
[shishi.git] / gss / context.c
blobbb438bd3da6ed5275d200dc54ce3a2136f5200a4
1 /* context.c Implementation of GSS-API Context functions.
2 * Copyright (C) 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 /**
25 * gss_init_sec_context:
26 * @minor_status: Mechanism specific status code.
27 * @initiator_cred_handle: Optional handle for credentials claimed.
28 * Supply GSS_C_NO_CREDENTIAL to act as a default initiator principal.
29 * If no default initiator is defined, the function will return
30 * GSS_S_NO_CRED.
31 * @context_handle: Context handle for new context. Supply
32 * GSS_C_NO_CONTEXT for first call; use value returned by first call
33 * in continuation calls. Resources associated with this
34 * context-handle must be released by the application after use with a
35 * call to gss_delete_sec_context().
36 * @target_name: Name of target.
37 * @mech_type: Optional object ID of desired mechanism. Supply
38 * GSS_C_NO_OID to obtain an implementation specific default
39 * @req_flags: Contains various independent flags, each of which
40 * requests that the context support a specific service option.
41 * Symbolic names are provided for each flag, and the symbolic names
42 * corresponding to the required flags should be logically-ORed
43 * together to form the bit-mask value. See below for details.
44 * @time_req: Optional Desired number of seconds for which context
45 * should remain valid. Supply 0 to request a default validity
46 * period.
47 * @input_chan_bindings: Optional Application-specified bindings.
48 * Allows application to securely bind channel identification
49 * information to the security context. Specify
50 * GSS_C_NO_CHANNEL_BINDINGS if channel bindings are not used.
51 * @input_token: Optional (see text) Token received from peer
52 * application. Supply GSS_C_NO_BUFFER, or a pointer to a buffer
53 * containing the value GSS_C_EMPTY_BUFFER on initial call.
54 * @actual_mech_type: Optional actual mechanism used. The OID
55 * returned via this parameter will be a pointer to static storage
56 * that should be treated as read-only; In particular the application
57 * should not attempt to free it. Specify NULL if not required.
58 * @output_token: Token to be sent to peer application. If the length
59 * field of the returned buffer is zero, no token need be sent to the
60 * peer application. Storage associated with this buffer must be
61 * freed by the application after use with a call to
62 * gss_release_buffer().
63 * @ret_flags: Optional various independent flags, each of which
64 * indicates that the context supports a specific service option.
65 * Specify NULL if not required. Symbolic names are provided for each
66 * flag, and the symbolic names corresponding to the required flags
67 * should be logically-ANDed with the ret_flags value to test whether
68 * a given option is supported by the context. See below for details.
69 * @time_rec: Optional number of seconds for which the context will
70 * remain valid. If the implementation does not support context
71 * expiration, the value GSS_C_INDEFINITE will be returned. Specify
72 * NULL if not required.
74 * Initiates the establishment of a security context between the
75 * application and a remote peer. Initially, the input_token
76 * parameter should be specified either as GSS_C_NO_BUFFER, or as a
77 * pointer to a gss_buffer_desc object whose length field contains the
78 * value zero. The routine may return a output_token which should be
79 * transferred to the peer application, where the peer application
80 * will present it to gss_accept_sec_context. If no token need be
81 * sent, gss_init_sec_context will indicate this by setting the length
82 * field of the output_token argument to zero. To complete the context
83 * establishment, one or more reply tokens may be required from the
84 * peer application; if so, gss_init_sec_context will return a status
85 * containing the supplementary information bit GSS_S_CONTINUE_NEEDED.
86 * In this case, gss_init_sec_context should be called again when the
87 * reply token is received from the peer application, passing the
88 * reply token to gss_init_sec_context via the input_token parameters.
90 * Portable applications should be constructed to use the token length
91 * and return status to determine whether a token needs to be sent or
92 * waited for. Thus a typical portable caller should always invoke
93 * gss_init_sec_context within a loop:
95 * int context_established = 0;
96 * gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
97 * ...
98 * input_token->length = 0;
100 * while (!context_established) {
101 * maj_stat = gss_init_sec_context(&min_stat, cred_hdl, &context_hdl,
102 * target_name, desired_mech,
103 * desired_services, desired_time,
104 * input_bindings, input_token, &actual_mech,
105 * output_token, &actual_services,
106 * &actual_time);
107 * if (GSS_ERROR(maj_stat)) {
108 * report_error(maj_stat, min_stat);
109 * };
111 * if (output_token->length != 0) {
112 * send_token_to_peer(output_token);
113 * gss_release_buffer(&min_stat, output_token)
114 * };
115 * if (GSS_ERROR(maj_stat)) {
117 * if (context_hdl != GSS_C_NO_CONTEXT)
118 * gss_delete_sec_context(&min_stat, &context_hdl, GSS_C_NO_BUFFER);
119 * break;
120 * };
122 * if (maj_stat & GSS_S_CONTINUE_NEEDED) {
123 * receive_token_from_peer(input_token);
124 * } else {
125 * context_established = 1;
126 * };
127 * };
129 * Whenever the routine returns a major status that includes the value
130 * GSS_S_CONTINUE_NEEDED, the context is not fully established and the
131 * following restrictions apply to the output parameters:
133 * The value returned via the time_rec parameter is undefined Unless
134 * the accompanying ret_flags parameter contains the bit
135 * GSS_C_PROT_READY_FLAG, indicating that per-message services may be
136 * applied in advance of a successful completion status, the value
137 * returned via the actual_mech_type parameter is undefined until the
138 * routine returns a major status value of GSS_S_COMPLETE.
140 * The values of the GSS_C_DELEG_FLAG, GSS_C_MUTUAL_FLAG,
141 * GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG,
142 * GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned via the
143 * ret_flags parameter should contain the values that the
144 * implementation expects would be valid if context establishment were
145 * to succeed. In particular, if the application has requested a
146 * service such as delegation or anonymous authentication via the
147 * req_flags argument, and such a service is unavailable from the
148 * underlying mechanism, gss_init_sec_context should generate a token
149 * that will not provide the service, and indicate via the ret_flags
150 * argument that the service will not be supported. The application
151 * may choose to abort the context establishment by calling
152 * gss_delete_sec_context (if it cannot continue in the absence of the
153 * service), or it may choose to transmit the token and continue
154 * context establishment (if the service was merely desired but not
155 * mandatory).
157 * The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
158 * within ret_flags should indicate the actual state at the time
159 * gss_init_sec_context returns, whether or not the context is fully
160 * established.
162 * GSS-API implementations that support per-message protection are
163 * encouraged to set the GSS_C_PROT_READY_FLAG in the final ret_flags
164 * returned to a caller (i.e. when accompanied by a GSS_S_COMPLETE
165 * status code). However, applications should not rely on this
166 * behavior as the flag was not defined in Version 1 of the GSS-API.
167 * Instead, applications should determine what per-message services
168 * are available after a successful context establishment according to
169 * the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
171 * All other bits within the ret_flags argument should be set to
172 * zero.
174 * If the initial call of gss_init_sec_context() fails, the
175 * implementation should not create a context object, and should leave
176 * the value of the context_handle parameter set to GSS_C_NO_CONTEXT
177 * to indicate this. In the event of a failure on a subsequent call,
178 * the implementation is permitted to delete the "half-built" security
179 * context (in which case it should set the context_handle parameter
180 * to GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
181 * security context untouched for the application to delete (using
182 * gss_delete_sec_context).
184 * During context establishment, the informational status bits
185 * GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors,
186 * and GSS-API mechanisms should always return them in association
187 * with a routine error of GSS_S_FAILURE. This requirement for
188 * pairing did not exist in version 1 of the GSS-API specification, so
189 * applications that wish to run over version 1 implementations must
190 * special-case these codes.
192 * The req_flags flags are:
194 * GSS_C_DELEG_FLAG
195 * True - Delegate credentials to remote peer
196 * False - Don't delegate
198 * GSS_C_MUTUAL_FLAG
199 * True - Request that remote peer authenticate itself
200 * False - Authenticate self to remote peer only
202 * GSS_C_REPLAY_FLAG
203 * True - Enable replay detection for messages protected with gss_wrap
204 * or gss_get_mic
205 * False - Don't attempt to detect replayed messages
207 * GSS_C_SEQUENCE_FLAG
208 * True - Enable detection of out-of-sequence protected messages
209 * False - Don't attempt to detect out-of-sequence messages
211 * GSS_C_CONF_FLAG
212 * True - Request that confidentiality service be made available (via gss_wrap)
213 * False - No per-message confidentiality service is required.
215 * GSS_C_INTEG_FLAG
216 * True - Request that integrity service be made available (via gss_wrap or
217 * gss_get_mic)
218 * False - No per-message integrity service is required.
220 * GSS_C_ANON_FLAG
221 * True - Do not reveal the initiator's identity to the acceptor.
222 * False - Authenticate normally.
224 * The ret_flags flags are:
226 * GSS_C_DELEG_FLAG
227 * True - Credentials were delegated to the remote peer
228 * False - No credentials were delegated
230 * GSS_C_MUTUAL_FLAG
231 * True - The remote peer has authenticated itself.
232 * False - Remote peer has not authenticated itself.
234 * GSS_C_REPLAY_FLAG
235 * True - replay of protected messages will be detected
236 * False - replayed messages will not be detected
238 * GSS_C_SEQUENCE_FLAG
239 * True - out-of-sequence protected messages will be detected
240 * False - out-of-sequence messages will not be detected
242 * GSS_C_CONF_FLAG
243 * True - Confidentiality service may be invoked by calling gss_wrap routine
244 * False - No confidentiality service (via gss_wrap) available. gss_wrap will
245 * provide message encapsulation, data-origin authentication and
246 * integrity services only.
248 * GSS_C_INTEG_FLAG
249 * True - Integrity service may be invoked by calling either gss_get_mic
250 * or gss_wrap routines.
251 * False - Per-message integrity service unavailable.
253 * GSS_C_ANON_FLAG
254 * True - The initiator's identity has not been revealed, and will not
255 * be revealed if any emitted token is passed to the acceptor.
256 * False - The initiator's identity has been or will be authenticated normally.
258 * GSS_C_PROT_READY_FLAG
259 * True - Protection services (as specified by the states of the
260 * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available for use if the
261 * accompanying major status return value is either GSS_S_COMPLETE or
262 * GSS_S_CONTINUE_NEEDED.
263 * False - Protection services (as specified by the states of the
264 * GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG) are available only if the
265 * accompanying major status return value is GSS_S_COMPLETE.
267 * GSS_C_TRANS_FLAG
268 * True - The resultant security context may be transferred to other
269 * processes via a call to gss_export_sec_context().
270 * False - The security context is not transferable.
272 * All other bits should be set to zero.
274 * Return value: Returns:
276 * GSS_S_COMPLETE Successful completion
278 * GSS_S_CONTINUE_NEEDED Indicates that a token from the peer
279 * application is required to complete the
280 * context, and that gss_init_sec_context
281 * must be called again with that token.
283 * GSS_S_DEFECTIVE_TOKEN Indicates that consistency checks performed
284 * on the input_token failed
286 * GSS_S_DEFECTIVE_CREDENTIAL Indicates that consistency checks
287 * performed on the credential failed.
289 * GSS_S_NO_CRED The supplied credentials were not valid for
290 * context initiation, or the credential handle
291 * did not reference any credentials.
293 * GSS_S_CREDENTIALS_EXPIRED The referenced credentials have expired
295 * GSS_S_BAD_BINDINGS The input_token contains different channel
296 * bindings to those specified via the
297 * input_chan_bindings parameter
299 * GSS_S_BAD_SIG The input_token contains an invalid MIC, or a MIC
300 * that could not be verified
302 * GSS_S_OLD_TOKEN The input_token was too old. This is a fatal
303 * error during context establishment
305 * GSS_S_DUPLICATE_TOKEN The input_token is valid, but is a duplicate
306 * of a token already processed. This is a
307 * fatal error during context establishment.
309 * GSS_S_NO_CONTEXT Indicates that the supplied context handle did
310 * not refer to a valid context
312 * GSS_S_BAD_NAMETYPE The provided target_name parameter contained an
313 * invalid or unsupported type of name
315 * GSS_S_BAD_NAME The provided target_name parameter was ill-formed.
317 * GSS_S_BAD_MECH The specified mechanism is not supported by the
318 * provided credential, or is unrecognized by the
319 * implementation.
322 OM_uint32
323 gss_init_sec_context (OM_uint32 * minor_status,
324 const gss_cred_id_t initiator_cred_handle,
325 gss_ctx_id_t * context_handle,
326 const gss_name_t target_name,
327 const gss_OID mech_type,
328 OM_uint32 req_flags,
329 OM_uint32 time_req,
330 const gss_channel_bindings_t input_chan_bindings,
331 const gss_buffer_t input_token,
332 gss_OID * actual_mech_type,
333 gss_buffer_t output_token,
334 OM_uint32 * ret_flags, OM_uint32 * time_rec)
336 return GSS_S_FAILURE;
339 OM_uint32
340 gss_accept_sec_context (OM_uint32 * minor_status,
341 gss_ctx_id_t * context_handle,
342 const gss_cred_id_t acceptor_cred_handle,
343 const gss_buffer_t input_token_buffer,
344 const gss_channel_bindings_t input_chan_bindings,
345 gss_name_t * src_name,
346 gss_OID * mech_type,
347 gss_buffer_t output_token,
348 OM_uint32 * ret_flags,
349 OM_uint32 * time_rec,
350 gss_cred_id_t * delegated_cred_handle)
352 return GSS_S_FAILURE;
356 * gss_delete_sec_context:
357 * @minor_status: Mechanism specific status code.
358 * @context_handle: Context handle identifying context to delete.
359 * After deleting the context, the GSS-API will set this context
360 * handle to GSS_C_NO_CONTEXT.
361 * @output_token: Optional token to be sent to remote application to
362 * instruct it to also delete the context. It is recommended that
363 * applications specify GSS_C_NO_BUFFER for this parameter, requesting
364 * local deletion only. If a buffer parameter is provided by the
365 * application, the mechanism may return a token in it; mechanisms
366 * that implement only local deletion should set the length field of
367 * this token to zero to indicate to the application that no token is
368 * to be sent to the peer.
370 * Delete a security context. gss_delete_sec_context() will delete
371 * the local data structures associated with the specified security
372 * context, and may generate an output_token, which when passed to the
373 * peer gss_process_context_token() will instruct it to do likewise.
374 * If no token is required by the mechanism, the GSS-API should set
375 * the length field of the output_token (if provided) to zero. No
376 * further security services may be obtained using the context
377 * specified by context_handle.
379 * In addition to deleting established security contexts,
380 * gss_delete_sec_context() must also be able to delete "half-built"
381 * security contexts resulting from an incomplete sequence of
382 * gss_init_sec_context()/gss_accept_sec_context() calls.
384 * The output_token parameter is retained for compatibility with
385 * version 1 of the GSS-API. It is recommended that both peer
386 * applications invoke gss_delete_sec_context() passing the value
387 * GSS_C_NO_BUFFER for the output_token parameter, indicating that no
388 * token is required, and that gss_delete_sec_context() should simply
389 * delete local context data structures. If the application does pass
390 * a valid buffer to gss_delete_sec_context(), mechanisms are
391 * encouraged to return a zero-length token, indicating that no peer
392 * action is necessary, and that no token should be transferred by the
393 * application.
395 * Return value: Returns GSS_S_COMPLETE for successful completion, and
396 * GSS_S_NO_CONTEXT if no valid context was supplied.
398 OM_uint32
399 gss_delete_sec_context (OM_uint32 * minor_status,
400 gss_ctx_id_t * context_handle,
401 gss_buffer_t output_token)
403 if (!context_handle || *context_handle == GSS_C_NO_CONTEXT)
404 return GSS_S_NO_CONTEXT;
406 if (output_token != GSS_C_NO_BUFFER)
407 output_token->length = 0;
409 free (*context_handle);
410 *context_handle = GSS_C_NO_CONTEXT;
412 return GSS_S_COMPLETE;
415 OM_uint32
416 gss_process_context_token (OM_uint32 * minor_status,
417 const gss_ctx_id_t context_handle,
418 const gss_buffer_t token_buffer)
420 return GSS_S_FAILURE;
423 OM_uint32
424 gss_context_time (OM_uint32 * minor_status,
425 const gss_ctx_id_t context_handle, OM_uint32 * time_rec)
427 return GSS_S_FAILURE;
430 OM_uint32
431 gss_inquire_context (OM_uint32 * minor_status,
432 const gss_ctx_id_t context_handle,
433 gss_name_t * src_name,
434 gss_name_t * targ_name,
435 OM_uint32 * lifetime_rec,
436 gss_OID * mech_type,
437 OM_uint32 * ctx_flags, int *locally_initiated, int *open)
439 return GSS_S_FAILURE;
442 OM_uint32
443 gss_wrap_size_limit (OM_uint32 * minor_status,
444 const gss_ctx_id_t context_handle,
445 int conf_req_flag,
446 gss_qop_t qop_req,
447 OM_uint32 req_output_size, OM_uint32 * max_input_size)
449 return GSS_S_FAILURE;
452 OM_uint32
453 gss_export_sec_context (OM_uint32 * minor_status,
454 gss_ctx_id_t * context_handle,
455 gss_buffer_t interprocess_token)
457 return GSS_S_FAILURE;
460 OM_uint32
461 gss_import_sec_context (OM_uint32 * minor_status,
462 const gss_buffer_t interprocess_token,
463 gss_ctx_id_t * context_handle)
465 return GSS_S_FAILURE;