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 (
|
gssapi_krb5_create_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
OM_uint32 flags,
|
OM_uint32 flags,
|
||||||
|
krb5_data *fwd_data,
|
||||||
Checksum *result)
|
Checksum *result)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
|
||||||
|
* field's format)
|
||||||
|
*/
|
||||||
result->cksumtype = 0x8003;
|
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);
|
result->checksum.data = malloc (result->checksum.length);
|
||||||
if (result->checksum.data == NULL)
|
if (result->checksum.data == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
@@ -111,8 +119,31 @@ gssapi_krb5_create_8003_checksum (
|
|||||||
p += 16;
|
p += 16;
|
||||||
encode_om_uint32 (flags, p);
|
encode_om_uint32 (flags, p);
|
||||||
p += 4;
|
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)
|
if (p - (u_char *)result->checksum.data != result->checksum.length)
|
||||||
abort ();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,14 +151,16 @@ krb5_error_code
|
|||||||
gssapi_krb5_verify_8003_checksum(
|
gssapi_krb5_verify_8003_checksum(
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
Checksum *cksum,
|
Checksum *cksum,
|
||||||
OM_uint32 *flags)
|
OM_uint32 *flags,
|
||||||
|
krb5_data *fwd_data)
|
||||||
{
|
{
|
||||||
unsigned char hash[16];
|
unsigned char hash[16];
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
OM_uint32 length;
|
OM_uint32 length;
|
||||||
|
int DlgOpt;
|
||||||
|
|
||||||
/* XXX should handle checksums > 24 bytes */
|
/* XXX should handle checksums > 24 bytes */
|
||||||
if(cksum->cksumtype != 0x8003 || cksum->checksum.length != 24)
|
if(cksum->cksumtype != 0x8003)
|
||||||
return GSS_S_BAD_BINDINGS;
|
return GSS_S_BAD_BINDINGS;
|
||||||
|
|
||||||
p = cksum->checksum.data;
|
p = cksum->checksum.data;
|
||||||
@@ -148,5 +181,23 @@ gssapi_krb5_verify_8003_checksum(
|
|||||||
|
|
||||||
decode_om_uint32(p, flags);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -45,4 +45,5 @@ libgssapi_la_SOURCES = \
|
|||||||
unwrap.c \
|
unwrap.c \
|
||||||
v1.c \
|
v1.c \
|
||||||
verify_mic.c \
|
verify_mic.c \
|
||||||
wrap.c
|
wrap.c \
|
||||||
|
address_to_krb5addr.c
|
||||||
|
@@ -75,9 +75,11 @@ gss_accept_sec_context
|
|||||||
OM_uint32 flags;
|
OM_uint32 flags;
|
||||||
krb5_ticket *ticket = NULL;
|
krb5_ticket *ticket = NULL;
|
||||||
krb5_keytab keytab = NULL;
|
krb5_keytab keytab = NULL;
|
||||||
|
krb5_data fwd_data;
|
||||||
|
|
||||||
gssapi_krb5_init ();
|
gssapi_krb5_init ();
|
||||||
|
|
||||||
|
krb5_data_zero (&fwd_data);
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
@@ -103,6 +105,70 @@ gss_accept_sec_context
|
|||||||
goto failure;
|
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;
|
int32_t tmp;
|
||||||
|
|
||||||
@@ -183,7 +249,8 @@ gss_accept_sec_context
|
|||||||
|
|
||||||
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
||||||
authenticator->cksum,
|
authenticator->cksum,
|
||||||
&flags);
|
&flags,
|
||||||
|
&fwd_data);
|
||||||
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
ret = GSS_S_FAILURE;
|
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;
|
flags |= GSS_C_TRANS_FLAG;
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
@@ -236,6 +346,8 @@ gss_accept_sec_context
|
|||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
|
if (fwd_data.length > 0)
|
||||||
|
free(fwd_data.data);
|
||||||
if (ticket != NULL)
|
if (ticket != NULL)
|
||||||
krb5_free_ticket (gssapi_krb5_context, ticket);
|
krb5_free_ticket (gssapi_krb5_context, ticket);
|
||||||
krb5_auth_con_free (gssapi_krb5_context,
|
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_keytab_data;
|
||||||
|
|
||||||
|
struct krb5_ccache_data;
|
||||||
|
|
||||||
typedef int gss_cred_usage_t;
|
typedef int gss_cred_usage_t;
|
||||||
|
|
||||||
typedef struct gss_cred_id_t_desc_struct {
|
typedef struct gss_cred_id_t_desc_struct {
|
||||||
@@ -97,6 +99,7 @@ typedef struct gss_cred_id_t_desc_struct {
|
|||||||
OM_uint32 lifetime;
|
OM_uint32 lifetime;
|
||||||
gss_cred_usage_t usage;
|
gss_cred_usage_t usage;
|
||||||
gss_OID_set mechanisms;
|
gss_OID_set mechanisms;
|
||||||
|
struct krb5_ccache_data *ccache;
|
||||||
} gss_cred_id_t_desc;
|
} gss_cred_id_t_desc;
|
||||||
|
|
||||||
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
||||||
|
@@ -47,13 +47,15 @@ krb5_error_code
|
|||||||
gssapi_krb5_create_8003_checksum (
|
gssapi_krb5_create_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
OM_uint32 flags,
|
OM_uint32 flags,
|
||||||
|
krb5_data *fwd_data,
|
||||||
Checksum *result);
|
Checksum *result);
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
gssapi_krb5_verify_8003_checksum (
|
gssapi_krb5_verify_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
Checksum *cksum,
|
Checksum *cksum,
|
||||||
OM_uint32 *flags);
|
OM_uint32 *flags,
|
||||||
|
krb5_data *fwd_data);
|
||||||
|
|
||||||
OM_uint32
|
OM_uint32
|
||||||
gssapi_krb5_encapsulate(
|
gssapi_krb5_encapsulate(
|
||||||
@@ -86,6 +88,12 @@ OM_uint32
|
|||||||
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
||||||
des_cblock *key);
|
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 */
|
/* sec_context flags */
|
||||||
|
|
||||||
#define SC_LOCAL_ADDRESS 0x01
|
#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).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -63,7 +63,9 @@ init_auth
|
|||||||
krb5_data authenticator;
|
krb5_data authenticator;
|
||||||
Checksum cksum;
|
Checksum cksum;
|
||||||
krb5_enctype enctype;
|
krb5_enctype enctype;
|
||||||
|
krb5_data fwd_data;
|
||||||
|
|
||||||
|
krb5_data_zero (&fwd_data);
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
@@ -93,7 +95,66 @@ init_auth
|
|||||||
goto failure;
|
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;
|
int32_t tmp;
|
||||||
|
|
||||||
krb5_auth_con_getflags(gssapi_krb5_context,
|
krb5_auth_con_getflags(gssapi_krb5_context,
|
||||||
@@ -108,30 +169,6 @@ init_auth
|
|||||||
if (actual_mech_type)
|
if (actual_mech_type)
|
||||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
*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);
|
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
@@ -179,8 +216,104 @@ init_auth
|
|||||||
(*context_handle)->auth_context,
|
(*context_handle)->auth_context,
|
||||||
&cred->session);
|
&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,
|
kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
|
||||||
flags,
|
flags,
|
||||||
|
&fwd_data,
|
||||||
&cksum);
|
&cksum);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
|
@@ -90,12 +90,20 @@ krb5_error_code
|
|||||||
gssapi_krb5_create_8003_checksum (
|
gssapi_krb5_create_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
OM_uint32 flags,
|
OM_uint32 flags,
|
||||||
|
krb5_data *fwd_data,
|
||||||
Checksum *result)
|
Checksum *result)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
|
||||||
|
* field's format)
|
||||||
|
*/
|
||||||
result->cksumtype = 0x8003;
|
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);
|
result->checksum.data = malloc (result->checksum.length);
|
||||||
if (result->checksum.data == NULL)
|
if (result->checksum.data == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
@@ -111,8 +119,31 @@ gssapi_krb5_create_8003_checksum (
|
|||||||
p += 16;
|
p += 16;
|
||||||
encode_om_uint32 (flags, p);
|
encode_om_uint32 (flags, p);
|
||||||
p += 4;
|
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)
|
if (p - (u_char *)result->checksum.data != result->checksum.length)
|
||||||
abort ();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,14 +151,16 @@ krb5_error_code
|
|||||||
gssapi_krb5_verify_8003_checksum(
|
gssapi_krb5_verify_8003_checksum(
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
Checksum *cksum,
|
Checksum *cksum,
|
||||||
OM_uint32 *flags)
|
OM_uint32 *flags,
|
||||||
|
krb5_data *fwd_data)
|
||||||
{
|
{
|
||||||
unsigned char hash[16];
|
unsigned char hash[16];
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
OM_uint32 length;
|
OM_uint32 length;
|
||||||
|
int DlgOpt;
|
||||||
|
|
||||||
/* XXX should handle checksums > 24 bytes */
|
/* XXX should handle checksums > 24 bytes */
|
||||||
if(cksum->cksumtype != 0x8003 || cksum->checksum.length != 24)
|
if(cksum->cksumtype != 0x8003)
|
||||||
return GSS_S_BAD_BINDINGS;
|
return GSS_S_BAD_BINDINGS;
|
||||||
|
|
||||||
p = cksum->checksum.data;
|
p = cksum->checksum.data;
|
||||||
@@ -148,5 +181,23 @@ gssapi_krb5_verify_8003_checksum(
|
|||||||
|
|
||||||
decode_om_uint32(p, flags);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -45,4 +45,5 @@ libgssapi_la_SOURCES = \
|
|||||||
unwrap.c \
|
unwrap.c \
|
||||||
v1.c \
|
v1.c \
|
||||||
verify_mic.c \
|
verify_mic.c \
|
||||||
wrap.c
|
wrap.c \
|
||||||
|
address_to_krb5addr.c
|
||||||
|
@@ -75,9 +75,11 @@ gss_accept_sec_context
|
|||||||
OM_uint32 flags;
|
OM_uint32 flags;
|
||||||
krb5_ticket *ticket = NULL;
|
krb5_ticket *ticket = NULL;
|
||||||
krb5_keytab keytab = NULL;
|
krb5_keytab keytab = NULL;
|
||||||
|
krb5_data fwd_data;
|
||||||
|
|
||||||
gssapi_krb5_init ();
|
gssapi_krb5_init ();
|
||||||
|
|
||||||
|
krb5_data_zero (&fwd_data);
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
@@ -103,6 +105,70 @@ gss_accept_sec_context
|
|||||||
goto failure;
|
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;
|
int32_t tmp;
|
||||||
|
|
||||||
@@ -183,7 +249,8 @@ gss_accept_sec_context
|
|||||||
|
|
||||||
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
kret = gssapi_krb5_verify_8003_checksum(input_chan_bindings,
|
||||||
authenticator->cksum,
|
authenticator->cksum,
|
||||||
&flags);
|
&flags,
|
||||||
|
&fwd_data);
|
||||||
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
ret = GSS_S_FAILURE;
|
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;
|
flags |= GSS_C_TRANS_FLAG;
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
@@ -236,6 +346,8 @@ gss_accept_sec_context
|
|||||||
return GSS_S_COMPLETE;
|
return GSS_S_COMPLETE;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
|
if (fwd_data.length > 0)
|
||||||
|
free(fwd_data.data);
|
||||||
if (ticket != NULL)
|
if (ticket != NULL)
|
||||||
krb5_free_ticket (gssapi_krb5_context, ticket);
|
krb5_free_ticket (gssapi_krb5_context, ticket);
|
||||||
krb5_auth_con_free (gssapi_krb5_context,
|
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_keytab_data;
|
||||||
|
|
||||||
|
struct krb5_ccache_data;
|
||||||
|
|
||||||
typedef int gss_cred_usage_t;
|
typedef int gss_cred_usage_t;
|
||||||
|
|
||||||
typedef struct gss_cred_id_t_desc_struct {
|
typedef struct gss_cred_id_t_desc_struct {
|
||||||
@@ -97,6 +99,7 @@ typedef struct gss_cred_id_t_desc_struct {
|
|||||||
OM_uint32 lifetime;
|
OM_uint32 lifetime;
|
||||||
gss_cred_usage_t usage;
|
gss_cred_usage_t usage;
|
||||||
gss_OID_set mechanisms;
|
gss_OID_set mechanisms;
|
||||||
|
struct krb5_ccache_data *ccache;
|
||||||
} gss_cred_id_t_desc;
|
} gss_cred_id_t_desc;
|
||||||
|
|
||||||
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
typedef gss_cred_id_t_desc *gss_cred_id_t;
|
||||||
|
@@ -47,13 +47,15 @@ krb5_error_code
|
|||||||
gssapi_krb5_create_8003_checksum (
|
gssapi_krb5_create_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
OM_uint32 flags,
|
OM_uint32 flags,
|
||||||
|
krb5_data *fwd_data,
|
||||||
Checksum *result);
|
Checksum *result);
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
gssapi_krb5_verify_8003_checksum (
|
gssapi_krb5_verify_8003_checksum (
|
||||||
const gss_channel_bindings_t input_chan_bindings,
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
Checksum *cksum,
|
Checksum *cksum,
|
||||||
OM_uint32 *flags);
|
OM_uint32 *flags,
|
||||||
|
krb5_data *fwd_data);
|
||||||
|
|
||||||
OM_uint32
|
OM_uint32
|
||||||
gssapi_krb5_encapsulate(
|
gssapi_krb5_encapsulate(
|
||||||
@@ -86,6 +88,12 @@ OM_uint32
|
|||||||
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
gss_krb5_getsomekey(const gss_ctx_id_t context_handle,
|
||||||
des_cblock *key);
|
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 */
|
/* sec_context flags */
|
||||||
|
|
||||||
#define SC_LOCAL_ADDRESS 0x01
|
#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).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -63,7 +63,9 @@ init_auth
|
|||||||
krb5_data authenticator;
|
krb5_data authenticator;
|
||||||
Checksum cksum;
|
Checksum cksum;
|
||||||
krb5_enctype enctype;
|
krb5_enctype enctype;
|
||||||
|
krb5_data fwd_data;
|
||||||
|
|
||||||
|
krb5_data_zero (&fwd_data);
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
@@ -93,7 +95,66 @@ init_auth
|
|||||||
goto failure;
|
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;
|
int32_t tmp;
|
||||||
|
|
||||||
krb5_auth_con_getflags(gssapi_krb5_context,
|
krb5_auth_con_getflags(gssapi_krb5_context,
|
||||||
@@ -108,30 +169,6 @@ init_auth
|
|||||||
if (actual_mech_type)
|
if (actual_mech_type)
|
||||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
*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);
|
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
@@ -179,8 +216,104 @@ init_auth
|
|||||||
(*context_handle)->auth_context,
|
(*context_handle)->auth_context,
|
||||||
&cred->session);
|
&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,
|
kret = gssapi_krb5_create_8003_checksum (input_chan_bindings,
|
||||||
flags,
|
flags,
|
||||||
|
&fwd_data,
|
||||||
&cksum);
|
&cksum);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
|
Reference in New Issue
Block a user