wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: 8003.c,v 1.20 2006/10/07 22:13:51 lha Exp $");
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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);
|
||||
_gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
|
||||
MD5_Update (&md5, num, sizeof(num));
|
||||
_gsskrb5_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);
|
||||
_gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
|
||||
MD5_Update (&md5, num, sizeof(num));
|
||||
_gsskrb5_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);
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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;
|
||||
_gsskrb5_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;
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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;
|
||||
_gsskrb5_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);
|
||||
|
||||
_gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,805 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: accept_sec_context.c,v 1.65 2006/11/07 14:52:05 lha Exp $");
|
||||
|
||||
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
|
||||
krb5_keytab _gsskrb5_keytab;
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_register_acceptor_identity (const char *identity)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = _gsskrb5_init();
|
||||
if(ret)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
|
||||
|
||||
if(_gsskrb5_keytab != NULL) {
|
||||
krb5_kt_close(_gsskrb5_context, _gsskrb5_keytab);
|
||||
_gsskrb5_keytab = NULL;
|
||||
}
|
||||
if (identity == NULL) {
|
||||
ret = krb5_kt_default(_gsskrb5_context, &_gsskrb5_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(_gsskrb5_context, p, &_gsskrb5_keytab);
|
||||
free(p);
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
|
||||
if(ret)
|
||||
return GSS_S_FAILURE;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
void
|
||||
_gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
|
||||
{
|
||||
krb5_keyblock *key;
|
||||
int acceptor = (ctx->more_flags & LOCAL) == 0;
|
||||
|
||||
*is_cfx = 0;
|
||||
|
||||
if (acceptor) {
|
||||
if (ctx->auth_context->local_subkey)
|
||||
key = ctx->auth_context->local_subkey;
|
||||
else
|
||||
key = ctx->auth_context->remote_subkey;
|
||||
} else {
|
||||
if (ctx->auth_context->remote_subkey)
|
||||
key = ctx->auth_context->remote_subkey;
|
||||
else
|
||||
key = ctx->auth_context->local_subkey;
|
||||
}
|
||||
if (key == NULL)
|
||||
key = ctx->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 && ctx->auth_context->local_subkey) ||
|
||||
(!acceptor && ctx->auth_context->remote_subkey))
|
||||
ctx->more_flags |= ACCEPTOR_SUBKEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OM_uint32
|
||||
gsskrb5_accept_delegated_token
|
||||
(OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
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 (_gsskrb5_context, &ccache);
|
||||
} else {
|
||||
*delegated_cred_handle = NULL;
|
||||
kret = krb5_cc_gen_new (_gsskrb5_context, &krb5_mcc_ops, &ccache);
|
||||
}
|
||||
if (kret) {
|
||||
ctx->flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
kret = krb5_cc_initialize(_gsskrb5_context, ccache, ctx->source);
|
||||
if (kret) {
|
||||
ctx->flags &= ~GSS_C_DELEG_FLAG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
krb5_auth_con_removeflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_DO_TIME,
|
||||
&ac_flags);
|
||||
kret = krb5_rd_cred2(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
ccache,
|
||||
&ctx->fwd_data);
|
||||
if (kret)
|
||||
_gsskrb5_set_error_string();
|
||||
krb5_auth_con_setflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
ac_flags);
|
||||
if (kret) {
|
||||
ctx->flags &= ~GSS_C_DELEG_FLAG;
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (delegated_cred_handle) {
|
||||
gsskrb5_cred handle;
|
||||
|
||||
ret = _gsskrb5_import_cred(minor_status,
|
||||
ccache,
|
||||
NULL,
|
||||
NULL,
|
||||
delegated_cred_handle);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
goto out;
|
||||
|
||||
handle = (gsskrb5_cred) *delegated_cred_handle;
|
||||
|
||||
handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
|
||||
krb5_cc_close(_gsskrb5_context, ccache);
|
||||
ccache = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ccache) {
|
||||
if (delegated_cred_handle == NULL)
|
||||
krb5_cc_close(_gsskrb5_context, ccache);
|
||||
else
|
||||
krb5_cc_destroy(_gsskrb5_context, ccache);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
gsskrb5_acceptor_ready(OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
gss_cred_id_t *delegated_cred_handle)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
int32_t seq_number;
|
||||
int is_cfx = 0;
|
||||
|
||||
krb5_auth_getremoteseqnumber (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
||||
|
||||
ret = _gssapi_msg_order_create(minor_status,
|
||||
&ctx->order,
|
||||
_gssapi_msg_order_f(ctx->flags),
|
||||
seq_number, 0, is_cfx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If requested, set local sequence num to remote sequence if this
|
||||
* isn't a mutual authentication context
|
||||
*/
|
||||
if (!(ctx->flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(ctx->flags)) {
|
||||
krb5_auth_con_setlocalseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
seq_number);
|
||||
}
|
||||
|
||||
/*
|
||||
* We should handle the delegation ticket, in case it's there
|
||||
*/
|
||||
if (ctx->fwd_data.length > 0 && (ctx->flags & GSS_C_DELEG_FLAG)) {
|
||||
ret = gsskrb5_accept_delegated_token(minor_status,
|
||||
ctx,
|
||||
delegated_cred_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
/* Well, looks like it wasn't there after all */
|
||||
ctx->flags &= ~GSS_C_DELEG_FLAG;
|
||||
}
|
||||
|
||||
ctx->state = ACCEPTOR_READY;
|
||||
ctx->more_flags |= OPEN;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
gsskrb5_acceptor_start(OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
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;
|
||||
krb5_keytab keytab = NULL;
|
||||
int is_cfx = 0;
|
||||
const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle;
|
||||
|
||||
/*
|
||||
* We may, or may not, have an escapsulation.
|
||||
*/
|
||||
ret = _gsskrb5_decapsulate (minor_status,
|
||||
input_token_buffer,
|
||||
&indata,
|
||||
"\x01\x00",
|
||||
GSS_KRB5_MECHANISM);
|
||||
|
||||
if (ret) {
|
||||
/* Assume that there is no OID wrapping. */
|
||||
indata.length = input_token_buffer->length;
|
||||
indata.data = input_token_buffer->value;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to get our keytab
|
||||
*/
|
||||
if (acceptor_cred == NULL) {
|
||||
if (_gsskrb5_keytab != NULL)
|
||||
keytab = _gsskrb5_keytab;
|
||||
} else if (acceptor_cred->keytab != NULL) {
|
||||
keytab = acceptor_cred->keytab;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to check the ticket and create the AP-REP packet
|
||||
*/
|
||||
|
||||
{
|
||||
krb5_rd_req_in_ctx in = NULL;
|
||||
krb5_rd_req_out_ctx out = NULL;
|
||||
|
||||
kret = krb5_rd_req_in_ctx_alloc(_gsskrb5_context, &in);
|
||||
if (kret == 0)
|
||||
kret = krb5_rd_req_in_set_keytab(_gsskrb5_context, in, keytab);
|
||||
if (kret) {
|
||||
if (in)
|
||||
krb5_rd_req_in_ctx_free(_gsskrb5_context, in);
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
kret = krb5_rd_req_ctx(_gsskrb5_context,
|
||||
&ctx->auth_context,
|
||||
&indata,
|
||||
(acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred->principal,
|
||||
in, &out);
|
||||
krb5_rd_req_in_ctx_free(_gsskrb5_context, in);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to remember some data on the context_handle.
|
||||
*/
|
||||
kret = krb5_rd_req_out_get_ap_req_options(_gsskrb5_context, out,
|
||||
&ap_options);
|
||||
if (kret == 0)
|
||||
kret = krb5_rd_req_out_get_ticket(_gsskrb5_context, out,
|
||||
&ctx->ticket);
|
||||
if (kret == 0)
|
||||
kret = krb5_rd_req_out_get_keyblock(_gsskrb5_context, out,
|
||||
&ctx->service_keyblock);
|
||||
ctx->lifetime = ctx->ticket->ticket.endtime;
|
||||
|
||||
krb5_rd_req_out_ctx_free(_gsskrb5_context, out);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We need to copy the principal names to the context and the
|
||||
* calling layer.
|
||||
*/
|
||||
kret = krb5_copy_principal(_gsskrb5_context,
|
||||
ctx->ticket->client,
|
||||
&ctx->source);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
}
|
||||
|
||||
kret = krb5_copy_principal(_gsskrb5_context,
|
||||
ctx->ticket->server,
|
||||
&ctx->target);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to setup some compat stuff, this assumes that
|
||||
* context_handle->target is already set.
|
||||
*/
|
||||
ret = _gss_DES3_get_mic_compat(minor_status, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (src_name != NULL) {
|
||||
kret = krb5_copy_principal (_gsskrb5_context,
|
||||
ctx->ticket->client,
|
||||
(gsskrb5_name*)src_name);
|
||||
if (kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to get the flags out of the 8003 checksum.
|
||||
*/
|
||||
{
|
||||
krb5_authenticator authenticator;
|
||||
|
||||
kret = krb5_auth_con_getauthenticator(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&authenticator);
|
||||
if(kret) {
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
|
||||
ret = _gsskrb5_verify_8003_checksum(minor_status,
|
||||
input_chan_bindings,
|
||||
authenticator->cksum,
|
||||
&ctx->flags,
|
||||
&ctx->fwd_data);
|
||||
|
||||
krb5_free_authenticator(_gsskrb5_context, &authenticator);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
krb5_crypto crypto;
|
||||
|
||||
kret = krb5_crypto_init(_gsskrb5_context,
|
||||
ctx->auth_context->keyblock,
|
||||
0, &crypto);
|
||||
if(kret) {
|
||||
krb5_free_authenticator(_gsskrb5_context, &authenticator);
|
||||
|
||||
ret = GSS_S_FAILURE;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows accepts Samba3's use of a kerberos, rather than
|
||||
* GSSAPI checksum here
|
||||
*/
|
||||
|
||||
kret = krb5_verify_checksum(_gsskrb5_context,
|
||||
crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
|
||||
authenticator->cksum);
|
||||
krb5_free_authenticator(_gsskrb5_context, &authenticator);
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
|
||||
if(kret) {
|
||||
ret = GSS_S_BAD_SIG;
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Samba style get some flags (but not DCE-STYLE)
|
||||
*/
|
||||
ctx->flags =
|
||||
GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->flags & GSS_C_MUTUAL_FLAG) {
|
||||
krb5_data outbuf;
|
||||
|
||||
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
||||
|
||||
if (is_cfx != 0
|
||||
|| (ap_options & AP_OPTS_USE_SUBKEY)) {
|
||||
kret = krb5_auth_con_addflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_USE_SUBKEY,
|
||||
NULL);
|
||||
ctx->more_flags |= ACCEPTOR_SUBKEY;
|
||||
}
|
||||
|
||||
kret = krb5_mk_rep(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&outbuf);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->flags & GSS_C_DCE_STYLE) {
|
||||
output_token->length = outbuf.length;
|
||||
output_token->value = outbuf.data;
|
||||
} else {
|
||||
ret = _gsskrb5_encapsulate(minor_status,
|
||||
&outbuf,
|
||||
output_token,
|
||||
"\x02\x00",
|
||||
GSS_KRB5_MECHANISM);
|
||||
krb5_data_free (&outbuf);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
/* Remember the flags */
|
||||
|
||||
ctx->lifetime = ctx->ticket->ticket.endtime;
|
||||
ctx->more_flags |= OPEN;
|
||||
|
||||
if (mech_type)
|
||||
*mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
if (time_rec) {
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
ctx->lifetime,
|
||||
time_rec);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from
|
||||
* the client.
|
||||
*/
|
||||
if (ctx->flags & GSS_C_DCE_STYLE) {
|
||||
/*
|
||||
* Return flags to caller, but we haven't processed
|
||||
* delgations yet
|
||||
*/
|
||||
if (ret_flags)
|
||||
*ret_flags = (ctx->flags & ~GSS_C_DELEG_FLAG);
|
||||
|
||||
ctx->state = ACCEPTOR_WAIT_FOR_DCESTYLE;
|
||||
return GSS_S_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
ret = gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle);
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = ctx->flags;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
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;
|
||||
krb5_error_code kret;
|
||||
krb5_data inbuf;
|
||||
int32_t r_seq_number, l_seq_number;
|
||||
|
||||
/*
|
||||
* We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP
|
||||
*/
|
||||
|
||||
inbuf.length = input_token_buffer->length;
|
||||
inbuf.data = input_token_buffer->value;
|
||||
|
||||
/*
|
||||
* We need to remeber the old remote seq_number, then check if the
|
||||
* client has replied with our local seq_number, and then reset
|
||||
* the remote seq_number to the old value
|
||||
*/
|
||||
{
|
||||
kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&l_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_auth_getremoteseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&r_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
l_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to verify the AP_REP, but we need to flag that this is
|
||||
* DCE_STYLE, so don't check the timestamps this time, but put the
|
||||
* flag DO_TIME back afterward.
|
||||
*/
|
||||
{
|
||||
krb5_ap_rep_enc_part *repl;
|
||||
int32_t auth_flags;
|
||||
|
||||
krb5_auth_con_removeflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_DO_TIME,
|
||||
&auth_flags);
|
||||
|
||||
kret = krb5_rd_rep(_gsskrb5_context, ctx->auth_context, &inbuf, &repl);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_free_ap_rep_enc_part(_gsskrb5_context, repl);
|
||||
krb5_auth_con_setflags(_gsskrb5_context, ctx->auth_context, auth_flags);
|
||||
}
|
||||
|
||||
/* We need to check the liftime */
|
||||
{
|
||||
OM_uint32 lifetime_rec;
|
||||
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
ctx->lifetime,
|
||||
&lifetime_rec);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
if (lifetime_rec == 0) {
|
||||
return GSS_S_CONTEXT_EXPIRED;
|
||||
}
|
||||
|
||||
if (time_rec) *time_rec = lifetime_rec;
|
||||
}
|
||||
|
||||
/* We need to give the caller the flags which are in use */
|
||||
if (ret_flags) *ret_flags = ctx->flags;
|
||||
|
||||
if (src_name) {
|
||||
kret = krb5_copy_principal(_gsskrb5_context,
|
||||
ctx->source,
|
||||
(gsskrb5_name*)src_name);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After the krb5_rd_rep() the remote and local seq_number should
|
||||
* be the same, because the client just replies the seq_number
|
||||
* from our AP-REP in its AP-REP, but then the client uses the
|
||||
* seq_number from its AP-REQ for GSS_wrap()
|
||||
*/
|
||||
{
|
||||
int32_t tmp_r_seq_number, tmp_l_seq_number;
|
||||
|
||||
kret = krb5_auth_getremoteseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&tmp_r_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&tmp_l_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we check if the client has responsed with our local seq_number,
|
||||
*/
|
||||
if (tmp_r_seq_number != tmp_l_seq_number) {
|
||||
return GSS_S_UNSEQ_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to reset the remote seq_number, because the client will use,
|
||||
* the old one for the GSS_wrap() calls
|
||||
*/
|
||||
{
|
||||
kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
r_seq_number);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
gsskrb5_ctx ctx;
|
||||
|
||||
GSSAPI_KRB5_INIT();
|
||||
|
||||
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) {
|
||||
ret = _gsskrb5_create_ctx(minor_status,
|
||||
context_handle,
|
||||
input_chan_bindings,
|
||||
ACCEPTOR_START);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx = (gsskrb5_ctx)*context_handle;
|
||||
|
||||
|
||||
/*
|
||||
* TODO: check the channel_bindings
|
||||
* (above just sets them to krb5 layer)
|
||||
*/
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
|
||||
switch (ctx->state) {
|
||||
case ACCEPTOR_START:
|
||||
ret = gsskrb5_acceptor_start(minor_status,
|
||||
ctx,
|
||||
acceptor_cred_handle,
|
||||
input_token_buffer,
|
||||
input_chan_bindings,
|
||||
src_name,
|
||||
mech_type,
|
||||
output_token,
|
||||
ret_flags,
|
||||
time_rec,
|
||||
delegated_cred_handle);
|
||||
break;
|
||||
case ACCEPTOR_WAIT_FOR_DCESTYLE:
|
||||
ret = acceptor_wait_for_dcestyle(minor_status,
|
||||
ctx,
|
||||
acceptor_cred_handle,
|
||||
input_token_buffer,
|
||||
input_chan_bindings,
|
||||
src_name,
|
||||
mech_type,
|
||||
output_token,
|
||||
ret_flags,
|
||||
time_rec,
|
||||
delegated_cred_handle);
|
||||
break;
|
||||
case ACCEPTOR_READY:
|
||||
/*
|
||||
* If we get there, the caller have called
|
||||
* gss_accept_sec_context() one time too many.
|
||||
*/
|
||||
ret = GSS_S_BAD_STATUS;
|
||||
break;
|
||||
default:
|
||||
/* TODO: is this correct here? --metze */
|
||||
ret = GSS_S_BAD_STATUS;
|
||||
break;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
if (GSS_ERROR(ret)) {
|
||||
OM_uint32 min2;
|
||||
_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: acquire_cred.c,v 1.31 2006/10/07 22:13:55 lha Exp $");
|
||||
|
||||
OM_uint32
|
||||
__gsskrb5_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(_gsskrb5_context, principal);
|
||||
if (realm == NULL) {
|
||||
_gsskrb5_clear_status ();
|
||||
*minor_status = KRB5_PRINC_NOMATCH; /* XXX */
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_make_principal(_gsskrb5_context, &in_cred.server,
|
||||
realm, KRB5_TGS_NAME, realm, NULL);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_get_credentials(_gsskrb5_context, 0,
|
||||
id, &in_cred, &out_cred);
|
||||
krb5_free_principal(_gsskrb5_context, in_cred.server);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
*lifetime = out_cred->times.endtime;
|
||||
krb5_free_creds(_gsskrb5_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 (_gsskrb5_keytab != NULL) {
|
||||
kret = krb5_kt_get_name(_gsskrb5_context,
|
||||
_gsskrb5_keytab,
|
||||
kt_name, sizeof(kt_name));
|
||||
if (kret == 0)
|
||||
kret = krb5_kt_resolve(_gsskrb5_context, kt_name, keytab);
|
||||
} else
|
||||
kret = krb5_kt_default(_gsskrb5_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,
|
||||
gsskrb5_cred 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 (_gsskrb5_context,
|
||||
handle->principal,
|
||||
NULL,
|
||||
&ccache);
|
||||
|
||||
if (ccache == NULL) {
|
||||
kret = krb5_cc_default(_gsskrb5_context, &ccache);
|
||||
if (kret)
|
||||
goto end;
|
||||
}
|
||||
kret = krb5_cc_get_principal(_gsskrb5_context, ccache,
|
||||
&def_princ);
|
||||
if (kret != 0) {
|
||||
/* we'll try to use a keytab below */
|
||||
krb5_cc_destroy(_gsskrb5_context, ccache);
|
||||
ccache = NULL;
|
||||
kret = 0;
|
||||
} else if (handle->principal == NULL) {
|
||||
kret = krb5_copy_principal(_gsskrb5_context, def_princ,
|
||||
&handle->principal);
|
||||
if (kret)
|
||||
goto end;
|
||||
} else if (handle->principal != NULL &&
|
||||
krb5_principal_compare(_gsskrb5_context, handle->principal,
|
||||
def_princ) == FALSE) {
|
||||
/* Before failing, lets check the keytab */
|
||||
krb5_free_principal(_gsskrb5_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(_gsskrb5_context,
|
||||
&handle->principal);
|
||||
if (kret)
|
||||
goto end;
|
||||
}
|
||||
kret = get_keytab(&keytab);
|
||||
if (kret)
|
||||
goto end;
|
||||
kret = krb5_get_init_creds_opt_alloc(_gsskrb5_context, &opt);
|
||||
if (kret)
|
||||
goto end;
|
||||
kret = krb5_get_init_creds_keytab(_gsskrb5_context, &cred,
|
||||
handle->principal, keytab, 0, NULL, opt);
|
||||
krb5_get_init_creds_opt_free(opt);
|
||||
if (kret)
|
||||
goto end;
|
||||
kret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops,
|
||||
&ccache);
|
||||
if (kret)
|
||||
goto end;
|
||||
kret = krb5_cc_initialize(_gsskrb5_context, ccache, cred.client);
|
||||
if (kret)
|
||||
goto end;
|
||||
kret = krb5_cc_store_cred(_gsskrb5_context, ccache, &cred);
|
||||
if (kret)
|
||||
goto end;
|
||||
handle->lifetime = cred.times.endtime;
|
||||
handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
|
||||
} else {
|
||||
|
||||
ret = __gsskrb5_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(_gsskrb5_context, &cred);
|
||||
if (def_princ != NULL)
|
||||
krb5_free_principal(_gsskrb5_context, def_princ);
|
||||
if (keytab != NULL)
|
||||
krb5_kt_close(_gsskrb5_context, keytab);
|
||||
if (ret != GSS_S_COMPLETE) {
|
||||
if (ccache != NULL)
|
||||
krb5_cc_close(_gsskrb5_context, ccache);
|
||||
if (kret != 0) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_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,
|
||||
gsskrb5_cred 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(_gsskrb5_context, handle->keytab,
|
||||
handle->principal, 0, 0, &entry);
|
||||
if (kret)
|
||||
goto end;
|
||||
krb5_kt_free_entry(_gsskrb5_context, &entry);
|
||||
}
|
||||
ret = GSS_S_COMPLETE;
|
||||
|
||||
end:
|
||||
if (ret != GSS_S_COMPLETE) {
|
||||
if (handle->keytab != NULL)
|
||||
krb5_kt_close(_gsskrb5_context, handle->keytab);
|
||||
if (kret != 0) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
OM_uint32 _gsskrb5_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
|
||||
)
|
||||
{
|
||||
gsskrb5_cred 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 = _gsskrb5_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 = calloc(1, sizeof(*handle));
|
||||
if (handle == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return (GSS_S_FAILURE);
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
|
||||
|
||||
if (desired_name != GSS_C_NO_NAME) {
|
||||
krb5_principal name = (krb5_principal)desired_name;
|
||||
ret = krb5_copy_principal(_gsskrb5_context, name, &handle->principal);
|
||||
if (ret) {
|
||||
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
free(handle);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
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(_gsskrb5_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(_gsskrb5_context, handle->principal);
|
||||
free(handle);
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
|
||||
&handle->mechanisms);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)handle,
|
||||
NULL, time_rec, NULL, actual_mechs);
|
||||
if (ret != GSS_S_COMPLETE) {
|
||||
if (handle->mechanisms != NULL)
|
||||
_gsskrb5_release_oid_set(NULL, &handle->mechanisms);
|
||||
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
||||
krb5_free_principal(_gsskrb5_context, handle->principal);
|
||||
free(handle);
|
||||
return (ret);
|
||||
}
|
||||
*minor_status = 0;
|
||||
if (time_rec) {
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
handle->lifetime,
|
||||
time_rec);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
handle->usage = cred_usage;
|
||||
*output_cred_handle = (gss_cred_id_t)handle;
|
||||
return (GSS_S_COMPLETE);
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: add_cred.c,v 1.9 2006/10/07 22:13:58 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
gsskrb5_cred cred, handle;
|
||||
krb5_const_principal dname;
|
||||
|
||||
handle = NULL;
|
||||
cred = (gsskrb5_cred)input_cred_handle;
|
||||
dname = (krb5_const_principal)desired_name;
|
||||
|
||||
if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
|
||||
if (cred == NULL && output_cred_handle == NULL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_NO_CRED;
|
||||
}
|
||||
|
||||
if (cred == NULL) { /* 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 (dname != NULL &&
|
||||
krb5_principal_compare(_gsskrb5_context, dname,
|
||||
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) {
|
||||
krb5_error_code kret;
|
||||
|
||||
handle = calloc(1, sizeof(*handle));
|
||||
if (handle == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
*minor_status = ENOMEM;
|
||||
return (GSS_S_FAILURE);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
kret = krb5_copy_principal(_gsskrb5_context, cred->principal,
|
||||
&handle->principal);
|
||||
if (kret) {
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
free(handle);
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (cred->keytab) {
|
||||
char name[KRB5_KT_PREFIX_MAX_LEN + MAXPATHLEN];
|
||||
int len;
|
||||
|
||||
ret = GSS_S_FAILURE;
|
||||
|
||||
kret = krb5_kt_get_type(_gsskrb5_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(_gsskrb5_context, cred->keytab,
|
||||
name + len,
|
||||
sizeof(name) - len);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_kt_resolve(_gsskrb5_context, name,
|
||||
&handle->keytab);
|
||||
if (kret){
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (cred->ccache) {
|
||||
const char *type, *name;
|
||||
char *type_name;
|
||||
|
||||
ret = GSS_S_FAILURE;
|
||||
|
||||
type = krb5_cc_get_type(_gsskrb5_context, cred->ccache);
|
||||
if (type == NULL){
|
||||
*minor_status = ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (strcmp(type, "MEMORY") == 0) {
|
||||
ret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops,
|
||||
&handle->ccache);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache,
|
||||
handle->ccache);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
} else {
|
||||
name = krb5_cc_get_name(_gsskrb5_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(_gsskrb5_context, type_name,
|
||||
&handle->ccache);
|
||||
free(type_name);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
|
||||
&handle->mechanisms);
|
||||
if (ret)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
|
||||
ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)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 = (gss_cred_id_t)handle;
|
||||
}
|
||||
|
||||
*minor_status = 0;
|
||||
return ret;
|
||||
|
||||
failure:
|
||||
|
||||
if (handle) {
|
||||
if (handle->principal)
|
||||
krb5_free_principal(_gsskrb5_context, handle->principal);
|
||||
if (handle->keytab)
|
||||
krb5_kt_close(_gsskrb5_context, handle->keytab);
|
||||
if (handle->ccache)
|
||||
krb5_cc_destroy(_gsskrb5_context, handle->ccache);
|
||||
if (handle->mechanisms)
|
||||
_gsskrb5_release_oid_set(NULL, &handle->mechanisms);
|
||||
free(handle);
|
||||
}
|
||||
if (output_cred_handle)
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: add_oid_set_member.c,v 1.10 2006/10/07 22:14:00 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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 = _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
#include <roken.h>
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5i_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 (_gsskrb5_context,
|
||||
addr_type,
|
||||
gss_addr->value,
|
||||
&sa,
|
||||
&sa_size,
|
||||
port);
|
||||
if (problem)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
problem = krb5_sockaddr2address (_gsskrb5_context, &sa, address);
|
||||
|
||||
return problem;
|
||||
}
|
||||
@@ -0,0 +1,752 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: arcfour.c,v 1.30 2006/11/07 19:05:16 lha Exp $");
|
||||
|
||||
/*
|
||||
* 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]
|
||||
*/
|
||||
|
||||
/*
|
||||
* WRAP in DCE-style have a fixed size header, the oid and length over
|
||||
* the WRAP header is a total of
|
||||
* GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE +
|
||||
* GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead,
|
||||
* remember the 2 bytes from APPL [0] SEQ).
|
||||
*/
|
||||
|
||||
#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
|
||||
#define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13
|
||||
|
||||
|
||||
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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
free(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = krb5_create_checksum(_gsskrb5_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(_gsskrb5_context, crypto);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
OM_uint32
|
||||
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx 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;
|
||||
|
||||
_gsskrb5_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) {
|
||||
_gsskrb5_release_buffer(minor_status, message_token);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = arcfour_mic_key(_gsskrb5_context, key,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
k6_data, sizeof(k6_data));
|
||||
if (ret) {
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&seq_number);
|
||||
p = p0 + 8; /* SND_SEQ */
|
||||
_gsskrb5_encode_be_om_uint32(seq_number, p);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (_gsskrb5_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 gsskrb5_ctx 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 = _gsskrb5_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(_gsskrb5_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));
|
||||
}
|
||||
|
||||
_gsskrb5_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 gsskrb5_ctx 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;
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
total_len += datalen;
|
||||
} else {
|
||||
datalen += 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 (_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&seq_number);
|
||||
|
||||
_gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (_gsskrb5_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);
|
||||
|
||||
if (!IS_DCE_STYLE(context_handle))
|
||||
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;
|
||||
_gsskrb5_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(_gsskrb5_context, &Klocal,
|
||||
p0 + 8, 4, /* SND_SEQ */
|
||||
k6_data, sizeof(k6_data));
|
||||
memset(Klocaldata, 0, sizeof(Klocaldata));
|
||||
if (ret) {
|
||||
_gsskrb5_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(_gsskrb5_context, key,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
k6_data, sizeof(k6_data));
|
||||
if (ret) {
|
||||
_gsskrb5_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 gsskrb5_ctx 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 = 0, len;
|
||||
|
||||
if (conf_state)
|
||||
*conf_state = 0;
|
||||
if (qop_state)
|
||||
*qop_state = 0;
|
||||
|
||||
p0 = input_message_buffer->value;
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
|
||||
GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
|
||||
if (input_message_buffer->length < len)
|
||||
return GSS_S_BAD_MECH;
|
||||
} else {
|
||||
len = input_message_buffer->length;
|
||||
}
|
||||
|
||||
omret = _gssapi_verify_mech_header(&p0,
|
||||
len,
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (omret)
|
||||
return omret;
|
||||
|
||||
/* length of mech header */
|
||||
len = (p0 - (u_char *)input_message_buffer->value) +
|
||||
GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
|
||||
if (len > input_message_buffer->length)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
/* length of data */
|
||||
datalen = input_message_buffer->length - len;
|
||||
|
||||
p = p0;
|
||||
|
||||
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(_gsskrb5_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));
|
||||
}
|
||||
|
||||
_gsskrb5_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(_gsskrb5_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));
|
||||
|
||||
if (!IS_DCE_STYLE(context_handle)) {
|
||||
ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
|
||||
if (ret) {
|
||||
_gsskrb5_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) {
|
||||
_gsskrb5_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) {
|
||||
_gsskrb5_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;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
max_wrap_length_arcfour(const gsskrb5_ctx ctx,
|
||||
krb5_crypto crypto,
|
||||
size_t input_length,
|
||||
OM_uint32 *max_input_size)
|
||||
{
|
||||
/*
|
||||
* if GSS_C_DCE_STYLE is in use:
|
||||
* - we only need to encapsulate the WRAP token
|
||||
* However, since this is a fixed since, we just
|
||||
*/
|
||||
if (IS_DCE_STYLE(ctx)) {
|
||||
size_t len, total_len;
|
||||
|
||||
len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
if (input_length < len)
|
||||
*max_input_size = 0;
|
||||
else
|
||||
*max_input_size = input_length - len;
|
||||
|
||||
} else {
|
||||
size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
|
||||
size_t blocksize = 8;
|
||||
size_t len, total_len;
|
||||
|
||||
len = 8 + input_length + blocksize + extrasize;
|
||||
|
||||
_gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
total_len -= input_length; /* token length */
|
||||
if (total_len < input_length) {
|
||||
*max_input_size = (input_length - total_len);
|
||||
(*max_input_size) &= (~(OM_uint32)(blocksize - 1));
|
||||
} else {
|
||||
*max_input_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gssapi_wrap_size_arcfour(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
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;
|
||||
|
||||
ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = max_wrap_length_arcfour(ctx, crypto,
|
||||
req_output_size, max_input_size);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: canonicalize_name.c,v 1.4 2006/10/07 22:14:08 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_canonicalize_name (
|
||||
OM_uint32 * minor_status,
|
||||
const gss_name_t input_name,
|
||||
const gss_OID mech_type,
|
||||
gss_name_t * output_name
|
||||
)
|
||||
{
|
||||
return _gsskrb5_duplicate_name (minor_status, input_name, output_name);
|
||||
}
|
||||
Executable
+887
@@ -0,0 +1,887 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: cfx.c,v 1.24 2006/10/24 21:13:22 lha Exp $");
|
||||
|
||||
/*
|
||||
* Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
|
||||
*/
|
||||
|
||||
#define CFXSentByAcceptor (1 << 0)
|
||||
#define CFXSealed (1 << 1)
|
||||
#define CFXAcceptorSubkey (1 << 2)
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5cfx_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(_gsskrb5_context, crypto, &type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_checksumsize(_gsskrb5_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(_gsskrb5_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(_gsskrb5_context,
|
||||
crypto, input_length);
|
||||
} else {
|
||||
/* Checksum is concatenated with data */
|
||||
*output_length += input_length + *cksumsize;
|
||||
}
|
||||
|
||||
assert(*output_length > input_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto,
|
||||
int conf_req_flag,
|
||||
size_t input_length,
|
||||
OM_uint32 *output_length)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
/* 16-byte header is always first */
|
||||
if (input_length < 16)
|
||||
return 0;
|
||||
input_length -= 16;
|
||||
|
||||
if (conf_req_flag) {
|
||||
size_t wrapped_size, sz;
|
||||
|
||||
wrapped_size = input_length + 1;
|
||||
do {
|
||||
wrapped_size--;
|
||||
sz = krb5_get_wrapped_length(_gsskrb5_context,
|
||||
crypto, wrapped_size);
|
||||
} while (wrapped_size && sz > input_length);
|
||||
if (wrapped_size == 0) {
|
||||
*output_length = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* inner header */
|
||||
if (wrapped_size < 16) {
|
||||
*output_length = 0;
|
||||
return 0;
|
||||
}
|
||||
wrapped_size -= 16;
|
||||
|
||||
*output_length = wrapped_size;
|
||||
} else {
|
||||
krb5_cksumtype type;
|
||||
size_t cksumsize;
|
||||
|
||||
ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_checksumsize(_gsskrb5_context, type, &cksumsize);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (input_length < cksumsize)
|
||||
return 0;
|
||||
|
||||
/* Checksum is concatenated with data */
|
||||
*output_length = input_length - cksumsize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx 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;
|
||||
|
||||
ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = _gsskrb5cfx_max_wrap_length_cfx(crypto, conf_req_flag,
|
||||
req_output_size, max_input_size);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
krb5_crypto_destroy(_gsskrb5_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 gsskrb5_ctx 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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = _gsskrb5cfx_wrap_length_cfx(crypto, conf_req_flag,
|
||||
input_message_buffer->length,
|
||||
&wrapped_len, &cksumsize, &padlength);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_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(_gsskrb5_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(_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&seq_number);
|
||||
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
|
||||
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
|
||||
krb5_auth_con_setlocalseqnumber(_gsskrb5_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(_gsskrb5_context, crypto,
|
||||
usage, p,
|
||||
input_message_buffer->length + padlength +
|
||||
sizeof(*token),
|
||||
&cipher);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
_gsskrb5_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) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
_gsskrb5_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(_gsskrb5_context, crypto);
|
||||
_gsskrb5_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(_gsskrb5_context, crypto,
|
||||
usage, 0, buf,
|
||||
input_message_buffer->length +
|
||||
sizeof(*token),
|
||||
&cksum);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
_gsskrb5_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) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
_gsskrb5_release_buffer(minor_status, output_message_buffer);
|
||||
free_Checksum(&cksum);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
free_Checksum(&cksum);
|
||||
}
|
||||
|
||||
krb5_crypto_destroy(_gsskrb5_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 gsskrb5_ctx 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
|
||||
*/
|
||||
_gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
|
||||
_gsskrb5_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);
|
||||
_gsskrb5_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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_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(_gsskrb5_context, crypto);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (token_flags & CFXSealed) {
|
||||
ret = krb5_decrypt(_gsskrb5_context, crypto, usage,
|
||||
p, len, &data);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_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(_gsskrb5_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(_gsskrb5_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(_gsskrb5_context,
|
||||
crypto, &cksum.cksumtype);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_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(_gsskrb5_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(_gsskrb5_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(_gsskrb5_context, crypto,
|
||||
usage,
|
||||
output_message_buffer->value,
|
||||
len + sizeof(*token),
|
||||
&cksum);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
_gsskrb5_release_buffer(minor_status, output_message_buffer);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
}
|
||||
|
||||
krb5_crypto_destroy(_gsskrb5_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 gsskrb5_ctx 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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_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(_gsskrb5_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(_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&seq_number);
|
||||
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
|
||||
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
|
||||
krb5_auth_con_setlocalseqnumber(_gsskrb5_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(_gsskrb5_context, crypto,
|
||||
usage, 0, buf, len, &cksum);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
free(buf);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_crypto_destroy(_gsskrb5_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 gsskrb5_ctx 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
|
||||
*/
|
||||
_gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
|
||||
_gsskrb5_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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto,
|
||||
&cksum.cksumtype);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
krb5_crypto_destroy(_gsskrb5_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(_gsskrb5_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(_gsskrb5_context, crypto,
|
||||
usage,
|
||||
buf,
|
||||
sizeof(*token) + message_buffer->length,
|
||||
&cksum);
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
if (ret != 0) {
|
||||
_gsskrb5_set_error_string();
|
||||
*minor_status = ret;
|
||||
free(buf);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if (qop_state != NULL) {
|
||||
*qop_state = GSS_C_QOP_DEFAULT;
|
||||
}
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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: cfx.h,v 1.7 2006/07/19 14:16:33 lha Exp $ */
|
||||
|
||||
#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;
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5cfx_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
|
||||
_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto,
|
||||
int conf_req_flag,
|
||||
size_t input_length,
|
||||
OM_uint32 *output_length);
|
||||
|
||||
|
||||
#endif /* GSSAPI_CFX_H_ */
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: compare_name.c,v 1.7 2006/10/07 22:14:15 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_compare_name
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_name_t name1,
|
||||
const gss_name_t name2,
|
||||
int * name_equal
|
||||
)
|
||||
{
|
||||
krb5_const_principal princ1 = (krb5_const_principal)name1;
|
||||
krb5_const_principal princ2 = (krb5_const_principal)name2;
|
||||
|
||||
GSSAPI_KRB5_INIT();
|
||||
|
||||
*name_equal = krb5_principal_compare (_gsskrb5_context,
|
||||
princ1, princ2);
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: compat.c,v 1.13 2006/10/07 22:14:17 lha Exp $");
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
check_compat(OM_uint32 *minor_status, krb5_const_principal 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(_gsskrb5_context, NULL, "gssapi",
|
||||
option, NULL);
|
||||
if(p == NULL)
|
||||
return 0;
|
||||
|
||||
match = NULL;
|
||||
for(q = p; *q; q++) {
|
||||
ret = krb5_parse_name(_gsskrb5_context, *q, &match);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (krb5_principal_match(_gsskrb5_context, name, match)) {
|
||||
*compat = match_val;
|
||||
break;
|
||||
}
|
||||
|
||||
krb5_free_principal(_gsskrb5_context, match);
|
||||
match = NULL;
|
||||
}
|
||||
if (match)
|
||||
krb5_free_principal(_gsskrb5_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, gsskrb5_ctx ctx)
|
||||
{
|
||||
krb5_boolean use_compat = FALSE;
|
||||
OM_uint32 ret;
|
||||
|
||||
if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) {
|
||||
ret = check_compat(minor_status, ctx->target,
|
||||
"broken_des3_mic", &use_compat, TRUE);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = 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;
|
||||
}
|
||||
|
||||
#if 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;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: context_time.c,v 1.13 2006/10/07 22:14:19 lha Exp $");
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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(_gsskrb5_context, &timeret);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (lifetime < timeret)
|
||||
*lifetime_rec = 0;
|
||||
else
|
||||
*lifetime_rec = lifetime - timeret;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
|
||||
OM_uint32 _gsskrb5_context_time
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_ctx_id_t context_handle,
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
OM_uint32 lifetime;
|
||||
OM_uint32 major_status;
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
lifetime = ctx->lifetime;
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
major_status = _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: copy_ccache.c,v 1.16 2006/11/08 02:42:50 lha Exp $");
|
||||
|
||||
#if 0
|
||||
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(_gsskrb5_context, cred->ccache, out);
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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;
|
||||
gsskrb5_cred handle;
|
||||
OM_uint32 ret;
|
||||
|
||||
*cred = NULL;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
handle = calloc(1, sizeof(*handle));
|
||||
if (handle == NULL) {
|
||||
_gsskrb5_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(_gsskrb5_context, id,
|
||||
&handle->principal);
|
||||
if (kret) {
|
||||
free(handle);
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (keytab_principal) {
|
||||
krb5_boolean match;
|
||||
|
||||
match = krb5_principal_compare(_gsskrb5_context,
|
||||
handle->principal,
|
||||
keytab_principal);
|
||||
if (match == FALSE) {
|
||||
krb5_free_principal(_gsskrb5_context, handle->principal);
|
||||
free(handle);
|
||||
_gsskrb5_clear_status ();
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = __gsskrb5_ccache_lifetime(minor_status,
|
||||
id,
|
||||
handle->principal,
|
||||
&handle->lifetime);
|
||||
if (ret != GSS_S_COMPLETE) {
|
||||
krb5_free_principal(_gsskrb5_context, handle->principal);
|
||||
free(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
kret = krb5_cc_get_full_name(_gsskrb5_context, id, &str);
|
||||
if (kret)
|
||||
goto out;
|
||||
|
||||
kret = krb5_cc_resolve(_gsskrb5_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(_gsskrb5_context,
|
||||
keytab_principal,
|
||||
&handle->principal);
|
||||
if (kret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
kret = krb5_kt_get_full_name(_gsskrb5_context, keytab, &str);
|
||||
if (kret)
|
||||
goto out;
|
||||
|
||||
kret = krb5_kt_resolve(_gsskrb5_context, str, &handle->keytab);
|
||||
free(str);
|
||||
if (kret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (id || keytab) {
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
ret = _gsskrb5_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 = (gss_cred_id_t)handle;
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
out:
|
||||
_gsskrb5_set_error_string ();
|
||||
if (handle->principal)
|
||||
krb5_free_principal(_gsskrb5_context, handle->principal);
|
||||
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
|
||||
free(handle);
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: create_emtpy_oid_set.c,v 1.7 2006/10/07 22:14:24 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: decapsulate.c,v 1.16 2006/10/07 22:14:26 lha Exp $");
|
||||
|
||||
/*
|
||||
* return the length of the mechanism in token or -1
|
||||
* (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
_gsskrb5_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 = _gsskrb5_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
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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 = _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: delete_sec_context.c,v 1.19 2006/10/07 22:14:28 lha Exp $");
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context_handle,
|
||||
gss_buffer_t output_token)
|
||||
{
|
||||
gsskrb5_ctx ctx;
|
||||
|
||||
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;
|
||||
|
||||
ctx = (gsskrb5_ctx) *context_handle;
|
||||
*context_handle = GSS_C_NO_CONTEXT;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
|
||||
krb5_auth_con_free (_gsskrb5_context, ctx->auth_context);
|
||||
if(ctx->source)
|
||||
krb5_free_principal (_gsskrb5_context, ctx->source);
|
||||
if(ctx->target)
|
||||
krb5_free_principal (_gsskrb5_context, ctx->target);
|
||||
if (ctx->ticket)
|
||||
krb5_free_ticket (_gsskrb5_context, ctx->ticket);
|
||||
if(ctx->order)
|
||||
_gssapi_msg_order_destroy(&ctx->order);
|
||||
if (ctx->service_keyblock)
|
||||
krb5_free_keyblock (_gsskrb5_context, ctx->service_keyblock);
|
||||
krb5_data_free(&ctx->fwd_data);
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free (ctx);
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: display_name.c,v 1.12 2006/10/07 22:14:31 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_display_name
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_name_t input_name,
|
||||
gss_buffer_t output_name_buffer,
|
||||
gss_OID * output_name_type
|
||||
)
|
||||
{
|
||||
krb5_const_principal name = (krb5_const_principal)input_name;
|
||||
krb5_error_code kret;
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
kret = krb5_unparse_name (_gsskrb5_context, name, &buf);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: display_status.c,v 1.16 2006/10/07 22:14:33 lha Exp $");
|
||||
|
||||
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
|
||||
_gsskrb5_clear_status (void)
|
||||
{
|
||||
struct gssapi_thr_context *ctx = _gsskrb5_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
|
||||
_gsskrb5_set_status (const char *fmt, ...)
|
||||
{
|
||||
struct gssapi_thr_context *ctx = _gsskrb5_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
|
||||
_gsskrb5_set_error_string (void)
|
||||
{
|
||||
char *e;
|
||||
|
||||
e = krb5_get_error_string(_gsskrb5_context);
|
||||
if (e) {
|
||||
_gsskrb5_set_status("%s", e);
|
||||
krb5_free_error_string(_gsskrb5_context, e);
|
||||
} else
|
||||
_gsskrb5_clear_status();
|
||||
}
|
||||
|
||||
char *
|
||||
_gsskrb5_get_error_string (void)
|
||||
{
|
||||
struct gssapi_thr_context *ctx = _gsskrb5_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 _gsskrb5_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 = _gsskrb5_get_error_string ();
|
||||
if (buf == NULL) {
|
||||
const char *tmp = krb5_get_err_text (_gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: duplicate_name.c,v 1.10 2006/10/07 22:14:35 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_duplicate_name (
|
||||
OM_uint32 * minor_status,
|
||||
const gss_name_t src_name,
|
||||
gss_name_t * dest_name
|
||||
)
|
||||
{
|
||||
krb5_const_principal src = (krb5_const_principal)src_name;
|
||||
krb5_principal *dest = (krb5_principal *)dest_name;
|
||||
krb5_error_code kret;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
kret = krb5_copy_principal (_gsskrb5_context, src, dest);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
} else {
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: encapsulate.c,v 1.12 2006/10/14 10:02:56 lha Exp $");
|
||||
|
||||
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 = der_length_len(*len);
|
||||
|
||||
*total_len = 1 + len_len + *len;
|
||||
}
|
||||
|
||||
void
|
||||
_gsskrb5_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 *
|
||||
_gsskrb5_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 = der_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
|
||||
_gsskrb5_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;
|
||||
|
||||
_gsskrb5_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 = _gsskrb5_make_header (output_token->value, len, type, mech);
|
||||
memcpy (p, in_data->data, in_data->length);
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: export_name.c,v 1.8 2006/10/07 22:14:40 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_export_name
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_name_t input_name,
|
||||
gss_buffer_t exported_name
|
||||
)
|
||||
{
|
||||
krb5_const_principal princ = (krb5_const_principal)input_name;
|
||||
krb5_error_code kret;
|
||||
char *buf, *name;
|
||||
size_t len;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
kret = krb5_unparse_name (_gsskrb5_context, princ, &name);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: export_sec_context.c,v 1.11 2006/10/07 22:14:42 lha Exp $");
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_export_sec_context (
|
||||
OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context_handle,
|
||||
gss_buffer_t interprocess_token
|
||||
)
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
|
||||
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(&ctx->ctx_id_mutex);
|
||||
|
||||
if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
*minor_status = 0;
|
||||
return GSS_S_UNAVAILABLE;
|
||||
}
|
||||
|
||||
sp = krb5_storage_emem ();
|
||||
if (sp == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
ac = ctx->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 = _gsskrb5_export_name (minor_status,
|
||||
(gss_name_t)ctx->source, &buffer);
|
||||
if (ret)
|
||||
goto failure;
|
||||
data.data = buffer.value;
|
||||
data.length = buffer.length;
|
||||
kret = krb5_store_data (sp, data);
|
||||
_gsskrb5_release_buffer (&minor, &buffer);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = _gsskrb5_export_name (minor_status,
|
||||
(gss_name_t)ctx->target, &buffer);
|
||||
if (ret)
|
||||
goto failure;
|
||||
data.data = buffer.value;
|
||||
data.length = buffer.length;
|
||||
|
||||
ret = GSS_S_FAILURE;
|
||||
|
||||
kret = krb5_store_data (sp, data);
|
||||
_gsskrb5_release_buffer (&minor, &buffer);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_store_int32 (sp, ctx->flags);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
kret = krb5_store_int32 (sp, ctx->more_flags);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
kret = krb5_store_int32 (sp, ctx->lifetime);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
kret = _gssapi_msg_order_export(sp, ctx->order);
|
||||
if (kret ) {
|
||||
*minor_status = kret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_storage_to_data (sp, &data);
|
||||
krb5_storage_free (sp);
|
||||
if (kret) {
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
interprocess_token->length = data.length;
|
||||
interprocess_token->value = data.data;
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
|
||||
GSS_C_NO_BUFFER);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
_gsskrb5_release_buffer (NULL, interprocess_token);
|
||||
*minor_status = 0;
|
||||
return ret;
|
||||
failure:
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
krb5_storage_free (sp);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
#include <gssapi_mech.h>
|
||||
|
||||
RCSID("$Id: external.c,v 1.22 2006/11/08 23:00:20 lha Exp $");
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc =
|
||||
{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"};
|
||||
|
||||
gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc;
|
||||
|
||||
/*
|
||||
* 1.2.752.43.13 Heimdal GSS-API Extentions
|
||||
*/
|
||||
|
||||
/* 1.2.752.43.13.1 */
|
||||
static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")};
|
||||
|
||||
gss_OID GSS_KRB5_COPY_CCACHE_X = &gss_krb5_copy_ccache_x_oid_desc;
|
||||
|
||||
/* 1.2.752.43.13.2 */
|
||||
static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_TKT_FLAGS_X = &gss_krb5_get_tkt_flags_x_oid_desc;
|
||||
|
||||
/* 1.2.752.43.13.3 */
|
||||
static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")};
|
||||
|
||||
gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
|
||||
|
||||
/* 1.2.752.43.13.4 */
|
||||
static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")};
|
||||
|
||||
gss_OID GSS_KRB5_COMPAT_DES3_MIC_X = &gss_krb5_compat_des3_mic_x_oid_desc;
|
||||
|
||||
/* 1.2.752.43.13.5 */
|
||||
static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")};
|
||||
|
||||
gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = &gss_krb5_register_acceptor_identity_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.6 */
|
||||
static gss_OID_desc gss_krb5_export_lucid_context_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")};
|
||||
|
||||
gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X = &gss_krb5_export_lucid_context_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.6.1 */
|
||||
static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc =
|
||||
{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")};
|
||||
|
||||
gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = &gss_krb5_export_lucid_context_v1_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.7 */
|
||||
static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")};
|
||||
|
||||
gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X = &gss_krb5_set_dns_canonicalize_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.8 */
|
||||
static gss_OID_desc gss_krb5_get_subkey_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_SUBKEY_X = &gss_krb5_get_subkey_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.9 */
|
||||
static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X = &gss_krb5_get_initiator_subkey_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.10 */
|
||||
static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = &gss_krb5_get_acceptor_subkey_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.11 */
|
||||
static gss_OID_desc gss_krb5_send_to_kdc_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")};
|
||||
|
||||
gss_OID GSS_KRB5_SEND_TO_KDC_X = &gss_krb5_send_to_kdc_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.12 */
|
||||
static gss_OID_desc gss_krb5_get_authtime_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_AUTHTIME_X = &gss_krb5_get_authtime_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.13 */
|
||||
static gss_OID_desc gss_krb5_get_service_keyblock_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")};
|
||||
|
||||
gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X = &gss_krb5_get_service_keyblock_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.14 */
|
||||
static gss_OID_desc gss_krb5_set_allowable_enctypes_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")};
|
||||
|
||||
gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X = &gss_krb5_set_allowable_enctypes_x_desc;
|
||||
|
||||
/* 1.2.752.43.13.15 */
|
||||
static gss_OID_desc gss_krb5_set_default_realm_x_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")};
|
||||
|
||||
gss_OID GSS_KRB5_SET_DEFAULT_REALM_X = &gss_krb5_set_default_realm_x_desc;
|
||||
|
||||
|
||||
/* 1.2.752.43.14.1 */
|
||||
static gss_OID_desc gss_sasl_digest_md5_mechanism_desc =
|
||||
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
|
||||
|
||||
gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc;
|
||||
|
||||
/*
|
||||
* Context for krb5 calls.
|
||||
*/
|
||||
|
||||
krb5_context _gsskrb5_context;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static gssapi_mech_interface_desc krb5_mech = {
|
||||
GMI_VERSION,
|
||||
"kerberos 5",
|
||||
{9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
|
||||
_gsskrb5_acquire_cred,
|
||||
_gsskrb5_release_cred,
|
||||
_gsskrb5_init_sec_context,
|
||||
_gsskrb5_accept_sec_context,
|
||||
_gsskrb5_process_context_token,
|
||||
_gsskrb5_delete_sec_context,
|
||||
_gsskrb5_context_time,
|
||||
_gsskrb5_get_mic,
|
||||
_gsskrb5_verify_mic,
|
||||
_gsskrb5_wrap,
|
||||
_gsskrb5_unwrap,
|
||||
_gsskrb5_display_status,
|
||||
_gsskrb5_indicate_mechs,
|
||||
_gsskrb5_compare_name,
|
||||
_gsskrb5_display_name,
|
||||
_gsskrb5_import_name,
|
||||
_gsskrb5_export_name,
|
||||
_gsskrb5_release_name,
|
||||
_gsskrb5_inquire_cred,
|
||||
_gsskrb5_inquire_context,
|
||||
_gsskrb5_wrap_size_limit,
|
||||
_gsskrb5_add_cred,
|
||||
_gsskrb5_inquire_cred_by_mech,
|
||||
_gsskrb5_export_sec_context,
|
||||
_gsskrb5_import_sec_context,
|
||||
_gsskrb5_inquire_names_for_mech,
|
||||
_gsskrb5_inquire_mechs_for_name,
|
||||
_gsskrb5_canonicalize_name,
|
||||
_gsskrb5_duplicate_name,
|
||||
_gsskrb5_inquire_sec_context_by_oid,
|
||||
_gsskrb5_inquire_cred_by_oid,
|
||||
_gsskrb5_set_sec_context_option,
|
||||
_gsskrb5_set_cred_option
|
||||
};
|
||||
|
||||
gssapi_mech_interface
|
||||
__gss_krb5_initialize(void)
|
||||
{
|
||||
return &krb5_mech;
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: get_mic.c,v 1.34 2006/10/18 15:59:23 lha Exp $");
|
||||
|
||||
static OM_uint32
|
||||
mic_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
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;
|
||||
|
||||
_gsskrb5_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 = _gsskrb5_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(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
|
||||
ctx->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,
|
||||
(ctx->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 (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->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 gsskrb5_ctx ctx,
|
||||
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];
|
||||
|
||||
_gsskrb5_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 = _gsskrb5_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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
free (tmp);
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_create_checksum (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
0,
|
||||
tmp,
|
||||
message_buffer->length + 8,
|
||||
&cksum);
|
||||
free (tmp);
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
|
||||
ctx->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,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
kret = krb5_crypto_init(_gsskrb5_context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->more_flags & COMPAT_OLD_DES3)
|
||||
memset(ivec, 0, 8);
|
||||
else
|
||||
memcpy(ivec, p + 8, 8);
|
||||
|
||||
kret = krb5_encrypt_ivec (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
seq, 8, &encdata, ivec);
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
free_Checksum (&cksum);
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32 _gsskrb5_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
|
||||
)
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
krb5_keyblock *key;
|
||||
OM_uint32 ret;
|
||||
krb5_keytype keytype;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_DES :
|
||||
ret = mic_des (minor_status, ctx, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
break;
|
||||
case KEYTYPE_DES3 :
|
||||
ret = mic_des3 (minor_status, ctx, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
break;
|
||||
case KEYTYPE_ARCFOUR:
|
||||
case KEYTYPE_ARCFOUR_56:
|
||||
ret = _gssapi_get_mic_arcfour (minor_status, ctx, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
break;
|
||||
default :
|
||||
ret = _gssapi_mic_cfx (minor_status, ctx, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
break;
|
||||
}
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# extended gss krb5 error messages
|
||||
#
|
||||
|
||||
id "$Id: gkrb5_err.et,v 1.1 2006/11/09 23:52:17 lha Exp $"
|
||||
|
||||
error_table gk5
|
||||
|
||||
prefix GSS_KRB5_S
|
||||
|
||||
error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string"
|
||||
error_code G_BAD_STRING_UID, "STRING-UID-NAME contains nondigits"
|
||||
error_code G_NOUSER, "UID does not resolve to username"
|
||||
error_code G_VALIDATE_FAILED, "Validation error"
|
||||
error_code G_BUFFER_ALLOC, "Couldn't allocate gss_buffer_t data"
|
||||
error_code G_BAD_MSG_CTX, "Message context invalid"
|
||||
error_code G_WRONG_SIZE, "Buffer is the wrong size"
|
||||
error_code G_BAD_USAGE, "Credential usage type is unknown"
|
||||
error_code G_UNKNOWN_QOP, "Unknown quality of protection specified"
|
||||
|
||||
index 128
|
||||
|
||||
error_code KG_CCACHE_NOMATCH, "Principal in credential cache does not match desired name"
|
||||
error_code KG_KEYTAB_NOMATCH, "No principal in keytab matches desired name"
|
||||
error_code KG_TGT_MISSING, "Credential cache has no TGT"
|
||||
error_code KG_NO_SUBKEY, "Authenticator has no subkey"
|
||||
error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established"
|
||||
error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token"
|
||||
error_code KG_BAD_LENGTH, "Invalid field length in token"
|
||||
error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context"
|
||||
@@ -0,0 +1,705 @@
|
||||
/* This is a generated file */
|
||||
#ifndef __gsskrb5_private_h__
|
||||
#define __gsskrb5_private_h__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
gssapi_mech_interface
|
||||
__gss_krb5_initialize (void);
|
||||
|
||||
OM_uint32
|
||||
__gsskrb5_ccache_lifetime (
|
||||
OM_uint32 */*minor_status*/,
|
||||
krb5_ccache /*id*/,
|
||||
krb5_principal /*principal*/,
|
||||
OM_uint32 */*lifetime*/);
|
||||
|
||||
OM_uint32
|
||||
_gss_DES3_get_mic_compat (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gsskrb5_ctx /*ctx*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_decapsulate (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gss_buffer_t /*input_token_buffer*/,
|
||||
krb5_data */*out_data*/,
|
||||
const gss_OID mech );
|
||||
|
||||
void
|
||||
_gssapi_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_get_mic_arcfour (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gsskrb5_ctx /*context_handle*/,
|
||||
gss_qop_t /*qop_req*/,
|
||||
const gss_buffer_t /*message_buffer*/,
|
||||
gss_buffer_t /*message_token*/,
|
||||
krb5_keyblock */*key*/);
|
||||
|
||||
void *
|
||||
_gssapi_make_mech_header (
|
||||
void */*ptr*/,
|
||||
size_t /*len*/,
|
||||
const gss_OID /*mech*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_mic_cfx (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*context_handle*/,
|
||||
gss_qop_t /*qop_req*/,
|
||||
const gss_buffer_t /*message_buffer*/,
|
||||
gss_buffer_t /*message_token*/,
|
||||
krb5_keyblock */*key*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_msg_order_check (
|
||||
struct gss_msg_order */*o*/,
|
||||
OM_uint32 /*seq_num*/);
|
||||
|
||||
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
|
||||
_gssapi_msg_order_destroy (struct gss_msg_order **/*m*/);
|
||||
|
||||
krb5_error_code
|
||||
_gssapi_msg_order_export (
|
||||
krb5_storage */*sp*/,
|
||||
struct gss_msg_order */*o*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_msg_order_f (OM_uint32 /*flags*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_msg_order_import (
|
||||
OM_uint32 */*minor_status*/,
|
||||
krb5_storage */*sp*/,
|
||||
struct gss_msg_order **/*o*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_unwrap_arcfour (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*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_unwrap_cfx (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*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_verify_mech_header (
|
||||
u_char **/*str*/,
|
||||
size_t /*total_len*/,
|
||||
gss_OID /*mech*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_verify_mic_arcfour (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gsskrb5_ctx /*context_handle*/,
|
||||
const gss_buffer_t /*message_buffer*/,
|
||||
const gss_buffer_t /*token_buffer*/,
|
||||
gss_qop_t * /*qop_state*/,
|
||||
krb5_keyblock */*key*/,
|
||||
char */*type*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_verify_mic_cfx (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*context_handle*/,
|
||||
const gss_buffer_t /*message_buffer*/,
|
||||
const gss_buffer_t /*token_buffer*/,
|
||||
gss_qop_t */*qop_state*/,
|
||||
krb5_keyblock */*key*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_verify_pad (
|
||||
gss_buffer_t /*wrapped_token*/,
|
||||
size_t /*datalen*/,
|
||||
size_t */*padlen*/);
|
||||
|
||||
OM_uint32
|
||||
_gssapi_wrap_arcfour (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gsskrb5_ctx /*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_wrap_cfx (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*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_wrap_size_arcfour (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*ctx*/,
|
||||
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_size_cfx (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gsskrb5_ctx /*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
|
||||
_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*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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
|
||||
_gsskrb5_add_oid_set_member (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_OID /*member_oid*/,
|
||||
gss_OID_set * oid_set );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_canonicalize_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*input_name*/,
|
||||
const gss_OID /*mech_type*/,
|
||||
gss_name_t * output_name );
|
||||
|
||||
void
|
||||
_gsskrb5_clear_status (void);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_compare_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*name1*/,
|
||||
const gss_name_t /*name2*/,
|
||||
int * name_equal );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_context_time (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_ctx_id_t /*context_handle*/,
|
||||
OM_uint32 * time_rec );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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
|
||||
_gsskrb5_create_ctx (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_ctx_id_t * /*context_handle*/,
|
||||
const gss_channel_bindings_t /*input_chan_bindings*/,
|
||||
enum gss_ctx_id_t_state /*state*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_create_empty_oid_set (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_OID_set * oid_set );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_decapsulate (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gss_buffer_t /*input_token_buffer*/,
|
||||
krb5_data */*out_data*/,
|
||||
const void */*type*/,
|
||||
gss_OID /*oid*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_decode_be_om_uint32 (
|
||||
const void */*ptr*/,
|
||||
OM_uint32 */*n*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_decode_om_uint32 (
|
||||
const void */*ptr*/,
|
||||
OM_uint32 */*n*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_delete_sec_context (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_ctx_id_t * /*context_handle*/,
|
||||
gss_buffer_t /*output_token*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_display_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*input_name*/,
|
||||
gss_buffer_t /*output_name_buffer*/,
|
||||
gss_OID * output_name_type );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_duplicate_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*src_name*/,
|
||||
gss_name_t * dest_name );
|
||||
|
||||
void
|
||||
_gsskrb5_encap_length (
|
||||
size_t /*data_len*/,
|
||||
size_t */*len*/,
|
||||
size_t */*total_len*/,
|
||||
const gss_OID /*mech*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_encapsulate (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const krb5_data */*in_data*/,
|
||||
gss_buffer_t /*output_token*/,
|
||||
const void */*type*/,
|
||||
const gss_OID mech );
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_encode_be_om_uint32 (
|
||||
OM_uint32 /*n*/,
|
||||
u_char */*p*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_encode_om_uint32 (
|
||||
OM_uint32 /*n*/,
|
||||
u_char */*p*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_export_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*input_name*/,
|
||||
gss_buffer_t exported_name );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_export_sec_context (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_ctx_id_t * /*context_handle*/,
|
||||
gss_buffer_t interprocess_token );
|
||||
|
||||
char *
|
||||
_gsskrb5_get_error_string (void);
|
||||
|
||||
ssize_t
|
||||
_gsskrb5_get_mech (
|
||||
const u_char */*ptr*/,
|
||||
size_t /*total_len*/,
|
||||
const u_char **/*mech_ret*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
struct gssapi_thr_context *
|
||||
_gsskrb5_get_thread_context (int /*createp*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_get_tkt_flags (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gsskrb5_ctx /*ctx*/,
|
||||
OM_uint32 */*tkt_flags*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_import_cred (
|
||||
OM_uint32 */*minor_status*/,
|
||||
krb5_ccache /*id*/,
|
||||
krb5_principal /*keytab_principal*/,
|
||||
krb5_keytab /*keytab*/,
|
||||
gss_cred_id_t */*cred*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_import_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_buffer_t /*input_name_buffer*/,
|
||||
const gss_OID /*input_name_type*/,
|
||||
gss_name_t * output_name );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_import_sec_context (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_buffer_t /*interprocess_token*/,
|
||||
gss_ctx_id_t * context_handle );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_indicate_mechs (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_OID_set * mech_set );
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_init (void);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_init_sec_context (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_cred_id_t /*initiator_cred_handle*/,
|
||||
gss_ctx_id_t * /*context_handle*/,
|
||||
const gss_name_t /*target_name*/,
|
||||
const gss_OID /*mech_type*/,
|
||||
OM_uint32 /*req_flags*/,
|
||||
OM_uint32 /*time_req*/,
|
||||
const gss_channel_bindings_t /*input_chan_bindings*/,
|
||||
const gss_buffer_t /*input_token*/,
|
||||
gss_OID * /*actual_mech_type*/,
|
||||
gss_buffer_t /*output_token*/,
|
||||
OM_uint32 * /*ret_flags*/,
|
||||
OM_uint32 * time_rec );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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
|
||||
_gsskrb5_inquire_cred (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_cred_id_t /*cred_handle*/,
|
||||
gss_name_t * /*output_name*/,
|
||||
OM_uint32 * /*lifetime*/,
|
||||
gss_cred_usage_t * /*cred_usage*/,
|
||||
gss_OID_set * mechanisms );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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
|
||||
_gsskrb5_inquire_cred_by_oid (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_cred_id_t /*cred_handle*/,
|
||||
const gss_OID /*desired_object*/,
|
||||
gss_buffer_set_t */*data_set*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_inquire_mechs_for_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_name_t /*input_name*/,
|
||||
gss_OID_set * mech_types );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_inquire_names_for_mech (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_OID /*mechanism*/,
|
||||
gss_OID_set * name_types );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_inquire_sec_context_by_oid (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gss_ctx_id_t /*context_handle*/,
|
||||
const gss_OID /*desired_object*/,
|
||||
gss_buffer_set_t */*data_set*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_krb5_ccache_name (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const char */*name*/,
|
||||
const char **/*out_name*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_lifetime_left (
|
||||
OM_uint32 */*minor_status*/,
|
||||
OM_uint32 /*lifetime*/,
|
||||
OM_uint32 */*lifetime_rec*/);
|
||||
|
||||
void *
|
||||
_gsskrb5_make_header (
|
||||
void */*ptr*/,
|
||||
size_t /*len*/,
|
||||
const void */*type*/,
|
||||
const gss_OID /*mech*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_process_context_token (
|
||||
OM_uint32 */*minor_status*/,
|
||||
const gss_ctx_id_t /*context_handle*/,
|
||||
const gss_buffer_t token_buffer );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_register_acceptor_identity (const char */*identity*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_release_buffer (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_buffer_t buffer );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_release_cred (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_cred_id_t * cred_handle );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_release_name (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_name_t * input_name );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_release_oid_set (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_OID_set * set );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_set_cred_option (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gss_cred_id_t */*cred_handle*/,
|
||||
const gss_OID /*desired_object*/,
|
||||
const gss_buffer_t /*value*/);
|
||||
|
||||
void
|
||||
_gsskrb5_set_error_string (void);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_set_sec_context_option (
|
||||
OM_uint32 */*minor_status*/,
|
||||
gss_ctx_id_t */*context_handle*/,
|
||||
const gss_OID /*desired_object*/,
|
||||
const gss_buffer_t /*value*/);
|
||||
|
||||
void
|
||||
_gsskrb5_set_status (
|
||||
const char */*fmt*/,
|
||||
...);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_sign (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_ctx_id_t /*context_handle*/,
|
||||
int /*qop_req*/,
|
||||
gss_buffer_t /*message_buffer*/,
|
||||
gss_buffer_t message_token );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_test_oid_set_member (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gss_OID /*member*/,
|
||||
const gss_OID_set /*set*/,
|
||||
int * present );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_verify (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
gss_ctx_id_t /*context_handle*/,
|
||||
gss_buffer_t /*message_buffer*/,
|
||||
gss_buffer_t /*token_buffer*/,
|
||||
int * qop_state );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_verify_header (
|
||||
u_char **/*str*/,
|
||||
size_t /*total_len*/,
|
||||
const void */*type*/,
|
||||
gss_OID /*oid*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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
|
||||
_gsskrb5_verify_mic_internal (
|
||||
OM_uint32 * /*minor_status*/,
|
||||
const gsskrb5_ctx /*context_handle*/,
|
||||
const gss_buffer_t /*message_buffer*/,
|
||||
const gss_buffer_t /*token_buffer*/,
|
||||
gss_qop_t * /*qop_state*/,
|
||||
char * type );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 );
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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_error_code
|
||||
_gsskrb5cfx_max_wrap_length_cfx (
|
||||
krb5_crypto /*crypto*/,
|
||||
int /*conf_req_flag*/,
|
||||
size_t /*input_length*/,
|
||||
OM_uint32 */*output_length*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5cfx_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
|
||||
_gsskrb5i_address_to_krb5addr (
|
||||
OM_uint32 /*gss_addr_type*/,
|
||||
gss_buffer_desc */*gss_addr*/,
|
||||
int16_t /*port*/,
|
||||
krb5_address */*address*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5i_get_acceptor_subkey (
|
||||
const gsskrb5_ctx /*ctx*/,
|
||||
krb5_keyblock **/*key*/);
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5i_get_initiator_subkey (
|
||||
const gsskrb5_ctx /*ctx*/,
|
||||
krb5_keyblock **/*key*/);
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5i_get_token_key (
|
||||
const gsskrb5_ctx /*ctx*/,
|
||||
krb5_keyblock **/*key*/);
|
||||
|
||||
void
|
||||
_gsskrb5i_is_cfx (
|
||||
gsskrb5_ctx /*ctx*/,
|
||||
int */*is_cfx*/);
|
||||
|
||||
#endif /* __gsskrb5_private_h__ */
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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.
|
||||
*/
|
||||
|
||||
/* $Id: gsskrb5_locl.h,v 1.8 2006/11/10 00:36:40 lha Exp $ */
|
||||
|
||||
#ifndef GSSKRB5_LOCL_H
|
||||
#define GSSKRB5_LOCL_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <krb5_locl.h>
|
||||
#include <gkrb5_err.h>
|
||||
#include <gssapi.h>
|
||||
#include <gssapi_mech.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "cfx.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
struct gss_msg_order;
|
||||
|
||||
typedef struct {
|
||||
struct krb5_auth_context_data *auth_context;
|
||||
krb5_principal source, target;
|
||||
#define IS_DCE_STYLE(ctx) (((ctx)->flags & GSS_C_DCE_STYLE) != 0)
|
||||
OM_uint32 flags;
|
||||
enum { LOCAL = 1, OPEN = 2,
|
||||
COMPAT_OLD_DES3 = 4,
|
||||
COMPAT_OLD_DES3_SELECTED = 8,
|
||||
ACCEPTOR_SUBKEY = 16
|
||||
} more_flags;
|
||||
enum gss_ctx_id_t_state {
|
||||
/* initiator states */
|
||||
INITIATOR_START,
|
||||
INITIATOR_WAIT_FOR_MUTAL,
|
||||
INITIATOR_READY,
|
||||
/* acceptor states */
|
||||
ACCEPTOR_START,
|
||||
ACCEPTOR_WAIT_FOR_DCESTYLE,
|
||||
ACCEPTOR_READY
|
||||
} state;
|
||||
struct krb5_ticket *ticket;
|
||||
OM_uint32 lifetime;
|
||||
HEIMDAL_MUTEX ctx_id_mutex;
|
||||
struct gss_msg_order *order;
|
||||
krb5_keyblock *service_keyblock;
|
||||
krb5_data fwd_data;
|
||||
} *gsskrb5_ctx;
|
||||
|
||||
typedef struct {
|
||||
krb5_principal 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;
|
||||
} *gsskrb5_cred;
|
||||
|
||||
typedef struct Principal *gsskrb5_name;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
extern krb5_context _gsskrb5_context;
|
||||
|
||||
extern krb5_keytab _gsskrb5_keytab;
|
||||
extern HEIMDAL_MUTEX gssapi_keytab_mutex;
|
||||
|
||||
struct gssapi_thr_context {
|
||||
HEIMDAL_MUTEX mutex;
|
||||
char *error_string;
|
||||
};
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
|
||||
#include <krb5/gsskrb5-private.h>
|
||||
|
||||
#define GSSAPI_KRB5_INIT() do { \
|
||||
krb5_error_code kret_gss_init; \
|
||||
if((kret_gss_init = _gsskrb5_init ()) != 0) { \
|
||||
*minor_status = kret_gss_init; \
|
||||
return GSS_S_FAILURE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* 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
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: import_name.c,v 1.17 2006/10/07 22:14:51 lha Exp $");
|
||||
|
||||
static OM_uint32
|
||||
parse_krb5_name (OM_uint32 *minor_status,
|
||||
const char *name,
|
||||
gss_name_t *output_name)
|
||||
{
|
||||
krb5_principal princ;
|
||||
krb5_error_code kerr;
|
||||
|
||||
kerr = krb5_parse_name (_gsskrb5_context, name, &princ);
|
||||
|
||||
if (kerr == 0) {
|
||||
*output_name = (gss_name_t)princ;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kerr;
|
||||
|
||||
if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
|
||||
return GSS_S_BAD_NAME;
|
||||
|
||||
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];
|
||||
krb5_principal princ = 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 (_gsskrb5_context,
|
||||
host,
|
||||
tmp,
|
||||
KRB5_NT_SRV_HST,
|
||||
&princ);
|
||||
free (tmp);
|
||||
*minor_status = kerr;
|
||||
if (kerr == 0) {
|
||||
*output_name = (gss_name_t)princ;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kerr;
|
||||
|
||||
if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
|
||||
return GSS_S_BAD_NAME;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: import_sec_context.c,v 1.17 2006/10/07 22:14:53 lha Exp $");
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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;
|
||||
gsskrb5_ctx ctx;
|
||||
gss_name_t name;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
*context_handle = GSS_C_NO_CONTEXT;
|
||||
|
||||
localp = remotep = NULL;
|
||||
|
||||
sp = krb5_storage_from_mem (interprocess_token->value,
|
||||
interprocess_token->length);
|
||||
if (sp == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
krb5_storage_free (sp);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
|
||||
|
||||
kret = krb5_auth_con_init (_gsskrb5_context,
|
||||
&ctx->auth_context);
|
||||
if (kret) {
|
||||
_gsskrb5_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 = ctx->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 (_gsskrb5_context, ac, localp, remotep);
|
||||
if (localp)
|
||||
krb5_free_address (_gsskrb5_context, localp);
|
||||
if (remotep)
|
||||
krb5_free_address (_gsskrb5_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 (_gsskrb5_context, ac, &keyblock);
|
||||
krb5_free_keyblock_contents (_gsskrb5_context, &keyblock);
|
||||
}
|
||||
if (flags & SC_LOCAL_SUBKEY) {
|
||||
if (krb5_ret_keyblock (sp, &keyblock) != 0)
|
||||
goto failure;
|
||||
krb5_auth_con_setlocalsubkey (_gsskrb5_context, ac, &keyblock);
|
||||
krb5_free_keyblock_contents (_gsskrb5_context, &keyblock);
|
||||
}
|
||||
if (flags & SC_REMOTE_SUBKEY) {
|
||||
if (krb5_ret_keyblock (sp, &keyblock) != 0)
|
||||
goto failure;
|
||||
krb5_auth_con_setremotesubkey (_gsskrb5_context, ac, &keyblock);
|
||||
krb5_free_keyblock_contents (_gsskrb5_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 = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
|
||||
&name);
|
||||
if (ret) {
|
||||
ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
|
||||
&name);
|
||||
if (ret) {
|
||||
krb5_data_free (&data);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
ctx->source = (krb5_principal)name;
|
||||
krb5_data_free (&data);
|
||||
|
||||
if (krb5_ret_data (sp, &data) != 0)
|
||||
goto failure;
|
||||
buffer.value = data.data;
|
||||
buffer.length = data.length;
|
||||
|
||||
ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
|
||||
&name);
|
||||
if (ret) {
|
||||
ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
|
||||
&name);
|
||||
if (ret) {
|
||||
krb5_data_free (&data);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
ctx->target = (krb5_principal)name;
|
||||
krb5_data_free (&data);
|
||||
|
||||
if (krb5_ret_int32 (sp, &tmp))
|
||||
goto failure;
|
||||
ctx->flags = tmp;
|
||||
if (krb5_ret_int32 (sp, &tmp))
|
||||
goto failure;
|
||||
ctx->more_flags = tmp;
|
||||
if (krb5_ret_int32 (sp, &tmp))
|
||||
goto failure;
|
||||
ctx->lifetime = tmp;
|
||||
|
||||
ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
krb5_storage_free (sp);
|
||||
|
||||
*context_handle = (gss_ctx_id_t)ctx;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
failure:
|
||||
krb5_auth_con_free (_gsskrb5_context,
|
||||
ctx->auth_context);
|
||||
if (ctx->source != NULL)
|
||||
krb5_free_principal(_gsskrb5_context, ctx->source);
|
||||
if (ctx->target != NULL)
|
||||
krb5_free_principal(_gsskrb5_context, ctx->target);
|
||||
if (localp)
|
||||
krb5_free_address (_gsskrb5_context, localp);
|
||||
if (remotep)
|
||||
krb5_free_address (_gsskrb5_context, remotep);
|
||||
if(ctx->order)
|
||||
_gssapi_msg_order_destroy(&ctx->order);
|
||||
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
||||
krb5_storage_free (sp);
|
||||
free (ctx);
|
||||
*context_handle = GSS_C_NO_CONTEXT;
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: indicate_mechs.c,v 1.9 2006/10/07 22:14:56 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_indicate_mechs
|
||||
(OM_uint32 * minor_status,
|
||||
gss_OID_set * mech_set
|
||||
)
|
||||
{
|
||||
OM_uint32 ret, junk;
|
||||
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, mech_set);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status,
|
||||
GSS_KRB5_MECHANISM, mech_set);
|
||||
if (ret) {
|
||||
_gsskrb5_release_oid_set(&junk, mech_set);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: init.c,v 1.9 2006/10/07 22:14:58 lha Exp $");
|
||||
|
||||
static HEIMDAL_MUTEX _gsskrb5_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 *
|
||||
_gsskrb5_get_thread_context(int createp)
|
||||
{
|
||||
struct gssapi_thr_context *ctx;
|
||||
int ret;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&_gsskrb5_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(&_gsskrb5_context_mutex);
|
||||
return ctx;
|
||||
fail:
|
||||
HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex);
|
||||
if (ctx)
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5_init (void)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex);
|
||||
|
||||
if(_gsskrb5_context == NULL)
|
||||
ret = krb5_init_context (&_gsskrb5_context);
|
||||
if (ret == 0 && !created_key) {
|
||||
HEIMDAL_key_create(&gssapi_context_key,
|
||||
gssapi_destroy_thread_context,
|
||||
ret);
|
||||
if (ret) {
|
||||
krb5_free_context(_gsskrb5_context);
|
||||
_gsskrb5_context = NULL;
|
||||
} else
|
||||
created_key = 1;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: init_sec_context.c,v 1.73 2006/11/07 17:40:01 lha Exp $");
|
||||
|
||||
/*
|
||||
* copy the addresses from `input_chan_bindings' (if any) to
|
||||
* the auth context `ac'
|
||||
*/
|
||||
|
||||
static OM_uint32
|
||||
set_addresses (krb5_auth_context ac,
|
||||
const gss_channel_bindings_t input_chan_bindings)
|
||||
{
|
||||
/* Port numbers are expected to be in application_data.value,
|
||||
* initator's port first */
|
||||
|
||||
krb5_address initiator_addr, acceptor_addr;
|
||||
krb5_error_code kret;
|
||||
|
||||
if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS
|
||||
|| input_chan_bindings->application_data.length !=
|
||||
2 * sizeof(ac->local_port))
|
||||
return 0;
|
||||
|
||||
memset(&initiator_addr, 0, sizeof(initiator_addr));
|
||||
memset(&acceptor_addr, 0, sizeof(acceptor_addr));
|
||||
|
||||
ac->local_port =
|
||||
*(int16_t *) input_chan_bindings->application_data.value;
|
||||
|
||||
ac->remote_port =
|
||||
*((int16_t *) input_chan_bindings->application_data.value + 1);
|
||||
|
||||
kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
|
||||
&input_chan_bindings->acceptor_address,
|
||||
ac->remote_port,
|
||||
&acceptor_addr);
|
||||
if (kret)
|
||||
return kret;
|
||||
|
||||
kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
|
||||
&input_chan_bindings->initiator_address,
|
||||
ac->local_port,
|
||||
&initiator_addr);
|
||||
if (kret) {
|
||||
krb5_free_address (_gsskrb5_context, &acceptor_addr);
|
||||
return kret;
|
||||
}
|
||||
|
||||
kret = krb5_auth_con_setaddrs(_gsskrb5_context,
|
||||
ac,
|
||||
&initiator_addr, /* local address */
|
||||
&acceptor_addr); /* remote address */
|
||||
|
||||
krb5_free_address (_gsskrb5_context, &initiator_addr);
|
||||
krb5_free_address (_gsskrb5_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
|
||||
|
||||
return kret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_create_ctx(
|
||||
OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context_handle,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
enum gss_ctx_id_t_state state)
|
||||
{
|
||||
krb5_error_code kret;
|
||||
gsskrb5_ctx ctx;
|
||||
|
||||
*context_handle = NULL;
|
||||
|
||||
ctx = malloc(sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
ctx->auth_context = NULL;
|
||||
ctx->source = NULL;
|
||||
ctx->target = NULL;
|
||||
ctx->state = state;
|
||||
ctx->flags = 0;
|
||||
ctx->more_flags = 0;
|
||||
ctx->service_keyblock = NULL;
|
||||
ctx->ticket = NULL;
|
||||
krb5_data_zero(&ctx->fwd_data);
|
||||
ctx->lifetime = GSS_C_INDEFINITE;
|
||||
ctx->order = NULL;
|
||||
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
|
||||
|
||||
kret = krb5_auth_con_init (_gsskrb5_context, &ctx->auth_context);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
_gsskrb5_set_error_string ();
|
||||
|
||||
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
||||
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = set_addresses(ctx->auth_context, input_chan_bindings);
|
||||
if (kret) {
|
||||
*minor_status = kret;
|
||||
|
||||
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
||||
|
||||
krb5_auth_con_free(_gsskrb5_context, ctx->auth_context);
|
||||
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need a sequence number
|
||||
*/
|
||||
|
||||
krb5_auth_con_addflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE |
|
||||
KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
|
||||
NULL);
|
||||
|
||||
*context_handle = (gss_ctx_id_t)ctx;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
|
||||
static OM_uint32
|
||||
gsskrb5_get_creds(
|
||||
OM_uint32 * minor_status,
|
||||
krb5_ccache ccache,
|
||||
gsskrb5_ctx ctx,
|
||||
krb5_const_principal target_name,
|
||||
OM_uint32 time_req,
|
||||
OM_uint32 * time_rec,
|
||||
krb5_creds ** cred)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
krb5_error_code kret;
|
||||
krb5_creds this_cred;
|
||||
OM_uint32 lifetime_rec;
|
||||
|
||||
*cred = NULL;
|
||||
|
||||
memset(&this_cred, 0, sizeof(this_cred));
|
||||
this_cred.client = ctx->source;
|
||||
this_cred.server = ctx->target;
|
||||
|
||||
if (time_req && time_req != GSS_C_INDEFINITE) {
|
||||
krb5_timestamp ts;
|
||||
|
||||
krb5_timeofday (_gsskrb5_context, &ts);
|
||||
this_cred.times.endtime = ts + time_req;
|
||||
} else {
|
||||
this_cred.times.endtime = 0;
|
||||
}
|
||||
|
||||
this_cred.session.keytype = KEYTYPE_NULL;
|
||||
|
||||
kret = krb5_get_credentials(_gsskrb5_context,
|
||||
0,
|
||||
ccache,
|
||||
&this_cred,
|
||||
cred);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ctx->lifetime = (*cred)->times.endtime;
|
||||
|
||||
ret = _gsskrb5_lifetime_left(minor_status, ctx->lifetime, &lifetime_rec);
|
||||
if (ret) return ret;
|
||||
|
||||
if (lifetime_rec == 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_CONTEXT_EXPIRED;
|
||||
}
|
||||
|
||||
if (time_rec) *time_rec = lifetime_rec;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
gsskrb5_initiator_ready(
|
||||
OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
int32_t seq_number;
|
||||
int is_cfx = 0;
|
||||
OM_uint32 flags = ctx->flags;
|
||||
|
||||
krb5_auth_getremoteseqnumber (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
||||
|
||||
ret = _gssapi_msg_order_create(minor_status,
|
||||
&ctx->order,
|
||||
_gssapi_msg_order_f(flags),
|
||||
seq_number, 0, is_cfx);
|
||||
if (ret) return ret;
|
||||
|
||||
ctx->state = INITIATOR_READY;
|
||||
ctx->more_flags |= OPEN;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle delegated creds in init-sec-context
|
||||
*/
|
||||
|
||||
static void
|
||||
do_delegation (krb5_auth_context ac,
|
||||
krb5_ccache ccache,
|
||||
krb5_creds *cred,
|
||||
krb5_const_principal name,
|
||||
krb5_data *fwd_data,
|
||||
uint32_t *flags)
|
||||
{
|
||||
krb5_creds creds;
|
||||
KDCOptions fwd_flags;
|
||||
krb5_error_code kret;
|
||||
|
||||
memset (&creds, 0, sizeof(creds));
|
||||
krb5_data_zero (fwd_data);
|
||||
|
||||
kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &creds.client);
|
||||
if (kret)
|
||||
goto out;
|
||||
|
||||
kret = krb5_build_principal(_gsskrb5_context,
|
||||
&creds.server,
|
||||
strlen(creds.client->realm),
|
||||
creds.client->realm,
|
||||
KRB5_TGS_NAME,
|
||||
creds.client->realm,
|
||||
NULL);
|
||||
if (kret)
|
||||
goto out;
|
||||
|
||||
creds.times.endtime = 0;
|
||||
|
||||
memset(&fwd_flags, 0, sizeof(fwd_flags));
|
||||
fwd_flags.forwarded = 1;
|
||||
fwd_flags.forwardable = 1;
|
||||
|
||||
if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
|
||||
name->name.name_string.len < 2)
|
||||
goto out;
|
||||
|
||||
kret = krb5_get_forwarded_creds(_gsskrb5_context,
|
||||
ac,
|
||||
ccache,
|
||||
KDCOptions2int(fwd_flags),
|
||||
name->name.name_string.val[1],
|
||||
&creds,
|
||||
fwd_data);
|
||||
|
||||
out:
|
||||
if (kret)
|
||||
*flags &= ~GSS_C_DELEG_FLAG;
|
||||
else
|
||||
*flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
if (creds.client)
|
||||
krb5_free_principal(_gsskrb5_context, creds.client);
|
||||
if (creds.server)
|
||||
krb5_free_principal(_gsskrb5_context, creds.server);
|
||||
}
|
||||
|
||||
/*
|
||||
* first stage of init-sec-context
|
||||
*/
|
||||
|
||||
static OM_uint32
|
||||
init_auth
|
||||
(OM_uint32 * minor_status,
|
||||
gsskrb5_cred initiator_cred_handle,
|
||||
gsskrb5_ctx ctx,
|
||||
krb5_const_principal name,
|
||||
const gss_OID mech_type,
|
||||
OM_uint32 req_flags,
|
||||
OM_uint32 time_req,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
const gss_buffer_t input_token,
|
||||
gss_OID * actual_mech_type,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags,
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
OM_uint32 ret = GSS_S_FAILURE;
|
||||
krb5_error_code kret;
|
||||
krb5_flags ap_options;
|
||||
krb5_creds *cred = NULL;
|
||||
krb5_data outbuf;
|
||||
krb5_ccache ccache = NULL;
|
||||
uint32_t flags;
|
||||
krb5_data authenticator;
|
||||
Checksum cksum;
|
||||
krb5_enctype enctype;
|
||||
krb5_data fwd_data;
|
||||
OM_uint32 lifetime_rec;
|
||||
|
||||
krb5_data_zero(&outbuf);
|
||||
krb5_data_zero(&fwd_data);
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (actual_mech_type)
|
||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
if (initiator_cred_handle == NULL) {
|
||||
kret = krb5_cc_default (_gsskrb5_context, &ccache);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
} else
|
||||
ccache = initiator_cred_handle->ccache;
|
||||
|
||||
kret = krb5_cc_get_principal (_gsskrb5_context, ccache, &ctx->source);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_copy_principal (_gsskrb5_context, name, &ctx->target);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = _gss_DES3_get_mic_compat(minor_status, ctx);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
|
||||
ret = gsskrb5_get_creds(minor_status,
|
||||
ccache,
|
||||
ctx,
|
||||
ctx->target,
|
||||
time_req,
|
||||
time_rec,
|
||||
&cred);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
ctx->lifetime = cred->times.endtime;
|
||||
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
ctx->lifetime,
|
||||
&lifetime_rec);
|
||||
if (ret) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (lifetime_rec == 0) {
|
||||
*minor_status = 0;
|
||||
ret = GSS_S_CONTEXT_EXPIRED;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
krb5_auth_con_setkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&cred->session);
|
||||
|
||||
kret = krb5_auth_con_generatelocalsubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&cred->session);
|
||||
if(kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the credential doesn't have ok-as-delegate, check what local
|
||||
* policy say about ok-as-delegate, default is FALSE that makes
|
||||
* code ignore the KDC setting and follow what the application
|
||||
* requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the
|
||||
* KDC doesn't set ok-as-delegate.
|
||||
*/
|
||||
if (!cred->flags.b.ok_as_delegate) {
|
||||
krb5_boolean delegate;
|
||||
|
||||
krb5_appdefault_boolean(_gsskrb5_context,
|
||||
"gssapi", name->realm,
|
||||
"ok-as-delegate", FALSE, &delegate);
|
||||
if (delegate)
|
||||
req_flags &= ~GSS_C_DELEG_FLAG;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
ap_options = 0;
|
||||
if (req_flags & GSS_C_DELEG_FLAG)
|
||||
do_delegation (ctx->auth_context,
|
||||
ccache, cred, name, &fwd_data, &flags);
|
||||
|
||||
if (req_flags & GSS_C_MUTUAL_FLAG) {
|
||||
flags |= GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
|
||||
if (req_flags & GSS_C_REPLAY_FLAG)
|
||||
flags |= GSS_C_REPLAY_FLAG;
|
||||
if (req_flags & GSS_C_SEQUENCE_FLAG)
|
||||
flags |= GSS_C_SEQUENCE_FLAG;
|
||||
if (req_flags & GSS_C_ANON_FLAG)
|
||||
; /* XXX */
|
||||
if (req_flags & GSS_C_DCE_STYLE) {
|
||||
/* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
|
||||
flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
|
||||
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||
}
|
||||
if (req_flags & GSS_C_IDENTIFY_FLAG)
|
||||
flags |= GSS_C_IDENTIFY_FLAG;
|
||||
if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
|
||||
flags |= GSS_C_EXTENDED_ERROR_FLAG;
|
||||
|
||||
flags |= GSS_C_CONF_FLAG;
|
||||
flags |= GSS_C_INTEG_FLAG;
|
||||
flags |= GSS_C_TRANS_FLAG;
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = flags;
|
||||
ctx->flags = flags;
|
||||
ctx->more_flags |= LOCAL;
|
||||
|
||||
ret = _gsskrb5_create_8003_checksum (minor_status,
|
||||
input_chan_bindings,
|
||||
flags,
|
||||
&fwd_data,
|
||||
&cksum);
|
||||
krb5_data_free (&fwd_data);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
enctype = ctx->auth_context->keyblock->keytype;
|
||||
|
||||
kret = krb5_build_authenticator (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
enctype,
|
||||
cred,
|
||||
&cksum,
|
||||
NULL,
|
||||
&authenticator,
|
||||
KRB5_KU_AP_REQ_AUTH);
|
||||
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
kret = krb5_build_ap_req (_gsskrb5_context,
|
||||
enctype,
|
||||
cred,
|
||||
ap_options,
|
||||
authenticator,
|
||||
&outbuf);
|
||||
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
ret = GSS_S_FAILURE;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,
|
||||
(u_char *)"\x01\x00", GSS_KRB5_MECHANISM);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
krb5_data_free (&outbuf);
|
||||
krb5_free_creds(_gsskrb5_context, cred);
|
||||
free_Checksum(&cksum);
|
||||
if (initiator_cred_handle == NULL)
|
||||
krb5_cc_close(_gsskrb5_context, ccache);
|
||||
|
||||
if (flags & GSS_C_MUTUAL_FLAG) {
|
||||
ctx->state = INITIATOR_WAIT_FOR_MUTAL;
|
||||
return GSS_S_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
return gsskrb5_initiator_ready(minor_status, ctx);
|
||||
failure:
|
||||
if(cred)
|
||||
krb5_free_creds(_gsskrb5_context, cred);
|
||||
if (ccache && initiator_cred_handle == NULL)
|
||||
krb5_cc_close(_gsskrb5_context, ccache);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
repl_mutual
|
||||
(OM_uint32 * minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
const gss_OID mech_type,
|
||||
OM_uint32 req_flags,
|
||||
OM_uint32 time_req,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
const gss_buffer_t input_token,
|
||||
gss_OID * actual_mech_type,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags,
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
krb5_error_code kret;
|
||||
krb5_data indata;
|
||||
krb5_ap_rep_enc_part *repl;
|
||||
int is_cfx = 0;
|
||||
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
if (actual_mech_type)
|
||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
if (ctx->flags & GSS_C_DCE_STYLE) {
|
||||
/* There is no OID wrapping. */
|
||||
indata.length = input_token->length;
|
||||
indata.data = input_token->value;
|
||||
} else {
|
||||
ret = _gsskrb5_decapsulate (minor_status,
|
||||
input_token,
|
||||
&indata,
|
||||
"\x02\x00",
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret) {
|
||||
/* XXX - Handle AP_ERROR */
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
kret = krb5_rd_rep (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&indata,
|
||||
&repl);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_free_ap_rep_enc_part (_gsskrb5_context,
|
||||
repl);
|
||||
|
||||
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
||||
if (is_cfx) {
|
||||
krb5_keyblock *key = NULL;
|
||||
|
||||
kret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&key);
|
||||
if (kret == 0 && key != NULL) {
|
||||
ctx->more_flags |= ACCEPTOR_SUBKEY;
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*minor_status = 0;
|
||||
if (time_rec) {
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
ctx->lifetime,
|
||||
time_rec);
|
||||
} else {
|
||||
ret = GSS_S_COMPLETE;
|
||||
}
|
||||
if (ret_flags)
|
||||
*ret_flags = ctx->flags;
|
||||
|
||||
if (req_flags & GSS_C_DCE_STYLE) {
|
||||
int32_t con_flags;
|
||||
krb5_data outbuf;
|
||||
|
||||
/* Do don't do sequence number for the mk-rep */
|
||||
krb5_auth_con_removeflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE,
|
||||
&con_flags);
|
||||
|
||||
kret = krb5_mk_rep(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
&outbuf);
|
||||
if (kret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
output_token->length = outbuf.length;
|
||||
output_token->value = outbuf.data;
|
||||
|
||||
krb5_auth_con_removeflags(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return gsskrb5_initiator_ready(minor_status, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* gss_init_sec_context
|
||||
*/
|
||||
|
||||
OM_uint32 _gsskrb5_init_sec_context
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_cred_id_t initiator_cred_handle,
|
||||
gss_ctx_id_t * context_handle,
|
||||
const gss_name_t target_name,
|
||||
const gss_OID mech_type,
|
||||
OM_uint32 req_flags,
|
||||
OM_uint32 time_req,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
const gss_buffer_t input_token,
|
||||
gss_OID * actual_mech_type,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags,
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
|
||||
krb5_const_principal name = (krb5_const_principal)target_name;
|
||||
gsskrb5_ctx ctx;
|
||||
OM_uint32 ret;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
|
||||
if (context_handle == NULL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||
}
|
||||
|
||||
if (ret_flags)
|
||||
*ret_flags = 0;
|
||||
if (time_rec)
|
||||
*time_rec = 0;
|
||||
|
||||
if (target_name == GSS_C_NO_NAME) {
|
||||
if (actual_mech_type)
|
||||
*actual_mech_type = GSS_C_NO_OID;
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_NAME;
|
||||
}
|
||||
|
||||
if (mech_type != GSS_C_NO_OID &&
|
||||
!gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
|
||||
OM_uint32 ret;
|
||||
|
||||
if (*context_handle != GSS_C_NO_CONTEXT) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||
}
|
||||
|
||||
ret = _gsskrb5_create_ctx(minor_status,
|
||||
context_handle,
|
||||
input_chan_bindings,
|
||||
INITIATOR_START);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*context_handle == GSS_C_NO_CONTEXT) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||
}
|
||||
|
||||
ctx = (gsskrb5_ctx) *context_handle;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
|
||||
switch (ctx->state) {
|
||||
case INITIATOR_START:
|
||||
ret = init_auth(minor_status,
|
||||
cred,
|
||||
ctx,
|
||||
name,
|
||||
mech_type,
|
||||
req_flags,
|
||||
time_req,
|
||||
input_chan_bindings,
|
||||
input_token,
|
||||
actual_mech_type,
|
||||
output_token,
|
||||
ret_flags,
|
||||
time_rec);
|
||||
break;
|
||||
case INITIATOR_WAIT_FOR_MUTAL:
|
||||
ret = repl_mutual(minor_status,
|
||||
ctx,
|
||||
mech_type,
|
||||
req_flags,
|
||||
time_req,
|
||||
input_chan_bindings,
|
||||
input_token,
|
||||
actual_mech_type,
|
||||
output_token,
|
||||
ret_flags,
|
||||
time_rec);
|
||||
break;
|
||||
case INITIATOR_READY:
|
||||
/*
|
||||
* If we get there, the caller have called
|
||||
* gss_init_sec_context() one time too many.
|
||||
*/
|
||||
*minor_status = 0;
|
||||
ret = GSS_S_BAD_STATUS;
|
||||
break;
|
||||
default:
|
||||
*minor_status = 0;
|
||||
ret = GSS_S_BAD_STATUS;
|
||||
break;
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
/* destroy context in case of error */
|
||||
if (GSS_ERROR(ret)) {
|
||||
OM_uint32 min2;
|
||||
_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_context.c,v 1.10 2006/10/07 22:15:03 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
|
||||
gss_name_t name;
|
||||
|
||||
if (src_name)
|
||||
*src_name = GSS_C_NO_NAME;
|
||||
if (targ_name)
|
||||
*targ_name = GSS_C_NO_NAME;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
|
||||
if (src_name) {
|
||||
name = (gss_name_t)ctx->source;
|
||||
ret = _gsskrb5_duplicate_name (minor_status, name, src_name);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (targ_name) {
|
||||
name = (gss_name_t)ctx->target;
|
||||
ret = _gsskrb5_duplicate_name (minor_status, name, targ_name);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (lifetime_rec) {
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
ctx->lifetime,
|
||||
lifetime_rec);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (mech_type)
|
||||
*mech_type = GSS_KRB5_MECHANISM;
|
||||
|
||||
if (ctx_flags)
|
||||
*ctx_flags = ctx->flags;
|
||||
|
||||
if (locally_initiated)
|
||||
*locally_initiated = ctx->more_flags & LOCAL;
|
||||
|
||||
if (open_context)
|
||||
*open_context = ctx->more_flags & OPEN;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
failed:
|
||||
if (src_name)
|
||||
_gsskrb5_release_name(NULL, src_name);
|
||||
if (targ_name)
|
||||
_gsskrb5_release_name(NULL, targ_name);
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_cred.c,v 1.12 2006/10/07 22:15:06 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_inquire_cred
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_cred_id_t cred_handle,
|
||||
gss_name_t * output_name,
|
||||
OM_uint32 * lifetime,
|
||||
gss_cred_usage_t * cred_usage,
|
||||
gss_OID_set * mechanisms
|
||||
)
|
||||
{
|
||||
gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL;
|
||||
gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL;
|
||||
gsskrb5_cred acred = NULL, icred = NULL;
|
||||
OM_uint32 ret;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (output_name)
|
||||
*output_name = NULL;
|
||||
if (mechanisms)
|
||||
*mechanisms = GSS_C_NO_OID_SET;
|
||||
|
||||
if (cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
ret = _gsskrb5_acquire_cred(minor_status,
|
||||
GSS_C_NO_NAME,
|
||||
GSS_C_INDEFINITE,
|
||||
GSS_C_NO_OID_SET,
|
||||
GSS_C_ACCEPT,
|
||||
&aqcred_accept,
|
||||
NULL,
|
||||
NULL);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
acred = (gsskrb5_cred)aqcred_accept;
|
||||
|
||||
ret = _gsskrb5_acquire_cred(minor_status,
|
||||
GSS_C_NO_NAME,
|
||||
GSS_C_INDEFINITE,
|
||||
GSS_C_NO_OID_SET,
|
||||
GSS_C_INITIATE,
|
||||
&aqcred_init,
|
||||
NULL,
|
||||
NULL);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
acred = (gsskrb5_cred)aqcred_init;
|
||||
|
||||
if (icred == NULL && acred == NULL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_NO_CRED;
|
||||
}
|
||||
} else
|
||||
acred = (gsskrb5_cred)cred_handle;
|
||||
|
||||
if (acred)
|
||||
HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
|
||||
if (icred)
|
||||
HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);
|
||||
|
||||
if (output_name != NULL) {
|
||||
if (icred && icred->principal != NULL) {
|
||||
gss_name_t name;
|
||||
|
||||
if (acred)
|
||||
name = (gss_name_t)acred->principal;
|
||||
else
|
||||
name = (gss_name_t)icred->principal;
|
||||
|
||||
ret = _gsskrb5_duplicate_name(minor_status, name, output_name);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else if (acred && acred->usage == GSS_C_ACCEPT) {
|
||||
krb5_principal princ;
|
||||
*minor_status = krb5_sname_to_principal(_gsskrb5_context, NULL,
|
||||
NULL, KRB5_NT_SRV_HST,
|
||||
&princ);
|
||||
if (*minor_status) {
|
||||
ret = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
*output_name = (gss_name_t)princ;
|
||||
} else {
|
||||
krb5_principal princ;
|
||||
*minor_status = krb5_get_default_principal(_gsskrb5_context,
|
||||
&princ);
|
||||
if (*minor_status) {
|
||||
ret = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
*output_name = (gss_name_t)princ;
|
||||
}
|
||||
}
|
||||
if (lifetime != NULL) {
|
||||
OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE;
|
||||
|
||||
if (acred) alife = acred->lifetime;
|
||||
if (icred) ilife = icred->lifetime;
|
||||
|
||||
ret = _gsskrb5_lifetime_left(minor_status,
|
||||
min(alife,ilife),
|
||||
lifetime);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
if (cred_usage != NULL) {
|
||||
if (acred && icred)
|
||||
*cred_usage = GSS_C_BOTH;
|
||||
else if (acred)
|
||||
*cred_usage = GSS_C_ACCEPT;
|
||||
else if (icred)
|
||||
*cred_usage = GSS_C_INITIATE;
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mechanisms != NULL) {
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, mechanisms);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (acred)
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status,
|
||||
&acred->mechanisms->elements[0],
|
||||
mechanisms);
|
||||
if (ret == GSS_S_COMPLETE && icred)
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status,
|
||||
&icred->mechanisms->elements[0],
|
||||
mechanisms);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
ret = GSS_S_COMPLETE;
|
||||
out:
|
||||
if (acred)
|
||||
HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex);
|
||||
if (icred)
|
||||
HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex);
|
||||
|
||||
if (aqcred_init != GSS_C_NO_CREDENTIAL)
|
||||
ret = _gsskrb5_release_cred(minor_status, &aqcred_init);
|
||||
if (aqcred_accept != GSS_C_NO_CREDENTIAL)
|
||||
ret = _gsskrb5_release_cred(minor_status, &aqcred_accept);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_cred_by_mech.c,v 1.4 2006/10/07 22:15:08 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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 = _gsskrb5_inquire_cred (minor_status,
|
||||
cred_handle,
|
||||
name,
|
||||
&lifetime,
|
||||
cred_usage,
|
||||
NULL);
|
||||
|
||||
if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) {
|
||||
gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
|
||||
gss_cred_usage_t usage;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
|
||||
usage = cred->usage;
|
||||
HEIMDAL_MUTEX_unlock(&cred->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;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_cred_by_oid.c,v 1.4 2006/10/07 22:15:10 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_inquire_cred_by_oid
|
||||
(OM_uint32 * minor_status,
|
||||
const gss_cred_id_t cred_handle,
|
||||
const gss_OID desired_object,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
|
||||
krb5_error_code ret;
|
||||
gss_buffer_desc buffer;
|
||||
char *str;
|
||||
|
||||
if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = krb5_cc_get_full_name(_gsskrb5_context, cred->ccache, &str);
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
_gsskrb5_set_error_string ();
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
buffer.value = str;
|
||||
buffer.length = strlen(str);
|
||||
|
||||
ret = gss_add_buffer_set_member(minor_status, &buffer, data_set);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
_gsskrb5_clear_status ();
|
||||
|
||||
free(str);
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_mechs_for_name.c,v 1.3 2006/10/07 22:15:13 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_inquire_mechs_for_name (
|
||||
OM_uint32 * minor_status,
|
||||
const gss_name_t input_name,
|
||||
gss_OID_set * mech_types
|
||||
)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
|
||||
ret = _gsskrb5_create_empty_oid_set(minor_status, mech_types);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status,
|
||||
GSS_KRB5_MECHANISM,
|
||||
mech_types);
|
||||
if (ret)
|
||||
_gsskrb5_release_oid_set(NULL, mech_types);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_names_for_mech.c,v 1.3 2006/10/07 22:15:15 lha Exp $");
|
||||
|
||||
|
||||
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 _gsskrb5_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 = _gsskrb5_create_empty_oid_set(minor_status, name_types);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
return ret;
|
||||
|
||||
for (i = 0; name_list[i] != NULL; i++) {
|
||||
ret = _gsskrb5_add_oid_set_member(minor_status,
|
||||
*(name_list[i]),
|
||||
name_types);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
_gsskrb5_release_oid_set(NULL, name_types);
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: inquire_sec_context_by_oid.c,v 1.11 2006/11/07 14:34:35 lha Exp $");
|
||||
|
||||
static int
|
||||
oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
|
||||
{
|
||||
int ret;
|
||||
heim_oid oid;
|
||||
heim_oid prefix;
|
||||
|
||||
*suffix = 0;
|
||||
|
||||
ret = der_get_oid(oid_enc->elements, oid_enc->length,
|
||||
&oid, NULL);
|
||||
if (ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = der_get_oid(prefix_enc->elements, prefix_enc->length,
|
||||
&prefix, NULL);
|
||||
if (ret) {
|
||||
der_free_oid(&oid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (oid.length - 1 == prefix.length) {
|
||||
*suffix = oid.components[oid.length - 1];
|
||||
oid.length--;
|
||||
ret = (der_heim_oid_cmp(&oid, &prefix) == 0);
|
||||
oid.length++;
|
||||
}
|
||||
|
||||
der_free_oid(&oid);
|
||||
der_free_oid(&prefix);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OM_uint32 inquire_sec_context_tkt_flags
|
||||
(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
OM_uint32 tkt_flags;
|
||||
unsigned char buf[4];
|
||||
gss_buffer_desc value;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
if (context_handle->ticket == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
_gsskrb5_set_status("No ticket from which to obtain flags");
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
|
||||
tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags);
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
_gsskrb5_encode_om_uint32(tkt_flags, buf);
|
||||
value.length = sizeof(buf);
|
||||
value.value = buf;
|
||||
|
||||
return gss_add_buffer_set_member(minor_status,
|
||||
&value,
|
||||
data_set);
|
||||
}
|
||||
|
||||
enum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY };
|
||||
|
||||
static OM_uint32 inquire_sec_context_get_subkey
|
||||
(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
enum keytype keytype,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
krb5_keyblock *key = NULL;
|
||||
krb5_storage *sp = NULL;
|
||||
krb5_data data;
|
||||
OM_uint32 maj_stat = GSS_S_COMPLETE;
|
||||
krb5_error_code ret;
|
||||
|
||||
krb5_data_zero(&data);
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
_gsskrb5_clear_status();
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
switch(keytype) {
|
||||
case ACCEPTOR_KEY:
|
||||
ret = _gsskrb5i_get_acceptor_subkey(context_handle, &key);
|
||||
if (ret)
|
||||
_gsskrb5_set_error_string ();
|
||||
break;
|
||||
case INITIATOR_KEY:
|
||||
ret = _gsskrb5i_get_initiator_subkey(context_handle, &key);
|
||||
if (ret)
|
||||
_gsskrb5_set_error_string ();
|
||||
break;
|
||||
case TOKEN_KEY:
|
||||
ret = _gsskrb5i_get_token_key(context_handle, &key);
|
||||
if (ret)
|
||||
_gsskrb5_set_error_string ();
|
||||
break;
|
||||
default:
|
||||
_gsskrb5_set_status("%d is not a valid subkey type", keytype);
|
||||
ret = EINVAL;
|
||||
break;
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (key == NULL) {
|
||||
_gsskrb5_set_status("have no subkey of type %d", keytype);
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_store_keyblock(sp, *key);
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_storage_to_data(sp, &data);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
gss_buffer_desc value;
|
||||
|
||||
value.length = data.length;
|
||||
value.value = data.data;
|
||||
|
||||
maj_stat = gss_add_buffer_set_member(minor_status,
|
||||
&value,
|
||||
data_set);
|
||||
}
|
||||
|
||||
out:
|
||||
krb5_data_free(&data);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
maj_stat = GSS_S_FAILURE;
|
||||
}
|
||||
return maj_stat;
|
||||
}
|
||||
|
||||
static OM_uint32 inquire_sec_context_authz_data
|
||||
(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
unsigned ad_type,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
krb5_data data;
|
||||
gss_buffer_desc ad_data;
|
||||
OM_uint32 ret;
|
||||
|
||||
*minor_status = 0;
|
||||
*data_set = GSS_C_NO_BUFFER_SET;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
if (context_handle->ticket == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
*minor_status = EINVAL;
|
||||
_gsskrb5_set_status("No ticket to obtain authz data from");
|
||||
return GSS_S_NO_CONTEXT;
|
||||
}
|
||||
|
||||
ret = krb5_ticket_get_authorization_data_type(_gsskrb5_context,
|
||||
context_handle->ticket,
|
||||
ad_type,
|
||||
&data);
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ad_data.value = data.data;
|
||||
ad_data.length = data.length;
|
||||
|
||||
ret = gss_add_buffer_set_member(minor_status,
|
||||
&ad_data,
|
||||
data_set);
|
||||
|
||||
krb5_data_free(&data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OM_uint32 inquire_sec_context_has_updated_spnego
|
||||
(OM_uint32 *minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
int is_updated = 0;
|
||||
|
||||
*minor_status = 0;
|
||||
*data_set = GSS_C_NO_BUFFER_SET;
|
||||
|
||||
/*
|
||||
* For Windows SPNEGO implementations, both the initiator and the
|
||||
* acceptor are assumed to have been updated if a "newer" [CLAR] or
|
||||
* different enctype is negotiated for use by the Kerberos GSS-API
|
||||
* mechanism.
|
||||
*/
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
_gsskrb5i_is_cfx(context_handle, &is_updated);
|
||||
if (is_updated == 0) {
|
||||
krb5_keyblock *acceptor_subkey;
|
||||
|
||||
if (context_handle->more_flags & LOCAL)
|
||||
acceptor_subkey = context_handle->auth_context->remote_subkey;
|
||||
else
|
||||
acceptor_subkey = context_handle->auth_context->local_subkey;
|
||||
|
||||
if (acceptor_subkey != NULL)
|
||||
is_updated = (acceptor_subkey->keytype !=
|
||||
context_handle->auth_context->keyblock->keytype);
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static OM_uint32
|
||||
export_lucid_sec_context_v1(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx context_handle,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
krb5_storage *sp = NULL;
|
||||
OM_uint32 major_status = GSS_S_COMPLETE;
|
||||
krb5_error_code ret;
|
||||
krb5_keyblock *key = NULL;
|
||||
int32_t number;
|
||||
int is_cfx;
|
||||
krb5_data data;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
_gsskrb5i_is_cfx(context_handle, &is_cfx);
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
_gsskrb5_clear_status();
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_store_int32(sp, 1);
|
||||
if (ret) goto out;
|
||||
ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0);
|
||||
if (ret) goto out;
|
||||
ret = krb5_store_int32(sp, context_handle->lifetime);
|
||||
if (ret) goto out;
|
||||
krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&number);
|
||||
ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
|
||||
ret = krb5_store_uint32(sp, (uint32_t)number);
|
||||
krb5_auth_getremoteseqnumber (_gsskrb5_context,
|
||||
context_handle->auth_context,
|
||||
&number);
|
||||
ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
|
||||
ret = krb5_store_uint32(sp, (uint32_t)number);
|
||||
ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0);
|
||||
if (ret) goto out;
|
||||
|
||||
ret = _gsskrb5i_get_token_key(context_handle, &key);
|
||||
if (ret) goto out;
|
||||
|
||||
if (is_cfx == 0) {
|
||||
int sign_alg, seal_alg;
|
||||
|
||||
switch (key->keytype) {
|
||||
case ETYPE_DES_CBC_CRC:
|
||||
case ETYPE_DES_CBC_MD4:
|
||||
case ETYPE_DES_CBC_MD5:
|
||||
sign_alg = 0;
|
||||
seal_alg = 0;
|
||||
break;
|
||||
case ETYPE_DES3_CBC_MD5:
|
||||
case ETYPE_DES3_CBC_SHA1:
|
||||
sign_alg = 4;
|
||||
seal_alg = 2;
|
||||
break;
|
||||
case ETYPE_ARCFOUR_HMAC_MD5:
|
||||
case ETYPE_ARCFOUR_HMAC_MD5_56:
|
||||
sign_alg = 17;
|
||||
seal_alg = 16;
|
||||
break;
|
||||
default:
|
||||
sign_alg = -1;
|
||||
seal_alg = -1;
|
||||
break;
|
||||
}
|
||||
ret = krb5_store_int32(sp, sign_alg);
|
||||
if (ret) goto out;
|
||||
ret = krb5_store_int32(sp, seal_alg);
|
||||
if (ret) goto out;
|
||||
/* ctx_key */
|
||||
ret = krb5_store_keyblock(sp, *key);
|
||||
if (ret) goto out;
|
||||
} else {
|
||||
int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0;
|
||||
|
||||
/* have_acceptor_subkey */
|
||||
ret = krb5_store_int32(sp, subkey_p);
|
||||
if (ret) goto out;
|
||||
/* ctx_key */
|
||||
ret = krb5_store_keyblock(sp, *key);
|
||||
if (ret) goto out;
|
||||
/* acceptor_subkey */
|
||||
if (subkey_p) {
|
||||
ret = krb5_store_keyblock(sp, *key);
|
||||
if (ret) goto out;
|
||||
}
|
||||
}
|
||||
ret = krb5_storage_to_data(sp, &data);
|
||||
if (ret) goto out;
|
||||
|
||||
{
|
||||
gss_buffer_desc ad_data;
|
||||
|
||||
ad_data.value = data.data;
|
||||
ad_data.length = data.length;
|
||||
|
||||
ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set);
|
||||
krb5_data_free(&data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (key)
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_status = GSS_S_FAILURE;
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return major_status;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
get_authtime(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
gss_buffer_set_t *data_set)
|
||||
|
||||
{
|
||||
gss_buffer_desc value;
|
||||
unsigned char buf[4];
|
||||
OM_uint32 authtime;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
if (ctx->ticket == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
_gsskrb5_set_status("No ticket to obtain auth time from");
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
authtime = ctx->ticket->ticket.authtime;
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
_gsskrb5_encode_om_uint32(authtime, buf);
|
||||
value.length = sizeof(buf);
|
||||
value.value = buf;
|
||||
|
||||
return gss_add_buffer_set_member(minor_status,
|
||||
&value,
|
||||
data_set);
|
||||
}
|
||||
|
||||
|
||||
static OM_uint32
|
||||
get_service_keyblock
|
||||
(OM_uint32 *minor_status,
|
||||
gsskrb5_ctx ctx,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
krb5_storage *sp = NULL;
|
||||
krb5_data data;
|
||||
OM_uint32 maj_stat = GSS_S_COMPLETE;
|
||||
krb5_error_code ret = EINVAL;
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
_gsskrb5_clear_status();
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
if (ctx->service_keyblock == NULL) {
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
_gsskrb5_set_status("No service keyblock on gssapi context");
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
krb5_data_zero(&data);
|
||||
|
||||
ret = krb5_store_keyblock(sp, *ctx->service_keyblock);
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = krb5_storage_to_data(sp, &data);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
{
|
||||
gss_buffer_desc value;
|
||||
|
||||
value.length = data.length;
|
||||
value.value = data.data;
|
||||
|
||||
maj_stat = gss_add_buffer_set_member(minor_status,
|
||||
&value,
|
||||
data_set);
|
||||
}
|
||||
|
||||
out:
|
||||
krb5_data_free(&data);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
maj_stat = GSS_S_FAILURE;
|
||||
}
|
||||
return maj_stat;
|
||||
}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
OM_uint32 _gsskrb5_inquire_sec_context_by_oid
|
||||
(OM_uint32 *minor_status,
|
||||
const gss_ctx_id_t context_handle,
|
||||
const gss_OID desired_object,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
unsigned suffix;
|
||||
|
||||
if (ctx == NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) {
|
||||
return inquire_sec_context_tkt_flags(minor_status,
|
||||
ctx,
|
||||
data_set);
|
||||
} else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) {
|
||||
return inquire_sec_context_has_updated_spnego(minor_status,
|
||||
ctx,
|
||||
data_set);
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) {
|
||||
return inquire_sec_context_get_subkey(minor_status,
|
||||
ctx,
|
||||
TOKEN_KEY,
|
||||
data_set);
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) {
|
||||
return inquire_sec_context_get_subkey(minor_status,
|
||||
ctx,
|
||||
INITIATOR_KEY,
|
||||
data_set);
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) {
|
||||
return inquire_sec_context_get_subkey(minor_status,
|
||||
ctx,
|
||||
ACCEPTOR_KEY,
|
||||
data_set);
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) {
|
||||
return get_authtime(minor_status, ctx, data_set);
|
||||
} else if (oid_prefix_equal(desired_object,
|
||||
GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X,
|
||||
&suffix)) {
|
||||
return inquire_sec_context_authz_data(minor_status,
|
||||
ctx,
|
||||
suffix,
|
||||
data_set);
|
||||
} else if (oid_prefix_equal(desired_object,
|
||||
GSS_KRB5_EXPORT_LUCID_CONTEXT_X,
|
||||
&suffix)) {
|
||||
if (suffix == 1)
|
||||
return export_lucid_sec_context_v1(minor_status,
|
||||
ctx,
|
||||
data_set);
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE;
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) {
|
||||
return get_service_keyblock(minor_status, ctx, data_set);
|
||||
} else {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: process_context_token.c,v 1.4 2006/10/07 22:15:19 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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 = _gsskrb5_verify_mic_internal(minor_status,
|
||||
(gsskrb5_ctx)context_handle,
|
||||
token_buffer, &empty_buffer,
|
||||
GSS_C_QOP_DEFAULT, "\x01\x02");
|
||||
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
ret = _gsskrb5_delete_sec_context(minor_status,
|
||||
rk_UNCONST(&context_handle),
|
||||
GSS_C_NO_BUFFER);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
*minor_status = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: release_buffer.c,v 1.7 2006/10/07 22:15:22 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: release_cred.c,v 1.13 2006/10/07 22:15:24 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_release_cred
|
||||
(OM_uint32 * minor_status,
|
||||
gss_cred_id_t * cred_handle
|
||||
)
|
||||
{
|
||||
gsskrb5_cred cred;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (*cred_handle == NULL)
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
cred = (gsskrb5_cred)*cred_handle;
|
||||
*cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
|
||||
|
||||
if (cred->principal != NULL)
|
||||
krb5_free_principal(_gsskrb5_context, cred->principal);
|
||||
if (cred->keytab != NULL)
|
||||
krb5_kt_close(_gsskrb5_context, cred->keytab);
|
||||
if (cred->ccache != NULL) {
|
||||
const krb5_cc_ops *ops;
|
||||
ops = krb5_cc_get_ops(_gsskrb5_context, cred->ccache);
|
||||
if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
|
||||
krb5_cc_destroy(_gsskrb5_context, cred->ccache);
|
||||
else
|
||||
krb5_cc_close(_gsskrb5_context, cred->ccache);
|
||||
}
|
||||
_gsskrb5_release_oid_set(NULL, &cred->mechanisms);
|
||||
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
|
||||
HEIMDAL_MUTEX_destroy(&cred->cred_id_mutex);
|
||||
memset(cred, 0, sizeof(*cred));
|
||||
free(cred);
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: release_name.c,v 1.10 2006/10/07 22:15:26 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_release_name
|
||||
(OM_uint32 * minor_status,
|
||||
gss_name_t * input_name
|
||||
)
|
||||
{
|
||||
krb5_principal name = (krb5_principal)*input_name;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
if (minor_status)
|
||||
*minor_status = 0;
|
||||
|
||||
*input_name = GSS_C_NO_NAME;
|
||||
|
||||
krb5_free_principal(_gsskrb5_context, name);
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: release_oid_set.c,v 1.7 2006/10/07 22:15:30 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
}
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: sequence.c,v 1.8 2006/10/07 22:15:32 lha Exp $");
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: set_cred_option.c,v 1.4 2006/10/24 20:14:13 lha Exp $");
|
||||
|
||||
static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
|
||||
{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */
|
||||
|
||||
gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
|
||||
|
||||
static OM_uint32
|
||||
import_cred(OM_uint32 *minor_status,
|
||||
gss_cred_id_t *cred_handle,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
OM_uint32 major_stat;
|
||||
krb5_error_code ret;
|
||||
krb5_principal keytab_principal = NULL;
|
||||
krb5_keytab keytab = NULL;
|
||||
krb5_storage *sp = NULL;
|
||||
krb5_ccache id = NULL;
|
||||
char *str;
|
||||
|
||||
if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
sp = krb5_storage_from_mem(value->value, value->length);
|
||||
if (sp == NULL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* credential cache name */
|
||||
ret = krb5_ret_string(sp, &str);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_stat = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
if (str[0]) {
|
||||
ret = krb5_cc_resolve(_gsskrb5_context, str, &id);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_stat = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
free(str);
|
||||
str = NULL;
|
||||
|
||||
/* keytab principal name */
|
||||
ret = krb5_ret_string(sp, &str);
|
||||
if (ret == 0 && str[0])
|
||||
ret = krb5_parse_name(_gsskrb5_context, str, &keytab_principal);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_stat = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
free(str);
|
||||
str = NULL;
|
||||
|
||||
/* keytab principal */
|
||||
ret = krb5_ret_string(sp, &str);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_stat = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
if (str[0]) {
|
||||
ret = krb5_kt_resolve(_gsskrb5_context, str, &keytab);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
major_stat = GSS_S_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
free(str);
|
||||
str = NULL;
|
||||
|
||||
major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal,
|
||||
keytab, cred_handle);
|
||||
out:
|
||||
if (id)
|
||||
krb5_cc_close(_gsskrb5_context, id);
|
||||
if (keytab_principal)
|
||||
krb5_free_principal(_gsskrb5_context, keytab_principal);
|
||||
if (keytab)
|
||||
krb5_kt_close(_gsskrb5_context, keytab);
|
||||
if (str)
|
||||
free(str);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
|
||||
return major_stat;
|
||||
}
|
||||
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_set_cred_option
|
||||
(OM_uint32 *minor_status,
|
||||
gss_cred_id_t *cred_handle,
|
||||
const gss_OID desired_object,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
if (value == GSS_C_NO_BUFFER) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) {
|
||||
return import_cred(minor_status, cred_handle, value);
|
||||
}
|
||||
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* glue routine for _gsskrb5_inquire_sec_context_by_oid
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: set_sec_context_option.c,v 1.8 2006/11/08 23:06:42 lha Exp $");
|
||||
|
||||
static OM_uint32
|
||||
get_bool(OM_uint32 *minor_status,
|
||||
const gss_buffer_t value,
|
||||
int *flag)
|
||||
{
|
||||
if (value->value == NULL || value->length != 1) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
*flag = *((const char *)value->value) != 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_set_sec_context_option
|
||||
(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context_handle,
|
||||
const gss_OID desired_object,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
OM_uint32 maj_stat;
|
||||
|
||||
GSSAPI_KRB5_INIT ();
|
||||
|
||||
if (value == GSS_C_NO_BUFFER) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
|
||||
gsskrb5_ctx ctx;
|
||||
int flag;
|
||||
|
||||
if (*context_handle == GSS_C_NO_CONTEXT) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_NO_CONTEXT;
|
||||
}
|
||||
|
||||
maj_stat = get_bool(minor_status, value, &flag);
|
||||
if (maj_stat != GSS_S_COMPLETE)
|
||||
return maj_stat;
|
||||
|
||||
ctx = (gsskrb5_ctx)*context_handle;
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
if (flag)
|
||||
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 GSS_S_COMPLETE;
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
|
||||
int flag;
|
||||
|
||||
maj_stat = get_bool(minor_status, value, &flag);
|
||||
if (maj_stat != GSS_S_COMPLETE)
|
||||
return maj_stat;
|
||||
|
||||
krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag);
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
|
||||
char *str;
|
||||
|
||||
if (value == NULL || value->length == 0) {
|
||||
str = NULL;
|
||||
} else {
|
||||
str = malloc(value->length + 1);
|
||||
if (str) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_UNAVAILABLE;
|
||||
}
|
||||
memcpy(str, value->value, value->length);
|
||||
str[value->length] = '\0';
|
||||
}
|
||||
|
||||
_gsskrb5_register_acceptor_identity(str);
|
||||
free(str);
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
|
||||
char *str;
|
||||
|
||||
if (value == NULL || value->length == 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_CALL_INACCESSIBLE_READ;
|
||||
}
|
||||
str = malloc(value->length + 1);
|
||||
if (str) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_UNAVAILABLE;
|
||||
}
|
||||
memcpy(str, value->value, value->length);
|
||||
str[value->length] = '\0';
|
||||
|
||||
krb5_set_default_realm(_gsskrb5_context, str);
|
||||
free(str);
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
|
||||
} else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {
|
||||
|
||||
if (value == NULL || value->length == 0) {
|
||||
krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL);
|
||||
} else {
|
||||
struct gsskrb5_send_to_kdc c;
|
||||
|
||||
if (value->length != sizeof(c)) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
memcpy(&c, value->value, sizeof(c));
|
||||
krb5_set_send_to_kdc_func(_gsskrb5_context,
|
||||
(krb5_send_to_kdc_func)c.func,
|
||||
c.ptr);
|
||||
}
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: test_oid_set_member.c,v 1.7 2006/10/07 22:15:50 lha Exp $");
|
||||
|
||||
OM_uint32 _gsskrb5_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;
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: unwrap.c,v 1.38 2006/10/18 15:59:28 lha Exp $");
|
||||
|
||||
static OM_uint32
|
||||
unwrap_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx 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 = _gsskrb5_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;
|
||||
_gsskrb5_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 gsskrb5_ctx 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 = _gsskrb5_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(_gsskrb5_context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
ret = krb5_decrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL,
|
||||
p, input_message_buffer->length - len, &tmp);
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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(_gsskrb5_context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
p, 8, &seq_data,
|
||||
&ivec);
|
||||
}
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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;
|
||||
_gsskrb5_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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_verify_checksum (_gsskrb5_context, crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
p + 20,
|
||||
input_message_buffer->length - len + 8,
|
||||
&csum);
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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 _gsskrb5_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;
|
||||
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
|
||||
|
||||
output_message_buffer->value = NULL;
|
||||
output_message_buffer->length = 0;
|
||||
|
||||
if (qop_state != NULL)
|
||||
*qop_state = GSS_C_QOP_DEFAULT;
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_DES :
|
||||
ret = unwrap_des (minor_status, ctx,
|
||||
input_message_buffer, output_message_buffer,
|
||||
conf_state, qop_state, key);
|
||||
break;
|
||||
case KEYTYPE_DES3 :
|
||||
ret = unwrap_des3 (minor_status, ctx,
|
||||
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, ctx,
|
||||
input_message_buffer, output_message_buffer,
|
||||
conf_state, qop_state, key);
|
||||
break;
|
||||
default :
|
||||
ret = _gssapi_unwrap_cfx (minor_status, ctx,
|
||||
input_message_buffer, output_message_buffer,
|
||||
conf_state, qop_state, key);
|
||||
break;
|
||||
}
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: verify_mic.c,v 1.36 2006/10/18 15:59:30 lha Exp $");
|
||||
|
||||
static OM_uint32
|
||||
verify_mic_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx 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 = _gsskrb5_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;
|
||||
_gsskrb5_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 gsskrb5_ctx 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 = _gsskrb5_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(_gsskrb5_context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret){
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
p, 8, &seq_data, ivec);
|
||||
if (ret) {
|
||||
if (docompat++) {
|
||||
_gsskrb5_set_error_string ();
|
||||
krb5_crypto_destroy (_gsskrb5_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 (_gsskrb5_context, crypto);
|
||||
return GSS_S_BAD_MIC;
|
||||
} else
|
||||
goto retry;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
seq = seq_data.data;
|
||||
_gsskrb5_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 (_gsskrb5_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 (_gsskrb5_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 (_gsskrb5_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 (_gsskrb5_context, crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
tmp, message_buffer->length + 8,
|
||||
&csum);
|
||||
free (tmp);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
krb5_crypto_destroy (_gsskrb5_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 (_gsskrb5_context, crypto);
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_verify_mic_internal
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx 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;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(context_handle, &key);
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
*minor_status = 0;
|
||||
krb5_enctype_to_keytype (_gsskrb5_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 (_gsskrb5_context, key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_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 = _gsskrb5_verify_mic_internal(minor_status,
|
||||
(gsskrb5_ctx)context_handle,
|
||||
message_buffer, token_buffer,
|
||||
qop_state, "\x01\x01");
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
/*
|
||||
* 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 "krb5/gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id: wrap.c,v 1.37 2006/10/18 15:59:33 lha Exp $");
|
||||
|
||||
/*
|
||||
* Return initiator subkey, or if that doesn't exists, the subkey.
|
||||
*/
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
*key = NULL;
|
||||
|
||||
if (ctx->more_flags & LOCAL) {
|
||||
ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
key);
|
||||
} else {
|
||||
ret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
key);
|
||||
}
|
||||
if (*key == NULL)
|
||||
ret = krb5_auth_con_getkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
key);
|
||||
if (*key == NULL) {
|
||||
_gsskrb5_set_status("No initiator subkey available");
|
||||
return GSS_KRB5_S_KG_NO_SUBKEY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
*key = NULL;
|
||||
|
||||
if (ctx->more_flags & LOCAL) {
|
||||
ret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
key);
|
||||
} else {
|
||||
ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
key);
|
||||
}
|
||||
if (*key == NULL) {
|
||||
_gsskrb5_set_status("No acceptor subkey available");
|
||||
return GSS_KRB5_S_KG_NO_SUBKEY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5i_get_token_key(const gsskrb5_ctx ctx, krb5_keyblock **key)
|
||||
{
|
||||
_gsskrb5i_get_acceptor_subkey(ctx, key);
|
||||
if(*key == NULL) {
|
||||
/*
|
||||
* Only use the initiator subkey or ticket session key if an
|
||||
* acceptor subkey was not required.
|
||||
*/
|
||||
if ((ctx->more_flags & ACCEPTOR_SUBKEY) == 0)
|
||||
_gsskrb5i_get_initiator_subkey(ctx, key);
|
||||
}
|
||||
if (*key == NULL) {
|
||||
_gsskrb5_set_status("No token key available");
|
||||
return GSS_KRB5_S_KG_NO_SUBKEY;
|
||||
}
|
||||
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;
|
||||
|
||||
_gsskrb5_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
|
||||
_gsskrb5_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;
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_DES :
|
||||
ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
|
||||
break;
|
||||
case KEYTYPE_ARCFOUR:
|
||||
case KEYTYPE_ARCFOUR_56:
|
||||
ret = _gssapi_wrap_size_arcfour(minor_status, ctx,
|
||||
conf_req_flag, qop_req,
|
||||
req_output_size, max_input_size, key);
|
||||
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, ctx,
|
||||
conf_req_flag, qop_req,
|
||||
req_output_size, max_input_size, key);
|
||||
break;
|
||||
}
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
*minor_status = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OM_uint32
|
||||
wrap_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
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;
|
||||
_gsskrb5_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 = _gsskrb5_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(&ctx->ctx_id_mutex);
|
||||
krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
|
||||
ctx->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,
|
||||
(ctx->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 (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->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 gsskrb5_ctx ctx,
|
||||
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;
|
||||
_gsskrb5_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 = _gsskrb5_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(_gsskrb5_context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
0,
|
||||
p + 20,
|
||||
datalen + 8,
|
||||
&cksum);
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (_gsskrb5_context,
|
||||
ctx->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,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
|
||||
ret = krb5_crypto_init(_gsskrb5_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 (_gsskrb5_context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
seq, 8, &encdata,
|
||||
&ivec);
|
||||
}
|
||||
krb5_crypto_destroy (_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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 (_gsskrb5_context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
/* encrypt the data */
|
||||
p += 28;
|
||||
|
||||
if(conf_req_flag) {
|
||||
krb5_data tmp;
|
||||
|
||||
ret = krb5_crypto_init(_gsskrb5_context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL,
|
||||
p, datalen, &tmp);
|
||||
krb5_crypto_destroy(_gsskrb5_context, crypto);
|
||||
if (ret) {
|
||||
_gsskrb5_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 _gsskrb5_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;
|
||||
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
ret = _gsskrb5i_get_token_key(ctx, &key);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
if (ret) {
|
||||
_gsskrb5_set_error_string ();
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype);
|
||||
|
||||
switch (keytype) {
|
||||
case KEYTYPE_DES :
|
||||
ret = wrap_des (minor_status, ctx, conf_req_flag,
|
||||
qop_req, input_message_buffer, conf_state,
|
||||
output_message_buffer, key);
|
||||
break;
|
||||
case KEYTYPE_DES3 :
|
||||
ret = wrap_des3 (minor_status, ctx, 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, ctx, conf_req_flag,
|
||||
qop_req, input_message_buffer, conf_state,
|
||||
output_message_buffer, key);
|
||||
break;
|
||||
default :
|
||||
ret = _gssapi_wrap_cfx (minor_status, ctx, conf_req_flag,
|
||||
qop_req, input_message_buffer, conf_state,
|
||||
output_message_buffer, key);
|
||||
break;
|
||||
}
|
||||
krb5_free_keyblock (_gsskrb5_context, key);
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user