move kerberos files to krb5/

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17698 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-06-28 08:56:35 +00:00
parent ee09f98c15
commit a1321d12ed
54 changed files with 0 additions and 11216 deletions

View File

@@ -1,248 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
krb5_error_code
gssapi_encode_om_uint32(OM_uint32 n, u_char *p)
{
p[0] = (n >> 0) & 0xFF;
p[1] = (n >> 8) & 0xFF;
p[2] = (n >> 16) & 0xFF;
p[3] = (n >> 24) & 0xFF;
return 0;
}
krb5_error_code
gssapi_encode_be_om_uint32(OM_uint32 n, u_char *p)
{
p[0] = (n >> 24) & 0xFF;
p[1] = (n >> 16) & 0xFF;
p[2] = (n >> 8) & 0xFF;
p[3] = (n >> 0) & 0xFF;
return 0;
}
krb5_error_code
gssapi_decode_om_uint32(const void *ptr, OM_uint32 *n)
{
const u_char *p = ptr;
*n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
return 0;
}
krb5_error_code
gssapi_decode_be_om_uint32(const void *ptr, OM_uint32 *n)
{
const u_char *p = ptr;
*n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
return 0;
}
static krb5_error_code
hash_input_chan_bindings (const gss_channel_bindings_t b,
u_char *p)
{
u_char num[4];
MD5_CTX md5;
MD5_Init(&md5);
gssapi_encode_om_uint32 (b->initiator_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
gssapi_encode_om_uint32 (b->initiator_address.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->initiator_address.length)
MD5_Update (&md5,
b->initiator_address.value,
b->initiator_address.length);
gssapi_encode_om_uint32 (b->acceptor_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
gssapi_encode_om_uint32 (b->acceptor_address.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->acceptor_address.length)
MD5_Update (&md5,
b->acceptor_address.value,
b->acceptor_address.length);
gssapi_encode_om_uint32 (b->application_data.length, num);
MD5_Update (&md5, num, sizeof(num));
if (b->application_data.length)
MD5_Update (&md5,
b->application_data.value,
b->application_data.length);
MD5_Final (p, &md5);
return 0;
}
/*
* create a checksum over the chanel bindings in
* `input_chan_bindings', `flags' and `fwd_data' and return it in
* `result'
*/
OM_uint32
gssapi_krb5_create_8003_checksum (
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
OM_uint32 flags,
const 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 = CKSUMTYPE_GSSAPI;
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) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = result->checksum.data;
gssapi_encode_om_uint32 (16, p);
p += 4;
if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {
memset (p, 0, 16);
} else {
hash_input_chan_bindings (input_chan_bindings, p);
}
p += 16;
gssapi_encode_om_uint32 (flags, p);
p += 4;
if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
*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;
}
return GSS_S_COMPLETE;
}
/*
* verify the checksum in `cksum' over `input_chan_bindings'
* returning `flags' and `fwd_data'
*/
OM_uint32
gssapi_krb5_verify_8003_checksum(
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
const Checksum *cksum,
OM_uint32 *flags,
krb5_data *fwd_data)
{
unsigned char hash[16];
unsigned char *p;
OM_uint32 length;
int DlgOpt;
static unsigned char zeros[16];
if (cksum == NULL) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
/* XXX should handle checksums > 24 bytes */
if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
p = cksum->checksum.data;
gssapi_decode_om_uint32(p, &length);
if(length != sizeof(hash)) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
p += 4;
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
&& memcmp(p, zeros, sizeof(zeros)) != 0) {
if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
if(memcmp(hash, p, sizeof(hash)) != 0) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
}
p += sizeof(hash);
gssapi_decode_om_uint32(p, flags);
p += 4;
if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
if(cksum->checksum.length < 28) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
DlgOpt = (p[0] << 0) | (p[1] << 8);
p += 2;
if (DlgOpt != 1) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
fwd_data->length = (p[0] << 0) | (p[1] << 8);
p += 2;
if(cksum->checksum.length < 28 + fwd_data->length) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
fwd_data->data = malloc(fwd_data->length);
if (fwd_data->data == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy(fwd_data->data, p, fwd_data->length);
}
return GSS_S_COMPLETE;
}

View File

@@ -1,934 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
krb5_keytab gssapi_krb5_keytab;
OM_uint32
gsskrb5_register_acceptor_identity (const char *identity)
{
krb5_error_code ret;
ret = gssapi_krb5_init();
if(ret)
return GSS_S_FAILURE;
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
if(gssapi_krb5_keytab != NULL) {
krb5_kt_close(gssapi_krb5_context, gssapi_krb5_keytab);
gssapi_krb5_keytab = NULL;
}
if (identity == NULL) {
ret = krb5_kt_default(gssapi_krb5_context, &gssapi_krb5_keytab);
} else {
char *p;
asprintf(&p, "FILE:%s", identity);
if(p == NULL) {
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
return GSS_S_FAILURE;
}
ret = krb5_kt_resolve(gssapi_krb5_context, p, &gssapi_krb5_keytab);
free(p);
}
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
if(ret)
return GSS_S_FAILURE;
return GSS_S_COMPLETE;
}
void
gsskrb5_is_cfx(gss_ctx_id_t context_handle, int *is_cfx)
{
krb5_keyblock *key;
int acceptor = (context_handle->more_flags & LOCAL) == 0;
*is_cfx = 0;
if (acceptor) {
if (context_handle->auth_context->local_subkey)
key = context_handle->auth_context->local_subkey;
else
key = context_handle->auth_context->remote_subkey;
} else {
if (context_handle->auth_context->remote_subkey)
key = context_handle->auth_context->remote_subkey;
else
key = context_handle->auth_context->local_subkey;
}
if (key == NULL)
key = context_handle->auth_context->keyblock;
if (key == NULL)
return;
switch (key->keytype) {
case ETYPE_DES_CBC_CRC:
case ETYPE_DES_CBC_MD4:
case ETYPE_DES_CBC_MD5:
case ETYPE_DES3_CBC_MD5:
case ETYPE_DES3_CBC_SHA1:
case ETYPE_ARCFOUR_HMAC_MD5:
case ETYPE_ARCFOUR_HMAC_MD5_56:
break;
default :
*is_cfx = 1;
if ((acceptor && context_handle->auth_context->local_subkey) ||
(!acceptor && context_handle->auth_context->remote_subkey))
context_handle->more_flags |= ACCEPTOR_SUBKEY;
break;
}
}
static OM_uint32
gsskrb5_accept_delegated_token
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
krb5_data *fwd_data,
OM_uint32 *flags,
krb5_principal principal,
gss_cred_id_t * delegated_cred_handle
)
{
krb5_ccache ccache = NULL;
krb5_error_code kret;
int32_t ac_flags, ret = GSS_S_COMPLETE;
*minor_status = 0;
/* XXX Create a new delegated_cred_handle? */
if (delegated_cred_handle == NULL)
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
else
kret = krb5_cc_gen_new (gssapi_krb5_context, &krb5_mcc_ops, &ccache);
if (kret) {
*flags &= ~GSS_C_DELEG_FLAG;
goto out;
}
kret = krb5_cc_initialize(gssapi_krb5_context, ccache, principal);
if (kret) {
*flags &= ~GSS_C_DELEG_FLAG;
goto out;
}
krb5_auth_con_removeflags(gssapi_krb5_context,
(*context_handle)->auth_context,
KRB5_AUTH_CONTEXT_DO_TIME,
&ac_flags);
kret = krb5_rd_cred2(gssapi_krb5_context,
(*context_handle)->auth_context,
ccache,
fwd_data);
if (kret)
gssapi_krb5_set_error_string();
krb5_auth_con_setflags(gssapi_krb5_context,
(*context_handle)->auth_context,
ac_flags);
if (kret) {
*flags &= ~GSS_C_DELEG_FLAG;
ret = GSS_S_FAILURE;
*minor_status = kret;
goto out;
}
if (delegated_cred_handle) {
ret = gss_krb5_import_cred(minor_status,
ccache,
NULL,
NULL,
delegated_cred_handle);
if (ret != GSS_S_COMPLETE)
goto out;
(*delegated_cred_handle)->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
ccache = NULL;
}
out:
if (ccache) {
if (delegated_cred_handle == NULL)
krb5_cc_close(gssapi_krb5_context, ccache);
else
krb5_cc_destroy(gssapi_krb5_context, ccache);
}
return ret;
}
static OM_uint32
gsskrb5_accept_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token_buffer,
const gss_channel_bindings_t input_chan_bindings,
gss_name_t * src_name,
gss_OID * mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags,
OM_uint32 * time_rec,
gss_cred_id_t * delegated_cred_handle
)
{
krb5_error_code kret;
OM_uint32 ret = GSS_S_COMPLETE;
krb5_data indata;
krb5_flags ap_options;
OM_uint32 flags;
krb5_ticket *ticket = NULL;
krb5_keytab keytab = NULL;
krb5_data fwd_data;
OM_uint32 minor;
int is_cfx = 0;
GSSAPI_KRB5_INIT();
krb5_data_zero (&fwd_data);
output_token->length = 0;
output_token->value = NULL;
if (src_name != NULL)
*src_name = NULL;
if (mech_type)
*mech_type = GSS_KRB5_MECHANISM;
if (*context_handle == GSS_C_NO_CONTEXT) {
*context_handle = malloc(sizeof(**context_handle));
if (*context_handle == GSS_C_NO_CONTEXT) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
}
HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);
(*context_handle)->auth_context = NULL;
(*context_handle)->source = NULL;
(*context_handle)->target = NULL;
(*context_handle)->flags = 0;
(*context_handle)->more_flags = 0;
(*context_handle)->ticket = NULL;
(*context_handle)->lifetime = GSS_C_INDEFINITE;
(*context_handle)->order = NULL;
kret = krb5_auth_con_init (gssapi_krb5_context,
&(*context_handle)->auth_context);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
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) {
gssapi_krb5_set_error_string ();
ret = GSS_S_BAD_BINDINGS;
*minor_status = kret;
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);
gssapi_krb5_set_error_string ();
ret = GSS_S_BAD_BINDINGS;
*minor_status = kret;
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) {
gssapi_krb5_set_error_string ();
ret = GSS_S_BAD_BINDINGS;
*minor_status = kret;
goto failure;
}
}
krb5_auth_con_addflags(gssapi_krb5_context,
(*context_handle)->auth_context,
KRB5_AUTH_CONTEXT_DO_SEQUENCE,
NULL);
ret = gssapi_krb5_decapsulate (minor_status,
input_token_buffer,
&indata,
"\x01\x00",
GSS_KRB5_MECHANISM);
if (ret)
goto failure;
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) {
if (gssapi_krb5_keytab != NULL) {
keytab = gssapi_krb5_keytab;
}
} else if (acceptor_cred_handle->keytab != NULL) {
keytab = acceptor_cred_handle->keytab;
}
kret = krb5_rd_req (gssapi_krb5_context,
&(*context_handle)->auth_context,
&indata,
(acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL
: acceptor_cred_handle->principal,
keytab,
&ap_options,
&ticket);
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
kret = krb5_copy_principal (gssapi_krb5_context,
ticket->client,
&(*context_handle)->source);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
kret = krb5_copy_principal (gssapi_krb5_context,
ticket->server,
&(*context_handle)->target);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
ret = _gss_DES3_get_mic_compat(minor_status, *context_handle);
if (ret)
goto failure;
if (src_name != NULL) {
kret = krb5_copy_principal (gssapi_krb5_context,
ticket->client,
src_name);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
}
{
krb5_authenticator authenticator;
kret = krb5_auth_con_getauthenticator(gssapi_krb5_context,
(*context_handle)->auth_context,
&authenticator);
if(kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
ret = gssapi_krb5_verify_8003_checksum(minor_status,
input_chan_bindings,
authenticator->cksum,
&flags,
&fwd_data);
krb5_free_authenticator(gssapi_krb5_context, &authenticator);
if (ret)
goto failure;
}
flags |= GSS_C_TRANS_FLAG;
if (ret_flags)
*ret_flags = flags;
(*context_handle)->lifetime = ticket->ticket.endtime;
(*context_handle)->flags = flags;
(*context_handle)->more_flags |= OPEN;
if (mech_type)
*mech_type = GSS_KRB5_MECHANISM;
if (time_rec) {
ret = gssapi_lifetime_left(minor_status,
(*context_handle)->lifetime,
time_rec);
if (ret)
goto failure;
}
gsskrb5_is_cfx(*context_handle, &is_cfx);
if(flags & GSS_C_MUTUAL_FLAG) {
krb5_data outbuf;
if (is_cfx != 0
|| (ap_options & AP_OPTS_USE_SUBKEY)) {
kret = krb5_auth_con_addflags(gssapi_krb5_context,
(*context_handle)->auth_context,
KRB5_AUTH_CONTEXT_USE_SUBKEY,
NULL);
(*context_handle)->more_flags |= ACCEPTOR_SUBKEY;
}
kret = krb5_mk_rep (gssapi_krb5_context,
(*context_handle)->auth_context,
&outbuf);
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
gssapi_krb5_set_error_string ();
goto failure;
}
ret = gssapi_krb5_encapsulate (minor_status,
&outbuf,
output_token,
(u_char *)"\x02\x00",
GSS_KRB5_MECHANISM);
krb5_data_free (&outbuf);
if (ret)
goto failure;
}
(*context_handle)->ticket = ticket;
{
int32_t seq_number;
krb5_auth_getremoteseqnumber (gssapi_krb5_context,
(*context_handle)->auth_context,
&seq_number);
ret = _gssapi_msg_order_create(minor_status,
&(*context_handle)->order,
_gssapi_msg_order_f(flags),
seq_number, 0, is_cfx);
if (ret)
goto failure;
if ((flags & GSS_C_MUTUAL_FLAG) == 0 && _gssapi_msg_order_f(flags)) {
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
(*context_handle)->auth_context,
seq_number);
}
}
if (fwd_data.length > 0) {
if (flags & GSS_C_DELEG_FLAG) {
ret = gsskrb5_accept_delegated_token(minor_status,
context_handle,
&fwd_data,
&flags,
ticket->client,
delegated_cred_handle);
if (ret)
goto failure;
}
free(fwd_data.data);
krb5_data_zero(&fwd_data);
}
*minor_status = 0;
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,
(*context_handle)->auth_context);
if((*context_handle)->source)
krb5_free_principal (gssapi_krb5_context,
(*context_handle)->source);
if((*context_handle)->target)
krb5_free_principal (gssapi_krb5_context,
(*context_handle)->target);
if((*context_handle)->order)
_gssapi_msg_order_destroy(&(*context_handle)->order);
HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
free (*context_handle);
if (src_name != NULL) {
gss_release_name (&minor, src_name);
*src_name = NULL;
}
*context_handle = GSS_C_NO_CONTEXT;
return ret;
}
static OM_uint32
code_NegTokenArg(OM_uint32 *minor_status,
const NegTokenTarg *targ,
krb5_data *data,
u_char **ret_buf)
{
OM_uint32 ret;
u_char *buf;
size_t buf_size, buf_len;
buf_size = 1024;
buf = malloc(buf_size);
if (buf == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
do {
ret = encode_NegTokenTarg(buf + buf_size - 1,
buf_size,
targ, &buf_len);
if (ret == 0) {
size_t tmp;
ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
buf_size - buf_len,
buf_len,
ASN1_C_CONTEXT,
CONS,
1,
&tmp);
if (ret == 0)
buf_len += tmp;
}
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
*minor_status = ENOMEM;
free(buf);
return GSS_S_FAILURE;
}
buf = tmp;
} else {
*minor_status = ret;
free(buf);
return GSS_S_FAILURE;
}
}
} while (ret == ASN1_OVERFLOW);
data->data = buf + buf_size - buf_len;
data->length = buf_len;
*ret_buf = buf;
return GSS_S_COMPLETE;
}
static OM_uint32
send_reject (OM_uint32 *minor_status,
gss_buffer_t output_token)
{
NegTokenTarg targ;
krb5_data data;
u_char *buf;
OM_uint32 ret;
ALLOC(targ.negResult, 1);
if (targ.negResult == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*(targ.negResult) = reject;
targ.supportedMech = NULL;
targ.responseToken = NULL;
targ.mechListMIC = NULL;
ret = code_NegTokenArg (minor_status, &targ, &data, &buf);
free_NegTokenTarg(&targ);
if (ret)
return ret;
#if 0
ret = _gssapi_encapsulate(minor_status,
&data,
output_token,
GSS_SPNEGO_MECHANISM);
#else
output_token->value = malloc(data.length);
if (output_token->value == NULL) {
*minor_status = ENOMEM;
ret = GSS_S_FAILURE;
} else {
output_token->length = data.length;
memcpy(output_token->value, data.data, output_token->length);
}
#endif
free(buf);
if (ret)
return ret;
return GSS_S_BAD_MECH;
}
static OM_uint32
send_accept (OM_uint32 *minor_status,
OM_uint32 major_status,
gss_buffer_t output_token,
gss_buffer_t mech_token,
gss_ctx_id_t context_handle,
const MechTypeList *mechtypelist)
{
NegTokenTarg targ;
krb5_data data;
u_char *buf;
OM_uint32 ret;
gss_buffer_desc mech_buf, mech_mic_buf;
krb5_boolean require_mic;
memset(&targ, 0, sizeof(targ));
ALLOC(targ.negResult, 1);
if (targ.negResult == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*(targ.negResult) = accept_completed;
ALLOC(targ.supportedMech, 1);
if (targ.supportedMech == NULL) {
free_NegTokenTarg(&targ);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
ret = der_get_oid(GSS_KRB5_MECHANISM->elements,
GSS_KRB5_MECHANISM->length,
targ.supportedMech,
NULL);
if (ret) {
free_NegTokenTarg(&targ);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
if (mech_token != NULL && mech_token->length != 0) {
ALLOC(targ.responseToken, 1);
if (targ.responseToken == NULL) {
free_NegTokenTarg(&targ);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
targ.responseToken->length = mech_token->length;
targ.responseToken->data = mech_token->value;
mech_token->length = 0;
mech_token->value = NULL;
} else {
targ.responseToken = NULL;
}
ret = _gss_spnego_require_mechlist_mic(minor_status, context_handle,
&require_mic);
if (ret) {
free_NegTokenTarg(&targ);
return ret;
}
if (major_status == GSS_S_COMPLETE && require_mic) {
size_t buf_len;
ALLOC(targ.mechListMIC, 1);
if (targ.mechListMIC == NULL) {
free_NegTokenTarg(&targ);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length,
mechtypelist, &buf_len, ret);
if (ret) {
free_NegTokenTarg(&targ);
return ret;
}
if (mech_buf.length != buf_len)
abort();
ret = gss_get_mic(minor_status, context_handle, 0, &mech_buf,
&mech_mic_buf);
free (mech_buf.value);
if (ret) {
free_NegTokenTarg(&targ);
return ret;
}
targ.mechListMIC->length = mech_mic_buf.length;
targ.mechListMIC->data = mech_mic_buf.value;
} else
targ.mechListMIC = NULL;
ret = code_NegTokenArg (minor_status, &targ, &data, &buf);
free_NegTokenTarg(&targ);
if (ret)
return ret;
#if 0
ret = _gssapi_encapsulate(minor_status,
&data,
output_token,
GSS_SPNEGO_MECHANISM);
#else
output_token->value = malloc(data.length);
if (output_token->value == NULL) {
*minor_status = ENOMEM;
ret = GSS_S_FAILURE;
} else {
output_token->length = data.length;
memcpy(output_token->value, data.data, output_token->length);
}
#endif
free(buf);
if (ret)
return ret;
return GSS_S_COMPLETE;
}
static OM_uint32
spnego_accept_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token_buffer,
const gss_channel_bindings_t input_chan_bindings,
gss_name_t * src_name,
gss_OID * mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags,
OM_uint32 * time_rec,
gss_cred_id_t * delegated_cred_handle
)
{
OM_uint32 ret, ret2;
NegTokenInit ni;
size_t ni_len;
int i;
int found = 0;
krb5_data data;
size_t len, taglen;
output_token->length = 0;
output_token->value = NULL;
ret = _gssapi_decapsulate (minor_status,
input_token_buffer,
&data,
GSS_SPNEGO_MECHANISM);
if (ret)
return ret;
ret = der_match_tag_and_length(data.data, data.length,
ASN1_C_CONTEXT, CONS, 0, &len, &taglen);
if (ret)
return ret;
if(len > data.length - taglen)
return ASN1_OVERRUN;
ret = decode_NegTokenInit((const unsigned char *)data.data + taglen, len,
&ni, &ni_len);
if (ret)
return GSS_S_DEFECTIVE_TOKEN;
if (ni.mechTypes == NULL) {
free_NegTokenInit(&ni);
return send_reject (minor_status, output_token);
}
for (i = 0; !found && i < ni.mechTypes->len; ++i) {
unsigned char mechbuf[17];
size_t mech_len;
ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1,
sizeof(mechbuf),
&ni.mechTypes->val[i],
&mech_len);
if (ret) {
free_NegTokenInit(&ni);
return GSS_S_DEFECTIVE_TOKEN;
}
if (mech_len == GSS_KRB5_MECHANISM->length
&& memcmp(GSS_KRB5_MECHANISM->elements,
mechbuf + sizeof(mechbuf) - mech_len,
mech_len) == 0)
found = 1;
}
if (found) {
gss_buffer_desc ibuf, obuf;
gss_buffer_t ot = NULL;
OM_uint32 minor;
if (ni.mechToken != NULL) {
ibuf.length = ni.mechToken->length;
ibuf.value = ni.mechToken->data;
ret = gsskrb5_accept_sec_context(&minor,
context_handle,
acceptor_cred_handle,
&ibuf,
input_chan_bindings,
src_name,
mech_type,
&obuf,
ret_flags,
time_rec,
delegated_cred_handle);
if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
ot = &obuf;
} else {
free_NegTokenInit(&ni);
send_reject (minor_status, output_token);
return ret;
}
}
ret2 = send_accept (minor_status, ret, output_token, ot,
*context_handle, ni.mechTypes);
if (ret2 != GSS_S_COMPLETE)
ret = ret2;
if (ot != NULL)
gss_release_buffer(&minor, ot);
free_NegTokenInit(&ni);
return ret;
} else {
free_NegTokenInit(&ni);
return send_reject (minor_status, output_token);
}
}
OM_uint32
gss_accept_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token_buffer,
const gss_channel_bindings_t input_chan_bindings,
gss_name_t * src_name,
gss_OID * mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags,
OM_uint32 * time_rec,
gss_cred_id_t * delegated_cred_handle
)
{
OM_uint32 ret;
ssize_t mech_len;
const u_char *p;
*minor_status = 0;
mech_len = gssapi_krb5_get_mech (input_token_buffer->value,
input_token_buffer->length,
&p);
if (mech_len < 0)
return GSS_S_DEFECTIVE_TOKEN;
if (mech_len == GSS_KRB5_MECHANISM->length
&& memcmp(p, GSS_KRB5_MECHANISM->elements, mech_len) == 0)
ret = gsskrb5_accept_sec_context(minor_status,
context_handle,
acceptor_cred_handle,
input_token_buffer,
input_chan_bindings,
src_name,
mech_type,
output_token,
ret_flags,
time_rec,
delegated_cred_handle);
else if (mech_len == GSS_SPNEGO_MECHANISM->length
&& memcmp(p, GSS_SPNEGO_MECHANISM->elements, mech_len) == 0)
ret = spnego_accept_sec_context(minor_status,
context_handle,
acceptor_cred_handle,
input_token_buffer,
input_chan_bindings,
src_name,
mech_type,
output_token,
ret_flags,
time_rec,
delegated_cred_handle);
else
return GSS_S_BAD_MECH;
return ret;
}

View File

@@ -1,378 +0,0 @@
/*
* Copyright (c) 1997 - 2005 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"
RCSID("$Id$");
OM_uint32
_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
krb5_ccache id,
krb5_principal principal,
OM_uint32 *lifetime)
{
krb5_creds in_cred, *out_cred;
krb5_const_realm realm;
krb5_error_code kret;
memset(&in_cred, 0, sizeof(in_cred));
in_cred.client = principal;
realm = krb5_principal_get_realm(gssapi_krb5_context, principal);
if (realm == NULL) {
gssapi_krb5_clear_status ();
*minor_status = KRB5_PRINC_NOMATCH; /* XXX */
return GSS_S_FAILURE;
}
kret = krb5_make_principal(gssapi_krb5_context, &in_cred.server,
realm, KRB5_TGS_NAME, realm, NULL);
if (kret) {
gssapi_krb5_set_error_string();
*minor_status = kret;
return GSS_S_FAILURE;
}
kret = krb5_get_credentials(gssapi_krb5_context, 0,
id, &in_cred, &out_cred);
krb5_free_principal(gssapi_krb5_context, in_cred.server);
if (kret) {
gssapi_krb5_set_error_string();
*minor_status = kret;
return GSS_S_FAILURE;
}
*lifetime = out_cred->times.endtime;
krb5_free_creds(gssapi_krb5_context, out_cred);
return GSS_S_COMPLETE;
}
static krb5_error_code
get_keytab(krb5_keytab *keytab)
{
char kt_name[256];
krb5_error_code kret;
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
if (gssapi_krb5_keytab != NULL) {
kret = krb5_kt_get_name(gssapi_krb5_context,
gssapi_krb5_keytab,
kt_name, sizeof(kt_name));
if (kret == 0)
kret = krb5_kt_resolve(gssapi_krb5_context, kt_name, keytab);
} else
kret = krb5_kt_default(gssapi_krb5_context, keytab);
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
return (kret);
}
static OM_uint32 acquire_initiator_cred
(OM_uint32 * minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec
)
{
OM_uint32 ret;
krb5_creds cred;
krb5_principal def_princ;
krb5_get_init_creds_opt *opt;
krb5_ccache ccache;
krb5_keytab keytab;
krb5_error_code kret;
keytab = NULL;
ccache = NULL;
def_princ = NULL;
ret = GSS_S_FAILURE;
memset(&cred, 0, sizeof(cred));
/* If we have a preferred principal, lets try to find it in all
* caches, otherwise, fall back to default cache. Ignore
* errors. */
if (handle->principal)
kret = krb5_cc_cache_match (gssapi_krb5_context,
handle->principal,
NULL,
&ccache);
if (ccache == NULL) {
kret = krb5_cc_default(gssapi_krb5_context, &ccache);
if (kret)
goto end;
}
kret = krb5_cc_get_principal(gssapi_krb5_context, ccache,
&def_princ);
if (kret != 0) {
/* we'll try to use a keytab below */
krb5_cc_destroy(gssapi_krb5_context, ccache);
ccache = NULL;
kret = 0;
} else if (handle->principal == NULL) {
kret = krb5_copy_principal(gssapi_krb5_context, def_princ,
&handle->principal);
if (kret)
goto end;
} else if (handle->principal != NULL &&
krb5_principal_compare(gssapi_krb5_context, handle->principal,
def_princ) == FALSE) {
/* Before failing, lets check the keytab */
krb5_free_principal(gssapi_krb5_context, def_princ);
def_princ = NULL;
}
if (def_princ == NULL) {
/* We have no existing credentials cache,
* so attempt to get a TGT using a keytab.
*/
if (handle->principal == NULL) {
kret = krb5_get_default_principal(gssapi_krb5_context,
&handle->principal);
if (kret)
goto end;
}
kret = get_keytab(&keytab);
if (kret)
goto end;
kret = krb5_get_init_creds_opt_alloc(gssapi_krb5_context, &opt);
if (kret)
goto end;
kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred,
handle->principal, keytab, 0, NULL, opt);
krb5_get_init_creds_opt_free(opt);
if (kret)
goto end;
kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops,
&ccache);
if (kret)
goto end;
kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client);
if (kret)
goto end;
kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred);
if (kret)
goto end;
handle->lifetime = cred.times.endtime;
handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
} else {
ret = _gssapi_krb5_ccache_lifetime(minor_status,
ccache,
handle->principal,
&handle->lifetime);
if (ret != GSS_S_COMPLETE)
goto end;
kret = 0;
}
handle->ccache = ccache;
ret = GSS_S_COMPLETE;
end:
if (cred.client != NULL)
krb5_free_cred_contents(gssapi_krb5_context, &cred);
if (def_princ != NULL)
krb5_free_principal(gssapi_krb5_context, def_princ);
if (keytab != NULL)
krb5_kt_close(gssapi_krb5_context, keytab);
if (ret != GSS_S_COMPLETE) {
if (ccache != NULL)
krb5_cc_close(gssapi_krb5_context, ccache);
if (kret != 0) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
}
}
return (ret);
}
static OM_uint32 acquire_acceptor_cred
(OM_uint32 * minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec
)
{
OM_uint32 ret;
krb5_error_code kret;
kret = 0;
ret = GSS_S_FAILURE;
kret = get_keytab(&handle->keytab);
if (kret)
goto end;
/* check that the requested principal exists in the keytab */
if (handle->principal) {
krb5_keytab_entry entry;
kret = krb5_kt_get_entry(gssapi_krb5_context, handle->keytab,
handle->principal, 0, 0, &entry);
if (kret)
goto end;
krb5_kt_free_entry(gssapi_krb5_context, &entry);
}
ret = GSS_S_COMPLETE;
end:
if (ret != GSS_S_COMPLETE) {
if (handle->keytab != NULL)
krb5_kt_close(gssapi_krb5_context, handle->keytab);
if (kret != 0) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
}
}
return (ret);
}
OM_uint32 gss_acquire_cred
(OM_uint32 * minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t * output_cred_handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec
)
{
gss_cred_id_t handle;
OM_uint32 ret;
if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
*minor_status = GSS_KRB5_S_G_BAD_USAGE;
return GSS_S_FAILURE;
}
GSSAPI_KRB5_INIT ();
*output_cred_handle = NULL;
if (time_rec)
*time_rec = 0;
if (actual_mechs)
*actual_mechs = GSS_C_NO_OID_SET;
if (desired_mechs) {
int present = 0;
ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
desired_mechs, &present);
if (ret)
return ret;
if (!present) {
*minor_status = 0;
return GSS_S_BAD_MECH;
}
}
handle = (gss_cred_id_t)malloc(sizeof(*handle));
if (handle == GSS_C_NO_CREDENTIAL) {
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
memset(handle, 0, sizeof (*handle));
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
if (desired_name != GSS_C_NO_NAME) {
ret = gss_duplicate_name(minor_status, desired_name,
&handle->principal);
if (ret != GSS_S_COMPLETE) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
free(handle);
return (ret);
}
}
if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
ret = acquire_initiator_cred(minor_status, desired_name, time_req,
desired_mechs, cred_usage, handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
krb5_free_principal(gssapi_krb5_context, handle->principal);
free(handle);
return (ret);
}
}
if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
ret = acquire_acceptor_cred(minor_status, desired_name, time_req,
desired_mechs, cred_usage, handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
krb5_free_principal(gssapi_krb5_context, handle->principal);
free(handle);
return (ret);
}
}
ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
&handle->mechanisms);
if (ret == GSS_S_COMPLETE)
ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL,
actual_mechs);
if (ret != GSS_S_COMPLETE) {
if (handle->mechanisms != NULL)
gss_release_oid_set(NULL, &handle->mechanisms);
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
krb5_free_principal(gssapi_krb5_context, handle->principal);
free(handle);
return (ret);
}
*minor_status = 0;
if (time_rec) {
ret = gssapi_lifetime_left(minor_status,
handle->lifetime,
time_rec);
if (ret)
return ret;
}
handle->usage = cred_usage;
*output_cred_handle = handle;
return (GSS_S_COMPLETE);
}

View File

@@ -1,250 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
OM_uint32 gss_add_cred (
OM_uint32 *minor_status,
const gss_cred_id_t input_cred_handle,
const gss_name_t desired_name,
const gss_OID desired_mech,
gss_cred_usage_t cred_usage,
OM_uint32 initiator_time_req,
OM_uint32 acceptor_time_req,
gss_cred_id_t *output_cred_handle,
gss_OID_set *actual_mechs,
OM_uint32 *initiator_time_rec,
OM_uint32 *acceptor_time_rec)
{
OM_uint32 ret, lifetime;
gss_cred_id_t cred, handle;
handle = NULL;
cred = input_cred_handle;
if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {
*minor_status = 0;
return GSS_S_BAD_MECH;
}
if (cred == GSS_C_NO_CREDENTIAL && output_cred_handle == NULL) {
*minor_status = 0;
return GSS_S_NO_CRED;
}
if (cred == GSS_C_NO_CREDENTIAL) { /* XXX standard conformance failure */
*minor_status = 0;
return GSS_S_NO_CRED;
}
/* check if requested output usage is compatible with output usage */
if (output_cred_handle != NULL) {
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = GSS_KRB5_S_G_BAD_USAGE;
return(GSS_S_FAILURE);
}
}
/* check that we have the same name */
if (desired_name != GSS_C_NO_NAME &&
krb5_principal_compare(gssapi_krb5_context, desired_name,
cred->principal) != FALSE) {
if (output_cred_handle)
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = 0;
return GSS_S_BAD_NAME;
}
/* make a copy */
if (output_cred_handle) {
handle = (gss_cred_id_t)malloc(sizeof(*handle));
if (handle == GSS_C_NO_CREDENTIAL) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
memset(handle, 0, sizeof (*handle));
handle->usage = cred_usage;
handle->lifetime = cred->lifetime;
handle->principal = NULL;
handle->keytab = NULL;
handle->ccache = NULL;
handle->mechanisms = NULL;
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
ret = GSS_S_FAILURE;
ret = gss_duplicate_name(minor_status, cred->principal,
&handle->principal);
if (ret) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
free(handle);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
if (cred->keytab) {
krb5_error_code kret;
char name[KRB5_KT_PREFIX_MAX_LEN + MAXPATHLEN];
int len;
ret = GSS_S_FAILURE;
kret = krb5_kt_get_type(gssapi_krb5_context, cred->keytab,
name, KRB5_KT_PREFIX_MAX_LEN);
if (kret) {
*minor_status = kret;
goto failure;
}
len = strlen(name);
name[len++] = ':';
kret = krb5_kt_get_name(gssapi_krb5_context, cred->keytab,
name + len,
sizeof(name) - len);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_kt_resolve(gssapi_krb5_context, name,
&handle->keytab);
if (kret){
*minor_status = kret;
goto failure;
}
}
if (cred->ccache) {
krb5_error_code kret;
const char *type, *name;
char *type_name;
ret = GSS_S_FAILURE;
type = krb5_cc_get_type(gssapi_krb5_context, cred->ccache);
if (type == NULL){
*minor_status = ENOMEM;
goto failure;
}
if (strcmp(type, "MEMORY") == 0) {
ret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops,
&handle->ccache);
if (ret) {
*minor_status = ret;
goto failure;
}
ret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache,
handle->ccache);
if (ret) {
*minor_status = ret;
goto failure;
}
} else {
name = krb5_cc_get_name(gssapi_krb5_context, cred->ccache);
if (name == NULL) {
*minor_status = ENOMEM;
goto failure;
}
asprintf(&type_name, "%s:%s", type, name);
if (type_name == NULL) {
*minor_status = ENOMEM;
goto failure;
}
kret = krb5_cc_resolve(gssapi_krb5_context, type_name,
&handle->ccache);
free(type_name);
if (kret) {
*minor_status = kret;
goto failure;
}
}
}
ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret)
goto failure;
ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
&handle->mechanisms);
if (ret)
goto failure;
}
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
ret = gss_inquire_cred(minor_status, cred, NULL, &lifetime,
NULL, actual_mechs);
if (ret)
goto failure;
if (initiator_time_rec)
*initiator_time_rec = lifetime;
if (acceptor_time_rec)
*acceptor_time_rec = lifetime;
if (output_cred_handle) {
*output_cred_handle = handle;
}
*minor_status = 0;
return ret;
failure:
if (handle) {
if (handle->principal)
gss_release_name(NULL, &handle->principal);
if (handle->keytab)
krb5_kt_close(gssapi_krb5_context, handle->keytab);
if (handle->ccache)
krb5_cc_destroy(gssapi_krb5_context, handle->ccache);
if (handle->mechanisms)
gss_release_oid_set(NULL, &handle->mechanisms);
free(handle);
}
if (output_cred_handle)
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
return ret;
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (c) 1997 - 2001, 2003 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"
RCSID("$Id$");
OM_uint32 gss_add_oid_set_member (
OM_uint32 * minor_status,
const gss_OID member_oid,
gss_OID_set * oid_set
)
{
gss_OID tmp;
size_t n;
OM_uint32 res;
int present;
res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present);
if (res != GSS_S_COMPLETE)
return res;
if (present) {
*minor_status = 0;
return GSS_S_COMPLETE;
}
n = (*oid_set)->count + 1;
tmp = realloc ((*oid_set)->elements, n * sizeof(gss_OID_desc));
if (tmp == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
(*oid_set)->elements = tmp;
(*oid_set)->count = n;
(*oid_set)->elements[n-1] = *member_oid;
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2000 - 2001 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"
#include <roken.h>
krb5_error_code
gss_address_to_krb5addr(OM_uint32 gss_addr_type,
gss_buffer_desc *gss_addr,
int16_t port,
krb5_address *address)
{
int addr_type;
struct sockaddr sa;
krb5_socklen_t sa_size = 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 (gssapi_krb5_context,
addr_type,
gss_addr->value,
&sa,
&sa_size,
port);
if (problem)
return GSS_S_FAILURE;
problem = krb5_sockaddr2address (gssapi_krb5_context, &sa, address);
return problem;
}

View File

@@ -1,636 +0,0 @@
/*
* Copyright (c) 2003 - 2005 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"
RCSID("$Id$");
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
*
* The arcfour message have the following formats:
*
* MIC token
* TOK_ID[2] = 01 01
* SGN_ALG[2] = 11 00
* Filler[4]
* SND_SEQ[8]
* SGN_CKSUM[8]
*
* WRAP token
* TOK_ID[2] = 02 01
* SGN_ALG[2];
* SEAL_ALG[2]
* Filler[2]
* SND_SEQ[2]
* SGN_CKSUM[8]
* Confounder[8]
*/
static krb5_error_code
arcfour_mic_key(krb5_context context, krb5_keyblock *key,
void *cksum_data, size_t cksum_size,
void *key6_data, size_t key6_size)
{
krb5_error_code ret;
Checksum cksum_k5;
krb5_keyblock key5;
char k5_data[16];
Checksum cksum_k6;
char T[4];
memset(T, 0, 4);
cksum_k5.checksum.data = k5_data;
cksum_k5.checksum.length = sizeof(k5_data);
if (key->keytype == KEYTYPE_ARCFOUR_56) {
char L40[14] = "fortybits";
memcpy(L40 + 10, T, sizeof(T));
ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,
L40, 14, 0, key, &cksum_k5);
memset(&k5_data[7], 0xAB, 9);
} else {
ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,
T, 4, 0, key, &cksum_k5);
}
if (ret)
return ret;
key5.keytype = KEYTYPE_ARCFOUR;
key5.keyvalue = cksum_k5.checksum;
cksum_k6.checksum.data = key6_data;
cksum_k6.checksum.length = key6_size;
return krb5_hmac(context, CKSUMTYPE_RSA_MD5,
cksum_data, cksum_size, 0, &key5, &cksum_k6);
}
static krb5_error_code
arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
u_char *sgn_cksum, size_t sgn_cksum_sz,
const u_char *v1, size_t l1,
const void *v2, size_t l2,
const void *v3, size_t l3)
{
Checksum CKSUM;
u_char *ptr;
size_t len;
krb5_crypto crypto;
krb5_error_code ret;
assert(sgn_cksum_sz == 8);
len = l1 + l2 + l3;
ptr = malloc(len);
if (ptr == NULL)
return ENOMEM;
memcpy(ptr, v1, l1);
memcpy(ptr + l1, v2, l2);
memcpy(ptr + l1 + l2, v3, l3);
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret) {
free(ptr);
return ret;
}
ret = krb5_create_checksum(gssapi_krb5_context,
crypto,
usage,
0,
ptr, len,
&CKSUM);
free(ptr);
if (ret == 0) {
memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);
free_Checksum(&CKSUM);
}
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return ret;
}
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key)
{
krb5_error_code ret;
int32_t seq_number;
size_t len, total_len;
u_char k6_data[16], *p0, *p;
RC4_KEY rc4_key;
gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
if (message_token->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p0 = _gssapi_make_mech_header(message_token->value,
len,
GSS_KRB5_MECHANISM);
p = p0;
*p++ = 0x01; /* TOK_ID */
*p++ = 0x01;
*p++ = 0x11; /* SGN_ALG */
*p++ = 0x00;
*p++ = 0xff; /* Filler */
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
p = NULL;
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SIGN,
p0 + 16, 8, /* SGN_CKSUM */
p0, 8, /* TOK_ID, SGN_ALG, Filer */
message_buffer->value, message_buffer->length,
NULL, 0);
if (ret) {
gss_release_buffer(minor_status, message_token);
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = arcfour_mic_key(gssapi_krb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
gss_release_buffer(minor_status, message_token);
*minor_status = ret;
return GSS_S_FAILURE;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
p = p0 + 8; /* SND_SEQ */
gssapi_encode_be_om_uint32(seq_number, p);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p, p);
memset(&rc4_key, 0, sizeof(rc4_key));
memset(k6_data, 0, sizeof(k6_data));
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32
_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
krb5_keyblock *key,
char *type)
{
krb5_error_code ret;
uint32_t seq_number;
OM_uint32 omret;
u_char SND_SEQ[8], cksum_data[8], *p;
char k6_data[16];
int cmp;
if (qop_state)
*qop_state = 0;
p = token_buffer->value;
omret = gssapi_krb5_verify_header (&p,
token_buffer->length,
(u_char *)type,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
return GSS_S_BAD_MIC;
p += 4;
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SIGN,
cksum_data, sizeof(cksum_data),
p - 8, 8,
message_buffer->value, message_buffer->length,
NULL, 0);
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = arcfour_mic_key(gssapi_krb5_context, key,
cksum_data, sizeof(cksum_data),
k6_data, sizeof(k6_data));
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
cmp = memcmp(cksum_data, p + 8, 8);
if (cmp) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
{
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), (void*)k6_data);
RC4 (&rc4_key, 8, p, SND_SEQ);
memset(&rc4_key, 0, sizeof(rc4_key));
memset(k6_data, 0, sizeof(k6_data));
}
gssapi_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
memset(SND_SEQ, 0, sizeof(SND_SEQ));
if (cmp != 0) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
omret = _gssapi_msg_order_check(context_handle->order, seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (omret)
return omret;
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32
_gssapi_wrap_arcfour(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key)
{
u_char Klocaldata[16], k6_data[16], *p, *p0;
size_t len, total_len, datalen;
krb5_keyblock Klocal;
krb5_error_code ret;
int32_t seq_number;
if (conf_state)
*conf_state = 0;
datalen = input_message_buffer->length + 1 /* padding */;
len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
output_message_buffer->length = total_len;
output_message_buffer->value = malloc (total_len);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p0 = _gssapi_make_mech_header(output_message_buffer->value,
len,
GSS_KRB5_MECHANISM);
p = p0;
*p++ = 0x02; /* TOK_ID */
*p++ = 0x01;
*p++ = 0x11; /* SGN_ALG */
*p++ = 0x00;
if (conf_req_flag) {
*p++ = 0x10; /* SEAL_ALG */
*p++ = 0x00;
} else {
*p++ = 0xff; /* SEAL_ALG */
*p++ = 0xff;
}
*p++ = 0xff; /* Filler */
*p++ = 0xff;
p = NULL;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
gssapi_encode_be_om_uint32(seq_number, p0 + 8);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
memset (p0 + 8 + 4,
(context_handle->more_flags & LOCAL) ? 0 : 0xff,
4);
krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */
/* p points to data */
p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
memcpy(p, input_message_buffer->value, input_message_buffer->length);
p[input_message_buffer->length] = 1; /* PADDING */
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL,
p0 + 16, 8, /* SGN_CKSUM */
p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
p0 + 24, 8, /* Confounder */
p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
datalen);
if (ret) {
*minor_status = ret;
gss_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
{
int i;
Klocal.keytype = key->keytype;
Klocal.keyvalue.data = Klocaldata;
Klocal.keyvalue.length = sizeof(Klocaldata);
for (i = 0; i < 16; i++)
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
}
ret = arcfour_mic_key(gssapi_krb5_context, &Klocal,
p0 + 8, 4, /* SND_SEQ */
k6_data, sizeof(k6_data));
memset(Klocaldata, 0, sizeof(Klocaldata));
if (ret) {
gss_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
if(conf_req_flag) {
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), (void *)k6_data);
/* XXX ? */
RC4 (&rc4_key, 8 + datalen, p0 + 24, p0 + 24); /* Confounder + data */
memset(&rc4_key, 0, sizeof(rc4_key));
}
memset(k6_data, 0, sizeof(k6_data));
ret = arcfour_mic_key(gssapi_krb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
gss_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
{
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 8, p0 + 8); /* SND_SEQ */
memset(&rc4_key, 0, sizeof(rc4_key));
memset(k6_data, 0, sizeof(k6_data));
}
if (conf_state)
*conf_state = conf_req_flag;
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key)
{
u_char Klocaldata[16];
krb5_keyblock Klocal;
krb5_error_code ret;
uint32_t seq_number;
size_t datalen;
OM_uint32 omret;
u_char k6_data[16], SND_SEQ[8], Confounder[8];
u_char cksum_data[8];
u_char *p, *p0;
int cmp;
int conf_flag;
size_t padlen;
if (conf_state)
*conf_state = 0;
if (qop_state)
*qop_state = 0;
p0 = input_message_buffer->value;
omret = _gssapi_verify_mech_header(&p0,
input_message_buffer->length,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
p = p0;
datalen = input_message_buffer->length -
(p - ((u_char *)input_message_buffer->value)) -
GSS_ARCFOUR_WRAP_TOKEN_SIZE;
if (memcmp(p, "\x02\x01", 2) != 0)
return GSS_S_BAD_SIG;
p += 2;
if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\x10\x00", 2) == 0)
conf_flag = 1;
else if (memcmp (p, "\xff\xff", 2) == 0)
conf_flag = 0;
else
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_BAD_MIC;
p = NULL;
ret = arcfour_mic_key(gssapi_krb5_context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
{
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 8, SND_SEQ); /* SND_SEQ */
memset(&rc4_key, 0, sizeof(rc4_key));
memset(k6_data, 0, sizeof(k6_data));
}
gssapi_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
{
int i;
Klocal.keytype = key->keytype;
Klocal.keyvalue.data = Klocaldata;
Klocal.keyvalue.length = sizeof(Klocaldata);
for (i = 0; i < 16; i++)
Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
}
ret = arcfour_mic_key(gssapi_krb5_context, &Klocal,
SND_SEQ, 4,
k6_data, sizeof(k6_data));
memset(Klocaldata, 0, sizeof(Klocaldata));
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
output_message_buffer->value = malloc(datalen);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
output_message_buffer->length = datalen;
if(conf_flag) {
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 24, Confounder); /* Confounder */
RC4 (&rc4_key, datalen, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
output_message_buffer->value);
memset(&rc4_key, 0, sizeof(rc4_key));
} else {
memcpy(Confounder, p0 + 24, 8); /* Confounder */
memcpy(output_message_buffer->value,
p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
datalen);
}
memset(k6_data, 0, sizeof(k6_data));
ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
if (ret) {
gss_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;
return ret;
}
output_message_buffer->length -= padlen;
ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL,
cksum_data, sizeof(cksum_data),
p0, 8,
Confounder, sizeof(Confounder),
output_message_buffer->value,
output_message_buffer->length + padlen);
if (ret) {
gss_release_buffer(minor_status, output_message_buffer);
*minor_status = ret;
return GSS_S_FAILURE;
}
cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
if (cmp) {
gss_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;
return GSS_S_BAD_MIC;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
omret = _gssapi_msg_order_check(context_handle->order, seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (omret)
return omret;
if (conf_state)
*conf_state = conf_flag;
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 2003 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.
*/
/* $Id$ */
#ifndef GSSAPI_ARCFOUR_H_
#define GSSAPI_ARCFOUR_H_ 1
#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
OM_uint32 _gssapi_wrap_arcfour(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key);
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key);
OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key);
OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t *qop_state,
krb5_keyblock *key,
char *type);
#endif /* GSSAPI_ARCFOUR_H_ */

View File

@@ -1,46 +0,0 @@
/*
* Copyright (c) 1997 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"
RCSID("$Id$");
OM_uint32 gss_canonicalize_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
const gss_OID mech_type,
gss_name_t * output_name
)
{
return gss_duplicate_name (minor_status, input_name, output_name);
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (c) 2004 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"
RCSID("$Id$");
char *last_out_name;
OM_uint32
gss_krb5_ccache_name(OM_uint32 *minor_status,
const char *name,
const char **out_name)
{
krb5_error_code kret;
*minor_status = 0;
GSSAPI_KRB5_INIT();
if (out_name) {
const char *n;
if (last_out_name) {
free(last_out_name);
last_out_name = NULL;
}
n = krb5_cc_default_name(gssapi_krb5_context);
if (n == NULL) {
*minor_status = ENOMEM;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
last_out_name = strdup(n);
if (last_out_name == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*out_name = last_out_name;
}
kret = krb5_cc_set_default_name(gssapi_krb5_context, name);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
return GSS_S_COMPLETE;
}

View File

@@ -1,840 +0,0 @@
/*
* Copyright (c) 2003, PADL Software Pty Ltd.
* 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 PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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"
RCSID("$Id$");
/*
* Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
*/
#define CFXSentByAcceptor (1 << 0)
#define CFXSealed (1 << 1)
#define CFXAcceptorSubkey (1 << 2)
static krb5_error_code
wrap_length_cfx(krb5_crypto crypto,
int conf_req_flag,
size_t input_length,
size_t *output_length,
size_t *cksumsize,
uint16_t *padlength)
{
krb5_error_code ret;
krb5_cksumtype type;
/* 16-byte header is always first */
*output_length = sizeof(gss_cfx_wrap_token_desc);
*padlength = 0;
ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto, &type);
if (ret) {
return ret;
}
ret = krb5_checksumsize(gssapi_krb5_context, type, cksumsize);
if (ret) {
return ret;
}
if (conf_req_flag) {
size_t padsize;
/* Header is concatenated with data before encryption */
input_length += sizeof(gss_cfx_wrap_token_desc);
ret = krb5_crypto_getpadsize(gssapi_krb5_context, crypto, &padsize);
if (ret) {
return ret;
}
if (padsize > 1) {
/* XXX check this */
*padlength = padsize - (input_length % padsize);
}
/* We add the pad ourselves (noted here for completeness only) */
input_length += *padlength;
*output_length += krb5_get_wrapped_length(gssapi_krb5_context,
crypto, input_length);
} else {
/* Checksum is concatenated with data */
*output_length += input_length + *cksumsize;
}
assert(*output_length > input_length);
return 0;
}
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
OM_uint32 req_output_size,
OM_uint32 *max_input_size,
krb5_keyblock *key)
{
krb5_error_code ret;
krb5_crypto crypto;
uint16_t padlength;
size_t output_length, cksumsize;
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = wrap_length_cfx(crypto, conf_req_flag,
req_output_size,
&output_length, &cksumsize, &padlength);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
if (output_length < req_output_size) {
*max_input_size = (req_output_size - output_length);
*max_input_size -= padlength;
} else {
/* Should this return an error? */
*max_input_size = 0;
}
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_COMPLETE;
}
/*
* Rotate "rrc" bytes to the front or back
*/
static krb5_error_code
rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
{
u_char *tmp, buf[256];
size_t left;
if (len == 0)
return 0;
rrc %= len;
if (rrc == 0)
return 0;
left = len - rrc;
if (rrc <= sizeof(buf)) {
tmp = buf;
} else {
tmp = malloc(rrc);
if (tmp == NULL)
return ENOMEM;
}
if (unrotate) {
memcpy(tmp, data, rrc);
memmove(data, (u_char *)data + rrc, left);
memcpy((u_char *)data + left, tmp, rrc);
} else {
memcpy(tmp, (u_char *)data + left, rrc);
memmove((u_char *)data + rrc, data, left);
memcpy(data, tmp, rrc);
}
if (rrc > sizeof(buf))
free(tmp);
return 0;
}
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key)
{
krb5_crypto crypto;
gss_cfx_wrap_token token;
krb5_error_code ret;
unsigned usage;
krb5_data cipher;
size_t wrapped_len, cksumsize;
uint16_t padlength, rrc = 0;
int32_t seq_number;
u_char *p;
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = wrap_length_cfx(crypto, conf_req_flag,
input_message_buffer->length,
&wrapped_len, &cksumsize, &padlength);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
/* Always rotate encrypted token (if any) and checksum to header */
rrc = (conf_req_flag ? sizeof(*token) : 0) + (uint16_t)cksumsize;
output_message_buffer->length = wrapped_len;
output_message_buffer->value = malloc(output_message_buffer->length);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
p = output_message_buffer->value;
token = (gss_cfx_wrap_token)p;
token->TOK_ID[0] = 0x05;
token->TOK_ID[1] = 0x04;
token->Flags = 0;
token->Filler = 0xFF;
if ((context_handle->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
if (context_handle->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
if (conf_req_flag) {
/*
* In Wrap tokens with confidentiality, the EC field is
* used to encode the size (in bytes) of the random filler.
*/
token->Flags |= CFXSealed;
token->EC[0] = (padlength >> 8) & 0xFF;
token->EC[1] = (padlength >> 0) & 0xFF;
} else {
/*
* In Wrap tokens without confidentiality, the EC field is
* used to encode the size (in bytes) of the trailing
* checksum.
*
* This is not used in the checksum calcuation itself,
* because the checksum length could potentially vary
* depending on the data length.
*/
token->EC[0] = 0;
token->EC[1] = 0;
}
/*
* In Wrap tokens that provide for confidentiality, the RRC
* field in the header contains the hex value 00 00 before
* encryption.
*
* In Wrap tokens that do not provide for confidentiality,
* both the EC and RRC fields in the appended checksum
* contain the hex value 00 00 for the purpose of calculating
* the checksum.
*/
token->RRC[0] = 0;
token->RRC[1] = 0;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]);
gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/*
* If confidentiality is requested, the token header is
* appended to the plaintext before encryption; the resulting
* token is {"header" | encrypt(plaintext | pad | "header")}.
*
* If no confidentiality is requested, the checksum is
* calculated over the plaintext concatenated with the
* token header.
*/
if (context_handle->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
}
if (conf_req_flag) {
/*
* Any necessary padding is added here to ensure that the
* encrypted token header is always at the end of the
* ciphertext.
*
* The specification does not require that the padding
* bytes are initialized.
*/
p += sizeof(*token);
memcpy(p, input_message_buffer->value, input_message_buffer->length);
memset(p + input_message_buffer->length, 0xFF, padlength);
memcpy(p + input_message_buffer->length + padlength,
token, sizeof(*token));
ret = krb5_encrypt(gssapi_krb5_context, crypto,
usage, p,
input_message_buffer->length + padlength +
sizeof(*token),
&cipher);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
assert(sizeof(*token) + cipher.length == wrapped_len);
token->RRC[0] = (rrc >> 8) & 0xFF;
token->RRC[1] = (rrc >> 0) & 0xFF;
ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(p, cipher.data, cipher.length);
krb5_data_free(&cipher);
} else {
char *buf;
Checksum cksum;
buf = malloc(input_message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(buf, input_message_buffer->value, input_message_buffer->length);
memcpy(buf + input_message_buffer->length, token, sizeof(*token));
ret = krb5_create_checksum(gssapi_krb5_context, crypto,
usage, 0, buf,
input_message_buffer->length +
sizeof(*token),
&cksum);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
free(buf);
return GSS_S_FAILURE;
}
free(buf);
assert(cksum.checksum.length == cksumsize);
token->EC[0] = (cksum.checksum.length >> 8) & 0xFF;
token->EC[1] = (cksum.checksum.length >> 0) & 0xFF;
token->RRC[0] = (rrc >> 8) & 0xFF;
token->RRC[1] = (rrc >> 0) & 0xFF;
p += sizeof(*token);
memcpy(p, input_message_buffer->value, input_message_buffer->length);
memcpy(p + input_message_buffer->length,
cksum.checksum.data, cksum.checksum.length);
ret = rrc_rotate(p,
input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
free_Checksum(&cksum);
return GSS_S_FAILURE;
}
free_Checksum(&cksum);
}
krb5_crypto_destroy(gssapi_krb5_context, crypto);
if (conf_state != NULL) {
*conf_state = conf_req_flag;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key)
{
krb5_crypto crypto;
gss_cfx_wrap_token token;
u_char token_flags;
krb5_error_code ret;
unsigned usage;
krb5_data data;
uint16_t ec, rrc;
OM_uint32 seq_number_lo, seq_number_hi;
size_t len;
u_char *p;
*minor_status = 0;
if (input_message_buffer->length < sizeof(*token)) {
return GSS_S_DEFECTIVE_TOKEN;
}
p = input_message_buffer->value;
token = (gss_cfx_wrap_token)p;
if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04) {
return GSS_S_DEFECTIVE_TOKEN;
}
/* Ignore unknown flags */
token_flags = token->Flags &
(CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
if ((context_handle->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
if (token_flags & CFXAcceptorSubkey)
return GSS_S_DEFECTIVE_TOKEN;
}
if (token->Filler != 0xFF) {
return GSS_S_DEFECTIVE_TOKEN;
}
if (conf_state != NULL) {
*conf_state = (token_flags & CFXSealed) ? 1 : 0;
}
ec = (token->EC[0] << 8) | token->EC[1];
rrc = (token->RRC[0] << 8) | token->RRC[1];
/*
* Check sequence number
*/
gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
if (seq_number_hi) {
/* no support for 64-bit sequence numbers */
*minor_status = ERANGE;
return GSS_S_UNSEQ_TOKEN;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
gss_release_buffer(minor_status, output_message_buffer);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/*
* Decrypt and/or verify checksum
*/
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
if (context_handle->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
}
p += sizeof(*token);
len = input_message_buffer->length;
len -= (p - (u_char *)input_message_buffer->value);
/* Rotate by RRC; bogus to do this in-place XXX */
*minor_status = rrc_rotate(p, len, rrc, TRUE);
if (*minor_status != 0) {
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
if (token_flags & CFXSealed) {
ret = krb5_decrypt(gssapi_krb5_context, crypto, usage,
p, len, &data);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_BAD_MIC;
}
/* Check that there is room for the pad and token header */
if (data.length < ec + sizeof(*token)) {
krb5_crypto_destroy(gssapi_krb5_context, crypto);
krb5_data_free(&data);
return GSS_S_DEFECTIVE_TOKEN;
}
p = data.data;
p += data.length - sizeof(*token);
/* RRC is unprotected; don't modify input buffer */
((gss_cfx_wrap_token)p)->RRC[0] = token->RRC[0];
((gss_cfx_wrap_token)p)->RRC[1] = token->RRC[1];
/* Check the integrity of the header */
if (memcmp(p, token, sizeof(*token)) != 0) {
krb5_crypto_destroy(gssapi_krb5_context, crypto);
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
output_message_buffer->value = data.data;
output_message_buffer->length = data.length - ec - sizeof(*token);
} else {
Checksum cksum;
/* Determine checksum type */
ret = krb5_crypto_get_checksum_type(gssapi_krb5_context,
crypto, &cksum.cksumtype);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
cksum.checksum.length = ec;
/* Check we have at least as much data as the checksum */
if (len < cksum.checksum.length) {
*minor_status = ERANGE;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_BAD_MIC;
}
/* Length now is of the plaintext only, no checksum */
len -= cksum.checksum.length;
cksum.checksum.data = p + len;
output_message_buffer->length = len; /* for later */
output_message_buffer->value = malloc(len + sizeof(*token));
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
/* Checksum is over (plaintext-data | "header") */
memcpy(output_message_buffer->value, p, len);
memcpy((u_char *)output_message_buffer->value + len,
token, sizeof(*token));
/* EC is not included in checksum calculation */
token = (gss_cfx_wrap_token)((u_char *)output_message_buffer->value +
len);
token->EC[0] = 0;
token->EC[1] = 0;
token->RRC[0] = 0;
token->RRC[1] = 0;
ret = krb5_verify_checksum(gssapi_krb5_context, crypto,
usage,
output_message_buffer->value,
len + sizeof(*token),
&cksum);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
gss_release_buffer(minor_status, output_message_buffer);
return GSS_S_BAD_MIC;
}
}
krb5_crypto_destroy(gssapi_krb5_context, crypto);
if (qop_state != NULL) {
*qop_state = GSS_C_QOP_DEFAULT;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key)
{
krb5_crypto crypto;
gss_cfx_mic_token token;
krb5_error_code ret;
unsigned usage;
Checksum cksum;
u_char *buf;
size_t len;
int32_t seq_number;
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
len = message_buffer->length + sizeof(*token);
buf = malloc(len);
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
memcpy(buf, message_buffer->value, message_buffer->length);
token = (gss_cfx_mic_token)(buf + message_buffer->length);
token->TOK_ID[0] = 0x04;
token->TOK_ID[1] = 0x04;
token->Flags = 0;
if ((context_handle->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
if (context_handle->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
memset(token->Filler, 0xFF, 5);
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]);
gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (context_handle->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
}
ret = krb5_create_checksum(gssapi_krb5_context, crypto,
usage, 0, buf, len, &cksum);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
free(buf);
return GSS_S_FAILURE;
}
krb5_crypto_destroy(gssapi_krb5_context, crypto);
/* Determine MIC length */
message_token->length = sizeof(*token) + cksum.checksum.length;
message_token->value = malloc(message_token->length);
if (message_token->value == NULL) {
*minor_status = ENOMEM;
free_Checksum(&cksum);
free(buf);
return GSS_S_FAILURE;
}
/* Token is { "header" | get_mic("header" | plaintext-data) } */
memcpy(message_token->value, token, sizeof(*token));
memcpy((u_char *)message_token->value + sizeof(*token),
cksum.checksum.data, cksum.checksum.length);
free_Checksum(&cksum);
free(buf);
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t *qop_state,
krb5_keyblock *key)
{
krb5_crypto crypto;
gss_cfx_mic_token token;
u_char token_flags;
krb5_error_code ret;
unsigned usage;
OM_uint32 seq_number_lo, seq_number_hi;
u_char *buf, *p;
Checksum cksum;
*minor_status = 0;
if (token_buffer->length < sizeof(*token)) {
return GSS_S_DEFECTIVE_TOKEN;
}
p = token_buffer->value;
token = (gss_cfx_mic_token)p;
if (token->TOK_ID[0] != 0x04 || token->TOK_ID[1] != 0x04) {
return GSS_S_DEFECTIVE_TOKEN;
}
/* Ignore unknown flags */
token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
if ((context_handle->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
if (token_flags & CFXAcceptorSubkey)
return GSS_S_DEFECTIVE_TOKEN;
}
if (memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
return GSS_S_DEFECTIVE_TOKEN;
}
/*
* Check sequence number
*/
gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
if (seq_number_hi) {
*minor_status = ERANGE;
return GSS_S_UNSEQ_TOKEN;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/*
* Verify checksum
*/
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto,
&cksum.cksumtype);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
cksum.checksum.data = p + sizeof(*token);
cksum.checksum.length = token_buffer->length - sizeof(*token);
if (context_handle->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
}
buf = malloc(message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
return GSS_S_FAILURE;
}
memcpy(buf, message_buffer->value, message_buffer->length);
memcpy(buf + message_buffer->length, token, sizeof(*token));
ret = krb5_verify_checksum(gssapi_krb5_context, crypto,
usage,
buf,
sizeof(*token) + message_buffer->length,
&cksum);
if (ret != 0) {
gssapi_krb5_set_error_string();
*minor_status = ret;
krb5_crypto_destroy(gssapi_krb5_context, crypto);
free(buf);
return GSS_S_BAD_MIC;
}
free(buf);
if (qop_state != NULL) {
*qop_state = GSS_C_QOP_DEFAULT;
}
return GSS_S_COMPLETE;
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2003, PADL Software Pty Ltd.
* 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 PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
*/
/* $Id$ */
#ifndef GSSAPI_CFX_H_
#define GSSAPI_CFX_H_ 1
/*
* Implementation of draft-ietf-krb-wg-gssapi-cfx-01.txt
*/
typedef struct gss_cfx_mic_token_desc_struct {
u_char TOK_ID[2]; /* 04 04 */
u_char Flags;
u_char Filler[5];
u_char SND_SEQ[8];
} gss_cfx_mic_token_desc, *gss_cfx_mic_token;
typedef struct gss_cfx_wrap_token_desc_struct {
u_char TOK_ID[2]; /* 04 05 */
u_char Flags;
u_char Filler;
u_char EC[2];
u_char RRC[2];
u_char SND_SEQ[8];
} gss_cfx_wrap_token_desc, *gss_cfx_wrap_token;
typedef struct gss_cfx_delete_token_desc_struct {
u_char TOK_ID[2]; /* 05 04 */
u_char Flags;
u_char Filler[5];
u_char SND_SEQ[8];
} gss_cfx_delete_token_desc, *gss_cfx_delete_token;
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
OM_uint32 req_output_size,
OM_uint32 *max_input_size,
krb5_keyblock *key);
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key);
OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key);
OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key);
OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t *qop_state,
krb5_keyblock *key);
#endif /* GSSAPI_CFX_H_ */

View File

@@ -1,51 +0,0 @@
/*
* Copyright (c) 1997-2003 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"
RCSID("$Id$");
OM_uint32 gss_compare_name
(OM_uint32 * minor_status,
const gss_name_t name1,
const gss_name_t name2,
int * name_equal
)
{
GSSAPI_KRB5_INIT();
*name_equal = krb5_principal_compare (gssapi_krb5_context,
name1, name2);
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,154 +0,0 @@
/*
* Copyright (c) 2003 - 2005 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"
RCSID("$Id$");
krb5_error_code
_gss_check_compat(OM_uint32 *minor_status, gss_name_t name,
const char *option, krb5_boolean *compat,
krb5_boolean match_val)
{
krb5_error_code ret = 0;
char **p, **q;
krb5_principal match;
p = krb5_config_get_strings(gssapi_krb5_context, NULL, "gssapi",
option, NULL);
if(p == NULL)
return 0;
match = NULL;
for(q = p; *q; q++) {
ret = krb5_parse_name(gssapi_krb5_context, *q, &match);
if (ret)
break;
if (krb5_principal_match(gssapi_krb5_context, name, match)) {
*compat = match_val;
break;
}
krb5_free_principal(gssapi_krb5_context, match);
match = NULL;
}
if (match)
krb5_free_principal(gssapi_krb5_context, match);
krb5_config_free_strings(p);
if (ret) {
if (minor_status)
*minor_status = ret;
return GSS_S_FAILURE;
}
return 0;
}
/*
* ctx->ctx_id_mutex is assumed to be locked
*/
OM_uint32
_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx)
{
krb5_boolean use_compat = FALSE;
OM_uint32 ret;
if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) {
ret = _gss_check_compat(minor_status, ctx->target,
"broken_des3_mic", &use_compat, TRUE);
if (ret)
return ret;
ret = _gss_check_compat(minor_status, ctx->target,
"correct_des3_mic", &use_compat, FALSE);
if (ret)
return ret;
if (use_compat)
ctx->more_flags |= COMPAT_OLD_DES3;
ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
}
return 0;
}
OM_uint32
gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on)
{
*minor_status = 0;
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
if (on) {
ctx->more_flags |= COMPAT_OLD_DES3;
} else {
ctx->more_flags &= ~COMPAT_OLD_DES3;
}
ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
return 0;
}
/*
* For compatability with the Windows SPNEGO implementation, the
* default is to ignore the mechListMIC unless the initiator specified
* CFX or configured in krb5.conf with the option
* [gssapi]require_mechlist_mic=target-principal-pattern.
* The option is valid for both initiator and acceptor.
*/
OM_uint32
_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status,
gss_ctx_id_t ctx,
krb5_boolean *require_mic)
{
OM_uint32 ret;
int is_cfx = 0;
gsskrb5_is_cfx(ctx, &is_cfx);
if (is_cfx) {
/* CFX session key was used */
*require_mic = TRUE;
} else {
*require_mic = FALSE;
ret = _gss_check_compat(minor_status, ctx->target,
"require_mechlist_mic",
require_mic, TRUE);
if (ret)
return ret;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32
gssapi_lifetime_left(OM_uint32 *minor_status,
OM_uint32 lifetime,
OM_uint32 *lifetime_rec)
{
krb5_timestamp timeret;
krb5_error_code kret;
if (lifetime == 0) {
*lifetime_rec = GSS_C_INDEFINITE;
return GSS_S_COMPLETE;
}
kret = krb5_timeofday(gssapi_krb5_context, &timeret);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
if (lifetime < timeret)
*lifetime_rec = 0;
else
*lifetime_rec = lifetime - timeret;
return GSS_S_COMPLETE;
}
OM_uint32 gss_context_time
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
OM_uint32 * time_rec
)
{
OM_uint32 lifetime;
OM_uint32 major_status;
GSSAPI_KRB5_INIT ();
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
lifetime = context_handle->lifetime;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec);
if (major_status != GSS_S_COMPLETE)
return major_status;
*minor_status = 0;
if (*time_rec == 0)
return GSS_S_CONTEXT_EXPIRED;
return GSS_S_COMPLETE;
}

View File

@@ -1,233 +0,0 @@
/*
* Copyright (c) 2000 - 2001, 2003 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"
RCSID("$Id$");
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
gss_cred_id_t cred,
krb5_ccache out)
{
krb5_error_code kret;
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
if (cred->ccache == NULL) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
kret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache, out);
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32
gss_krb5_import_cred(OM_uint32 *minor_status,
krb5_ccache id,
krb5_principal keytab_principal,
krb5_keytab keytab,
gss_cred_id_t *cred)
{
krb5_error_code kret;
gss_cred_id_t handle;
OM_uint32 ret;
*cred = NULL;
GSSAPI_KRB5_INIT ();
handle = (gss_cred_id_t)calloc(1, sizeof(*handle));
if (handle == GSS_C_NO_CREDENTIAL) {
gssapi_krb5_clear_status ();
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
handle->usage = 0;
if (id) {
char *str;
handle->usage |= GSS_C_INITIATE;
kret = krb5_cc_get_principal(gssapi_krb5_context, id,
&handle->principal);
if (kret) {
free(handle);
gssapi_krb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
if (keytab_principal) {
krb5_boolean match;
match = krb5_principal_compare(gssapi_krb5_context,
handle->principal,
keytab_principal);
if (match == FALSE) {
krb5_free_principal(gssapi_krb5_context, handle->principal);
free(handle);
gssapi_krb5_clear_status ();
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
}
ret = _gssapi_krb5_ccache_lifetime(minor_status,
id,
handle->principal,
&handle->lifetime);
if (ret != GSS_S_COMPLETE) {
krb5_free_principal(gssapi_krb5_context, handle->principal);
free(handle);
return ret;
}
kret = krb5_cc_get_full_name(gssapi_krb5_context, id, &str);
if (kret)
goto out;
kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
free(str);
if (kret)
goto out;
}
if (keytab) {
char *str;
handle->usage |= GSS_C_ACCEPT;
if (keytab_principal && handle->principal == NULL) {
kret = krb5_copy_principal(gssapi_krb5_context,
keytab_principal,
&handle->principal);
if (kret)
goto out;
}
kret = krb5_kt_get_full_name(gssapi_krb5_context, keytab, &str);
if (kret)
goto out;
kret = krb5_kt_resolve(gssapi_krb5_context, str, &handle->keytab);
free(str);
if (kret)
goto out;
}
if (id || keytab) {
ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
&handle->mechanisms);
if (ret != GSS_S_COMPLETE) {
kret = *minor_status;
goto out;
}
}
*minor_status = 0;
*cred = handle;
return GSS_S_COMPLETE;
out:
gssapi_krb5_set_error_string ();
if (handle->principal)
krb5_free_principal(gssapi_krb5_context, handle->principal);
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
free(handle);
*minor_status = kret;
return GSS_S_FAILURE;
}
OM_uint32
gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int ad_type,
gss_buffer_t ad_data)
{
krb5_error_code ret;
krb5_data data;
ad_data->value = NULL;
ad_data->length = 0;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
if (context_handle->ticket == NULL) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
ret = krb5_ticket_get_authorization_data_type(gssapi_krb5_context,
context_handle->ticket,
ad_type,
&data);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ad_data->value = malloc(data.length);
if (ad_data->value == NULL) {
krb5_data_free(&data);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
ad_data->length = data.length;
memcpy(ad_data->value, data.data, ad_data->length);
krb5_data_free(&data);
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (c) 1997 - 2001, 2003 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"
RCSID("$Id$");
OM_uint32 gss_create_empty_oid_set (
OM_uint32 * minor_status,
gss_OID_set * oid_set
)
{
*oid_set = malloc(sizeof(**oid_set));
if (*oid_set == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
(*oid_set)->count = 0;
(*oid_set)->elements = NULL;
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,209 +0,0 @@
/*
* Copyright (c) 1997 - 2001 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"
RCSID("$Id$");
/*
* return the length of the mechanism in token or -1
* (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
*/
ssize_t
gssapi_krb5_get_mech (const u_char *ptr,
size_t total_len,
const u_char **mech_ret)
{
size_t len, len_len, mech_len, foo;
const u_char *p = ptr;
int e;
if (total_len < 1)
return -1;
if (*p++ != 0x60)
return -1;
e = der_get_length (p, total_len - 1, &len, &len_len);
if (e || 1 + len_len + len != total_len)
return -1;
p += len_len;
if (*p++ != 0x06)
return -1;
e = der_get_length (p, total_len - 1 - len_len - 1,
&mech_len, &foo);
if (e)
return -1;
p += foo;
*mech_ret = p;
return mech_len;
}
OM_uint32
_gssapi_verify_mech_header(u_char **str,
size_t total_len,
gss_OID mech)
{
const u_char *p;
ssize_t mech_len;
mech_len = gssapi_krb5_get_mech (*str, total_len, &p);
if (mech_len < 0)
return GSS_S_DEFECTIVE_TOKEN;
if (mech_len != mech->length)
return GSS_S_BAD_MECH;
if (memcmp(p,
mech->elements,
mech->length) != 0)
return GSS_S_BAD_MECH;
p += mech_len;
*str = rk_UNCONST(p);
return GSS_S_COMPLETE;
}
OM_uint32
gssapi_krb5_verify_header(u_char **str,
size_t total_len,
const void *type,
gss_OID oid)
{
OM_uint32 ret;
size_t len;
u_char *p = *str;
ret = _gssapi_verify_mech_header(str, total_len, oid);
if (ret)
return ret;
len = total_len - (*str - p);
if (len < 2)
return GSS_S_DEFECTIVE_TOKEN;
if (memcmp (*str, type, 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
*str += 2;
return 0;
}
/*
* Remove the GSS-API wrapping from `in_token' giving `out_data.
* Does not copy data, so just free `in_token'.
*/
OM_uint32
_gssapi_decapsulate(
OM_uint32 *minor_status,
gss_buffer_t input_token_buffer,
krb5_data *out_data,
const gss_OID mech
)
{
u_char *p;
OM_uint32 ret;
p = input_token_buffer->value;
ret = _gssapi_verify_mech_header(&p,
input_token_buffer->length,
mech);
if (ret) {
*minor_status = 0;
return ret;
}
out_data->length = input_token_buffer->length -
(p - (u_char *)input_token_buffer->value);
out_data->data = p;
return GSS_S_COMPLETE;
}
/*
* Remove the GSS-API wrapping from `in_token' giving `out_data.
* Does not copy data, so just free `in_token'.
*/
OM_uint32
gssapi_krb5_decapsulate(OM_uint32 *minor_status,
gss_buffer_t input_token_buffer,
krb5_data *out_data,
const void *type,
gss_OID oid)
{
u_char *p;
OM_uint32 ret;
p = input_token_buffer->value;
ret = gssapi_krb5_verify_header(&p,
input_token_buffer->length,
type,
oid);
if (ret) {
*minor_status = 0;
return ret;
}
out_data->length = input_token_buffer->length -
(p - (u_char *)input_token_buffer->value);
out_data->data = p;
return GSS_S_COMPLETE;
}
/*
* Verify padding of a gss wrapped message and return its length.
*/
OM_uint32
_gssapi_verify_pad(gss_buffer_t wrapped_token,
size_t datalen,
size_t *padlen)
{
u_char *pad;
size_t padlength;
int i;
pad = (u_char *)wrapped_token->value + wrapped_token->length - 1;
padlength = *pad;
if (padlength > datalen)
return GSS_S_BAD_MECH;
for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
;
if (i != 0)
return GSS_S_BAD_MIC;
*padlen = padlength;
return 0;
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32 gss_delete_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_buffer_t output_token
)
{
GSSAPI_KRB5_INIT ();
*minor_status = 0;
if (output_token) {
output_token->length = 0;
output_token->value = NULL;
}
if (*context_handle == GSS_C_NO_CONTEXT)
return GSS_S_COMPLETE;
HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex);
krb5_auth_con_free (gssapi_krb5_context,
(*context_handle)->auth_context);
if((*context_handle)->source)
krb5_free_principal (gssapi_krb5_context,
(*context_handle)->source);
if((*context_handle)->target)
krb5_free_principal (gssapi_krb5_context,
(*context_handle)->target);
if ((*context_handle)->ticket)
krb5_free_ticket (gssapi_krb5_context,
(*context_handle)->ticket);
if((*context_handle)->order)
_gssapi_msg_order_destroy(&(*context_handle)->order);
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
memset(*context_handle, 0, sizeof(**context_handle));
free (*context_handle);
*context_handle = GSS_C_NO_CONTEXT;
return GSS_S_COMPLETE;
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32 gss_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t output_name_buffer,
gss_OID * output_name_type
)
{
krb5_error_code kret;
char *buf;
size_t len;
GSSAPI_KRB5_INIT ();
kret = krb5_unparse_name (gssapi_krb5_context,
input_name,
&buf);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
len = strlen (buf);
output_name_buffer->length = len;
output_name_buffer->value = malloc(len + 1);
if (output_name_buffer->value == NULL) {
free (buf);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (output_name_buffer->value, buf, len);
((char *)output_name_buffer->value)[len] = '\0';
free (buf);
if (output_name_type)
*output_name_type = GSS_KRB5_NT_PRINCIPAL_NAME;
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,230 +0,0 @@
/*
* Copyright (c) 1998 - 2005 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"
RCSID("$Id$");
static const char *
calling_error(OM_uint32 v)
{
static const char *msgs[] = {
NULL, /* 0 */
"A required input parameter could not be read.", /* */
"A required output parameter could not be written.", /* */
"A parameter was malformed"
};
v >>= GSS_C_CALLING_ERROR_OFFSET;
if (v == 0)
return "";
else if (v >= sizeof(msgs)/sizeof(*msgs))
return "unknown calling error";
else
return msgs[v];
}
static const char *
routine_error(OM_uint32 v)
{
static const char *msgs[] = {
NULL, /* 0 */
"An unsupported mechanism was requested",
"An invalid name was supplied",
"A supplied name was of an unsupported type",
"Incorrect channel bindings were supplied",
"An invalid status code was supplied",
"A token had an invalid MIC",
"No credentials were supplied, "
"or the credentials were unavailable or inaccessible.",
"No context has been established",
"A token was invalid",
"A credential was invalid",
"The referenced credentials have expired",
"The context has expired",
"Miscellaneous failure (see text)",
"The quality-of-protection requested could not be provide",
"The operation is forbidden by local security policy",
"The operation or option is not available",
"The requested credential element already exists",
"The provided name was not a mechanism name.",
};
v >>= GSS_C_ROUTINE_ERROR_OFFSET;
if (v == 0)
return "";
else if (v >= sizeof(msgs)/sizeof(*msgs))
return "unknown routine error";
else
return msgs[v];
}
static const char *
supplementary_error(OM_uint32 v)
{
static const char *msgs[] = {
"normal completion",
"continuation call to routine required",
"duplicate per-message token detected",
"timed-out per-message token detected",
"reordered (early) per-message token detected",
"skipped predecessor token(s) detected"
};
v >>= GSS_C_SUPPLEMENTARY_OFFSET;
if (v >= sizeof(msgs)/sizeof(*msgs))
return "unknown routine error";
else
return msgs[v];
}
void
gssapi_krb5_clear_status (void)
{
struct gssapi_thr_context *ctx = gssapi_get_thread_context(1);
if (ctx == NULL)
return;
HEIMDAL_MUTEX_lock(&ctx->mutex);
if (ctx->error_string)
free(ctx->error_string);
ctx->error_string = NULL;
HEIMDAL_MUTEX_unlock(&ctx->mutex);
}
void
gssapi_krb5_set_status (const char *fmt, ...)
{
struct gssapi_thr_context *ctx = gssapi_get_thread_context(1);
va_list args;
if (ctx == NULL)
return;
HEIMDAL_MUTEX_lock(&ctx->mutex);
va_start(args, fmt);
if (ctx->error_string)
free(ctx->error_string);
/* ignore failures, will use status code instead */
vasprintf(&ctx->error_string, fmt, args);
va_end(args);
HEIMDAL_MUTEX_unlock(&ctx->mutex);
}
void
gssapi_krb5_set_error_string (void)
{
char *e;
e = krb5_get_error_string(gssapi_krb5_context);
if (e) {
gssapi_krb5_set_status("%s", e);
krb5_free_error_string(gssapi_krb5_context, e);
} else
gssapi_krb5_clear_status();
}
char *
gssapi_krb5_get_error_string (void)
{
struct gssapi_thr_context *ctx = gssapi_get_thread_context(0);
char *ret;
if (ctx == NULL)
return NULL;
HEIMDAL_MUTEX_lock(&ctx->mutex);
ret = ctx->error_string;
ctx->error_string = NULL;
HEIMDAL_MUTEX_unlock(&ctx->mutex);
return ret;
}
OM_uint32 gss_display_status
(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
const gss_OID mech_type,
OM_uint32 *message_context,
gss_buffer_t status_string)
{
char *buf;
GSSAPI_KRB5_INIT ();
status_string->length = 0;
status_string->value = NULL;
if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 &&
gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) {
*minor_status = 0;
return GSS_C_GSS_CODE;
}
if (status_type == GSS_C_GSS_CODE) {
if (GSS_SUPPLEMENTARY_INFO(status_value))
asprintf(&buf, "%s",
supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value)));
else
asprintf (&buf, "%s %s",
calling_error(GSS_CALLING_ERROR(status_value)),
routine_error(GSS_ROUTINE_ERROR(status_value)));
} else if (status_type == GSS_C_MECH_CODE) {
buf = gssapi_krb5_get_error_string ();
if (buf == NULL) {
const char *tmp = krb5_get_err_text (gssapi_krb5_context,
status_value);
if (tmp == NULL)
asprintf(&buf, "unknown mech error-code %u",
(unsigned)status_value);
else
buf = strdup(tmp);
}
} else {
*minor_status = EINVAL;
return GSS_S_BAD_STATUS;
}
if (buf == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*message_context = 0;
*minor_status = 0;
status_string->length = strlen(buf);
status_string->value = buf;
return GSS_S_COMPLETE;
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32 gss_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
gss_name_t * dest_name
)
{
krb5_error_code kret;
GSSAPI_KRB5_INIT ();
kret = krb5_copy_principal (gssapi_krb5_context,
src_name,
dest_name);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
} else {
*minor_status = 0;
return GSS_S_COMPLETE;
}
}

View File

@@ -1,155 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
void
_gssapi_encap_length (size_t data_len,
size_t *len,
size_t *total_len,
const gss_OID mech)
{
size_t len_len;
*len = 1 + 1 + mech->length + data_len;
len_len = length_len(*len);
*total_len = 1 + len_len + *len;
}
void
gssapi_krb5_encap_length (size_t data_len,
size_t *len,
size_t *total_len,
const gss_OID mech)
{
_gssapi_encap_length(data_len + 2, len, total_len, mech);
}
void *
gssapi_krb5_make_header (void *ptr,
size_t len,
const void *type,
const gss_OID mech)
{
u_char *p = ptr;
p = _gssapi_make_mech_header(p, len, mech);
memcpy (p, type, 2);
p += 2;
return p;
}
void *
_gssapi_make_mech_header(void *ptr,
size_t len,
const gss_OID mech)
{
u_char *p = ptr;
int e;
size_t len_len, foo;
*p++ = 0x60;
len_len = length_len(len);
e = der_put_length (p + len_len - 1, len_len, len, &foo);
if(e || foo != len_len)
abort ();
p += len_len;
*p++ = 0x06;
*p++ = mech->length;
memcpy (p, mech->elements, mech->length);
p += mech->length;
return p;
}
/*
* Give it a krb5_data and it will encapsulate with extra GSS-API wrappings.
*/
OM_uint32
_gssapi_encapsulate(
OM_uint32 *minor_status,
const krb5_data *in_data,
gss_buffer_t output_token,
const gss_OID mech
)
{
size_t len, outer_len;
void *p;
_gssapi_encap_length (in_data->length, &len, &outer_len, mech);
output_token->length = outer_len;
output_token->value = malloc (outer_len);
if (output_token->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = _gssapi_make_mech_header (output_token->value, len, mech);
memcpy (p, in_data->data, in_data->length);
return GSS_S_COMPLETE;
}
/*
* Give it a krb5_data and it will encapsulate with extra GSS-API krb5
* wrappings.
*/
OM_uint32
gssapi_krb5_encapsulate(
OM_uint32 *minor_status,
const krb5_data *in_data,
gss_buffer_t output_token,
const void *type,
const gss_OID mech
)
{
size_t len, outer_len;
u_char *p;
gssapi_krb5_encap_length (in_data->length, &len, &outer_len, mech);
output_token->length = outer_len;
output_token->value = malloc (outer_len);
if (output_token->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = gssapi_krb5_make_header (output_token->value, len, type, mech);
memcpy (p, in_data->data, in_data->length);
return GSS_S_COMPLETE;
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (c) 1997, 1999, 2003 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"
RCSID("$Id$");
OM_uint32 gss_export_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t exported_name
)
{
krb5_error_code kret;
char *buf, *name;
size_t len;
GSSAPI_KRB5_INIT ();
kret = krb5_unparse_name (gssapi_krb5_context,
input_name,
&name);
if (kret) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
return GSS_S_FAILURE;
}
len = strlen (name);
exported_name->length = 10 + len + GSS_KRB5_MECHANISM->length;
exported_name->value = malloc(exported_name->length);
if (exported_name->value == NULL) {
free (name);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
/* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
buf = exported_name->value;
memcpy(buf, "\x04\x01", 2);
buf += 2;
buf[0] = ((GSS_KRB5_MECHANISM->length + 2) >> 8) & 0xff;
buf[1] = (GSS_KRB5_MECHANISM->length + 2) & 0xff;
buf+= 2;
buf[0] = 0x06;
buf[1] = (GSS_KRB5_MECHANISM->length) & 0xFF;
buf+= 2;
memcpy(buf, GSS_KRB5_MECHANISM->elements, GSS_KRB5_MECHANISM->length);
buf += GSS_KRB5_MECHANISM->length;
buf[0] = (len >> 24) & 0xff;
buf[1] = (len >> 16) & 0xff;
buf[2] = (len >> 8) & 0xff;
buf[3] = (len) & 0xff;
buf += 4;
memcpy (buf, name, len);
free (name);
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,236 +0,0 @@
/*
* Copyright (c) 1999 - 2003 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"
RCSID("$Id$");
OM_uint32
gss_export_sec_context (
OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_buffer_t interprocess_token
)
{
krb5_storage *sp;
krb5_auth_context ac;
OM_uint32 ret = GSS_S_COMPLETE;
krb5_data data;
gss_buffer_desc buffer;
int flags;
OM_uint32 minor;
krb5_error_code kret;
GSSAPI_KRB5_INIT ();
HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex);
if (!((*context_handle)->flags & GSS_C_TRANS_FLAG)) {
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
*minor_status = 0;
return GSS_S_UNAVAILABLE;
}
sp = krb5_storage_emem ();
if (sp == NULL) {
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
ac = (*context_handle)->auth_context;
/* flagging included fields */
flags = 0;
if (ac->local_address)
flags |= SC_LOCAL_ADDRESS;
if (ac->remote_address)
flags |= SC_REMOTE_ADDRESS;
if (ac->keyblock)
flags |= SC_KEYBLOCK;
if (ac->local_subkey)
flags |= SC_LOCAL_SUBKEY;
if (ac->remote_subkey)
flags |= SC_REMOTE_SUBKEY;
kret = krb5_store_int32 (sp, flags);
if (kret) {
*minor_status = kret;
goto failure;
}
/* marshall auth context */
kret = krb5_store_int32 (sp, ac->flags);
if (kret) {
*minor_status = kret;
goto failure;
}
if (ac->local_address) {
kret = krb5_store_address (sp, *ac->local_address);
if (kret) {
*minor_status = kret;
goto failure;
}
}
if (ac->remote_address) {
kret = krb5_store_address (sp, *ac->remote_address);
if (kret) {
*minor_status = kret;
goto failure;
}
}
kret = krb5_store_int16 (sp, ac->local_port);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int16 (sp, ac->remote_port);
if (kret) {
*minor_status = kret;
goto failure;
}
if (ac->keyblock) {
kret = krb5_store_keyblock (sp, *ac->keyblock);
if (kret) {
*minor_status = kret;
goto failure;
}
}
if (ac->local_subkey) {
kret = krb5_store_keyblock (sp, *ac->local_subkey);
if (kret) {
*minor_status = kret;
goto failure;
}
}
if (ac->remote_subkey) {
kret = krb5_store_keyblock (sp, *ac->remote_subkey);
if (kret) {
*minor_status = kret;
goto failure;
}
}
kret = krb5_store_int32 (sp, ac->local_seqnumber);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, ac->remote_seqnumber);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, ac->keytype);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, ac->cksumtype);
if (kret) {
*minor_status = kret;
goto failure;
}
/* names */
ret = gss_export_name (minor_status, (*context_handle)->source, &buffer);
if (ret)
goto failure;
data.data = buffer.value;
data.length = buffer.length;
kret = krb5_store_data (sp, data);
gss_release_buffer (&minor, &buffer);
if (kret) {
*minor_status = kret;
goto failure;
}
ret = gss_export_name (minor_status, (*context_handle)->target, &buffer);
if (ret)
goto failure;
data.data = buffer.value;
data.length = buffer.length;
ret = GSS_S_FAILURE;
kret = krb5_store_data (sp, data);
gss_release_buffer (&minor, &buffer);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, (*context_handle)->flags);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, (*context_handle)->more_flags);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = krb5_store_int32 (sp, (*context_handle)->lifetime);
if (kret) {
*minor_status = kret;
goto failure;
}
kret = _gssapi_msg_order_export(sp, (*context_handle)->order);
if (kret ) {
*minor_status = kret;
goto failure;
}
kret = krb5_storage_to_data (sp, &data);
krb5_storage_free (sp);
if (kret) {
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
*minor_status = kret;
return GSS_S_FAILURE;
}
interprocess_token->length = data.length;
interprocess_token->value = data.data;
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
ret = gss_delete_sec_context (minor_status, context_handle,
GSS_C_NO_BUFFER);
if (ret != GSS_S_COMPLETE)
gss_release_buffer (NULL, interprocess_token);
*minor_status = 0;
return ret;
failure:
HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex);
krb5_storage_free (sp);
return ret;
}

View File

@@ -1,267 +0,0 @@
/*
* Copyright (c) 1997 - 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"
RCSID("$Id$");
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
* "\x01\x02\x01\x01"},
* corresponding to an object-identifier value of
* {iso(1) member-body(2) United States(840) mit(113554)
* infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
* GSS_C_NT_USER_NAME should be initialized to point
* to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_user_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")};
gss_OID GSS_C_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
* "\x01\x02\x01\x02"},
* corresponding to an object-identifier value of
* {iso(1) member-body(2) United States(840) mit(113554)
* infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
* The constant GSS_C_NT_MACHINE_UID_NAME should be
* initialized to point to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_machine_uid_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")};
gss_OID GSS_C_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
* "\x01\x02\x01\x03"},
* corresponding to an object-identifier value of
* {iso(1) member-body(2) United States(840) mit(113554)
* infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
* The constant GSS_C_NT_STRING_UID_NAME should be
* initialized to point to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_string_uid_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")};
gss_OID GSS_C_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
* corresponding to an object-identifier value of
* {iso(1) org(3) dod(6) internet(1) security(5)
* nametypes(6) gss-host-based-services(2)). The constant
* GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
* to that gss_OID_desc. This is a deprecated OID value, and
* implementations wishing to support hostbased-service names
* should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
* defined below, to identify such names;
* GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
* for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
* parameter, but should not be emitted by GSS-API
* implementations
*/
static gss_OID_desc gss_c_nt_hostbased_service_x_oid_desc =
{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")};
gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &gss_c_nt_hostbased_service_x_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
* "\x01\x02\x01\x04"}, corresponding to an
* object-identifier value of {iso(1) member-body(2)
* Unites States(840) mit(113554) infosys(1) gssapi(2)
* generic(1) service_name(4)}. The constant
* GSS_C_NT_HOSTBASED_SERVICE should be initialized
* to point to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_hostbased_service_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")};
gss_OID GSS_C_NT_HOSTBASED_SERVICE = &gss_c_nt_hostbased_service_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {6, (void *)"\x2b\x06\01\x05\x06\x03"},
* corresponding to an object identifier value of
* {1(iso), 3(org), 6(dod), 1(internet), 5(security),
* 6(nametypes), 3(gss-anonymous-name)}. The constant
* and GSS_C_NT_ANONYMOUS should be initialized to point
* to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_anonymous_oid_desc =
{6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")};
gss_OID GSS_C_NT_ANONYMOUS = &gss_c_nt_anonymous_oid_desc;
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
* {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
* corresponding to an object-identifier value of
* {1(iso), 3(org), 6(dod), 1(internet), 5(security),
* 6(nametypes), 4(gss-api-exported-name)}. The constant
* GSS_C_NT_EXPORT_NAME should be initialized to point
* to that gss_OID_desc.
*/
static gss_OID_desc gss_c_nt_export_name_oid_desc =
{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") };
gss_OID GSS_C_NT_EXPORT_NAME = &gss_c_nt_export_name_oid_desc;
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
* krb5(2) krb5_name(1)}. The recommended symbolic name for this type
* is "GSS_KRB5_NT_PRINCIPAL_NAME".
*/
static gss_OID_desc gss_krb5_nt_principal_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") };
gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &gss_krb5_nt_principal_name_oid_desc;
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
* generic(1) user_name(1)}. The recommended symbolic name for this
* type is "GSS_KRB5_NT_USER_NAME".
*/
gss_OID GSS_KRB5_NT_USER_NAME = &gss_c_nt_user_name_oid_desc;
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
* generic(1) machine_uid_name(2)}. The recommended symbolic name for
* this type is "GSS_KRB5_NT_MACHINE_UID_NAME".
*/
gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &gss_c_nt_machine_uid_name_oid_desc;
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
* generic(1) string_uid_name(3)}. The recommended symbolic name for
* this type is "GSS_KRB5_NT_STRING_UID_NAME".
*/
gss_OID GSS_KRB5_NT_STRING_UID_NAME = &gss_c_nt_string_uid_name_oid_desc;
/*
* To support ongoing experimentation, testing, and evolution of the
* specification, the Kerberos V5 GSS-API mechanism as defined in this
* and any successor memos will be identified with the following Object
* Identifier, as defined in RFC-1510, until the specification is
* advanced to the level of Proposed Standard RFC:
*
* {iso(1), org(3), dod(5), internet(1), security(5), kerberosv5(2)}
*
* Upon advancement to the level of Proposed Standard RFC, the Kerberos
* V5 GSS-API mechanism will be identified by an Object Identifier
* having the value:
*
* {iso(1) member-body(2) United States(840) mit(113554) infosys(1)
* gssapi(2) krb5(2)}
*/
#if 0 /* This is the old OID */
static gss_OID_desc gss_krb5_mechanism_oid_desc =
{5, rk_UNCONST("\x2b\x05\x01\x05\x02")};
#endif
static gss_OID_desc gss_krb5_mechanism_oid_desc =
{9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc;
/*
* RFC2478, SPNEGO:
* The security mechanism of the initial
* negotiation token is identified by the Object Identifier
* iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
*/
static gss_OID_desc gss_spnego_mechanism_oid_desc =
{6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")};
gss_OID GSS_SPNEGO_MECHANISM = &gss_spnego_mechanism_oid_desc;
/*
* draft-ietf-cat-iakerb-09, IAKERB:
* The mechanism ID for IAKERB proxy GSS-API Kerberos, in accordance
* with the mechanism proposed by SPNEGO [7] for negotiating protocol
* variations, is: {iso(1) org(3) dod(6) internet(1) security(5)
* mechanisms(5) iakerb(10) iakerbProxyProtocol(1)}. The proposed
* mechanism ID for IAKERB minimum messages GSS-API Kerberos, in
* accordance with the mechanism proposed by SPNEGO for negotiating
* protocol variations, is: {iso(1) org(3) dod(6) internet(1)
* security(5) mechanisms(5) iakerb(10)
* iakerbMinimumMessagesProtocol(2)}.
*/
static gss_OID_desc gss_iakerb_proxy_mechanism_oid_desc =
{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")};
gss_OID GSS_IAKERB_PROXY_MECHANISM = &gss_iakerb_proxy_mechanism_oid_desc;
static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc =
{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") };
gss_OID GSS_IAKERB_MIN_MSG_MECHANISM = &gss_iakerb_min_msg_mechanism_oid_desc;
/*
* Context for krb5 calls.
*/
krb5_context gssapi_krb5_context;

View File

@@ -1,314 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
static OM_uint32
mic_des
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key
)
{
u_char *p;
MD5_CTX md5;
u_char hash[16];
DES_key_schedule schedule;
DES_cblock deskey;
DES_cblock zero;
int32_t seq_number;
size_t len, total_len;
gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
if (message_token->value == NULL) {
message_token->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = gssapi_krb5_make_header(message_token->value,
len,
"\x01\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
memcpy (p, "\x00\x00", 2); /* SGN_ALG = DES MAC MD5 */
p += 2;
memcpy (p, "\xff\xff\xff\xff", 4); /* Filler */
p += 4;
/* Fill in later (SND-SEQ) */
memset (p, 0, 16);
p += 16;
/* checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, message_buffer->value, message_buffer->length);
MD5_Final (hash, &md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
memcpy (p - 8, hash, 8); /* SGN_CKSUM */
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
/* sequence number */
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
p -= 16; /* SND_SEQ */
p[0] = (seq_number >> 0) & 0xFF;
p[1] = (seq_number >> 8) & 0xFF;
p[2] = (seq_number >> 16) & 0xFF;
p[3] = (seq_number >> 24) & 0xFF;
memset (p + 4,
(context_handle->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
*minor_status = 0;
return GSS_S_COMPLETE;
}
static OM_uint32
mic_des3
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key
)
{
u_char *p;
Checksum cksum;
u_char seq[8];
int32_t seq_number;
size_t len, total_len;
krb5_crypto crypto;
krb5_error_code kret;
krb5_data encdata;
char *tmp;
char ivec[8];
gssapi_krb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
if (message_token->value == NULL) {
message_token->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = gssapi_krb5_make_header(message_token->value,
len,
"\x01\x01", /* TOK-ID */
GSS_KRB5_MECHANISM);
memcpy (p, "\x04\x00", 2); /* SGN_ALG = HMAC SHA1 DES3-KD */
p += 2;
memcpy (p, "\xff\xff\xff\xff", 4); /* filler */
p += 4;
/* this should be done in parts */
tmp = malloc (message_buffer->length + 8);
if (tmp == NULL) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (tmp, p - 8, 8);
memcpy (tmp + 8, message_buffer->value, message_buffer->length);
kret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
free (tmp);
gssapi_krb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
kret = krb5_create_checksum (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SIGN,
0,
tmp,
message_buffer->length + 8,
&cksum);
free (tmp);
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
gssapi_krb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
/* sequence number */
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
seq[0] = (seq_number >> 0) & 0xFF;
seq[1] = (seq_number >> 8) & 0xFF;
seq[2] = (seq_number >> 16) & 0xFF;
seq[3] = (seq_number >> 24) & 0xFF;
memset (seq + 4,
(context_handle->more_flags & LOCAL) ? 0 : 0xFF,
4);
kret = krb5_crypto_init(gssapi_krb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
gssapi_krb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
if (context_handle->more_flags & COMPAT_OLD_DES3)
memset(ivec, 0, 8);
else
memcpy(ivec, p + 8, 8);
kret = krb5_encrypt_ivec (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
seq, 8, &encdata, ivec);
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (kret) {
free (message_token->value);
message_token->value = NULL;
message_token->length = 0;
gssapi_krb5_set_error_string ();
*minor_status = kret;
return GSS_S_FAILURE;
}
assert (encdata.length == 8);
memcpy (p, encdata.data, encdata.length);
krb5_data_free (&encdata);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
free_Checksum (&cksum);
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 gss_get_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token
)
{
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
ret = gss_krb5_get_subkey(context_handle, &key);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
ret = mic_des (minor_status, context_handle, qop_req,
message_buffer, message_token, key);
break;
case KEYTYPE_DES3 :
ret = mic_des3 (minor_status, context_handle, qop_req,
message_buffer, message_token, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
ret = _gssapi_get_mic_arcfour (minor_status, context_handle, qop_req,
message_buffer, message_token, key);
break;
default :
ret = _gssapi_mic_cfx (minor_status, context_handle, qop_req,
message_buffer, message_token, key);
break;
}
krb5_free_keyblock (gssapi_krb5_context, key);
return ret;
}

View File

@@ -1,299 +0,0 @@
/*
* Copyright (c) 1997 - 2004 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.
*/
/* $Id$ */
#ifndef GSSAPI_LOCL_H
#define GSSAPI_LOCL_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <krb5_locl.h>
#include <gssapi.h>
#include <assert.h>
#include "cfx.h"
#include "arcfour.h"
#include "spnego_asn1.h"
/*
*
*/
struct gss_msg_order;
typedef struct gss_ctx_id_t_desc_struct {
struct krb5_auth_context_data *auth_context;
gss_name_t source, target;
OM_uint32 flags;
enum { LOCAL = 1, OPEN = 2,
COMPAT_OLD_DES3 = 4,
COMPAT_OLD_DES3_SELECTED = 8,
ACCEPTOR_SUBKEY = 16
} more_flags;
struct krb5_ticket *ticket;
OM_uint32 lifetime;
HEIMDAL_MUTEX ctx_id_mutex;
struct gss_msg_order *order;
} gss_ctx_id_t_desc;
typedef struct gss_cred_id_t_desc_struct {
gss_name_t principal;
int cred_flags;
#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
struct krb5_keytab_data *keytab;
OM_uint32 lifetime;
gss_cred_usage_t usage;
gss_OID_set mechanisms;
struct krb5_ccache_data *ccache;
HEIMDAL_MUTEX cred_id_mutex;
} gss_cred_id_t_desc;
/*
*
*/
extern krb5_context gssapi_krb5_context;
extern krb5_keytab gssapi_krb5_keytab;
extern HEIMDAL_MUTEX gssapi_keytab_mutex;
struct gssapi_thr_context {
HEIMDAL_MUTEX mutex;
char *error_string;
};
/*
* Prototypes
*/
krb5_error_code gssapi_krb5_init (void);
#define GSSAPI_KRB5_INIT() do { \
krb5_error_code kret_gss_init; \
if((kret_gss_init = gssapi_krb5_init ()) != 0) { \
*minor_status = kret_gss_init; \
return GSS_S_FAILURE; \
} \
} while (0)
struct gssapi_thr_context *
gssapi_get_thread_context(int);
void
gsskrb5_is_cfx(gss_ctx_id_t, int *);
OM_uint32
gssapi_krb5_create_8003_checksum (
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
OM_uint32 flags,
const krb5_data *fwd_data,
Checksum *result);
OM_uint32
gssapi_krb5_verify_8003_checksum (
OM_uint32 *minor_status,
const gss_channel_bindings_t input_chan_bindings,
const Checksum *cksum,
OM_uint32 *flags,
krb5_data *fwd_data);
void
_gssapi_encap_length (size_t data_len,
size_t *len,
size_t *total_len,
const gss_OID mech);
void
gssapi_krb5_encap_length (size_t data_len,
size_t *len,
size_t *total_len,
const gss_OID mech);
OM_uint32
_gssapi_encapsulate(OM_uint32 *minor_status,
const krb5_data *in_data,
gss_buffer_t output_token,
const gss_OID mech);
OM_uint32
gssapi_krb5_encapsulate(OM_uint32 *minor_status,
const krb5_data *in_data,
gss_buffer_t output_token,
const void *type,
const gss_OID mech);
OM_uint32
gssapi_krb5_decapsulate(OM_uint32 *minor_status,
gss_buffer_t input_token_buffer,
krb5_data *out_data,
const void *type,
gss_OID oid);
void *
gssapi_krb5_make_header (void *ptr,
size_t len,
const void *type,
const gss_OID mech);
void *
_gssapi_make_mech_header(void *ptr,
size_t len,
const gss_OID mech);
OM_uint32
_gssapi_verify_mech_header(u_char **str,
size_t total_len,
gss_OID oid);
OM_uint32
gssapi_krb5_verify_header(u_char **str,
size_t total_len,
const void *type,
gss_OID oid);
OM_uint32
_gssapi_decapsulate(OM_uint32 *minor_status,
gss_buffer_t input_token_buffer,
krb5_data *out_data,
const gss_OID mech);
ssize_t
gssapi_krb5_get_mech (const u_char *, size_t, const u_char **);
OM_uint32
_gssapi_verify_pad(gss_buffer_t, size_t, size_t *);
OM_uint32
gss_verify_mic_internal(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
char * type);
OM_uint32
gss_krb5_get_subkey(const gss_ctx_id_t context_handle,
krb5_keyblock **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
#define SC_REMOTE_ADDRESS 0x02
#define SC_KEYBLOCK 0x04
#define SC_LOCAL_SUBKEY 0x08
#define SC_REMOTE_SUBKEY 0x10
int
gss_oid_equal(const gss_OID a, const gss_OID b);
void
gssapi_krb5_clear_status (void);
void
gssapi_krb5_set_status (const char *fmt, ...);
void
gssapi_krb5_set_error_string (void);
char *
gssapi_krb5_get_error_string (void);
OM_uint32
_gss_DES3_get_mic_compat(OM_uint32 *, gss_ctx_id_t);
OM_uint32
_gss_spnego_require_mechlist_mic(OM_uint32 *, gss_ctx_id_t, krb5_boolean *);
krb5_error_code
_gss_check_compat(OM_uint32 *, gss_name_t, const char *,
krb5_boolean *, krb5_boolean);
OM_uint32
gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *);
OM_uint32
_gssapi_krb5_ccache_lifetime(OM_uint32 *, krb5_ccache,
krb5_principal, OM_uint32 *);
/* sequence */
OM_uint32
_gssapi_msg_order_create(OM_uint32 *, struct gss_msg_order **,
OM_uint32, OM_uint32, OM_uint32, int);
OM_uint32
_gssapi_msg_order_destroy(struct gss_msg_order **);
OM_uint32
_gssapi_msg_order_check(struct gss_msg_order *, OM_uint32);
OM_uint32
_gssapi_msg_order_f(OM_uint32);
OM_uint32
_gssapi_msg_order_import(OM_uint32 *, krb5_storage *,
struct gss_msg_order **);
krb5_error_code
_gssapi_msg_order_export(krb5_storage *, struct gss_msg_order *);
/* 8003 */
krb5_error_code
gssapi_encode_om_uint32(OM_uint32, u_char *);
krb5_error_code
gssapi_encode_be_om_uint32(OM_uint32, u_char *);
krb5_error_code
gssapi_decode_om_uint32(const void *, OM_uint32 *);
krb5_error_code
gssapi_decode_be_om_uint32(const void *, OM_uint32 *);
#endif

View File

@@ -1,230 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
static OM_uint32
parse_krb5_name (OM_uint32 *minor_status,
const char *name,
gss_name_t *output_name)
{
krb5_error_code kerr;
kerr = krb5_parse_name (gssapi_krb5_context, name, output_name);
if (kerr == 0)
return GSS_S_COMPLETE;
else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) {
gssapi_krb5_set_error_string ();
*minor_status = kerr;
return GSS_S_BAD_NAME;
} else {
gssapi_krb5_set_error_string ();
*minor_status = kerr;
return GSS_S_FAILURE;
}
}
static OM_uint32
import_krb5_name (OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
gss_name_t *output_name)
{
OM_uint32 ret;
char *tmp;
tmp = malloc (input_name_buffer->length + 1);
if (tmp == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (tmp,
input_name_buffer->value,
input_name_buffer->length);
tmp[input_name_buffer->length] = '\0';
ret = parse_krb5_name(minor_status, tmp, output_name);
free(tmp);
return ret;
}
static OM_uint32
import_hostbased_name (OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
gss_name_t *output_name)
{
krb5_error_code kerr;
char *tmp;
char *p;
char *host;
char local_hostname[MAXHOSTNAMELEN];
*output_name = NULL;
tmp = malloc (input_name_buffer->length + 1);
if (tmp == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (tmp,
input_name_buffer->value,
input_name_buffer->length);
tmp[input_name_buffer->length] = '\0';
p = strchr (tmp, '@');
if (p != NULL) {
*p = '\0';
host = p + 1;
} else {
if (gethostname(local_hostname, sizeof(local_hostname)) < 0) {
*minor_status = errno;
free (tmp);
return GSS_S_FAILURE;
}
host = local_hostname;
}
kerr = krb5_sname_to_principal (gssapi_krb5_context,
host,
tmp,
KRB5_NT_SRV_HST,
output_name);
free (tmp);
*minor_status = kerr;
if (kerr == 0)
return GSS_S_COMPLETE;
else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) {
gssapi_krb5_set_error_string ();
*minor_status = kerr;
return GSS_S_BAD_NAME;
} else {
gssapi_krb5_set_error_string ();
*minor_status = kerr;
return GSS_S_FAILURE;
}
}
static OM_uint32
import_export_name (OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
gss_name_t *output_name)
{
unsigned char *p;
uint32_t length;
OM_uint32 ret;
char *name;
if (input_name_buffer->length < 10 + GSS_KRB5_MECHANISM->length)
return GSS_S_BAD_NAME;
/* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
p = input_name_buffer->value;
if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 ||
p[3] != GSS_KRB5_MECHANISM->length + 2 ||
p[4] != 0x06 ||
p[5] != GSS_KRB5_MECHANISM->length ||
memcmp(&p[6], GSS_KRB5_MECHANISM->elements,
GSS_KRB5_MECHANISM->length) != 0)
return GSS_S_BAD_NAME;
p += 6 + GSS_KRB5_MECHANISM->length;
length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
p += 4;
if (length > input_name_buffer->length - 10 - GSS_KRB5_MECHANISM->length)
return GSS_S_BAD_NAME;
name = malloc(length + 1);
if (name == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy(name, p, length);
name[length] = '\0';
ret = parse_krb5_name(minor_status, name, output_name);
free(name);
return ret;
}
int
gss_oid_equal(const gss_OID a, const gss_OID b)
{
if (a == b)
return 1;
else if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
return 0;
else
return memcmp(a->elements, b->elements, a->length) == 0;
}
OM_uint32 gss_import_name
(OM_uint32 * minor_status,
const gss_buffer_t input_name_buffer,
const gss_OID input_name_type,
gss_name_t * output_name
)
{
GSSAPI_KRB5_INIT ();
*minor_status = 0;
*output_name = GSS_C_NO_NAME;
if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||
gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X))
return import_hostbased_name (minor_status,
input_name_buffer,
output_name);
else if (gss_oid_equal(input_name_type, GSS_C_NO_OID)
|| gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)
|| gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
/* default printable syntax */
return import_krb5_name (minor_status,
input_name_buffer,
output_name);
else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) {
return import_export_name(minor_status,
input_name_buffer,
output_name);
} else {
*minor_status = 0;
return GSS_S_BAD_NAMETYPE;
}
}

View File

@@ -1,222 +0,0 @@
/*
* Copyright (c) 1999 - 2003 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"
RCSID("$Id$");
OM_uint32
gss_import_sec_context (
OM_uint32 * minor_status,
const gss_buffer_t interprocess_token,
gss_ctx_id_t * context_handle
)
{
OM_uint32 ret = GSS_S_FAILURE;
krb5_error_code kret;
krb5_storage *sp;
krb5_auth_context ac;
krb5_address local, remote;
krb5_address *localp, *remotep;
krb5_data data;
gss_buffer_desc buffer;
krb5_keyblock keyblock;
int32_t tmp;
int32_t flags;
OM_uint32 minor;
GSSAPI_KRB5_INIT ();
localp = remotep = NULL;
sp = krb5_storage_from_mem (interprocess_token->value,
interprocess_token->length);
if (sp == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*context_handle = malloc(sizeof(**context_handle));
if (*context_handle == NULL) {
*minor_status = ENOMEM;
krb5_storage_free (sp);
return GSS_S_FAILURE;
}
memset (*context_handle, 0, sizeof(**context_handle));
HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);
kret = krb5_auth_con_init (gssapi_krb5_context,
&(*context_handle)->auth_context);
if (kret) {
gssapi_krb5_set_error_string ();
*minor_status = kret;
ret = GSS_S_FAILURE;
goto failure;
}
/* flags */
*minor_status = 0;
if (krb5_ret_int32 (sp, &flags) != 0)
goto failure;
/* retrieve the auth context */
ac = (*context_handle)->auth_context;
if (krb5_ret_uint32 (sp, &ac->flags) != 0)
goto failure;
if (flags & SC_LOCAL_ADDRESS) {
if (krb5_ret_address (sp, localp = &local) != 0)
goto failure;
}
if (flags & SC_REMOTE_ADDRESS) {
if (krb5_ret_address (sp, remotep = &remote) != 0)
goto failure;
}
krb5_auth_con_setaddrs (gssapi_krb5_context, ac, localp, remotep);
if (localp)
krb5_free_address (gssapi_krb5_context, localp);
if (remotep)
krb5_free_address (gssapi_krb5_context, remotep);
localp = remotep = NULL;
if (krb5_ret_int16 (sp, &ac->local_port) != 0)
goto failure;
if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
goto failure;
if (flags & SC_KEYBLOCK) {
if (krb5_ret_keyblock (sp, &keyblock) != 0)
goto failure;
krb5_auth_con_setkey (gssapi_krb5_context, ac, &keyblock);
krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
}
if (flags & SC_LOCAL_SUBKEY) {
if (krb5_ret_keyblock (sp, &keyblock) != 0)
goto failure;
krb5_auth_con_setlocalsubkey (gssapi_krb5_context, ac, &keyblock);
krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
}
if (flags & SC_REMOTE_SUBKEY) {
if (krb5_ret_keyblock (sp, &keyblock) != 0)
goto failure;
krb5_auth_con_setremotesubkey (gssapi_krb5_context, ac, &keyblock);
krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
}
if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
goto failure;
if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
goto failure;
if (krb5_ret_int32 (sp, &tmp) != 0)
goto failure;
ac->keytype = tmp;
if (krb5_ret_int32 (sp, &tmp) != 0)
goto failure;
ac->cksumtype = tmp;
/* names */
if (krb5_ret_data (sp, &data))
goto failure;
buffer.value = data.data;
buffer.length = data.length;
ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
&(*context_handle)->source);
if (ret) {
ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
&(*context_handle)->source);
if (ret) {
krb5_data_free (&data);
goto failure;
}
}
krb5_data_free (&data);
if (krb5_ret_data (sp, &data) != 0)
goto failure;
buffer.value = data.data;
buffer.length = data.length;
ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
&(*context_handle)->target);
if (ret) {
ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
&(*context_handle)->target);
if (ret) {
krb5_data_free (&data);
goto failure;
}
}
krb5_data_free (&data);
if (krb5_ret_int32 (sp, &tmp))
goto failure;
(*context_handle)->flags = tmp;
if (krb5_ret_int32 (sp, &tmp))
goto failure;
(*context_handle)->more_flags = tmp;
if (krb5_ret_int32 (sp, &tmp))
goto failure;
(*context_handle)->lifetime = tmp;
ret = _gssapi_msg_order_import(minor_status, sp, &(*context_handle)->order);
if (ret)
goto failure;
krb5_storage_free (sp);
return GSS_S_COMPLETE;
failure:
krb5_auth_con_free (gssapi_krb5_context,
(*context_handle)->auth_context);
if ((*context_handle)->source != NULL)
gss_release_name(&minor, &(*context_handle)->source);
if ((*context_handle)->target != NULL)
gss_release_name(&minor, &(*context_handle)->target);
if (localp)
krb5_free_address (gssapi_krb5_context, localp);
if (remotep)
krb5_free_address (gssapi_krb5_context, remotep);
if((*context_handle)->order)
_gssapi_msg_order_destroy(&(*context_handle)->order);
HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
krb5_storage_free (sp);
free (*context_handle);
*context_handle = GSS_C_NO_CONTEXT;
return ret;
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 1997 - 2001, 2003 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"
RCSID("$Id$");
OM_uint32 gss_indicate_mechs
(OM_uint32 * minor_status,
gss_OID_set * mech_set
)
{
OM_uint32 ret;
ret = gss_create_empty_oid_set(minor_status, mech_set);
if (ret)
return ret;
ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set);
if (ret) {
gss_release_oid_set(NULL, mech_set);
return ret;
}
ret = gss_add_oid_set_member(minor_status, GSS_SPNEGO_MECHANISM, mech_set);
if (ret) {
gss_release_oid_set(NULL, mech_set);
return ret;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 1997 - 2001, 2003 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"
RCSID("$Id$");
static HEIMDAL_MUTEX gssapi_krb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER;
static int created_key;
static HEIMDAL_thread_key gssapi_context_key;
static void
gssapi_destroy_thread_context(void *ptr)
{
struct gssapi_thr_context *ctx = ptr;
if (ctx == NULL)
return;
if (ctx->error_string)
free(ctx->error_string);
HEIMDAL_MUTEX_destroy(&ctx->mutex);
free(ctx);
}
struct gssapi_thr_context *
gssapi_get_thread_context(int createp)
{
struct gssapi_thr_context *ctx;
int ret;
HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex);
if (!created_key)
abort();
ctx = HEIMDAL_getspecific(gssapi_context_key);
if (ctx == NULL) {
if (!createp)
goto fail;
ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
goto fail;
ctx->error_string = NULL;
HEIMDAL_MUTEX_init(&ctx->mutex);
HEIMDAL_setspecific(gssapi_context_key, ctx, ret);
if (ret)
goto fail;
}
HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
return ctx;
fail:
HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
if (ctx)
free(ctx);
return NULL;
}
krb5_error_code
gssapi_krb5_init (void)
{
krb5_error_code ret = 0;
HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex);
if(gssapi_krb5_context == NULL)
ret = krb5_init_context (&gssapi_krb5_context);
if (ret == 0 && !created_key) {
HEIMDAL_key_create(&gssapi_context_key,
gssapi_destroy_thread_context,
ret);
if (ret) {
krb5_free_context(gssapi_krb5_context);
gssapi_krb5_context = NULL;
} else
created_key = 1;
}
HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex);
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +0,0 @@
/*
* Copyright (c) 1997, 2003 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"
RCSID("$Id$");
OM_uint32 gss_inquire_context (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_name_t * src_name,
gss_name_t * targ_name,
OM_uint32 * lifetime_rec,
gss_OID * mech_type,
OM_uint32 * ctx_flags,
int * locally_initiated,
int * open_context
)
{
OM_uint32 ret;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
if (src_name) {
ret = gss_duplicate_name (minor_status,
context_handle->source,
src_name);
if (ret)
goto failed;
}
if (targ_name) {
ret = gss_duplicate_name (minor_status,
context_handle->target,
targ_name);
if (ret)
goto failed;
}
if (lifetime_rec) {
ret = gssapi_lifetime_left(minor_status,
context_handle->lifetime,
lifetime_rec);
if (ret)
goto failed;
}
if (mech_type)
*mech_type = GSS_KRB5_MECHANISM;
if (ctx_flags)
*ctx_flags = context_handle->flags;
if (locally_initiated)
*locally_initiated = context_handle->more_flags & LOCAL;
if (open_context)
*open_context = context_handle->more_flags & OPEN;
*minor_status = 0;
ret = GSS_S_COMPLETE;
failed:
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright (c) 1997, 2003 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"
RCSID("$Id$");
OM_uint32 gss_inquire_cred
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
gss_name_t * name,
OM_uint32 * lifetime,
gss_cred_usage_t * cred_usage,
gss_OID_set * mechanisms
)
{
gss_cred_id_t cred;
OM_uint32 ret;
*minor_status = 0;
if (name)
*name = NULL;
if (mechanisms)
*mechanisms = GSS_C_NO_OID_SET;
if (cred_handle == GSS_C_NO_CREDENTIAL) {
ret = gss_acquire_cred(minor_status,
GSS_C_NO_NAME,
GSS_C_INDEFINITE,
GSS_C_NO_OID_SET,
GSS_C_BOTH,
&cred,
NULL,
NULL);
if (ret)
return ret;
} else
cred = (gss_cred_id_t)cred_handle;
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
if (name != NULL) {
if (cred->principal != NULL) {
ret = gss_duplicate_name(minor_status, cred->principal,
name);
if (ret)
goto out;
} else if (cred->usage == GSS_C_ACCEPT) {
*minor_status = krb5_sname_to_principal(gssapi_krb5_context, NULL,
NULL, KRB5_NT_SRV_HST, name);
if (*minor_status) {
ret = GSS_S_FAILURE;
goto out;
}
} else {
*minor_status = krb5_get_default_principal(gssapi_krb5_context,
name);
if (*minor_status) {
ret = GSS_S_FAILURE;
goto out;
}
}
}
if (lifetime != NULL) {
ret = gssapi_lifetime_left(minor_status,
cred->lifetime,
lifetime);
if (ret)
goto out;
}
if (cred_usage != NULL)
*cred_usage = cred->usage;
if (mechanisms != NULL) {
ret = gss_create_empty_oid_set(minor_status, mechanisms);
if (ret)
goto out;
ret = gss_add_oid_set_member(minor_status,
&cred->mechanisms->elements[0],
mechanisms);
if (ret)
goto out;
}
ret = GSS_S_COMPLETE;
out:
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
if (cred_handle == GSS_C_NO_CREDENTIAL)
ret = gss_release_cred(minor_status, &cred);
return ret;
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
OM_uint32 gss_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
const gss_OID mech_type,
gss_name_t * name,
OM_uint32 * initiator_lifetime,
OM_uint32 * acceptor_lifetime,
gss_cred_usage_t * cred_usage
)
{
OM_uint32 ret;
OM_uint32 lifetime;
if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 &&
gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) {
*minor_status = EINVAL;
return GSS_S_BAD_MECH;
}
ret = gss_inquire_cred (minor_status,
cred_handle,
name,
&lifetime,
cred_usage,
NULL);
if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) {
gss_cred_usage_t usage;
HEIMDAL_MUTEX_lock(&cred_handle->cred_id_mutex);
usage = cred_handle->usage;
HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex);
if (initiator_lifetime) {
if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH)
*initiator_lifetime = lifetime;
}
if (acceptor_lifetime) {
if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH)
*acceptor_lifetime = lifetime;
}
}
return ret;
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
OM_uint32 gss_inquire_mechs_for_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
gss_OID_set * mech_types
)
{
OM_uint32 ret;
ret = gss_create_empty_oid_set(minor_status, mech_types);
if (ret)
return ret;
ret = gss_add_oid_set_member(minor_status,
GSS_KRB5_MECHANISM,
mech_types);
if (ret)
gss_release_oid_set(NULL, mech_types);
return ret;
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
static gss_OID *name_list[] = {
&GSS_C_NT_HOSTBASED_SERVICE,
&GSS_C_NT_USER_NAME,
&GSS_KRB5_NT_PRINCIPAL_NAME,
&GSS_C_NT_EXPORT_NAME,
NULL
};
OM_uint32 gss_inquire_names_for_mech (
OM_uint32 * minor_status,
const gss_OID mechanism,
gss_OID_set * name_types
)
{
OM_uint32 ret;
int i;
*minor_status = 0;
if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 &&
gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) {
*name_types = GSS_C_NO_OID_SET;
return GSS_S_BAD_MECH;
}
ret = gss_create_empty_oid_set(minor_status, name_types);
if (ret != GSS_S_COMPLETE)
return ret;
for (i = 0; name_list[i] != NULL; i++) {
ret = gss_add_oid_set_member(minor_status,
*(name_list[i]),
name_types);
if (ret != GSS_S_COMPLETE)
break;
}
if (ret != GSS_S_COMPLETE)
gss_release_oid_set(NULL, name_types);
return GSS_S_COMPLETE;
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2006 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"
RCSID("$Id$");
OM_uint32
gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
{
krb5_error_code ret;
size_t size;
heim_oid o;
char *p;
oid_str->value = NULL;
oid_str->length = 0;
ret = der_get_oid (oid->elements, oid->length, &o, &size);
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = der_print_heim_oid(&o, &p);
free_oid(&o);
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
oid_str->value = p;
oid_str->length = strlen(p) + 1;
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
OM_uint32 gss_process_context_token (
OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t token_buffer
)
{
OM_uint32 ret = GSS_S_FAILURE;
gss_buffer_desc empty_buffer;
gss_qop_t qop_state;
empty_buffer.length = 0;
empty_buffer.value = NULL;
qop_state = GSS_C_QOP_DEFAULT;
ret = gss_verify_mic_internal(minor_status, context_handle,
token_buffer, &empty_buffer,
GSS_C_QOP_DEFAULT, "\x01\x02");
if (ret == GSS_S_COMPLETE)
ret = gss_delete_sec_context(minor_status,
rk_UNCONST(&context_handle),
GSS_C_NO_BUFFER);
if (ret == GSS_S_COMPLETE)
*minor_status = 0;
return ret;
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 1997 - 2000, 2003 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"
RCSID("$Id$");
OM_uint32 gss_release_buffer
(OM_uint32 * minor_status,
gss_buffer_t buffer
)
{
*minor_status = 0;
free (buffer->value);
buffer->value = NULL;
buffer->length = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 1997-2003 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"
RCSID("$Id$");
OM_uint32 gss_release_cred
(OM_uint32 * minor_status,
gss_cred_id_t * cred_handle
)
{
*minor_status = 0;
if (*cred_handle == GSS_C_NO_CREDENTIAL) {
return GSS_S_COMPLETE;
}
GSSAPI_KRB5_INIT ();
HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex);
if ((*cred_handle)->principal != NULL)
krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
if ((*cred_handle)->keytab != NULL)
krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
if ((*cred_handle)->ccache != NULL) {
const krb5_cc_ops *ops;
ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache);
if ((*cred_handle)->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache);
else
krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache);
}
gss_release_oid_set(NULL, &(*cred_handle)->mechanisms);
HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex);
HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex);
memset(*cred_handle, 0, sizeof(**cred_handle));
free(*cred_handle);
*cred_handle = GSS_C_NO_CREDENTIAL;
return GSS_S_COMPLETE;
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32 gss_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
)
{
GSSAPI_KRB5_INIT ();
if (minor_status)
*minor_status = 0;
krb5_free_principal(gssapi_krb5_context,
*input_name);
*input_name = GSS_C_NO_NAME;
return GSS_S_COMPLETE;
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) 1997 - 2000, 2003 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"
RCSID("$Id$");
OM_uint32 gss_release_oid_set
(OM_uint32 * minor_status,
gss_OID_set * set
)
{
if (minor_status)
*minor_status = 0;
free ((*set)->elements);
free (*set);
*set = GSS_C_NO_OID_SET;
return GSS_S_COMPLETE;
}

View File

@@ -1,294 +0,0 @@
/*
* Copyright (c) 2003 - 2006 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"
RCSID("$Id$");
#define DEFAULT_JITTER_WINDOW 20
struct gss_msg_order {
OM_uint32 flags;
OM_uint32 start;
OM_uint32 length;
OM_uint32 jitter_window;
OM_uint32 first_seq;
OM_uint32 elem[1];
};
/*
*
*/
static OM_uint32
msg_order_alloc(OM_uint32 *minor_status,
struct gss_msg_order **o,
OM_uint32 jitter_window)
{
size_t len;
len = jitter_window * sizeof((*o)->elem[0]);
len += sizeof(**o);
len -= sizeof((*o)->elem[0]);
*o = calloc(1, len);
if (*o == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
/*
*
*/
OM_uint32
_gssapi_msg_order_create(OM_uint32 *minor_status,
struct gss_msg_order **o,
OM_uint32 flags,
OM_uint32 seq_num,
OM_uint32 jitter_window,
int use_64)
{
OM_uint32 ret;
if (jitter_window == 0)
jitter_window = DEFAULT_JITTER_WINDOW;
ret = msg_order_alloc(minor_status, o, jitter_window);
if(ret != GSS_S_COMPLETE)
return ret;
(*o)->flags = flags;
(*o)->length = 0;
(*o)->first_seq = seq_num;
(*o)->jitter_window = jitter_window;
(*o)->elem[0] = seq_num - 1;
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32
_gssapi_msg_order_destroy(struct gss_msg_order **m)
{
free(*m);
*m = NULL;
return GSS_S_COMPLETE;
}
static void
elem_set(struct gss_msg_order *o, unsigned int slot, OM_uint32 val)
{
o->elem[slot % o->jitter_window] = val;
}
static void
elem_insert(struct gss_msg_order *o,
unsigned int after_slot,
OM_uint32 seq_num)
{
assert(o->jitter_window > after_slot);
if (o->length > after_slot)
memmove(&o->elem[after_slot + 1], &o->elem[after_slot],
(o->length - after_slot - 1) * sizeof(o->elem[0]));
elem_set(o, after_slot, seq_num);
if (o->length < o->jitter_window)
o->length++;
}
/* rule 1: expected sequence number */
/* rule 2: > expected sequence number */
/* rule 3: seqnum < seqnum(first) */
/* rule 4+5: seqnum in [seqnum(first),seqnum(last)] */
OM_uint32
_gssapi_msg_order_check(struct gss_msg_order *o, OM_uint32 seq_num)
{
OM_uint32 r;
int i;
if (o == NULL)
return GSS_S_COMPLETE;
if ((o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) == 0)
return GSS_S_COMPLETE;
/* check if the packet is the next in order */
if (o->elem[0] == seq_num - 1) {
elem_insert(o, 0, seq_num);
return GSS_S_COMPLETE;
}
r = (o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG))==GSS_C_REPLAY_FLAG;
/* sequence number larger then largest sequence number
* or smaller then the first sequence number */
if (seq_num > o->elem[0]
|| seq_num < o->first_seq
|| o->length == 0)
{
elem_insert(o, 0, seq_num);
if (r) {
return GSS_S_COMPLETE;
} else {
return GSS_S_GAP_TOKEN;
}
}
assert(o->length > 0);
/* sequence number smaller the first sequence number */
if (seq_num < o->elem[o->length - 1]) {
if (r)
return(GSS_S_OLD_TOKEN);
else
return(GSS_S_UNSEQ_TOKEN);
}
if (seq_num == o->elem[o->length - 1]) {
return GSS_S_DUPLICATE_TOKEN;
}
for (i = 0; i < o->length - 1; i++) {
if (o->elem[i] == seq_num)
return GSS_S_DUPLICATE_TOKEN;
if (o->elem[i + 1] < seq_num && o->elem[i] < seq_num) {
elem_insert(o, i, seq_num);
if (r)
return GSS_S_COMPLETE;
else
return GSS_S_UNSEQ_TOKEN;
}
}
return GSS_S_FAILURE;
}
OM_uint32
_gssapi_msg_order_f(OM_uint32 flags)
{
return flags & (GSS_C_SEQUENCE_FLAG|GSS_C_REPLAY_FLAG);
}
/*
* Translate `o` into inter-process format and export in to `sp'.
*/
krb5_error_code
_gssapi_msg_order_export(krb5_storage *sp, struct gss_msg_order *o)
{
krb5_error_code kret;
OM_uint32 i;
kret = krb5_store_int32(sp, o->flags);
if (kret)
return kret;
kret = krb5_store_int32(sp, o->start);
if (kret)
return kret;
kret = krb5_store_int32(sp, o->length);
if (kret)
return kret;
kret = krb5_store_int32(sp, o->jitter_window);
if (kret)
return kret;
kret = krb5_store_int32(sp, o->first_seq);
if (kret)
return kret;
for (i = 0; i < o->jitter_window; i++) {
kret = krb5_store_int32(sp, o->elem[i]);
if (kret)
return kret;
}
return 0;
}
OM_uint32
_gssapi_msg_order_import(OM_uint32 *minor_status,
krb5_storage *sp,
struct gss_msg_order **o)
{
OM_uint32 ret;
krb5_error_code kret;
int32_t i, flags, start, length, jitter_window, first_seq;
kret = krb5_ret_int32(sp, &flags);
if (kret)
goto failed;
ret = krb5_ret_int32(sp, &start);
if (kret)
goto failed;
ret = krb5_ret_int32(sp, &length);
if (kret)
goto failed;
ret = krb5_ret_int32(sp, &jitter_window);
if (kret)
goto failed;
ret = krb5_ret_int32(sp, &first_seq);
if (kret)
goto failed;
ret = msg_order_alloc(minor_status, o, jitter_window);
if (ret != GSS_S_COMPLETE)
return ret;
(*o)->flags = flags;
(*o)->start = start;
(*o)->length = length;
(*o)->jitter_window = jitter_window;
(*o)->first_seq = first_seq;
for( i = 0; i < jitter_window; i++ ) {
kret = krb5_ret_int32(sp, (int32_t*)&((*o)->elem[i]));
if (kret)
goto failed;
}
*minor_status = 0;
return GSS_S_COMPLETE;
failed:
_gssapi_msg_order_destroy(o);
*minor_status = kret;
return GSS_S_FAILURE;
}

View File

@@ -1,240 +0,0 @@
-- from rfc2025
-- $Id$
SpkmGssTokens DEFINITIONS ::=
BEGIN
IMPORTS AlgorithmIdentifier, Validity,
Attribute, Certificate, CertificateList, CertificatePair, Name
FROM rfc2459
AuthorizationData FROM krb5;
SPKM-REQ ::= SEQUENCE {
requestToken REQ-TOKEN,
certif-data [0] CertificationData OPTIONAL,
auth-data [1] AuthorizationData OPTIONAL
}
CertificationData ::= SEQUENCE {
certificationPath [0] CertificationPath OPTIONAL,
certificateRevocationList [1] CertificateList OPTIONAL
} -- at least one of the above shall be present
CertificationPath ::= SEQUENCE {
userKeyId [0] OCTET STRING OPTIONAL,
userCertif [1] Certificate OPTIONAL,
verifKeyId [2] OCTET STRING OPTIONAL,
userVerifCertif [3] Certificate OPTIONAL,
theCACertificates [4] SEQUENCE OF CertificatePair OPTIONAL
} -- Presence of [2] or [3] implies that [0] or [1] must also be
-- present. Presence of [4] implies that at least one of [0], [1],
-- [2], and [3] must also be present.
REQ-TOKEN ::= SEQUENCE {
req-contents Req-contents,
algId AlgorithmIdentifier,
req-integrity Integrity -- "token" is Req-contents
}
Integrity ::= BIT STRING
-- If corresponding algId specifies a signing algorithm,
-- "Integrity" holds the result of applying the signing procedure
-- specified in algId to the BER-encoded octet string which results
-- from applying the hashing procedure (also specified in algId) to
-- the DER-encoded octets of "token".
-- Alternatively, if corresponding algId specifies a MACing
-- algorithm, "Integrity" holds the result of applying the MACing
-- procedure specified in algId to the DER-encoded octets of
-- "token"
Req-contents ::= SEQUENCE {
tok-id INTEGER --(256)--, -- shall contain 0100 (hex)
context-id Random-Integer,
pvno BIT STRING,
timestamp UTCTime OPTIONAL, -- mandatory for SPKM-2
randSrc Random-Integer,
targ-name Name,
src-name [0] Name OPTIONAL,
req-data Context-Data,
validity [1] Validity OPTIONAL,
key-estb-set Key-Estb-Algs,
key-estb-req BIT STRING OPTIONAL,
key-src-bind OCTET STRING OPTIONAL
-- This field must be present for the case of SPKM-2
-- unilateral authen. if the K-ALG in use does not provide
-- such a binding (but is optional for all other cases).
-- The octet string holds the result of applying the
-- mandatory hashing procedure (in MANDATORY I-ALG;
-- see Section 2.1) as follows: MD5(src || context_key),
-- where "src" is the DER-encoded octets of src-name,
-- "context-key" is the symmetric key (i.e., the
-- unprotected version of what is transmitted in
-- key-estb-req), and "||" is the concatenation operation.
}
Random-Integer ::= BIT STRING
Context-Data ::= SEQUENCE {
channelId ChannelId OPTIONAL,
seq-number INTEGER OPTIONAL,
options Options,
conf-alg Conf-Algs,
intg-alg Intg-Algs,
owf-alg OWF-Algs
}
ChannelId ::= OCTET STRING
Options ::= BIT STRING {
delegation-state (0),
mutual-state (1),
replay-det-state (2),
sequence-state (3),
conf-avail (4),
integ-avail (5),
target-certif-data-required (6)
}
Conf-Algs ::= CHOICE {
algs [0] SEQUENCE OF AlgorithmIdentifier,
null [1] NULL
}
Intg-Algs ::= SEQUENCE OF AlgorithmIdentifier
OWF-Algs ::= SEQUENCE OF AlgorithmIdentifier
Key-Estb-Algs ::= SEQUENCE OF AlgorithmIdentifier
SPKM-REP-TI ::= SEQUENCE {
responseToken REP-TI-TOKEN,
certif-data CertificationData OPTIONAL
-- present if target-certif-data-required option was
} -- set to TRUE in SPKM-REQ
REP-TI-TOKEN ::= SEQUENCE {
rep-ti-contents Rep-ti-contents,
algId AlgorithmIdentifier,
rep-ti-integ Integrity -- "token" is Rep-ti-contents
}
Rep-ti-contents ::= SEQUENCE {
tok-id INTEGER --(512)--, -- shall contain 0200 (hex)
context-id Random-Integer,
pvno [0] BIT STRING OPTIONAL,
timestamp UTCTime OPTIONAL, -- mandatory for SPKM-2
randTarg Random-Integer,
src-name [1] Name OPTIONAL,
targ-name Name,
randSrc Random-Integer,
rep-data Context-Data,
validity [2] Validity OPTIONAL,
key-estb-id AlgorithmIdentifier OPTIONAL,
key-estb-str BIT STRING OPTIONAL
}
SPKM-REP-IT ::= SEQUENCE {
responseToken REP-IT-TOKEN,
algId AlgorithmIdentifier,
rep-it-integ Integrity -- "token" is REP-IT-TOKEN
}
REP-IT-TOKEN ::= SEQUENCE {
tok-id INTEGER --(768)--, -- shall contain 0300 (hex)
context-id Random-Integer,
randSrc Random-Integer,
randTarg Random-Integer,
targ-name Name,
src-name Name OPTIONAL,
key-estb-rep BIT STRING OPTIONAL
}
SPKM-ERROR ::= SEQUENCE {
errorToken ERROR-TOKEN,
algId AlgorithmIdentifier,
integrity Integrity -- "token" is ERROR-TOKEN
}
ERROR-TOKEN ::= SEQUENCE {
tok-id INTEGER --(1024)--, -- shall contain 0400 (hex)
context-id Random-Integer
}
SPKM-MIC ::= SEQUENCE {
mic-header Mic-Header,
int-cksum BIT STRING
}
Mic-Header ::= SEQUENCE {
tok-id INTEGER --(257)--, -- shall contain 0101 (hex)
context-id Random-Integer,
int-alg [0] AlgorithmIdentifier OPTIONAL,
snd-seq [1] SeqNum OPTIONAL
}
SeqNum ::= SEQUENCE {
num INTEGER,
dir-ind BOOLEAN
}
SPKM-WRAP ::= SEQUENCE {
wrap-header Wrap-Header,
wrap-body Wrap-Body
}
Wrap-Header ::= SEQUENCE {
tok-id INTEGER --(513)--, -- shall contain 0201 (hex)
context-id Random-Integer,
int-alg [0] AlgorithmIdentifier OPTIONAL,
conf-alg [1] Conf-Alg OPTIONAL,
snd-seq [2] SeqNum OPTIONAL
}
Wrap-Body ::= SEQUENCE {
int-cksum BIT STRING,
data BIT STRING
}
Conf-Alg ::= CHOICE {
algId [0] AlgorithmIdentifier,
null [1] NULL
}
SPKM-DEL ::= SEQUENCE {
del-header Del-Header,
int-cksum BIT STRING
}
Del-Header ::= SEQUENCE {
tok-id INTEGER --(769)--, -- shall contain 0301 (hex)
context-id Random-Integer,
int-alg [0] AlgorithmIdentifier OPTIONAL,
snd-seq [1] SeqNum OPTIONAL
}
-- other types --
MechType ::= OBJECT IDENTIFIER
SPKMInnerContextToken ::= CHOICE {
req [0] SPKM-REQ,
rep-ti [1] SPKM-REP-TI,
rep-it [2] SPKM-REP-IT,
error [3] SPKM-ERROR,
mic [4] SPKM-MIC,
wrap [5] SPKM-WRAP,
del [6] SPKM-DEL
}
InitialContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
thisMech MechType,
innerContextToken SPKMInnerContextToken
} -- when thisMech is SPKM-1 or SPKM-2
END

View File

@@ -1,42 +0,0 @@
-- $Id$
SPNEGO DEFINITIONS ::=
BEGIN
MechType::= OBJECT IDENTIFIER
MechTypeList ::= SEQUENCE OF MechType
ContextFlags ::= BIT STRING {
delegFlag (0),
mutualFlag (1),
replayFlag (2),
sequenceFlag (3),
anonFlag (4),
confFlag (5),
integFlag (6)
}
NegTokenInit ::= SEQUENCE {
mechTypes [0] MechTypeList OPTIONAL,
reqFlags [1] ContextFlags OPTIONAL,
mechToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
NegTokenTarg ::= SEQUENCE {
negResult [0] ENUMERATED {
accept_completed (0),
accept_incomplete (1),
reject (2) } OPTIONAL,
supportedMech [1] MechType OPTIONAL,
responseToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
NegotiationToken ::= CHOICE {
negTokenInit[0] NegTokenInit,
negTokenTarg[1] NegTokenTarg
}
END

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 1997, 2003 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"
RCSID("$Id$");
OM_uint32 gss_test_oid_set_member (
OM_uint32 * minor_status,
const gss_OID member,
const gss_OID_set set,
int * present
)
{
size_t i;
*minor_status = 0;
*present = 0;
for (i = 0; i < set->count; ++i)
if (gss_oid_equal(member, &set->elements[i]) != 0) {
*present = 1;
break;
}
return GSS_S_COMPLETE;
}

View File

@@ -1,369 +0,0 @@
/*
* Copyright (c) 2003 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"
RCSID("$Id$");
/* correct ordering */
OM_uint32 pattern1[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
};
/* gap 10 */
OM_uint32 pattern2[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13
};
/* dup 9 */
OM_uint32 pattern3[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13
};
/* gaps */
OM_uint32 pattern4[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15, 16, 18, 100
};
/* 11 before 10 */
OM_uint32 pattern5[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
};
/* long */
OM_uint32 pattern6[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59
};
/* dont start at 0 */
OM_uint32 pattern7[] = {
11, 12, 13
};
/* wrap around */
OM_uint32 pattern8[] = {
4294967293U, 4294967294U, 4294967295U, 0, 1, 2
};
static int
test_seq(int t, OM_uint32 flags, OM_uint32 start_seq,
OM_uint32 *pattern, int pattern_len, OM_uint32 expected_error)
{
struct gss_msg_order *o;
OM_uint32 maj_stat, min_stat;
krb5_storage *sp;
int i;
maj_stat = _gssapi_msg_order_create(&min_stat, &o, flags,
start_seq, 20, 0);
if (maj_stat)
errx(1, "create: %d %d", maj_stat, min_stat);
sp = krb5_storage_emem();
if (sp == NULL)
errx(1, "krb5_storage_from_emem");
_gssapi_msg_order_export(sp, o);
for (i = 0; i < pattern_len; i++) {
maj_stat = _gssapi_msg_order_check(o, pattern[i]);
if (maj_stat)
break;
}
if (maj_stat != expected_error) {
printf("test pattern %d failed with %d (should have been %d)\n",
t, maj_stat, expected_error);
krb5_storage_free(sp);
_gssapi_msg_order_destroy(&o);
return 1;
}
_gssapi_msg_order_destroy(&o);
/* try again, now with export/imported blob */
krb5_storage_seek(sp, 0, SEEK_SET);
maj_stat = _gssapi_msg_order_import(&min_stat, sp, &o);
if (maj_stat)
errx(1, "import: %d %d", maj_stat, min_stat);
for (i = 0; i < pattern_len; i++) {
maj_stat = _gssapi_msg_order_check(o, pattern[i]);
if (maj_stat)
break;
}
if (maj_stat != expected_error) {
printf("import/export test pattern %d failed "
"with %d (should have been %d)\n",
t, maj_stat, expected_error);
_gssapi_msg_order_destroy(&o);
krb5_storage_free(sp);
return 1;
}
_gssapi_msg_order_destroy(&o);
krb5_storage_free(sp);
return 0;
}
struct {
OM_uint32 flags;
OM_uint32 *pattern;
int pattern_len;
OM_uint32 error_code;
OM_uint32 start_seq;
} pl[] = {
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern1,
sizeof(pattern1)/sizeof(pattern1[0]),
0
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern2,
sizeof(pattern2)/sizeof(pattern2[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern3,
sizeof(pattern3)/sizeof(pattern3[0]),
GSS_S_DUPLICATE_TOKEN
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern4,
sizeof(pattern4)/sizeof(pattern4[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern5,
sizeof(pattern5)/sizeof(pattern5[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern6,
sizeof(pattern6)/sizeof(pattern6[0]),
GSS_S_COMPLETE
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern7,
sizeof(pattern7)/sizeof(pattern7[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG,
pattern8,
sizeof(pattern8)/sizeof(pattern8[0]),
GSS_S_COMPLETE,
4294967293U
},
{
0,
pattern1,
sizeof(pattern1)/sizeof(pattern1[0]),
GSS_S_COMPLETE
},
{
0,
pattern2,
sizeof(pattern2)/sizeof(pattern2[0]),
GSS_S_COMPLETE
},
{
0,
pattern3,
sizeof(pattern3)/sizeof(pattern3[0]),
GSS_S_COMPLETE
},
{
0,
pattern4,
sizeof(pattern4)/sizeof(pattern4[0]),
GSS_S_COMPLETE
},
{
0,
pattern5,
sizeof(pattern5)/sizeof(pattern5[0]),
GSS_S_COMPLETE
},
{
0,
pattern6,
sizeof(pattern6)/sizeof(pattern6[0]),
GSS_S_COMPLETE
},
{
0,
pattern7,
sizeof(pattern7)/sizeof(pattern7[0]),
GSS_S_COMPLETE
},
{
0,
pattern8,
sizeof(pattern8)/sizeof(pattern8[0]),
GSS_S_COMPLETE,
4294967293U
},
{
GSS_C_REPLAY_FLAG,
pattern1,
sizeof(pattern1)/sizeof(pattern1[0]),
GSS_S_COMPLETE
},
{
GSS_C_REPLAY_FLAG,
pattern2,
sizeof(pattern2)/sizeof(pattern2[0]),
GSS_S_COMPLETE
},
{
GSS_C_REPLAY_FLAG,
pattern3,
sizeof(pattern3)/sizeof(pattern3[0]),
GSS_S_DUPLICATE_TOKEN
},
{
GSS_C_REPLAY_FLAG,
pattern4,
sizeof(pattern4)/sizeof(pattern4[0]),
GSS_S_COMPLETE
},
{
GSS_C_REPLAY_FLAG,
pattern5,
sizeof(pattern5)/sizeof(pattern5[0]),
0
},
{
GSS_C_REPLAY_FLAG,
pattern6,
sizeof(pattern6)/sizeof(pattern6[0]),
GSS_S_COMPLETE
},
{
GSS_C_REPLAY_FLAG,
pattern7,
sizeof(pattern7)/sizeof(pattern7[0]),
GSS_S_COMPLETE
},
{
GSS_C_SEQUENCE_FLAG,
pattern8,
sizeof(pattern8)/sizeof(pattern8[0]),
GSS_S_COMPLETE,
4294967293U
},
{
GSS_C_SEQUENCE_FLAG,
pattern1,
sizeof(pattern1)/sizeof(pattern1[0]),
0
},
{
GSS_C_SEQUENCE_FLAG,
pattern2,
sizeof(pattern2)/sizeof(pattern2[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_SEQUENCE_FLAG,
pattern3,
sizeof(pattern3)/sizeof(pattern3[0]),
GSS_S_DUPLICATE_TOKEN
},
{
GSS_C_SEQUENCE_FLAG,
pattern4,
sizeof(pattern4)/sizeof(pattern4[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_SEQUENCE_FLAG,
pattern5,
sizeof(pattern5)/sizeof(pattern5[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_SEQUENCE_FLAG,
pattern6,
sizeof(pattern6)/sizeof(pattern6[0]),
GSS_S_COMPLETE
},
{
GSS_C_SEQUENCE_FLAG,
pattern7,
sizeof(pattern7)/sizeof(pattern7[0]),
GSS_S_GAP_TOKEN
},
{
GSS_C_REPLAY_FLAG,
pattern8,
sizeof(pattern8)/sizeof(pattern8[0]),
GSS_S_COMPLETE,
4294967293U
}
};
int
main(int argc, char **argv)
{
int i, failed = 0;
for (i = 0; i < sizeof(pl)/sizeof(pl[0]); i++) {
if (test_seq(i,
pl[i].flags,
pl[i].start_seq,
pl[i].pattern,
pl[i].pattern_len,
pl[i].error_code))
failed++;
}
if (failed)
printf("FAILED %d tests\n", failed);
return failed != 0;
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2004 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"
RCSID("$Id$");
OM_uint32
gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
OM_uint32 *tkt_flags)
{
if (context_handle == GSS_C_NO_CONTEXT) {
*minor_status = EINVAL;
return GSS_S_NO_CONTEXT;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
if (context_handle->ticket == NULL) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
*minor_status = EINVAL;
return GSS_S_BAD_MECH;
}
*tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
*minor_status = 0;
return GSS_S_COMPLETE;
}

View File

@@ -1,413 +0,0 @@
/*
* Copyright (c) 1997 - 2004 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"
RCSID("$Id$");
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
gss_qop_t * qop_state,
krb5_keyblock *key
)
{
u_char *p, *seq;
size_t len;
MD5_CTX md5;
u_char hash[16];
DES_key_schedule schedule;
DES_cblock deskey;
DES_cblock zero;
int i;
uint32_t seq_number;
size_t padlength;
OM_uint32 ret;
int cstate;
int cmp;
p = input_message_buffer->value;
ret = gssapi_krb5_verify_header (&p,
input_message_buffer->length,
"\x02\x01",
GSS_KRB5_MECHANISM);
if (ret)
return ret;
if (memcmp (p, "\x00\x00", 2) != 0)
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\x00\x00", 2) == 0) {
cstate = 1;
} else if (memcmp (p, "\xFF\xFF", 2) == 0) {
cstate = 0;
} else
return GSS_S_BAD_MIC;
p += 2;
if(conf_state != NULL)
*conf_state = cstate;
if (memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
p += 2;
p += 16;
len = p - (u_char *)input_message_buffer->value;
if(cstate) {
/* decrypt data */
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
DES_set_key (&deskey, &schedule);
memset (&zero, 0, sizeof(zero));
DES_cbc_encrypt ((void *)p,
(void *)p,
input_message_buffer->length - len,
&schedule,
&zero,
DES_DECRYPT);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
}
/* check pad */
ret = _gssapi_verify_pad(input_message_buffer,
input_message_buffer->length - len,
&padlength);
if (ret)
return ret;
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, p, input_message_buffer->length - len);
MD5_Final (hash, &md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
if (memcmp (p - 8, hash, 8) != 0)
return GSS_S_BAD_MIC;
/* verify sequence number */
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)hash, DES_DECRYPT);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
seq = p;
gssapi_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
if (ret) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/* copy out data */
output_message_buffer->length = input_message_buffer->length
- len - padlength - 8;
output_message_buffer->value = malloc(output_message_buffer->length);
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
return GSS_S_FAILURE;
memcpy (output_message_buffer->value,
p + 24,
output_message_buffer->length);
return GSS_S_COMPLETE;
}
static OM_uint32
unwrap_des3
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
gss_qop_t * qop_state,
krb5_keyblock *key
)
{
u_char *p;
size_t len;
u_char *seq;
krb5_data seq_data;
u_char cksum[20];
uint32_t seq_number;
size_t padlength;
OM_uint32 ret;
int cstate;
krb5_crypto crypto;
Checksum csum;
int cmp;
p = input_message_buffer->value;
ret = gssapi_krb5_verify_header (&p,
input_message_buffer->length,
"\x02\x01",
GSS_KRB5_MECHANISM);
if (ret)
return ret;
if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\x02\x00", 2) == 0) {
cstate = 1;
} else if (memcmp (p, "\xff\xff", 2) == 0) {
cstate = 0;
} else
return GSS_S_BAD_MIC;
p += 2;
if(conf_state != NULL)
*conf_state = cstate;
if (memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
p += 2;
p += 28;
len = p - (u_char *)input_message_buffer->value;
if(cstate) {
/* decrypt data */
krb5_data tmp;
ret = krb5_crypto_init(gssapi_krb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_decrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL,
p, input_message_buffer->length - len, &tmp);
krb5_crypto_destroy(gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
assert (tmp.length == input_message_buffer->length - len);
memcpy (p, tmp.data, tmp.length);
krb5_data_free(&tmp);
}
/* check pad */
ret = _gssapi_verify_pad(input_message_buffer,
input_message_buffer->length - len,
&padlength);
if (ret)
return ret;
/* verify sequence number */
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 28;
ret = krb5_crypto_init(gssapi_krb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_FAILURE;
}
{
DES_cblock ivec;
memcpy(&ivec, p + 8, 8);
ret = krb5_decrypt_ivec (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
p, 8, &seq_data,
&ivec);
}
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_FAILURE;
}
if (seq_data.length != 8) {
krb5_data_free (&seq_data);
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
seq = seq_data.data;
gssapi_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
if (ret) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/* verify checksum */
memcpy (cksum, p + 8, 20);
memcpy (p + 20, p - 8, 8);
csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
csum.checksum.length = 20;
csum.checksum.data = cksum;
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_verify_checksum (gssapi_krb5_context, crypto,
KRB5_KU_USAGE_SIGN,
p + 20,
input_message_buffer->length - len + 8,
&csum);
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
/* copy out data */
output_message_buffer->length = input_message_buffer->length
- len - padlength - 8;
output_message_buffer->value = malloc(output_message_buffer->length);
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
return GSS_S_FAILURE;
memcpy (output_message_buffer->value,
p + 36,
output_message_buffer->length);
return GSS_S_COMPLETE;
}
OM_uint32 gss_unwrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
gss_qop_t * qop_state
)
{
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
output_message_buffer->value = NULL;
output_message_buffer->length = 0;
if (qop_state != NULL)
*qop_state = GSS_C_QOP_DEFAULT;
ret = gss_krb5_get_subkey(context_handle, &key);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
*minor_status = 0;
switch (keytype) {
case KEYTYPE_DES :
ret = unwrap_des (minor_status, context_handle,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
case KEYTYPE_DES3 :
ret = unwrap_des3 (minor_status, context_handle,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
ret = _gssapi_unwrap_arcfour (minor_status, context_handle,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
default :
ret = _gssapi_unwrap_cfx (minor_status, context_handle,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
}
krb5_free_keyblock (gssapi_krb5_context, key);
return ret;
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 1997 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"
RCSID("$Id$");
/* These functions are for V1 compatibility */
OM_uint32 gss_sign
(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int qop_req,
gss_buffer_t message_buffer,
gss_buffer_t message_token
)
{
return gss_get_mic(minor_status,
context_handle,
(gss_qop_t)qop_req,
message_buffer,
message_token);
}
OM_uint32 gss_verify
(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t message_buffer,
gss_buffer_t token_buffer,
int * qop_state
)
{
return gss_verify_mic(minor_status,
context_handle,
message_buffer,
token_buffer,
(gss_qop_t *)qop_state);
}
OM_uint32 gss_seal
(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
int qop_req,
gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer
)
{
return gss_wrap(minor_status,
context_handle,
conf_req_flag,
(gss_qop_t)qop_req,
input_message_buffer,
conf_state,
output_message_buffer);
}
OM_uint32 gss_unseal
(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
int * qop_state
)
{
return gss_unwrap(minor_status,
context_handle,
input_message_buffer,
output_message_buffer,
conf_state,
(gss_qop_t *)qop_state);
}

View File

@@ -1,336 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
krb5_keyblock *key,
char *type
)
{
u_char *p;
MD5_CTX md5;
u_char hash[16], *seq;
DES_key_schedule schedule;
DES_cblock zero;
DES_cblock deskey;
uint32_t seq_number;
OM_uint32 ret;
int cmp;
p = token_buffer->value;
ret = gssapi_krb5_verify_header (&p,
token_buffer->length,
type,
GSS_KRB5_MECHANISM);
if (ret)
return ret;
if (memcmp(p, "\x00\x00", 2) != 0)
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
return GSS_S_BAD_MIC;
p += 4;
p += 16;
/* verify checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, message_buffer->value,
message_buffer->length);
MD5_Final (hash, &md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
if (memcmp (p - 8, hash, 8) != 0) {
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
return GSS_S_BAD_MIC;
}
/* verify sequence number */
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)hash, DES_DECRYPT);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
seq = p;
gssapi_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
if (ret) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_COMPLETE;
}
static OM_uint32
verify_mic_des3
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
krb5_keyblock *key,
char *type
)
{
u_char *p;
u_char *seq;
uint32_t seq_number;
OM_uint32 ret;
krb5_crypto crypto;
krb5_data seq_data;
int cmp, docompat;
Checksum csum;
char *tmp;
char ivec[8];
p = token_buffer->value;
ret = gssapi_krb5_verify_header (&p,
token_buffer->length,
type,
GSS_KRB5_MECHANISM);
if (ret)
return ret;
if (memcmp(p, "\x04\x00", 2) != 0) /* SGN_ALG = HMAC SHA1 DES3-KD */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
return GSS_S_BAD_MIC;
p += 4;
ret = krb5_crypto_init(gssapi_krb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret){
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
/* verify sequence number */
docompat = 0;
retry:
if (docompat)
memset(ivec, 0, 8);
else
memcpy(ivec, p + 8, 8);
ret = krb5_decrypt_ivec (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
p, 8, &seq_data, ivec);
if (ret) {
if (docompat++) {
gssapi_krb5_set_error_string ();
krb5_crypto_destroy (gssapi_krb5_context, crypto);
*minor_status = ret;
return GSS_S_FAILURE;
} else
goto retry;
}
if (seq_data.length != 8) {
krb5_data_free (&seq_data);
if (docompat++) {
krb5_crypto_destroy (gssapi_krb5_context, crypto);
return GSS_S_BAD_MIC;
} else
goto retry;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
seq = seq_data.data;
gssapi_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
krb5_crypto_destroy (gssapi_krb5_context, crypto);
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
if (ret) {
krb5_crypto_destroy (gssapi_krb5_context, crypto);
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return ret;
}
/* verify checksum */
tmp = malloc (message_buffer->length + 8);
if (tmp == NULL) {
krb5_crypto_destroy (gssapi_krb5_context, crypto);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (tmp, p - 8, 8);
memcpy (tmp + 8, message_buffer->value, message_buffer->length);
csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
csum.checksum.length = 20;
csum.checksum.data = p + 8;
ret = krb5_verify_checksum (gssapi_krb5_context, crypto,
KRB5_KU_USAGE_SIGN,
tmp, message_buffer->length + 8,
&csum);
free (tmp);
if (ret) {
gssapi_krb5_set_error_string ();
krb5_crypto_destroy (gssapi_krb5_context, crypto);
*minor_status = ret;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
return GSS_S_BAD_MIC;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
krb5_crypto_destroy (gssapi_krb5_context, crypto);
return GSS_S_COMPLETE;
}
OM_uint32
gss_verify_mic_internal
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
char * type
)
{
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
ret = gss_krb5_get_subkey(context_handle, &key);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
*minor_status = 0;
krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
ret = verify_mic_des (minor_status, context_handle,
message_buffer, token_buffer, qop_state, key,
type);
break;
case KEYTYPE_DES3 :
ret = verify_mic_des3 (minor_status, context_handle,
message_buffer, token_buffer, qop_state, key,
type);
break;
case KEYTYPE_ARCFOUR :
case KEYTYPE_ARCFOUR_56 :
ret = _gssapi_verify_mic_arcfour (minor_status, context_handle,
message_buffer, token_buffer,
qop_state, key, type);
break;
default :
ret = _gssapi_verify_mic_cfx (minor_status, context_handle,
message_buffer, token_buffer, qop_state,
key);
break;
}
krb5_free_keyblock (gssapi_krb5_context, key);
return ret;
}
OM_uint32
gss_verify_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state
)
{
OM_uint32 ret;
if (qop_state != NULL)
*qop_state = GSS_C_QOP_DEFAULT;
ret = gss_verify_mic_internal(minor_status, context_handle,
message_buffer, token_buffer,
qop_state, "\x01\x01");
return ret;
}

View File

@@ -1,506 +0,0 @@
/*
* Copyright (c) 1997 - 2003 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"
RCSID("$Id$");
OM_uint32
gss_krb5_get_subkey(const gss_ctx_id_t context_handle,
krb5_keyblock **key)
{
krb5_keyblock *skey = NULL;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
if (context_handle->more_flags & LOCAL) {
krb5_auth_con_getremotesubkey(gssapi_krb5_context,
context_handle->auth_context,
&skey);
} else {
krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
context_handle->auth_context,
&skey);
}
/*
* Only use the initiator subkey or ticket session key if
* an acceptor subkey was not required.
*/
if (skey == NULL &&
(context_handle->more_flags & ACCEPTOR_SUBKEY) == 0) {
if (context_handle->more_flags & LOCAL) {
krb5_auth_con_getlocalsubkey(gssapi_krb5_context,
context_handle->auth_context,
&skey);
} else {
krb5_auth_con_getremotesubkey(gssapi_krb5_context,
context_handle->auth_context,
&skey);
}
if(skey == NULL)
krb5_auth_con_getkey(gssapi_krb5_context,
context_handle->auth_context,
&skey);
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if(skey == NULL)
return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */
*key = skey;
return 0;
}
static OM_uint32
sub_wrap_size (
OM_uint32 req_output_size,
OM_uint32 * max_input_size,
int blocksize,
int extrasize
)
{
size_t len, total_len;
len = 8 + req_output_size + blocksize + extrasize;
gssapi_krb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
total_len -= req_output_size; /* token length */
if (total_len < req_output_size) {
*max_input_size = (req_output_size - total_len);
(*max_input_size) &= (~(OM_uint32)(blocksize - 1));
} else {
*max_input_size = 0;
}
return GSS_S_COMPLETE;
}
OM_uint32
gss_wrap_size_limit (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
OM_uint32 req_output_size,
OM_uint32 * max_input_size
)
{
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
ret = gss_krb5_get_subkey(context_handle, &key);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
break;
case KEYTYPE_DES3 :
ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
break;
default :
ret = _gssapi_wrap_size_cfx(minor_status, context_handle,
conf_req_flag, qop_req,
req_output_size, max_input_size, key);
break;
}
krb5_free_keyblock (gssapi_krb5_context, key);
*minor_status = 0;
return ret;
}
static OM_uint32
wrap_des
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key
)
{
u_char *p;
MD5_CTX md5;
u_char hash[16];
DES_key_schedule schedule;
DES_cblock deskey;
DES_cblock zero;
int i;
int32_t seq_number;
size_t len, total_len, padlength, datalen;
padlength = 8 - (input_message_buffer->length % 8);
datalen = input_message_buffer->length + padlength + 8;
len = datalen + 22;
gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
output_message_buffer->length = total_len;
output_message_buffer->value = malloc (total_len);
if (output_message_buffer->value == NULL) {
output_message_buffer->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = gssapi_krb5_make_header(output_message_buffer->value,
len,
"\x02\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
/* SGN_ALG */
memcpy (p, "\x00\x00", 2);
p += 2;
/* SEAL_ALG */
if(conf_req_flag)
memcpy (p, "\x00\x00", 2);
else
memcpy (p, "\xff\xff", 2);
p += 2;
/* Filler */
memcpy (p, "\xff\xff", 2);
p += 2;
/* fill in later */
memset (p, 0, 16);
p += 16;
/* confounder + data + pad */
krb5_generate_random_block(p, 8);
memcpy (p + 8, input_message_buffer->value,
input_message_buffer->length);
memset (p + 8 + input_message_buffer->length, padlength, padlength);
/* checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, p, datalen);
MD5_Final (hash, &md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
memcpy (p - 8, hash, 8);
/* sequence number */
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
p -= 16;
p[0] = (seq_number >> 0) & 0xFF;
p[1] = (seq_number >> 8) & 0xFF;
p[2] = (seq_number >> 16) & 0xFF;
p[3] = (seq_number >> 24) & 0xFF;
memset (p + 4,
(context_handle->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/* encrypt the data */
p += 16;
if(conf_req_flag) {
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
DES_set_key (&deskey, &schedule);
memset (&zero, 0, sizeof(zero));
DES_cbc_encrypt ((void *)p,
(void *)p,
datalen,
&schedule,
&zero,
DES_ENCRYPT);
}
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
if(conf_state != NULL)
*conf_state = conf_req_flag;
*minor_status = 0;
return GSS_S_COMPLETE;
}
static OM_uint32
wrap_des3
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key
)
{
u_char *p;
u_char seq[8];
int32_t seq_number;
size_t len, total_len, padlength, datalen;
uint32_t ret;
krb5_crypto crypto;
Checksum cksum;
krb5_data encdata;
padlength = 8 - (input_message_buffer->length % 8);
datalen = input_message_buffer->length + padlength + 8;
len = datalen + 34;
gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
output_message_buffer->length = total_len;
output_message_buffer->value = malloc (total_len);
if (output_message_buffer->value == NULL) {
output_message_buffer->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p = gssapi_krb5_make_header(output_message_buffer->value,
len,
"\x02\x01", /* TOK_ID */
GSS_KRB5_MECHANISM);
/* SGN_ALG */
memcpy (p, "\x04\x00", 2); /* HMAC SHA1 DES3-KD */
p += 2;
/* SEAL_ALG */
if(conf_req_flag)
memcpy (p, "\x02\x00", 2); /* DES3-KD */
else
memcpy (p, "\xff\xff", 2);
p += 2;
/* Filler */
memcpy (p, "\xff\xff", 2);
p += 2;
/* calculate checksum (the above + confounder + data + pad) */
memcpy (p + 20, p - 8, 8);
krb5_generate_random_block(p + 28, 8);
memcpy (p + 28 + 8, input_message_buffer->value,
input_message_buffer->length);
memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength);
ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto);
if (ret) {
gssapi_krb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_create_checksum (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SIGN,
0,
p + 20,
datalen + 8,
&cksum);
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
/* zero out SND_SEQ + SGN_CKSUM in case */
memset (p, 0, 28);
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
free_Checksum (&cksum);
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
/* sequence number */
krb5_auth_con_getlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
&seq_number);
seq[0] = (seq_number >> 0) & 0xFF;
seq[1] = (seq_number >> 8) & 0xFF;
seq[2] = (seq_number >> 16) & 0xFF;
seq[3] = (seq_number >> 24) & 0xFF;
memset (seq + 4,
(context_handle->more_flags & LOCAL) ? 0 : 0xFF,
4);
ret = krb5_crypto_init(gssapi_krb5_context, key, ETYPE_DES3_CBC_NONE,
&crypto);
if (ret) {
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
{
DES_cblock ivec;
memcpy (&ivec, p + 8, 8);
ret = krb5_encrypt_ivec (gssapi_krb5_context,
crypto,
KRB5_KU_USAGE_SEQ,
seq, 8, &encdata,
&ivec);
}
krb5_crypto_destroy (gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
assert (encdata.length == 8);
memcpy (p, encdata.data, encdata.length);
krb5_data_free (&encdata);
krb5_auth_con_setlocalseqnumber (gssapi_krb5_context,
context_handle->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
/* encrypt the data */
p += 28;
if(conf_req_flag) {
krb5_data tmp;
ret = krb5_crypto_init(gssapi_krb5_context, key,
ETYPE_DES3_CBC_NONE, &crypto);
if (ret) {
gssapi_krb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_encrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL,
p, datalen, &tmp);
krb5_crypto_destroy(gssapi_krb5_context, crypto);
if (ret) {
gssapi_krb5_set_error_string ();
free (output_message_buffer->value);
output_message_buffer->length = 0;
output_message_buffer->value = NULL;
*minor_status = ret;
return GSS_S_FAILURE;
}
assert (tmp.length == datalen);
memcpy (p, tmp.data, datalen);
krb5_data_free(&tmp);
}
if(conf_state != NULL)
*conf_state = conf_req_flag;
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 gss_wrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer
)
{
krb5_keyblock *key;
OM_uint32 ret;
krb5_keytype keytype;
ret = gss_krb5_get_subkey(context_handle, &key);
if (ret) {
gssapi_krb5_set_error_string ();
*minor_status = ret;
return GSS_S_FAILURE;
}
krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
ret = wrap_des (minor_status, context_handle, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
case KEYTYPE_DES3 :
ret = wrap_des3 (minor_status, context_handle, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
ret = _gssapi_wrap_arcfour (minor_status, context_handle, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
default :
ret = _gssapi_wrap_cfx (minor_status, context_handle, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
}
krb5_free_keyblock (gssapi_krb5_context, key);
return ret;
}