code for token delegation. From Daniel Kouril <kouril@ics.muni.cz> and Miroslav Ruda <ruda@ics.muni.cz>
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@8429 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -90,12 +90,20 @@ krb5_error_code
|
||||
gssapi_krb5_create_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
OM_uint32 flags,
|
||||
krb5_data *fwd_data,
|
||||
Checksum *result)
|
||||
{
|
||||
u_char *p;
|
||||
|
||||
/*
|
||||
* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
|
||||
* field's format)
|
||||
*/
|
||||
result->cksumtype = 0x8003;
|
||||
result->checksum.length = 24;
|
||||
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG))
|
||||
result->checksum.length = 24 + 4 + fwd_data->length;
|
||||
else
|
||||
result->checksum.length = 24;
|
||||
result->checksum.data = malloc (result->checksum.length);
|
||||
if (result->checksum.data == NULL)
|
||||
return ENOMEM;
|
||||
@@ -111,8 +119,31 @@ gssapi_krb5_create_8003_checksum (
|
||||
p += 16;
|
||||
encode_om_uint32 (flags, p);
|
||||
p += 4;
|
||||
|
||||
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
|
||||
#if 0
|
||||
u_char *tmp;
|
||||
|
||||
result->checksum.length = 28 + fwd_data->length;
|
||||
tmp = realloc(result->checksum.data, result->checksum.length);
|
||||
if (tmp == NULL)
|
||||
return ENOMEM;
|
||||
result->checksum.data = tmp;
|
||||
|
||||
p = (u_char*)result->checksum.data + 24;
|
||||
#endif
|
||||
*p++ = (1 >> 0) & 0xFF; /* DlgOpt */ /* == 1 */
|
||||
*p++ = (1 >> 8) & 0xFF; /* DlgOpt */ /* == 0 */
|
||||
*p++ = (fwd_data->length >> 0) & 0xFF; /* Dlgth */
|
||||
*p++ = (fwd_data->length >> 8) & 0xFF; /* Dlgth */
|
||||
memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);
|
||||
|
||||
p += fwd_data->length;
|
||||
|
||||
if (p - (u_char *)result->checksum.data != result->checksum.length)
|
||||
abort ();
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,14 +151,16 @@ krb5_error_code
|
||||
gssapi_krb5_verify_8003_checksum(
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
Checksum *cksum,
|
||||
OM_uint32 *flags)
|
||||
OM_uint32 *flags,
|
||||
krb5_data *fwd_data)
|
||||
{
|
||||
unsigned char hash[16];
|
||||
unsigned char *p;
|
||||
OM_uint32 length;
|
||||
int DlgOpt;
|
||||
|
||||
/* XXX should handle checksums > 24 bytes */
|
||||
if(cksum->cksumtype != 0x8003 || cksum->checksum.length != 24)
|
||||
if(cksum->cksumtype != 0x8003)
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
|
||||
p = cksum->checksum.data;
|
||||
@@ -147,6 +180,24 @@ gssapi_krb5_verify_8003_checksum(
|
||||
p += sizeof(hash);
|
||||
|
||||
decode_om_uint32(p, flags);
|
||||
|
||||
if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
|
||||
|
||||
p += 4;
|
||||
|
||||
DlgOpt = (p[0] << 0) | (p[1] << 8 );
|
||||
if (DlgOpt != 1)
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
|
||||
p += 2;
|
||||
fwd_data->length = (p[0] << 0) | (p[1] << 8);
|
||||
fwd_data->data = malloc(fwd_data->length);
|
||||
if (fwd_data->data == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
p += 2;
|
||||
memcpy(fwd_data->data, p, fwd_data->length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -45,4 +45,5 @@ libgssapi_la_SOURCES = \
|
||||
unwrap.c \
|
||||
v1.c \
|
||||
verify_mic.c \
|
||||
wrap.c
|
||||
wrap.c \
|
||||
address_to_krb5addr.c
|
||||
|
@@ -75,9 +75,11 @@ gss_accept_sec_context
|
||||
OM_uint32 flags;
|
||||
krb5_ticket *ticket = NULL;
|
||||
krb5_keytab keytab = NULL;
|
||||
krb5_data fwd_data;
|
||||
|
||||
gssapi_krb5_init ();
|
||||
|
||||
krb5_data_zero (&fwd_data);
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
@@ -103,6 +105,70 @@ gss_accept_sec_context
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
|
||||
&& input_chan_bindings->application_data.length ==
|
||||
2 * sizeof((*context_handle)->auth_context->local_port)
|
||||
) {
|
||||
|
||||
/* Port numbers are expected to be in application_data.value,
|
||||
* initator's port first */
|
||||
|
||||
krb5_address initiator_addr, acceptor_addr;
|
||||
|
||||
memset(&initiator_addr, 0, sizeof(initiator_addr));
|
||||
memset(&acceptor_addr, 0, sizeof(acceptor_addr));
|
||||
|
||||
(*context_handle)->auth_context->remote_port =
|
||||
*(int16_t *) input_chan_bindings->application_data.value;
|
||||
|
||||
(*context_handle)->auth_context->local_port =
|
||||
*((int16_t *) input_chan_bindings->application_data.value + 1);
|
||||
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
|
||||
&input_chan_bindings->acceptor_address,
|
||||
(*context_handle)->auth_context->local_port,
|
||||
&acceptor_addr);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
|
||||
&input_chan_bindings->initiator_address,
|
||||
(*context_handle)->auth_context->remote_port,
|
||||
&initiator_addr);
|
||||
if (kret) {
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setaddrs(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
&acceptor_addr, /* local address */
|
||||
&initiator_addr); /* remote address */
|
||||
|
||||
krb5_free_address (gssapi_krb5_context, &initiator_addr);
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
|
||||
#if 0
|
||||
free(input_chan_bindings->application_data.value);
|
||||
input_chan_bindings->application_data.value = NULL;
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
#endif
|
||||
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
int32_t tmp;
|
||||
|
||||
@@ -183,7 +249,8 @@ gss_accept_sec_context
|
||||
|
||||
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
||||
authenticator->cksum,
|
||||
&flags);
|
||||
&flags,
|
||||
&fwd_data);
|
||||
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
@@ -191,6 +258,49 @@ gss_accept_sec_context
|
||||
}
|
||||
}
|
||||
|
||||
if (fwd_data.length > 0 && (flags & GSS_C_DELEG_FLAG)) {
|
||||
|
||||
krb5_ccache ccache;
|
||||
|
||||
if (delegated_cred_handle == NULL || *delegated_cred_handle == NULL)
|
||||
/* XXX Create a new delegated_cred_handle? */
|
||||
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||
|
||||
else {
|
||||
if ((*delegated_cred_handle)->ccache == NULL)
|
||||
kret = krb5_cc_gen_new (gssapi_krb5_context,
|
||||
&krb5_mcc_ops,
|
||||
&(*delegated_cred_handle)->ccache);
|
||||
ccache = (*delegated_cred_handle)->ccache;
|
||||
}
|
||||
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
kret = krb5_cc_initialize(gssapi_krb5_context,
|
||||
ccache,
|
||||
*src_name);
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
kret = krb5_rd_cred(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
ccache,
|
||||
&fwd_data);
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
end_fwd:
|
||||
free(fwd_data.data);
|
||||
}
|
||||
|
||||
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
@@ -236,6 +346,8 @@ gss_accept_sec_context
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
failure:
|
||||
if (fwd_data.length > 0)
|
||||
free(fwd_data.data);
|
||||
if (ticket != NULL)
|
||||
krb5_free_ticket (gssapi_krb5_context, ticket);
|
||||
krb5_auth_con_free (gssapi_krb5_context,
|
||||
|
73
lib/gssapi/address_to_krb5addr.c
Normal file
73
lib/gssapi/address_to_krb5addr.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gssapi_locl.h"
|
||||
|
||||
krb5_error_code
|
||||
gss_address_to_krb5addr(OM_uint32 gss_addr_type,
|
||||
gss_buffer_desc *gss_addr,
|
||||
int16_t port,
|
||||
krb5_address *address)
|
||||
{
|
||||
sa_family_t addr_type;
|
||||
struct sockaddr sa;
|
||||
int sa_len = sizeof(sa);
|
||||
krb5_error_code problem;
|
||||
|
||||
if (gss_addr == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
switch (gss_addr_type) {
|
||||
#ifdef HAVE_IPV6
|
||||
case GSS_C_AF_INET6: addr_type = AF_INET6;
|
||||
break;
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
case GSS_C_AF_INET: addr_type = AF_INET;
|
||||
break;
|
||||
default:
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
problem = krb5_h_addr2sockaddr (addr_type,
|
||||
gss_addr->value,
|
||||
&sa,
|
||||
&sa_len,
|
||||
port);
|
||||
if (problem)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
problem = krb5_sockaddr2address (&sa, address);
|
||||
|
||||
return problem;
|
||||
}
|
@@ -89,6 +89,8 @@ typedef struct gss_OID_set_desc_struct {
|
||||
|
||||
struct krb5_keytab_data;
|
||||
|
||||
struct krb5_ccache_data;
|
||||
|
||||
typedef int gss_cred_usage_t;
|
||||
|
||||
typedef struct gss_cred_id_t_desc_struct {
|
||||
@@ -97,6 +99,7 @@ typedef struct gss_cred_id_t_desc_struct {
|
||||
OM_uint32 lifetime;
|
||||
gss_cred_usage_t usage;
|
||||
gss_OID_set mechanisms;
|
||||
struct krb5_ccache_data *ccache;
|
||||
} gss_cred_id_t_desc;
|
||||
|
||||
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
||||
|
@@ -47,13 +47,15 @@ krb5_error_code
|
||||
gssapi_krb5_create_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
OM_uint32 flags,
|
||||
krb5_data *fwd_data,
|
||||
Checksum *result);
|
||||
|
||||
krb5_error_code
|
||||
gssapi_krb5_verify_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
Checksum *cksum,
|
||||
OM_uint32 *flags);
|
||||
OM_uint32 *flags,
|
||||
krb5_data *fwd_data);
|
||||
|
||||
OM_uint32
|
||||
gssapi_krb5_encapsulate(
|
||||
@@ -86,6 +88,12 @@ OM_uint32
|
||||
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
||||
des_cblock *key);
|
||||
|
||||
krb5_error_code
|
||||
gss_address_to_krb5addr(OM_uint32 gss_addr_type,
|
||||
gss_buffer_desc *gss_addr,
|
||||
int16_t port,
|
||||
krb5_address *address);
|
||||
|
||||
/* sec_context flags */
|
||||
|
||||
#define SC_LOCAL_ADDRESS 0x01
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2000 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -63,7 +63,9 @@ init_auth
|
||||
krb5_data authenticator;
|
||||
Checksum cksum;
|
||||
krb5_enctype enctype;
|
||||
krb5_data fwd_data;
|
||||
|
||||
krb5_data_zero (&fwd_data);
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
@@ -93,7 +95,66 @@ init_auth
|
||||
goto failure;
|
||||
}
|
||||
|
||||
{
|
||||
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS &&
|
||||
input_chan_bindings->application_data.length ==
|
||||
2 * sizeof((*context_handle)->auth_context->local_port)) {
|
||||
/* Port numbers are expected to be in application_data.value,
|
||||
* initator's port first */
|
||||
|
||||
krb5_address initiator_addr, acceptor_addr;
|
||||
|
||||
memset(&initiator_addr, 0, sizeof(initiator_addr));
|
||||
memset(&acceptor_addr, 0, sizeof(acceptor_addr));
|
||||
|
||||
(*context_handle)->auth_context->local_port =
|
||||
*(int16_t *) input_chan_bindings->application_data.value;
|
||||
|
||||
(*context_handle)->auth_context->remote_port =
|
||||
*((int16_t *) input_chan_bindings->application_data.value + 1);
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
|
||||
&input_chan_bindings->acceptor_address,
|
||||
(*context_handle)->auth_context->remote_port,
|
||||
&acceptor_addr);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
|
||||
&input_chan_bindings->initiator_address,
|
||||
(*context_handle)->auth_context->local_port,
|
||||
&initiator_addr);
|
||||
if (kret) {
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setaddrs(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
&initiator_addr, /* local address */
|
||||
&acceptor_addr); /* remote address */
|
||||
|
||||
krb5_free_address (gssapi_krb5_context, &initiator_addr);
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
|
||||
#if 0
|
||||
free(input_chan_bindings->application_data.value);
|
||||
input_chan_bindings->application_data.value = NULL;
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
#endif
|
||||
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int32_t tmp;
|
||||
|
||||
krb5_auth_con_getflags(gssapi_krb5_context,
|
||||
@@ -108,30 +169,6 @@ init_auth
|
||||
if (actual_mech_type)
|
||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
flags = 0;
|
||||
ap_options = 0;
|
||||
if (req_flags & GSS_C_DELEG_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_MUTUAL_FLAG) {
|
||||
flags |= GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
if (req_flags & GSS_C_REPLAY_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_SEQUENCE_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_ANON_FLAG)
|
||||
; /* XXX */
|
||||
flags |= GSS_C_CONF_FLAG;
|
||||
flags |= GSS_C_INTEG_FLAG;
|
||||
flags |= GSS_C_SEQUENCE_FLAG;
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = flags;
|
||||
(*context_handle)->flags = flags;
|
||||
(*context_handle)->more_flags = LOCAL;
|
||||
|
||||
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
@@ -179,8 +216,104 @@ init_auth
|
||||
(*context_handle)->auth_context,
|
||||
&cred->session);
|
||||
|
||||
flags = 0;
|
||||
ap_options = 0;
|
||||
if (req_flags & GSS_C_DELEG_FLAG) {
|
||||
krb5_creds creds;
|
||||
krb5_kdc_flags fwd_flags;
|
||||
krb5_keyblock *subkey;
|
||||
|
||||
memset ((char *)&creds, 0, sizeof(creds));
|
||||
|
||||
subkey = (krb5_keyblock *) malloc(sizeof(subkey));
|
||||
if (subkey == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
krb5_generate_subkey (gssapi_krb5_context,
|
||||
&cred->session,
|
||||
&subkey);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_auth_con_setlocalsubkey(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
subkey);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_cc_get_principal(gssapi_krb5_context,
|
||||
ccache,
|
||||
&creds.client);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_build_principal(gssapi_krb5_context,
|
||||
&creds.server,
|
||||
strlen(creds.client->realm),
|
||||
creds.client->realm,
|
||||
KRB5_TGS_NAME,
|
||||
creds.client->realm,
|
||||
NULL);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
creds.times.endtime = 0;
|
||||
|
||||
fwd_flags.i = 0;
|
||||
fwd_flags.b.forwarded = 1;
|
||||
fwd_flags.b.forwardable = 1;
|
||||
|
||||
if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
|
||||
target_name->name.name_string.len < 2)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_get_forwarded_creds(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
ccache,
|
||||
fwd_flags.i,
|
||||
target_name->name.name_string.val[1],
|
||||
&creds,
|
||||
&fwd_data);
|
||||
|
||||
end_fwd:
|
||||
if (kret)
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
else
|
||||
flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
if (creds.client)
|
||||
krb5_free_principal(gssapi_krb5_context, creds.client);
|
||||
if (creds.server)
|
||||
krb5_free_principal(gssapi_krb5_context, creds.server);
|
||||
}
|
||||
|
||||
if (req_flags & GSS_C_MUTUAL_FLAG) {
|
||||
flags |= GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
|
||||
if (req_flags & GSS_C_REPLAY_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_SEQUENCE_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_ANON_FLAG)
|
||||
; /* XXX */
|
||||
flags |= GSS_C_CONF_FLAG;
|
||||
flags |= GSS_C_INTEG_FLAG;
|
||||
flags |= GSS_C_SEQUENCE_FLAG;
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = flags;
|
||||
(*context_handle)->flags = flags;
|
||||
(*context_handle)->more_flags = LOCAL;
|
||||
|
||||
kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
|
||||
flags,
|
||||
&fwd_data,
|
||||
&cksum);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
|
@@ -90,12 +90,20 @@ krb5_error_code
|
||||
gssapi_krb5_create_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
OM_uint32 flags,
|
||||
krb5_data *fwd_data,
|
||||
Checksum *result)
|
||||
{
|
||||
u_char *p;
|
||||
|
||||
/*
|
||||
* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
|
||||
* field's format)
|
||||
*/
|
||||
result->cksumtype = 0x8003;
|
||||
result->checksum.length = 24;
|
||||
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG))
|
||||
result->checksum.length = 24 + 4 + fwd_data->length;
|
||||
else
|
||||
result->checksum.length = 24;
|
||||
result->checksum.data = malloc (result->checksum.length);
|
||||
if (result->checksum.data == NULL)
|
||||
return ENOMEM;
|
||||
@@ -111,8 +119,31 @@ gssapi_krb5_create_8003_checksum (
|
||||
p += 16;
|
||||
encode_om_uint32 (flags, p);
|
||||
p += 4;
|
||||
|
||||
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
|
||||
#if 0
|
||||
u_char *tmp;
|
||||
|
||||
result->checksum.length = 28 + fwd_data->length;
|
||||
tmp = realloc(result->checksum.data, result->checksum.length);
|
||||
if (tmp == NULL)
|
||||
return ENOMEM;
|
||||
result->checksum.data = tmp;
|
||||
|
||||
p = (u_char*)result->checksum.data + 24;
|
||||
#endif
|
||||
*p++ = (1 >> 0) & 0xFF; /* DlgOpt */ /* == 1 */
|
||||
*p++ = (1 >> 8) & 0xFF; /* DlgOpt */ /* == 0 */
|
||||
*p++ = (fwd_data->length >> 0) & 0xFF; /* Dlgth */
|
||||
*p++ = (fwd_data->length >> 8) & 0xFF; /* Dlgth */
|
||||
memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);
|
||||
|
||||
p += fwd_data->length;
|
||||
|
||||
if (p - (u_char *)result->checksum.data != result->checksum.length)
|
||||
abort ();
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,14 +151,16 @@ krb5_error_code
|
||||
gssapi_krb5_verify_8003_checksum(
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
Checksum *cksum,
|
||||
OM_uint32 *flags)
|
||||
OM_uint32 *flags,
|
||||
krb5_data *fwd_data)
|
||||
{
|
||||
unsigned char hash[16];
|
||||
unsigned char *p;
|
||||
OM_uint32 length;
|
||||
int DlgOpt;
|
||||
|
||||
/* XXX should handle checksums > 24 bytes */
|
||||
if(cksum->cksumtype != 0x8003 || cksum->checksum.length != 24)
|
||||
if(cksum->cksumtype != 0x8003)
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
|
||||
p = cksum->checksum.data;
|
||||
@@ -147,6 +180,24 @@ gssapi_krb5_verify_8003_checksum(
|
||||
p += sizeof(hash);
|
||||
|
||||
decode_om_uint32(p, flags);
|
||||
|
||||
if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
|
||||
|
||||
p += 4;
|
||||
|
||||
DlgOpt = (p[0] << 0) | (p[1] << 8 );
|
||||
if (DlgOpt != 1)
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
|
||||
p += 2;
|
||||
fwd_data->length = (p[0] << 0) | (p[1] << 8);
|
||||
fwd_data->data = malloc(fwd_data->length);
|
||||
if (fwd_data->data == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
p += 2;
|
||||
memcpy(fwd_data->data, p, fwd_data->length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -45,4 +45,5 @@ libgssapi_la_SOURCES = \
|
||||
unwrap.c \
|
||||
v1.c \
|
||||
verify_mic.c \
|
||||
wrap.c
|
||||
wrap.c \
|
||||
address_to_krb5addr.c
|
||||
|
@@ -75,9 +75,11 @@ gss_accept_sec_context
|
||||
OM_uint32 flags;
|
||||
krb5_ticket *ticket = NULL;
|
||||
krb5_keytab keytab = NULL;
|
||||
krb5_data fwd_data;
|
||||
|
||||
gssapi_krb5_init ();
|
||||
|
||||
krb5_data_zero (&fwd_data);
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
@@ -103,6 +105,70 @@ gss_accept_sec_context
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
|
||||
&& input_chan_bindings->application_data.length ==
|
||||
2 * sizeof((*context_handle)->auth_context->local_port)
|
||||
) {
|
||||
|
||||
/* Port numbers are expected to be in application_data.value,
|
||||
* initator's port first */
|
||||
|
||||
krb5_address initiator_addr, acceptor_addr;
|
||||
|
||||
memset(&initiator_addr, 0, sizeof(initiator_addr));
|
||||
memset(&acceptor_addr, 0, sizeof(acceptor_addr));
|
||||
|
||||
(*context_handle)->auth_context->remote_port =
|
||||
*(int16_t *) input_chan_bindings->application_data.value;
|
||||
|
||||
(*context_handle)->auth_context->local_port =
|
||||
*((int16_t *) input_chan_bindings->application_data.value + 1);
|
||||
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
|
||||
&input_chan_bindings->acceptor_address,
|
||||
(*context_handle)->auth_context->local_port,
|
||||
&acceptor_addr);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
|
||||
&input_chan_bindings->initiator_address,
|
||||
(*context_handle)->auth_context->remote_port,
|
||||
&initiator_addr);
|
||||
if (kret) {
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setaddrs(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
&acceptor_addr, /* local address */
|
||||
&initiator_addr); /* remote address */
|
||||
|
||||
krb5_free_address (gssapi_krb5_context, &initiator_addr);
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
|
||||
#if 0
|
||||
free(input_chan_bindings->application_data.value);
|
||||
input_chan_bindings->application_data.value = NULL;
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
#endif
|
||||
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
int32_t tmp;
|
||||
|
||||
@@ -183,7 +249,8 @@ gss_accept_sec_context
|
||||
|
||||
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
||||
authenticator->cksum,
|
||||
&flags);
|
||||
&flags,
|
||||
&fwd_data);
|
||||
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
@@ -191,6 +258,49 @@ gss_accept_sec_context
|
||||
}
|
||||
}
|
||||
|
||||
if (fwd_data.length > 0 && (flags & GSS_C_DELEG_FLAG)) {
|
||||
|
||||
krb5_ccache ccache;
|
||||
|
||||
if (delegated_cred_handle == NULL || *delegated_cred_handle == NULL)
|
||||
/* XXX Create a new delegated_cred_handle? */
|
||||
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||
|
||||
else {
|
||||
if ((*delegated_cred_handle)->ccache == NULL)
|
||||
kret = krb5_cc_gen_new (gssapi_krb5_context,
|
||||
&krb5_mcc_ops,
|
||||
&(*delegated_cred_handle)->ccache);
|
||||
ccache = (*delegated_cred_handle)->ccache;
|
||||
}
|
||||
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
kret = krb5_cc_initialize(gssapi_krb5_context,
|
||||
ccache,
|
||||
*src_name);
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
kret = krb5_rd_cred(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
ccache,
|
||||
&fwd_data);
|
||||
if (kret) {
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto end_fwd;
|
||||
}
|
||||
|
||||
end_fwd:
|
||||
free(fwd_data.data);
|
||||
}
|
||||
|
||||
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
@@ -236,6 +346,8 @@ gss_accept_sec_context
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
failure:
|
||||
if (fwd_data.length > 0)
|
||||
free(fwd_data.data);
|
||||
if (ticket != NULL)
|
||||
krb5_free_ticket (gssapi_krb5_context, ticket);
|
||||
krb5_auth_con_free (gssapi_krb5_context,
|
||||
|
73
lib/gssapi/krb5/address_to_krb5addr.c
Normal file
73
lib/gssapi/krb5/address_to_krb5addr.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gssapi_locl.h"
|
||||
|
||||
krb5_error_code
|
||||
gss_address_to_krb5addr(OM_uint32 gss_addr_type,
|
||||
gss_buffer_desc *gss_addr,
|
||||
int16_t port,
|
||||
krb5_address *address)
|
||||
{
|
||||
sa_family_t addr_type;
|
||||
struct sockaddr sa;
|
||||
int sa_len = sizeof(sa);
|
||||
krb5_error_code problem;
|
||||
|
||||
if (gss_addr == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
switch (gss_addr_type) {
|
||||
#ifdef HAVE_IPV6
|
||||
case GSS_C_AF_INET6: addr_type = AF_INET6;
|
||||
break;
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
case GSS_C_AF_INET: addr_type = AF_INET;
|
||||
break;
|
||||
default:
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
problem = krb5_h_addr2sockaddr (addr_type,
|
||||
gss_addr->value,
|
||||
&sa,
|
||||
&sa_len,
|
||||
port);
|
||||
if (problem)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
problem = krb5_sockaddr2address (&sa, address);
|
||||
|
||||
return problem;
|
||||
}
|
@@ -89,6 +89,8 @@ typedef struct gss_OID_set_desc_struct {
|
||||
|
||||
struct krb5_keytab_data;
|
||||
|
||||
struct krb5_ccache_data;
|
||||
|
||||
typedef int gss_cred_usage_t;
|
||||
|
||||
typedef struct gss_cred_id_t_desc_struct {
|
||||
@@ -97,6 +99,7 @@ typedef struct gss_cred_id_t_desc_struct {
|
||||
OM_uint32 lifetime;
|
||||
gss_cred_usage_t usage;
|
||||
gss_OID_set mechanisms;
|
||||
struct krb5_ccache_data *ccache;
|
||||
} gss_cred_id_t_desc;
|
||||
|
||||
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
||||
|
@@ -47,13 +47,15 @@ krb5_error_code
|
||||
gssapi_krb5_create_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
OM_uint32 flags,
|
||||
krb5_data *fwd_data,
|
||||
Checksum *result);
|
||||
|
||||
krb5_error_code
|
||||
gssapi_krb5_verify_8003_checksum (
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
Checksum *cksum,
|
||||
OM_uint32 *flags);
|
||||
OM_uint32 *flags,
|
||||
krb5_data *fwd_data);
|
||||
|
||||
OM_uint32
|
||||
gssapi_krb5_encapsulate(
|
||||
@@ -86,6 +88,12 @@ OM_uint32
|
||||
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
||||
des_cblock *key);
|
||||
|
||||
krb5_error_code
|
||||
gss_address_to_krb5addr(OM_uint32 gss_addr_type,
|
||||
gss_buffer_desc *gss_addr,
|
||||
int16_t port,
|
||||
krb5_address *address);
|
||||
|
||||
/* sec_context flags */
|
||||
|
||||
#define SC_LOCAL_ADDRESS 0x01
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2000 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -63,7 +63,9 @@ init_auth
|
||||
krb5_data authenticator;
|
||||
Checksum cksum;
|
||||
krb5_enctype enctype;
|
||||
krb5_data fwd_data;
|
||||
|
||||
krb5_data_zero (&fwd_data);
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
@@ -93,7 +95,66 @@ init_auth
|
||||
goto failure;
|
||||
}
|
||||
|
||||
{
|
||||
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS &&
|
||||
input_chan_bindings->application_data.length ==
|
||||
2 * sizeof((*context_handle)->auth_context->local_port)) {
|
||||
/* Port numbers are expected to be in application_data.value,
|
||||
* initator's port first */
|
||||
|
||||
krb5_address initiator_addr, acceptor_addr;
|
||||
|
||||
memset(&initiator_addr, 0, sizeof(initiator_addr));
|
||||
memset(&acceptor_addr, 0, sizeof(acceptor_addr));
|
||||
|
||||
(*context_handle)->auth_context->local_port =
|
||||
*(int16_t *) input_chan_bindings->application_data.value;
|
||||
|
||||
(*context_handle)->auth_context->remote_port =
|
||||
*((int16_t *) input_chan_bindings->application_data.value + 1);
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
|
||||
&input_chan_bindings->acceptor_address,
|
||||
(*context_handle)->auth_context->remote_port,
|
||||
&acceptor_addr);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
|
||||
&input_chan_bindings->initiator_address,
|
||||
(*context_handle)->auth_context->local_port,
|
||||
&initiator_addr);
|
||||
if (kret) {
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setaddrs(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
&initiator_addr, /* local address */
|
||||
&acceptor_addr); /* remote address */
|
||||
|
||||
krb5_free_address (gssapi_krb5_context, &initiator_addr);
|
||||
krb5_free_address (gssapi_krb5_context, &acceptor_addr);
|
||||
|
||||
#if 0
|
||||
free(input_chan_bindings->application_data.value);
|
||||
input_chan_bindings->application_data.value = NULL;
|
||||
input_chan_bindings->application_data.length = 0;
|
||||
#endif
|
||||
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_BAD_BINDINGS;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int32_t tmp;
|
||||
|
||||
krb5_auth_con_getflags(gssapi_krb5_context,
|
||||
@@ -108,30 +169,6 @@ init_auth
|
||||
if (actual_mech_type)
|
||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
flags = 0;
|
||||
ap_options = 0;
|
||||
if (req_flags & GSS_C_DELEG_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_MUTUAL_FLAG) {
|
||||
flags |= GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
if (req_flags & GSS_C_REPLAY_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_SEQUENCE_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_ANON_FLAG)
|
||||
; /* XXX */
|
||||
flags |= GSS_C_CONF_FLAG;
|
||||
flags |= GSS_C_INTEG_FLAG;
|
||||
flags |= GSS_C_SEQUENCE_FLAG;
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = flags;
|
||||
(*context_handle)->flags = flags;
|
||||
(*context_handle)->more_flags = LOCAL;
|
||||
|
||||
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
@@ -179,8 +216,104 @@ init_auth
|
||||
(*context_handle)->auth_context,
|
||||
&cred->session);
|
||||
|
||||
flags = 0;
|
||||
ap_options = 0;
|
||||
if (req_flags & GSS_C_DELEG_FLAG) {
|
||||
krb5_creds creds;
|
||||
krb5_kdc_flags fwd_flags;
|
||||
krb5_keyblock *subkey;
|
||||
|
||||
memset ((char *)&creds, 0, sizeof(creds));
|
||||
|
||||
subkey = (krb5_keyblock *) malloc(sizeof(subkey));
|
||||
if (subkey == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
krb5_generate_subkey (gssapi_krb5_context,
|
||||
&cred->session,
|
||||
&subkey);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_auth_con_setlocalsubkey(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
subkey);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_cc_get_principal(gssapi_krb5_context,
|
||||
ccache,
|
||||
&creds.client);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_build_principal(gssapi_krb5_context,
|
||||
&creds.server,
|
||||
strlen(creds.client->realm),
|
||||
creds.client->realm,
|
||||
KRB5_TGS_NAME,
|
||||
creds.client->realm,
|
||||
NULL);
|
||||
if (kret)
|
||||
goto end_fwd;
|
||||
|
||||
creds.times.endtime = 0;
|
||||
|
||||
fwd_flags.i = 0;
|
||||
fwd_flags.b.forwarded = 1;
|
||||
fwd_flags.b.forwardable = 1;
|
||||
|
||||
if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
|
||||
target_name->name.name_string.len < 2)
|
||||
goto end_fwd;
|
||||
|
||||
kret = krb5_get_forwarded_creds(gssapi_krb5_context,
|
||||
(*context_handle)->auth_context,
|
||||
ccache,
|
||||
fwd_flags.i,
|
||||
target_name->name.name_string.val[1],
|
||||
&creds,
|
||||
&fwd_data);
|
||||
|
||||
end_fwd:
|
||||
if (kret)
|
||||
flags &= ~GSS_C_DELEG_FLAG;
|
||||
else
|
||||
flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
if (creds.client)
|
||||
krb5_free_principal(gssapi_krb5_context, creds.client);
|
||||
if (creds.server)
|
||||
krb5_free_principal(gssapi_krb5_context, creds.server);
|
||||
}
|
||||
|
||||
if (req_flags & GSS_C_MUTUAL_FLAG) {
|
||||
flags |= GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
|
||||
if (req_flags & GSS_C_REPLAY_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_SEQUENCE_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_ANON_FLAG)
|
||||
; /* XXX */
|
||||
flags |= GSS_C_CONF_FLAG;
|
||||
flags |= GSS_C_INTEG_FLAG;
|
||||
flags |= GSS_C_SEQUENCE_FLAG;
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = flags;
|
||||
(*context_handle)->flags = flags;
|
||||
(*context_handle)->more_flags = LOCAL;
|
||||
|
||||
kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
|
||||
flags,
|
||||
&fwd_data,
|
||||
&cksum);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
|
Reference in New Issue
Block a user