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:
		@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;  
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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_ */
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										840
									
								
								lib/gssapi/cfx.c
									
									
									
									
									
								
							
							
						
						
									
										840
									
								
								lib/gssapi/cfx.c
									
									
									
									
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								lib/gssapi/cfx.h
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								lib/gssapi/cfx.h
									
									
									
									
									
								
							@@ -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_ */
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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
											
										
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								lib/gssapi/v1.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								lib/gssapi/v1.c
									
									
									
									
									
								
							@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user