2 * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "gssapi_locl.h"
38 static krb5_keytab gss_keytab
;
41 gsskrb5_register_acceptor_identity (char *identity
)
44 if(gss_keytab
!= NULL
) {
45 krb5_kt_close(gssapi_krb5_context
, gss_keytab
);
48 asprintf(&p
, "FILE:%s", identity
);
51 krb5_kt_resolve(gssapi_krb5_context
, p
, &gss_keytab
);
53 return GSS_S_COMPLETE
;
57 gss_accept_sec_context
58 (OM_uint32
* minor_status
,
59 gss_ctx_id_t
* context_handle
,
60 const gss_cred_id_t acceptor_cred_handle
,
61 const gss_buffer_t input_token_buffer
,
62 const gss_channel_bindings_t input_chan_bindings
,
63 gss_name_t
* src_name
,
65 gss_buffer_t output_token
,
66 OM_uint32
* ret_flags
,
68 gss_cred_id_t
* delegated_cred_handle
74 krb5_flags ap_options
;
76 krb5_ticket
*ticket
= NULL
;
77 krb5_keytab keytab
= NULL
;
82 krb5_data_zero (&fwd_data
);
83 output_token
->length
= 0;
84 output_token
->value
= NULL
;
86 if (*context_handle
== GSS_C_NO_CONTEXT
) {
87 *context_handle
= malloc(sizeof(**context_handle
));
88 if (*context_handle
== GSS_C_NO_CONTEXT
) {
89 *minor_status
= ENOMEM
;
94 (*context_handle
)->auth_context
= NULL
;
95 (*context_handle
)->source
= NULL
;
96 (*context_handle
)->target
= NULL
;
97 (*context_handle
)->flags
= 0;
98 (*context_handle
)->more_flags
= 0;
99 (*context_handle
)->ticket
= NULL
;
101 kret
= krb5_auth_con_init (gssapi_krb5_context
,
102 &(*context_handle
)->auth_context
);
108 if (input_chan_bindings
!= GSS_C_NO_CHANNEL_BINDINGS
109 && input_chan_bindings
->application_data
.length
==
110 2 * sizeof((*context_handle
)->auth_context
->local_port
)
113 /* Port numbers are expected to be in application_data.value,
114 * initator's port first */
116 krb5_address initiator_addr
, acceptor_addr
;
118 memset(&initiator_addr
, 0, sizeof(initiator_addr
));
119 memset(&acceptor_addr
, 0, sizeof(acceptor_addr
));
121 (*context_handle
)->auth_context
->remote_port
=
122 *(int16_t *) input_chan_bindings
->application_data
.value
;
124 (*context_handle
)->auth_context
->local_port
=
125 *((int16_t *) input_chan_bindings
->application_data
.value
+ 1);
128 kret
= gss_address_to_krb5addr(input_chan_bindings
->acceptor_addrtype
,
129 &input_chan_bindings
->acceptor_address
,
130 (*context_handle
)->auth_context
->local_port
,
133 *minor_status
= kret
;
134 ret
= GSS_S_BAD_BINDINGS
;
138 kret
= gss_address_to_krb5addr(input_chan_bindings
->initiator_addrtype
,
139 &input_chan_bindings
->initiator_address
,
140 (*context_handle
)->auth_context
->remote_port
,
143 krb5_free_address (gssapi_krb5_context
, &acceptor_addr
);
144 *minor_status
= kret
;
145 ret
= GSS_S_BAD_BINDINGS
;
149 kret
= krb5_auth_con_setaddrs(gssapi_krb5_context
,
150 (*context_handle
)->auth_context
,
151 &acceptor_addr
, /* local address */
152 &initiator_addr
); /* remote address */
154 krb5_free_address (gssapi_krb5_context
, &initiator_addr
);
155 krb5_free_address (gssapi_krb5_context
, &acceptor_addr
);
158 free(input_chan_bindings
->application_data
.value
);
159 input_chan_bindings
->application_data
.value
= NULL
;
160 input_chan_bindings
->application_data
.length
= 0;
164 *minor_status
= kret
;
165 ret
= GSS_S_BAD_BINDINGS
;
175 krb5_auth_con_getflags(gssapi_krb5_context
,
176 (*context_handle
)->auth_context
,
178 tmp
|= KRB5_AUTH_CONTEXT_DO_SEQUENCE
;
179 krb5_auth_con_setflags(gssapi_krb5_context
,
180 (*context_handle
)->auth_context
,
184 ret
= gssapi_krb5_decapsulate (input_token_buffer
,
192 if (acceptor_cred_handle
== GSS_C_NO_CREDENTIAL
) {
193 if (gss_keytab
!= NULL
) {
196 } else if (acceptor_cred_handle
->keytab
!= NULL
) {
197 keytab
= acceptor_cred_handle
->keytab
;
200 kret
= krb5_rd_req (gssapi_krb5_context
,
201 &(*context_handle
)->auth_context
,
203 (acceptor_cred_handle
== GSS_C_NO_CREDENTIAL
) ? NULL
204 : acceptor_cred_handle
->principal
,
213 kret
= krb5_copy_principal (gssapi_krb5_context
,
215 &(*context_handle
)->source
);
221 kret
= krb5_copy_principal (gssapi_krb5_context
,
223 &(*context_handle
)->target
);
230 kret
= krb5_copy_principal (gssapi_krb5_context
,
240 krb5_authenticator authenticator
;
242 kret
= krb5_auth_getauthenticator(gssapi_krb5_context
,
243 (*context_handle
)->auth_context
,
250 kret
= gssapi_krb5_verify_8003_checksum(input_chan_bindings
,
251 authenticator
->cksum
,
254 krb5_free_authenticator(gssapi_krb5_context
, &authenticator
);
261 if (fwd_data
.length
> 0 && (flags
& GSS_C_DELEG_FLAG
)) {
265 if (delegated_cred_handle
== NULL
|| *delegated_cred_handle
== NULL
)
266 /* XXX Create a new delegated_cred_handle? */
267 kret
= krb5_cc_default (gssapi_krb5_context
, &ccache
);
270 if ((*delegated_cred_handle
)->ccache
== NULL
)
271 kret
= krb5_cc_gen_new (gssapi_krb5_context
,
273 &(*delegated_cred_handle
)->ccache
);
274 ccache
= (*delegated_cred_handle
)->ccache
;
278 flags
&= ~GSS_C_DELEG_FLAG
;
282 kret
= krb5_cc_initialize(gssapi_krb5_context
,
286 flags
&= ~GSS_C_DELEG_FLAG
;
290 kret
= krb5_rd_cred(gssapi_krb5_context
,
291 (*context_handle
)->auth_context
,
295 flags
&= ~GSS_C_DELEG_FLAG
;
304 flags
|= GSS_C_TRANS_FLAG
;
308 (*context_handle
)->flags
= flags
;
309 (*context_handle
)->more_flags
|= OPEN
;
312 *mech_type
= GSS_KRB5_MECHANISM
;
315 *time_rec
= GSS_C_INDEFINITE
;
317 if(flags
& GSS_C_MUTUAL_FLAG
) {
320 kret
= krb5_mk_rep (gssapi_krb5_context
,
321 &(*context_handle
)->auth_context
,
324 krb5_data_free (&outbuf
);
328 ret
= gssapi_krb5_encapsulate (&outbuf
,
336 output_token
->length
= 0;
339 (*context_handle
)->ticket
= ticket
;
343 krb5_free_ticket (context
, ticket
);
346 return GSS_S_COMPLETE
;
349 if (fwd_data
.length
> 0)
352 krb5_free_ticket (gssapi_krb5_context
, ticket
);
353 krb5_auth_con_free (gssapi_krb5_context
,
354 (*context_handle
)->auth_context
);
355 if((*context_handle
)->source
)
356 krb5_free_principal (gssapi_krb5_context
,
357 (*context_handle
)->source
);
358 if((*context_handle
)->target
)
359 krb5_free_principal (gssapi_krb5_context
,
360 (*context_handle
)->target
);
361 free (*context_handle
);
362 *context_handle
= GSS_C_NO_CONTEXT
;
363 *minor_status
= kret
;
364 return GSS_S_FAILURE
;