aboutsummaryrefslogtreecommitdiffstats
path: root/lib/gssapi/krb5
diff options
context:
space:
mode:
authorHiroki Sato <hrs@FreeBSD.org>2018-04-04 04:21:19 +0000
committerHiroki Sato <hrs@FreeBSD.org>2018-04-04 04:21:19 +0000
commitd684f11da759490a8d98d7b790796106285f4084 (patch)
tree27b7356df710fdf1440fe2c23154b8121e99f2ab /lib/gssapi/krb5
parentf52d4664e3f68828c06f85bfc1afa271e3e04713 (diff)
downloadsrc-vendor/heimdal.tar.gz
src-vendor/heimdal.zip
Notes
Notes: svn path=/vendor-crypto/heimdal/dist/; revision=331978 svn path=/vendor-crypto/heimdal/7.5.0/; revision=331979; tag=vendor/heimdal/7.5.0
Diffstat (limited to 'lib/gssapi/krb5')
-rw-r--r--lib/gssapi/krb5/8003.c2
-rw-r--r--lib/gssapi/krb5/accept_sec_context.c132
-rw-r--r--lib/gssapi/krb5/acquire_cred.c529
-rw-r--r--lib/gssapi/krb5/add_cred.c184
-rw-r--r--lib/gssapi/krb5/aeap.c98
-rw-r--r--lib/gssapi/krb5/arcfour.c650
-rw-r--r--lib/gssapi/krb5/authorize_localname.c2
-rw-r--r--lib/gssapi/krb5/canonicalize_name.c4
-rw-r--r--lib/gssapi/krb5/cfx.c6
-rw-r--r--lib/gssapi/krb5/compare_name.c4
-rw-r--r--lib/gssapi/krb5/context_time.c21
-rw-r--r--lib/gssapi/krb5/copy_ccache.c7
-rw-r--r--lib/gssapi/krb5/creds.c29
-rw-r--r--lib/gssapi/krb5/decapsulate.c3
-rw-r--r--lib/gssapi/krb5/display_name.c2
-rw-r--r--lib/gssapi/krb5/duplicate_name.c2
-rw-r--r--lib/gssapi/krb5/export_name.c2
-rw-r--r--lib/gssapi/krb5/export_sec_context.c12
-rw-r--r--lib/gssapi/krb5/external.c98
-rw-r--r--lib/gssapi/krb5/get_mic.c17
-rw-r--r--lib/gssapi/krb5/gsskrb5-private.h111
-rw-r--r--lib/gssapi/krb5/gsskrb5_locl.h7
-rw-r--r--lib/gssapi/krb5/import_name.c36
-rw-r--r--lib/gssapi/krb5/import_sec_context.c6
-rw-r--r--lib/gssapi/krb5/init_sec_context.c83
-rw-r--r--lib/gssapi/krb5/inquire_context.c4
-rw-r--r--lib/gssapi/krb5/inquire_cred.c257
-rw-r--r--lib/gssapi/krb5/inquire_cred_by_mech.c6
-rw-r--r--lib/gssapi/krb5/inquire_cred_by_oid.c2
-rw-r--r--lib/gssapi/krb5/inquire_mechs_for_name.c2
-rw-r--r--lib/gssapi/krb5/inquire_sec_context_by_oid.c7
-rw-r--r--lib/gssapi/krb5/pname_to_uid.c41
-rw-r--r--lib/gssapi/krb5/prf.c4
-rw-r--r--lib/gssapi/krb5/process_context_token.c2
-rw-r--r--lib/gssapi/krb5/set_sec_context_option.c18
-rw-r--r--lib/gssapi/krb5/store_cred.c83
-rw-r--r--lib/gssapi/krb5/test_acquire_cred.c162
-rw-r--r--lib/gssapi/krb5/test_cfx.c2
-rw-r--r--lib/gssapi/krb5/test_cred.c217
-rw-r--r--lib/gssapi/krb5/test_kcred.c152
-rw-r--r--lib/gssapi/krb5/test_oid.c51
-rw-r--r--lib/gssapi/krb5/unwrap.c17
-rw-r--r--lib/gssapi/krb5/verify_mic.c32
-rw-r--r--lib/gssapi/krb5/wrap.c34
44 files changed, 2382 insertions, 758 deletions
diff --git a/lib/gssapi/krb5/8003.c b/lib/gssapi/krb5/8003.c
index d4555c51042b..5af477fe99fc 100644
--- a/lib/gssapi/krb5/8003.c
+++ b/lib/gssapi/krb5/8003.c
@@ -157,7 +157,7 @@ _gsskrb5_create_8003_checksum (
*p++ = (fwd_data->length >> 8) & 0xFF; /* Dlgth */
memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);
- p += fwd_data->length;
+ /* p += fwd_data->length; */ /* commented out to quiet warning */
}
return GSS_S_COMPLETE;
diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c
index 5a00e124c2cf..d4680e9e8fb6 100644
--- a/lib/gssapi/krb5/accept_sec_context.c
+++ b/lib/gssapi/krb5/accept_sec_context.c
@@ -104,7 +104,6 @@ _gsskrb5_register_acceptor_identity(OM_uint32 *min_stat, const char *identity)
void
_gsskrb5i_is_cfx(krb5_context context, gsskrb5_ctx ctx, int acceptor)
{
- krb5_error_code ret;
krb5_keyblock *key;
if (acceptor) {
@@ -144,7 +143,8 @@ _gsskrb5i_is_cfx(krb5_context context, gsskrb5_ctx ctx, int acceptor)
}
if (ctx->crypto)
krb5_crypto_destroy(context, ctx->crypto);
- ret = krb5_crypto_init(context, key, 0, &ctx->crypto);
+ /* XXX We really shouldn't ignore this; will come back to this */
+ (void) krb5_crypto_init(context, key, 0, &ctx->crypto);
}
@@ -164,12 +164,13 @@ gsskrb5_accept_delegated_token
/* XXX Create a new delegated_cred_handle? */
if (delegated_cred_handle == NULL) {
- kret = krb5_cc_default (context, &ccache);
- } else {
- *delegated_cred_handle = NULL;
- kret = krb5_cc_new_unique (context, krb5_cc_type_memory,
- NULL, &ccache);
+ ret = GSS_S_COMPLETE;
+ goto out;
}
+
+ *delegated_cred_handle = NULL;
+ kret = krb5_cc_new_unique (context, krb5_cc_type_memory,
+ NULL, &ccache);
if (kret) {
ctx->flags &= ~GSS_C_DELEG_FLAG;
goto out;
@@ -270,7 +271,7 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status,
ctx,
context,
delegated_cred_handle);
- if (ret)
+ if (ret != GSS_S_COMPLETE)
return ret;
} else {
/* Well, looks like it wasn't there after all */
@@ -347,7 +348,7 @@ static OM_uint32
gsskrb5_acceptor_start(OM_uint32 * minor_status,
gsskrb5_ctx ctx,
krb5_context context,
- const gss_cred_id_t acceptor_cred_handle,
+ gss_const_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,
@@ -363,6 +364,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
krb5_flags ap_options;
krb5_keytab keytab = NULL;
int is_cfx = 0;
+ int close_kt = 0;
const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle;
/*
@@ -384,8 +386,20 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
* We need to get our keytab
*/
if (acceptor_cred == NULL) {
- if (_gsskrb5_keytab != NULL)
- keytab = _gsskrb5_keytab;
+ HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
+ if (_gsskrb5_keytab != NULL) {
+ char *name = NULL;
+ kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name);
+ if (kret == 0) {
+ kret = krb5_kt_resolve(context, name, &keytab);
+ krb5_xfree(name);
+ }
+ if (kret == 0)
+ close_kt = 1;
+ else
+ keytab = NULL;
+ }
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
} else if (acceptor_cred->keytab != NULL) {
keytab = acceptor_cred->keytab;
}
@@ -408,6 +422,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if (kret) {
if (in)
krb5_rd_req_in_ctx_free(context, in);
+ if (close_kt)
+ krb5_kt_close(context, keytab);
*minor_status = kret;
return GSS_S_FAILURE;
}
@@ -418,6 +434,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
server,
in, &out);
krb5_rd_req_in_ctx_free(context, in);
+ if (close_kt)
+ krb5_kt_close(context, keytab);
if (kret == KRB5KRB_AP_ERR_SKEW || kret == KRB5KRB_AP_ERR_TKT_NYV) {
/*
* No reply in non-MUTUAL mode, but we don't know that its
@@ -443,7 +461,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if (kret == 0)
kret = krb5_rd_req_out_get_keyblock(context, out,
&ctx->service_keyblock);
- ctx->lifetime = ctx->ticket->ticket.endtime;
+ ctx->endtime = ctx->ticket->ticket.endtime;
krb5_rd_req_out_ctx_free(context, out);
if (kret) {
@@ -464,6 +482,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if (kret) {
ret = GSS_S_FAILURE;
*minor_status = kret;
+ return ret;
}
kret = krb5_copy_principal(context,
@@ -510,62 +529,61 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
return ret;
}
- if (authenticator->cksum == NULL) {
- krb5_free_authenticator(context, &authenticator);
- *minor_status = 0;
- return GSS_S_BAD_BINDINGS;
- }
-
- if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
+ if (authenticator->cksum != NULL
+ && 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(context, &authenticator);
if (ret) {
+ krb5_free_authenticator(context, &authenticator);
return ret;
}
} else {
- krb5_crypto crypto;
-
- kret = krb5_crypto_init(context,
- ctx->auth_context->keyblock,
- 0, &crypto);
- if(kret) {
- krb5_free_authenticator(context, &authenticator);
-
- ret = GSS_S_FAILURE;
- *minor_status = kret;
- return ret;
+ if (authenticator->cksum != NULL) {
+ krb5_crypto crypto;
+
+ kret = krb5_crypto_init(context,
+ ctx->auth_context->keyblock,
+ 0, &crypto);
+ if (kret) {
+ krb5_free_authenticator(context, &authenticator);
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+
+ /*
+ * Windows accepts Samba3's use of a kerberos, rather than
+ * GSSAPI checksum here
+ */
+
+ kret = krb5_verify_checksum(context,
+ crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
+ authenticator->cksum);
+ krb5_crypto_destroy(context, crypto);
+
+ if (kret) {
+ krb5_free_authenticator(context, &authenticator);
+ ret = GSS_S_BAD_SIG;
+ *minor_status = kret;
+ return ret;
+ }
}
/*
- * Windows accepts Samba3's use of a kerberos, rather than
- * GSSAPI checksum here
+ * If there is no checksum or a kerberos checksum (which Windows
+ * and Samba accept), we use the ap_options to guess the mutual
+ * flag.
*/
- kret = krb5_verify_checksum(context,
- crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
- authenticator->cksum);
- krb5_free_authenticator(context, &authenticator);
- krb5_crypto_destroy(context, crypto);
-
- if(kret) {
- ret = GSS_S_BAD_SIG;
- *minor_status = kret;
- return ret;
- }
-
- /*
- * Samba style get some flags (but not DCE-STYLE), use
- * ap_options to guess the mutual flag.
- */
- ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
ctx->flags |= GSS_C_MUTUAL_FLAG;
- }
+ }
+ krb5_free_authenticator(context, &authenticator);
}
if(ctx->flags & GSS_C_MUTUAL_FLAG) {
@@ -593,8 +611,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
rkey);
if (kret == 0)
use_subkey = 1;
- krb5_free_keyblock(context, rkey);
}
+ krb5_free_keyblock(context, rkey);
}
if (use_subkey) {
ctx->more_flags |= ACCEPTOR_SUBKEY;
@@ -630,7 +648,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
/* Remember the flags */
- ctx->lifetime = ctx->ticket->ticket.endtime;
+ ctx->endtime = ctx->ticket->ticket.endtime;
ctx->more_flags |= OPEN;
if (mech_type)
@@ -639,7 +657,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if (time_rec) {
ret = _gsskrb5_lifetime_left(minor_status,
context,
- ctx->lifetime,
+ ctx->endtime,
time_rec);
if (ret) {
return ret;
@@ -675,7 +693,7 @@ static OM_uint32
acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
gsskrb5_ctx ctx,
krb5_context context,
- const gss_cred_id_t acceptor_cred_handle,
+ gss_const_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,
@@ -757,7 +775,7 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
ret = _gsskrb5_lifetime_left(minor_status,
context,
- ctx->lifetime,
+ ctx->endtime,
&lifetime_rec);
if (ret) {
return ret;
@@ -838,7 +856,7 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_accept_sec_context(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
- const gss_cred_id_t acceptor_cred_handle,
+ gss_const_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,
diff --git a/lib/gssapi/krb5/acquire_cred.c b/lib/gssapi/krb5/acquire_cred.c
index 0f1f5f81cffc..9c880b334fd6 100644
--- a/lib/gssapi/krb5/acquire_cred.c
+++ b/lib/gssapi/krb5/acquire_cred.c
@@ -40,37 +40,16 @@ __gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
krb5_principal principal,
OM_uint32 *lifetime)
{
- krb5_creds in_cred, out_cred;
- krb5_const_realm realm;
krb5_error_code kret;
+ time_t left;
- memset(&in_cred, 0, sizeof(in_cred));
- in_cred.client = principal;
-
- realm = krb5_principal_get_realm(context, principal);
- if (realm == NULL) {
- _gsskrb5_clear_status ();
- *minor_status = KRB5_PRINC_NOMATCH; /* XXX */
- return GSS_S_FAILURE;
- }
-
- kret = krb5_make_principal(context, &in_cred.server,
- realm, KRB5_TGS_NAME, realm, NULL);
- if (kret) {
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
-
- kret = krb5_cc_retrieve_cred(context, id, 0, &in_cred, &out_cred);
- krb5_free_principal(context, in_cred.server);
+ kret = krb5_cc_get_lifetime(context, id, &left);
if (kret) {
- *minor_status = 0;
- *lifetime = 0;
- return GSS_S_COMPLETE;
+ *minor_status = kret;
+ return GSS_S_FAILURE;
}
- *lifetime = out_cred.times.endtime;
- krb5_free_cred_contents(context, &out_cred);
+ *lifetime = left;
return GSS_S_COMPLETE;
}
@@ -101,146 +80,282 @@ get_keytab(krb5_context context, krb5_keytab *keytab)
return (kret);
}
-static OM_uint32 acquire_initiator_cred
- (OM_uint32 * minor_status,
- krb5_context context,
- gss_const_OID credential_type,
- const void *credential_data,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- gss_const_OID desired_mech,
- gss_cred_usage_t cred_usage,
- gsskrb5_cred handle
- )
+/*
+ * This function produces a cred with a MEMORY ccache containing a TGT
+ * acquired with a password.
+ */
+static OM_uint32
+acquire_cred_with_password(OM_uint32 *minor_status,
+ krb5_context context,
+ const char *password,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gsskrb5_cred handle)
{
- OM_uint32 ret;
+ OM_uint32 ret = GSS_S_FAILURE;
krb5_creds cred;
- krb5_principal def_princ;
krb5_get_init_creds_opt *opt;
- krb5_ccache ccache;
- krb5_keytab keytab;
+ krb5_ccache ccache = NULL;
krb5_error_code kret;
+ time_t now;
+ OM_uint32 left;
+
+ if (cred_usage == GSS_C_ACCEPT) {
+ /*
+ * TODO: Here we should eventually support user2user (when we get
+ * support for that via an extension to the mechanism
+ * allowing for more than two security context tokens),
+ * and/or new unique MEMORY keytabs (we have MEMORY keytab
+ * support, but we don't have a keytab equivalent of
+ * krb5_cc_new_unique()). Either way, for now we can't
+ * support this.
+ */
+ *minor_status = ENOTSUP; /* XXX Better error? */
+ return GSS_S_FAILURE;
+ }
+
+ memset(&cred, 0, sizeof(cred));
+
+ if (handle->principal == NULL) {
+ kret = krb5_get_default_principal(context, &handle->principal);
+ if (kret)
+ goto end;
+ }
+ kret = krb5_get_init_creds_opt_alloc(context, &opt);
+ if (kret)
+ goto end;
+
+ /*
+ * Get the current time before the AS exchange so we don't
+ * accidentally end up returning a value that puts advertised
+ * expiration past the real expiration.
+ *
+ * We need to do this because krb5_cc_get_lifetime() returns a
+ * relative time that we need to add to the current time. We ought
+ * to have a version of krb5_cc_get_lifetime() that returns absolute
+ * time...
+ */
+ krb5_timeofday(context, &now);
+
+ kret = krb5_get_init_creds_password(context, &cred, handle->principal,
+ password, NULL, NULL, 0, NULL, opt);
+ krb5_get_init_creds_opt_free(context, opt);
+ if (kret)
+ goto end;
+
+ kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
+ if (kret)
+ goto end;
+
+ kret = krb5_cc_initialize(context, ccache, cred.client);
+ if (kret)
+ goto end;
- keytab = NULL;
+ kret = krb5_cc_store_cred(context, ccache, &cred);
+ if (kret)
+ goto end;
+
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+
+ ret = __gsskrb5_ccache_lifetime(minor_status, context, ccache,
+ handle->principal, &left);
+ if (ret != GSS_S_COMPLETE)
+ goto end;
+ handle->endtime = now + left;
+ handle->ccache = ccache;
ccache = NULL;
- def_princ = NULL;
- ret = GSS_S_FAILURE;
+ ret = GSS_S_COMPLETE;
+ kret = 0;
+
+end:
+ if (ccache != NULL)
+ krb5_cc_destroy(context, ccache);
+ if (cred.client != NULL)
+ krb5_free_cred_contents(context, &cred);
+ if (ret != GSS_S_COMPLETE && kret != 0)
+ *minor_status = kret;
+ return (ret);
+}
+
+/*
+ * Acquires an initiator credential from a ccache or using a keytab.
+ */
+static OM_uint32
+acquire_initiator_cred(OM_uint32 *minor_status,
+ krb5_context context,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gsskrb5_cred handle)
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ krb5_creds cred;
+ krb5_get_init_creds_opt *opt;
+ krb5_principal def_princ = NULL;
+ krb5_ccache def_ccache = NULL;
+ krb5_ccache ccache = NULL; /* we may store into this ccache */
+ krb5_keytab keytab = NULL;
+ krb5_error_code kret = 0;
+ OM_uint32 left;
+ time_t lifetime = 0;
+ time_t now;
+
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 all
- * errors while searching.
+ * Get current time early so we can set handle->endtime to a value that
+ * cannot accidentally be past the real endtime. We need a variant of
+ * krb5_cc_get_lifetime() that returns absolute endtime.
*/
+ krb5_timeofday(context, &now);
- if (credential_type != GSS_C_NO_OID &&
- !gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
- kret = KRB5_NOCREDS_SUPPLIED; /* XXX */
- goto end;
- }
+ /*
+ * First look for a ccache that has the desired_name (which may be
+ * the default credential name).
+ *
+ * If we don't have an unexpired credential, acquire one with a
+ * keytab.
+ *
+ * If we acquire one with a keytab, save it in the ccache we found
+ * with the expired credential, if any.
+ *
+ * If we don't have any such ccache, then use a MEMORY ccache.
+ */
- if (handle->principal) {
- kret = krb5_cc_cache_match (context,
- handle->principal,
- &ccache);
+ if (handle->principal != NULL) {
+ /*
+ * Not default credential case. See if we can find a ccache in
+ * the cccol for the desired_name.
+ */
+ kret = krb5_cc_cache_match(context,
+ handle->principal,
+ &ccache);
if (kret == 0) {
- ret = GSS_S_COMPLETE;
- goto found;
+ kret = krb5_cc_get_lifetime(context, ccache, &lifetime);
+ if (kret == 0) {
+ if (lifetime > 0)
+ goto found;
+ else
+ goto try_keytab;
+ }
}
+ /*
+ * Fall through. We shouldn't find this in the default ccache
+ * either, but we'll give it a try, then we'll try using a keytab.
+ */
}
- if (ccache == NULL) {
- kret = krb5_cc_default(context, &ccache);
- if (kret)
- goto end;
- }
- kret = krb5_cc_get_principal(context, ccache, &def_princ);
- if (kret != 0) {
- /* we'll try to use a keytab below */
- krb5_cc_close(context, ccache);
- def_princ = NULL;
- kret = 0;
- } else if (handle->principal == NULL) {
- kret = krb5_copy_principal(context, def_princ, &handle->principal);
- if (kret)
- goto end;
- } else if (handle->principal != NULL &&
- krb5_principal_compare(context, handle->principal,
- def_princ) == FALSE) {
- krb5_free_principal(context, def_princ);
- def_princ = NULL;
- krb5_cc_close(context, ccache);
- ccache = NULL;
+ /*
+ * Either desired_name was GSS_C_NO_NAME (default cred) or
+ * krb5_cc_cache_match() failed (or found expired).
+ */
+ kret = krb5_cc_default(context, &def_ccache);
+ if (kret != 0)
+ goto try_keytab;
+ kret = krb5_cc_get_lifetime(context, def_ccache, &lifetime);
+ if (kret != 0)
+ lifetime = 0;
+ kret = krb5_cc_get_principal(context, def_ccache, &def_princ);
+ if (kret != 0)
+ goto try_keytab;
+ /*
+ * Have a default ccache; see if it matches desired_name.
+ */
+ if (handle->principal == NULL ||
+ krb5_principal_compare(context, handle->principal,
+ def_princ) == TRUE) {
+ /*
+ * It matches.
+ *
+ * If we end up trying a keytab then we can write the result to
+ * the default ccache.
+ */
+ if (handle->principal == NULL) {
+ kret = krb5_copy_principal(context, def_princ, &handle->principal);
+ if (kret)
+ goto end;
+ }
+ if (ccache != NULL)
+ krb5_cc_close(context, ccache);
+ ccache = def_ccache;
+ def_ccache = NULL;
+ if (lifetime > 0)
+ goto found;
+ /* else we fall through and try using a keytab */
}
- 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(context, &handle->principal);
- if (kret)
- goto end;
- }
- kret = krb5_get_init_creds_opt_alloc(context, &opt);
- if (kret)
- goto end;
- if (credential_type != GSS_C_NO_OID &&
- gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
- gss_buffer_t password = (gss_buffer_t)credential_data;
-
- /* XXX are we requiring password to be NUL terminated? */
-
- kret = krb5_get_init_creds_password(context, &cred,
- handle->principal,
- password->value,
- NULL, NULL, 0, NULL, opt);
- } else {
- kret = get_keytab(context, &keytab);
- if (kret) {
- krb5_get_init_creds_opt_free(context, opt);
- goto end;
- }
- kret = krb5_get_init_creds_keytab(context, &cred,
- handle->principal, keytab,
- 0, NULL, opt);
- }
- krb5_get_init_creds_opt_free(context, opt);
- if (kret)
- goto end;
- kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
- NULL, &ccache);
- if (kret)
- goto end;
- kret = krb5_cc_initialize(context, ccache, cred.client);
- if (kret) {
- krb5_cc_destroy(context, ccache);
- goto end;
- }
- kret = krb5_cc_store_cred(context, ccache, &cred);
- if (kret) {
- krb5_cc_destroy(context, ccache);
- goto end;
- }
- handle->lifetime = cred.times.endtime;
- handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
- } else {
- ret = __gsskrb5_ccache_lifetime(minor_status,
- context,
- ccache,
- handle->principal,
- &handle->lifetime);
- if (ret != GSS_S_COMPLETE) {
- krb5_cc_close(context, ccache);
- goto end;
- }
- kret = 0;
+try_keytab:
+ if (handle->principal == NULL) {
+ /* We need to know what client principal to use */
+ kret = krb5_get_default_principal(context, &handle->principal);
+ if (kret)
+ goto end;
}
- found:
+ kret = get_keytab(context, &keytab);
+ if (kret)
+ goto end;
+
+ kret = krb5_get_init_creds_opt_alloc(context, &opt);
+ if (kret)
+ goto end;
+ krb5_timeofday(context, &now);
+ kret = krb5_get_init_creds_keytab(context, &cred, handle->principal,
+ keytab, 0, NULL, opt);
+ krb5_get_init_creds_opt_free(context, opt);
+ if (kret)
+ goto end;
+
+ /*
+ * We got a credential with a keytab. Save it if we can.
+ */
+ if (ccache == NULL) {
+ /*
+ * There's no ccache we can overwrite with the credentials we acquired
+ * with a keytab. We'll use a MEMORY ccache then.
+ *
+ * Note that an application that falls into this repeatedly will do an
+ * AS exchange every time it acquires a credential handle. Hopefully
+ * this doesn't happen much. A workaround is to kinit -k once so that
+ * we always re-initialize the matched/default ccache here. I.e., once
+ * there's a FILE/DIR ccache, we'll keep it frash automatically if we
+ * have a keytab, but if there's no FILE/DIR ccache, then we'll
+ * get a fresh credential *every* time we're asked.
+ */
+ kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
+ if (kret)
+ goto end;
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ } /* else we'll re-initialize whichever ccache we matched above */
+
+ kret = krb5_cc_initialize(context, ccache, cred.client);
+ if (kret)
+ goto end;
+ kret = krb5_cc_store_cred(context, ccache, &cred);
+ if (kret)
+ goto end;
+
+found:
+ assert(handle->principal != NULL);
+ ret = __gsskrb5_ccache_lifetime(minor_status, context, ccache,
+ handle->principal, &left);
+ if (ret != GSS_S_COMPLETE)
+ goto end;
+ handle->endtime = now + left;
handle->ccache = ccache;
+ ccache = NULL;
ret = GSS_S_COMPLETE;
+ kret = 0;
end:
+ if (ccache != NULL) {
+ if ((handle->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE) != 0)
+ krb5_cc_destroy(context, ccache);
+ else
+ krb5_cc_close(context, ccache);
+ }
+ if (def_ccache != NULL)
+ krb5_cc_close(context, def_ccache);
if (cred.client != NULL)
krb5_free_cred_contents(context, &cred);
if (def_princ != NULL)
@@ -252,28 +367,19 @@ end:
return (ret);
}
-static OM_uint32 acquire_acceptor_cred
- (OM_uint32 * minor_status,
- krb5_context context,
- gss_const_OID credential_type,
- const void *credential_data,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- gss_const_OID desired_mech,
- gss_cred_usage_t cred_usage,
- gsskrb5_cred handle
- )
+static OM_uint32
+acquire_acceptor_cred(OM_uint32 * minor_status,
+ krb5_context context,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gsskrb5_cred handle)
{
OM_uint32 ret;
krb5_error_code kret;
ret = GSS_S_FAILURE;
- if (credential_type != GSS_C_NO_OID) {
- kret = EINVAL;
- goto end;
- }
-
kret = get_keytab(context, &handle->keytab);
if (kret)
goto end;
@@ -318,7 +424,7 @@ end:
OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred
(OM_uint32 * minor_status,
- const gss_name_t desired_name,
+ gss_const_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
@@ -366,7 +472,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred
OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
(OM_uint32 * minor_status,
- const gss_name_t desired_name,
+ gss_const_name_t desired_name,
gss_const_OID credential_type,
const void *credential_data,
OM_uint32 time_req,
@@ -381,25 +487,26 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
cred_usage &= GSS_C_OPTION_MASK;
- if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
+ 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(&context);
- *output_cred_handle = NULL;
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
handle = calloc(1, sizeof(*handle));
if (handle == NULL) {
*minor_status = ENOMEM;
- return (GSS_S_FAILURE);
+ return GSS_S_FAILURE;
}
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
if (desired_name != GSS_C_NO_NAME) {
- ret = _gsskrb5_canon_name(minor_status, context, 1, NULL,
+ ret = _gsskrb5_canon_name(minor_status, context,
desired_name, &handle->principal);
if (ret) {
HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
@@ -407,29 +514,75 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
return ret;
}
}
- if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
- ret = acquire_initiator_cred(minor_status, context,
- credential_type, credential_data,
- desired_name, time_req,
- desired_mech, cred_usage, handle);
- if (ret != GSS_S_COMPLETE) {
- HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
- krb5_free_principal(context, handle->principal);
- free(handle);
- return (ret);
- }
- }
- if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
- ret = acquire_acceptor_cred(minor_status, context,
- credential_type, credential_data,
- desired_name, time_req,
- desired_mech, cred_usage, handle);
- if (ret != GSS_S_COMPLETE) {
- HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
- krb5_free_principal(context, handle->principal);
- free(handle);
- return (ret);
- }
+
+ if (credential_type != GSS_C_NO_OID &&
+ gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
+ /* Acquire a cred with a password */
+ gss_const_buffer_t pwbuf = credential_data;
+ char *pw;
+
+ if (pwbuf == NULL) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ *minor_status = KRB5_NOCREDS_SUPPLIED; /* see below */
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ }
+
+ /* NUL-terminate the password, if it wasn't already */
+ pw = strndup(pwbuf->value, pwbuf->length);
+ if (pw == NULL) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ *minor_status = krb5_enomem(context);
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ }
+ ret = acquire_cred_with_password(minor_status, context, pw, time_req,
+ desired_mech, cred_usage, handle);
+ free(pw);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ } else if (credential_type != GSS_C_NO_OID) {
+ /*
+ * _gss_acquire_cred_ext() called with something other than a password.
+ *
+ * Not supported.
+ *
+ * _gss_acquire_cred_ext() is not a supported public interface, so
+ * we don't have to try too hard as to minor status codes here.
+ */
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ *minor_status = ENOTSUP;
+ return GSS_S_FAILURE;
+ } else {
+ /*
+ * Acquire a credential from the background credential store (ccache,
+ * keytab).
+ */
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
+ ret = acquire_initiator_cred(minor_status, context, time_req,
+ desired_mech, cred_usage, handle);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ }
+ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
+ ret = acquire_acceptor_cred(minor_status, context, time_req,
+ desired_mech, cred_usage, handle);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ }
}
ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
if (ret == GSS_S_COMPLETE)
diff --git a/lib/gssapi/krb5/add_cred.c b/lib/gssapi/krb5/add_cred.c
index 00cf55f62d65..42f6b48181b4 100644
--- a/lib/gssapi/krb5/add_cred.c
+++ b/lib/gssapi/krb5/add_cred.c
@@ -35,8 +35,8 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
OM_uint32 *minor_status,
- const gss_cred_id_t input_cred_handle,
- const gss_name_t desired_name,
+ gss_const_cred_id_t input_cred_handle,
+ gss_const_name_t desired_name,
const gss_OID desired_mech,
gss_cred_usage_t cred_usage,
OM_uint32 initiator_time_req,
@@ -47,7 +47,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
OM_uint32 *acceptor_time_rec)
{
krb5_context context;
- OM_uint32 ret, lifetime;
+ OM_uint32 major, lifetime;
gsskrb5_cred cred, handle;
krb5_const_principal dname;
@@ -55,99 +55,120 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
cred = (gsskrb5_cred)input_cred_handle;
dname = (krb5_const_principal)desired_name;
+ if (cred == NULL && output_cred_handle == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ }
+
GSSAPI_KRB5_INIT (&context);
- if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {
+ if (desired_mech != GSS_C_NO_OID &&
+ 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;
- }
+ if (cred == NULL) {
+ /*
+ * Acquire a credential; output_cred_handle can't be NULL, see above.
+ */
+ heim_assert(output_cred_handle != NULL,
+ "internal error in _gsskrb5_add_cred()");
+
+ major = _gsskrb5_acquire_cred(minor_status, desired_name,
+ min(initiator_time_req,
+ acceptor_time_req),
+ GSS_C_NO_OID_SET,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs, &lifetime);
+ if (major != GSS_S_COMPLETE)
+ goto failure;
+
+ } else {
+ /*
+ * Check that we're done or copy input to output if
+ * output_cred_handle != NULL.
+ */
- /* check if requested output usage is compatible with output usage */
- if (output_cred_handle != NULL) {
HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+
+ /* Check if requested output usage is compatible with output usage */
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(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;
+ /* Check that we have the same name */
+ if (dname != NULL &&
+ krb5_principal_compare(context, dname,
+ cred->principal) != FALSE) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ if (output_cred_handle == NULL) {
+ /*
+ * This case is basically useless as we implement a single
+ * mechanism here, so we can't add elements to the
+ * input_cred_handle.
+ */
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ /*
+ * Copy input to output -- this works as if we were a
+ * GSS_Duplicate_cred() for one mechanism element.
+ */
handle = calloc(1, sizeof(*handle));
if (handle == NULL) {
- HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ if (cred != NULL)
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
handle->usage = cred_usage;
- handle->lifetime = cred->lifetime;
+ handle->endtime = cred->endtime;
handle->principal = NULL;
handle->keytab = NULL;
handle->ccache = NULL;
handle->mechanisms = NULL;
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
- ret = GSS_S_FAILURE;
+ major = GSS_S_FAILURE;
- kret = krb5_copy_principal(context, cred->principal,
- &handle->principal);
- if (kret) {
+ *minor_status = krb5_copy_principal(context, cred->principal,
+ &handle->principal);
+ if (*minor_status) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
free(handle);
- *minor_status = kret;
return GSS_S_FAILURE;
}
if (cred->keytab) {
char *name = NULL;
- ret = GSS_S_FAILURE;
-
- kret = krb5_kt_get_full_name(context, cred->keytab, &name);
- if (kret) {
- *minor_status = kret;
+ *minor_status = krb5_kt_get_full_name(context, cred->keytab,
+ &name);
+ if (*minor_status)
goto failure;
- }
- kret = krb5_kt_resolve(context, name,
- &handle->keytab);
+ *minor_status = krb5_kt_resolve(context, name, &handle->keytab);
krb5_xfree(name);
- if (kret){
- *minor_status = kret;
+ if (*minor_status)
goto failure;
- }
}
if (cred->ccache) {
const char *type, *name;
char *type_name = NULL;
- ret = GSS_S_FAILURE;
-
type = krb5_cc_get_type(context, cred->ccache);
if (type == NULL){
*minor_status = ENOMEM;
@@ -155,19 +176,15 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
}
if (strcmp(type, "MEMORY") == 0) {
- ret = krb5_cc_new_unique(context, type,
- NULL, &handle->ccache);
- if (ret) {
- *minor_status = ret;
+ *minor_status = krb5_cc_new_unique(context, type,
+ NULL, &handle->ccache);
+ if (*minor_status)
goto failure;
- }
- ret = krb5_cc_copy_cache(context, cred->ccache,
- handle->ccache);
- if (ret) {
- *minor_status = ret;
+ *minor_status = krb5_cc_copy_cache(context, cred->ccache,
+ handle->ccache);
+ if (*minor_status)
goto failure;
- }
} else {
name = krb5_cc_get_name(context, cred->ccache);
@@ -176,52 +193,47 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
goto failure;
}
- kret = asprintf(&type_name, "%s:%s", type, name);
- if (kret < 0 || type_name == NULL) {
+ if (asprintf(&type_name, "%s:%s", type, name) == -1 ||
+ type_name == NULL) {
*minor_status = ENOMEM;
goto failure;
}
- kret = krb5_cc_resolve(context, type_name,
- &handle->ccache);
+ *minor_status = krb5_cc_resolve(context, type_name,
+ &handle->ccache);
free(type_name);
- if (kret) {
- *minor_status = kret;
+ if (*minor_status)
goto failure;
- }
}
}
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
- if (ret)
+ major = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (major != GSS_S_COMPLETE)
goto failure;
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
- if (ret)
+ major = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (major != GSS_S_COMPLETE)
goto failure;
- }
- HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ 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;
+ major = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)cred,
+ NULL, &lifetime, NULL, actual_mechs);
+ if (major != GSS_S_COMPLETE)
+ goto failure;
+
+ *output_cred_handle = (gss_cred_id_t)handle;
+ }
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:
+ return major;
+failure:
if (handle) {
if (handle->principal)
krb5_free_principal(context, handle->principal);
@@ -233,7 +245,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
gss_release_oid_set(NULL, &handle->mechanisms);
free(handle);
}
- if (output_cred_handle)
+ if (cred && output_cred_handle)
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
- return ret;
+ return major;
}
diff --git a/lib/gssapi/krb5/aeap.c b/lib/gssapi/krb5/aeap.c
index 47913e4aec03..fe95ecf0b9cc 100644
--- a/lib/gssapi/krb5/aeap.c
+++ b/lib/gssapi/krb5/aeap.c
@@ -44,17 +44,43 @@ _gk_wrap_iov(OM_uint32 * minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
- const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
- krb5_context context;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
+ OM_uint32 ret;
+ krb5_keyblock *key;
+ krb5_keytype keytype;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
+ conf_req_flag, conf_state,
+ iov, iov_count);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype(context, key->keytype, &keytype);
- GSSAPI_KRB5_INIT (&context);
+ switch (keytype) {
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_wrap_iov_arcfour(minor_status, ctx, context,
+ conf_req_flag, conf_state,
+ iov, iov_count, key);
+ break;
- if (ctx->more_flags & IS_CFX)
- return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
- conf_req_flag, conf_state,
- iov, iov_count);
+ default:
+ ret = GSS_S_FAILURE;
+ break;
+ }
- return GSS_S_FAILURE;
+ krb5_free_keyblock(context, key);
+ return ret;
}
OM_uint32 GSSAPI_CALLCONV
@@ -67,6 +93,9 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
{
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+ krb5_keyblock *key;
GSSAPI_KRB5_INIT (&context);
@@ -74,7 +103,30 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
conf_state, qop_state, iov, iov_count);
- return GSS_S_FAILURE;
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype(context, key->keytype, &keytype);
+
+ switch (keytype) {
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_unwrap_iov_arcfour(minor_status, ctx, context,
+ conf_state, qop_state,
+ iov, iov_count, key);
+ break;
+
+ default:
+ ret = GSS_S_FAILURE;
+ break;
+ }
+
+ krb5_free_keyblock(context, key);
+ return ret;
}
OM_uint32 GSSAPI_CALLCONV
@@ -88,6 +140,9 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
{
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+ krb5_keyblock *key;
GSSAPI_KRB5_INIT (&context);
@@ -96,5 +151,28 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
conf_req_flag, qop_req, conf_state,
iov, iov_count);
- return GSS_S_FAILURE;
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype(context, key->keytype, &keytype);
+
+ switch (keytype) {
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_wrap_iov_length_arcfour(minor_status, ctx, context,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+ break;
+
+ default:
+ ret = GSS_S_FAILURE;
+ break;
+ }
+
+ krb5_free_keyblock(context, key);
+ return ret;
}
diff --git a/lib/gssapi/krb5/arcfour.c b/lib/gssapi/krb5/arcfour.c
index 15b1b343409a..0aa2da0808bf 100644
--- a/lib/gssapi/krb5/arcfour.c
+++ b/lib/gssapi/krb5/arcfour.c
@@ -69,7 +69,7 @@
static krb5_error_code
arcfour_mic_key(krb5_context context, krb5_keyblock *key,
- void *cksum_data, size_t cksum_size,
+ const void *cksum_data, size_t cksum_size,
void *key6_data, size_t key6_size)
{
krb5_error_code ret;
@@ -86,7 +86,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
cksum_k5.checksum.data = k5_data;
cksum_k5.checksum.length = sizeof(k5_data);
- if (key->keytype == ENCTYPE_ARCFOUR_HMAC_MD5_56) {
+ if (key->keytype == KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56) {
char L40[14] = "fortybits";
memcpy(L40 + 10, T, sizeof(T));
@@ -100,7 +100,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
if (ret)
return ret;
- key5.keytype = ENCTYPE_ARCFOUR_HMAC_MD5;
+ key5.keytype = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5;
key5.keyvalue = cksum_k5.checksum;
cksum_k6.checksum.data = key6_data;
@@ -112,30 +112,73 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
static krb5_error_code
-arcfour_mic_cksum(krb5_context context,
- 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)
+arcfour_mic_cksum_iov(krb5_context context,
+ 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 gss_iov_buffer_desc *iov,
+ int iov_count,
+ const gss_iov_buffer_desc *padding)
{
Checksum CKSUM;
u_char *ptr;
size_t len;
+ size_t ofs = 0;
+ int i;
krb5_crypto crypto;
krb5_error_code ret;
assert(sgn_cksum_sz == 8);
- len = l1 + l2 + l3;
+ len = l1 + l2;
+
+ for (i=0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ continue;
+ }
+
+ len += iov[i].buffer.length;
+ }
+
+ if (padding) {
+ len += padding->buffer.length;
+ }
ptr = malloc(len);
if (ptr == NULL)
return ENOMEM;
- memcpy(ptr, v1, l1);
- memcpy(ptr + l1, v2, l2);
- memcpy(ptr + l1 + l2, v3, l3);
+ memcpy(ptr + ofs, v1, l1);
+ ofs += l1;
+ memcpy(ptr + ofs, v2, l2);
+ ofs += l2;
+
+ for (i=0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ continue;
+ }
+
+ memcpy(ptr + ofs,
+ iov[i].buffer.value,
+ iov[i].buffer.length);
+ ofs += iov[i].buffer.length;
+ }
+
+ if (padding) {
+ memcpy(ptr + ofs,
+ padding->buffer.value,
+ padding->buffer.length);
+ ofs += padding->buffer.length;
+ }
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret) {
@@ -149,6 +192,7 @@ arcfour_mic_cksum(krb5_context context,
0,
ptr, len,
&CKSUM);
+ memset(ptr, 0, len);
free(ptr);
if (ret == 0) {
memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);
@@ -159,6 +203,26 @@ arcfour_mic_cksum(krb5_context context,
return ret;
}
+static krb5_error_code
+arcfour_mic_cksum(krb5_context context,
+ 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)
+{
+ gss_iov_buffer_desc iov;
+
+ iov.type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
+ iov.buffer.value = rk_UNCONST(v3);
+ iov.buffer.length = l3;
+
+ return arcfour_mic_cksum_iov(context, key, usage,
+ sgn_cksum, sgn_cksum_sz,
+ v1, l1, v2, l2,
+ &iov, 1, NULL);
+}
+
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
@@ -760,3 +824,563 @@ _gssapi_wrap_size_arcfour(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
+
+OM_uint32
+_gssapi_wrap_iov_length_arcfour(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 major_status;
+ size_t data_len = 0;
+ int i;
+ gss_iov_buffer_desc *header = NULL;
+ gss_iov_buffer_desc *padding = NULL;
+ gss_iov_buffer_desc *trailer = NULL;
+
+ *minor_status = 0;
+
+ for (i = 0; i < iov_count; i++) {
+ switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_EMPTY:
+ break;
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data_len += iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_HEADER:
+ if (header != NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ header = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_TRAILER:
+ if (trailer != NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ trailer = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ if (padding != NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ padding = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ if (IS_DCE_STYLE(ctx)) {
+ size_t len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ size_t total_len;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ header->buffer.length = total_len;
+ } else {
+ size_t len;
+ size_t total_len;
+ if (padding) {
+ data_len += 1; /* padding */
+ }
+ len = data_len + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ header->buffer.length = total_len - data_len;
+ }
+
+ if (trailer) {
+ trailer->buffer.length = 0;
+ }
+
+ if (padding) {
+ padding->buffer.length = 1;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ krb5_keyblock *key)
+{
+ OM_uint32 major_status, junk;
+ gss_iov_buffer_desc *header, *padding, *trailer;
+ krb5_error_code kret;
+ int32_t seq_number;
+ u_char Klocaldata[16], k6_data[16], *p, *p0;
+ size_t make_len = 0;
+ size_t header_len = 0;
+ size_t data_len = 0;
+ krb5_keyblock Klocal;
+ int i;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ break;
+ default:
+ continue;
+ }
+
+ data_len += iov[i].buffer.length;
+ }
+
+ if (padding) {
+ data_len += 1;
+ }
+
+ if (IS_DCE_STYLE(ctx)) {
+ size_t unwrapped_len;
+ unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(unwrapped_len,
+ &make_len,
+ &header_len,
+ GSS_KRB5_MECHANISM);
+ } else {
+ size_t unwrapped_len;
+ unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + data_len;
+ _gssapi_encap_length(unwrapped_len,
+ &make_len,
+ &header_len,
+ GSS_KRB5_MECHANISM);
+ header_len -= data_len;
+ }
+
+ if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = _gk_allocate_buffer(minor_status, header,
+ header_len);
+ if (major_status != GSS_S_COMPLETE)
+ goto failure;
+ } else if (header->buffer.length < header_len) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else {
+ header->buffer.length = header_len;
+ }
+
+ if (padding) {
+ if (GSS_IOV_BUFFER_FLAGS(padding->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = _gk_allocate_buffer(minor_status, padding, 1);
+ if (major_status != GSS_S_COMPLETE)
+ goto failure;
+ } else if (padding->buffer.length < 1) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else {
+ padding->buffer.length = 1;
+ }
+ memset(padding->buffer.value, 1, 1);
+ }
+
+ if (trailer) {
+ trailer->buffer.length = 0;
+ trailer->buffer.value = NULL;
+ }
+
+ p0 = _gssapi_make_mech_header(header->buffer.value,
+ make_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(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);
+
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ memset(p0 + 8 + 4,
+ (ctx->more_flags & LOCAL) ? 0 : 0xff,
+ 4);
+
+ krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */
+
+ /* Sign Data */
+ kret = arcfour_mic_cksum_iov(context,
+ key, KRB5_KU_USAGE_SEAL,
+ p0 + 16, 8, /* SGN_CKSUM */
+ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
+ p0 + 24, 8, /* Confounder */
+ iov, iov_count, /* Data + SignOnly */
+ padding); /* padding */
+ if (kret) {
+ *minor_status = kret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ 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;
+ }
+ kret = arcfour_mic_key(context, &Klocal,
+ p0 + 8, 4, /* SND_SEQ */
+ k6_data, sizeof(k6_data));
+ memset(Klocaldata, 0, sizeof(Klocaldata));
+ if (kret) {
+ *minor_status = kret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (conf_req_flag) {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+
+ /* Confounder */
+ EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8);
+
+ /* Seal Data */
+ for (i=0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ break;
+ default:
+ continue;
+ }
+
+ EVP_Cipher(&rc4_key, iov[i].buffer.value,
+ iov[i].buffer.value, iov[i].buffer.length);
+ }
+
+ /* Padding */
+ if (padding) {
+ EVP_Cipher(&rc4_key, padding->buffer.value,
+ padding->buffer.value, padding->buffer.length);
+ }
+
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ }
+ memset(k6_data, 0, sizeof(k6_data));
+
+ kret = arcfour_mic_key(context, key,
+ p0 + 16, 8, /* SGN_CKSUM */
+ k6_data, sizeof(k6_data));
+ if (kret) {
+ *minor_status = kret;
+ major_status = GSS_S_FAILURE;
+ return major_status;
+ }
+
+ {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p0 + 8, p0 + 8, 8); /* SND_SEQ */
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
+ memset(k6_data, 0, sizeof(k6_data));
+ }
+
+ if (conf_state)
+ *conf_state = conf_req_flag;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+failure:
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+
+OM_uint32
+_gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int *pconf_state,
+ gss_qop_t *pqop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count,
+ krb5_keyblock *key)
+{
+ OM_uint32 major_status;
+ gss_iov_buffer_desc *header, *padding, *trailer;
+ krb5_keyblock Klocal;
+ uint8_t Klocaldata[16];
+ uint8_t k6_data[16], snd_seq[8], Confounder[8];
+ uint8_t cksum_data[8];
+ uint8_t *_p = NULL;
+ const uint8_t *p, *p0;
+ size_t verify_len = 0;
+ uint32_t seq_number;
+ size_t hlen = 0;
+ int conf_state;
+ int cmp;
+ size_t i;
+ krb5_error_code kret;
+ OM_uint32 ret;
+
+ if (pconf_state != NULL) {
+ *pconf_state = 0;
+ }
+ if (pqop_state != NULL) {
+ *pqop_state = 0;
+ }
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ /* Check if the packet is correct */
+ major_status = _gk_verify_buffers(minor_status,
+ ctx,
+ header,
+ padding,
+ trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ if (padding != NULL && padding->buffer.length != 1) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (IS_DCE_STYLE(context)) {
+ verify_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
+ GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
+ if (header->buffer.length > verify_len) {
+ return GSS_S_BAD_MECH;
+ }
+ } else {
+ verify_len = header->buffer.length;
+ }
+ _p = header->buffer.value;
+
+ ret = _gssapi_verify_mech_header(&_p,
+ verify_len,
+ GSS_KRB5_MECHANISM);
+ if (ret) {
+ return ret;
+ }
+ p0 = _p;
+
+ /* length of mech header */
+ hlen = (p0 - (uint8_t *)header->buffer.value);
+ hlen += GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+
+ if (hlen > header->buffer.length) {
+ return GSS_S_BAD_MECH;
+ }
+
+ 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_state = 1;
+ else if (memcmp (p, "\xff\xff", 2) == 0)
+ conf_state = 0;
+ else
+ return GSS_S_BAD_SIG;
+
+ p += 2;
+ if (memcmp (p, "\xff\xff", 2) != 0)
+ return GSS_S_BAD_MIC;
+ p = NULL;
+
+ kret = arcfour_mic_key(context,
+ key,
+ p0 + 16, /* SGN_CKSUM */
+ 8, /* SGN_CKSUM_LEN */
+ k6_data,
+ sizeof(k6_data));
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, snd_seq, p0 + 8, 8); /* SND_SEQ */
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
+ memset(k6_data, 0, sizeof(k6_data));
+ }
+
+ _gsskrb5_decode_be_om_uint32(snd_seq, &seq_number);
+
+ if (ctx->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;
+ }
+
+ if (ctx->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;
+ }
+
+ /* keyblock */
+ 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;
+ }
+
+ kret = arcfour_mic_key(context,
+ &Klocal,
+ snd_seq,
+ 4,
+ k6_data, sizeof(k6_data));
+ memset(Klocaldata, 0, sizeof(Klocaldata));
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (conf_state == 1) {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+
+ /* Confounder */
+ EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
+
+ /* Data */
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ break;
+ default:
+ continue;
+ }
+
+ EVP_Cipher(&rc4_key, iov[i].buffer.value,
+ iov[i].buffer.value, iov[i].buffer.length);
+ }
+
+ /* Padding */
+ if (padding) {
+ EVP_Cipher(&rc4_key, padding->buffer.value,
+ padding->buffer.value, padding->buffer.length);
+ }
+
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ } else {
+ /* Confounder */
+ memcpy(Confounder, p0 + 24, 8);
+ }
+ memset(k6_data, 0, sizeof(k6_data));
+
+ /* Prepare the buffer for signing */
+ kret = arcfour_mic_cksum_iov(context,
+ key, KRB5_KU_USAGE_SEAL,
+ cksum_data, sizeof(cksum_data),
+ p0, 8,
+ Confounder, sizeof(Confounder),
+ iov, iov_count,
+ padding);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
+ if (cmp != 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_MIC;
+ }
+
+ if (padding) {
+ size_t plen;
+
+ ret = _gssapi_verify_pad(&padding->buffer, 1, &plen);
+ if (ret) {
+ *minor_status = 0;
+ return ret;
+ }
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (pconf_state) {
+ *pconf_state = conf_state;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/lib/gssapi/krb5/authorize_localname.c b/lib/gssapi/krb5/authorize_localname.c
index 4bab062ac4ce..5621c1f9cfe0 100644
--- a/lib/gssapi/krb5/authorize_localname.c
+++ b/lib/gssapi/krb5/authorize_localname.c
@@ -34,7 +34,7 @@
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_authorize_localname(OM_uint32 *minor_status,
- const gss_name_t input_name,
+ gss_const_name_t input_name,
gss_const_buffer_t user_name,
gss_const_OID user_name_type)
{
diff --git a/lib/gssapi/krb5/canonicalize_name.c b/lib/gssapi/krb5/canonicalize_name.c
index 7fc921bac095..62de42358f62 100644
--- a/lib/gssapi/krb5/canonicalize_name.c
+++ b/lib/gssapi/krb5/canonicalize_name.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_canonicalize_name (
OM_uint32 * minor_status,
- const gss_name_t input_name,
+ gss_const_name_t input_name,
const gss_OID mech_type,
gss_name_t * output_name
)
@@ -48,7 +48,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_canonicalize_name (
GSSAPI_KRB5_INIT (&context);
- ret = _gsskrb5_canon_name(minor_status, context, 1, NULL, input_name, &name);
+ ret = _gsskrb5_canon_name(minor_status, context, input_name, &name);
if (ret)
return ret;
diff --git a/lib/gssapi/krb5/cfx.c b/lib/gssapi/krb5/cfx.c
index 3c1536b60ea5..29fecca861ce 100644
--- a/lib/gssapi/krb5/cfx.c
+++ b/lib/gssapi/krb5/cfx.c
@@ -391,7 +391,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
if (IS_DCE_STYLE(ctx))
rrc -= ec;
gsshsize += gsstsize;
- gsstsize = 0;
} else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
major_status = _gk_allocate_buffer(minor_status, trailer, gsstsize);
if (major_status)
@@ -683,6 +682,7 @@ unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int
if (iov[i].buffer.length <= skip) {
skip -= iov[i].buffer.length;
} else {
+ /* copy back to original buffer */
memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip);
q += iov[i].buffer.length - skip;
skip = 0;
@@ -697,13 +697,14 @@ unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
{
- memcpy(q, iov[i].buffer.value, min(iov[i].buffer.length, skip));
+ memcpy(iov[i].buffer.value, q, min(iov[i].buffer.length, skip));
if (iov[i].buffer.length > skip)
break;
skip -= iov[i].buffer.length;
q += iov[i].buffer.length;
}
}
+ free(p);
return GSS_S_COMPLETE;
}
@@ -930,7 +931,6 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
}
gsshsize += gsstsize;
- gsstsize = 0;
} else if (trailer->buffer.length != gsstsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
diff --git a/lib/gssapi/krb5/compare_name.c b/lib/gssapi/krb5/compare_name.c
index 7409d45fcb89..4a37e877df5d 100644
--- a/lib/gssapi/krb5/compare_name.c
+++ b/lib/gssapi/krb5/compare_name.c
@@ -35,8 +35,8 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_compare_name
(OM_uint32 * minor_status,
- const gss_name_t name1,
- const gss_name_t name2,
+ gss_const_name_t name1,
+ gss_const_name_t name2,
int * name_equal
)
{
diff --git a/lib/gssapi/krb5/context_time.c b/lib/gssapi/krb5/context_time.c
index cb1550011cd7..58249cb5a311 100644
--- a/lib/gssapi/krb5/context_time.c
+++ b/lib/gssapi/krb5/context_time.c
@@ -36,27 +36,28 @@
OM_uint32
_gsskrb5_lifetime_left(OM_uint32 *minor_status,
krb5_context context,
- OM_uint32 lifetime,
+ OM_uint32 endtime,
OM_uint32 *lifetime_rec)
{
- krb5_timestamp timeret;
+ krb5_timestamp now;
krb5_error_code kret;
- if (lifetime == 0) {
+ if (endtime == 0) {
*lifetime_rec = GSS_C_INDEFINITE;
return GSS_S_COMPLETE;
}
- kret = krb5_timeofday(context, &timeret);
+ kret = krb5_timeofday(context, &now);
if (kret) {
+ *lifetime_rec = 0;
*minor_status = kret;
return GSS_S_FAILURE;
}
- if (lifetime < timeret)
+ if (endtime < now)
*lifetime_rec = 0;
else
- *lifetime_rec = lifetime - timeret;
+ *lifetime_rec = endtime - now;
return GSS_S_COMPLETE;
}
@@ -64,23 +65,23 @@ _gsskrb5_lifetime_left(OM_uint32 *minor_status,
OM_uint32 GSSAPI_CALLCONV _gsskrb5_context_time
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
OM_uint32 * time_rec
)
{
krb5_context context;
- OM_uint32 lifetime;
+ OM_uint32 endtime;
OM_uint32 major_status;
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
GSSAPI_KRB5_INIT (&context);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
- lifetime = ctx->lifetime;
+ endtime = ctx->endtime;
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
major_status = _gsskrb5_lifetime_left(minor_status, context,
- lifetime, time_rec);
+ endtime, time_rec);
if (major_status != GSS_S_COMPLETE)
return major_status;
diff --git a/lib/gssapi/krb5/copy_ccache.c b/lib/gssapi/krb5/copy_ccache.c
index e332d29c84aa..14296bccd7e2 100644
--- a/lib/gssapi/krb5/copy_ccache.c
+++ b/lib/gssapi/krb5/copy_ccache.c
@@ -89,6 +89,8 @@ _gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
handle->usage = 0;
if (id) {
+ time_t now;
+ OM_uint32 left;
char *str;
handle->usage |= GSS_C_INITIATE;
@@ -116,17 +118,18 @@ _gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
}
}
+ krb5_timeofday(context, &now);
ret = __gsskrb5_ccache_lifetime(minor_status,
context,
id,
handle->principal,
- &handle->lifetime);
+ &left);
if (ret != GSS_S_COMPLETE) {
krb5_free_principal(context, handle->principal);
free(handle);
return ret;
}
-
+ handle->endtime = now + left;
kret = krb5_cc_get_full_name(context, id, &str);
if (kret)
diff --git a/lib/gssapi/krb5/creds.c b/lib/gssapi/krb5/creds.c
index fa45d19b9812..1cc3ac848ad0 100644
--- a/lib/gssapi/krb5/creds.c
+++ b/lib/gssapi/krb5/creds.c
@@ -62,6 +62,9 @@ _gsskrb5_export_cred(OM_uint32 *minor_status,
type = krb5_cc_get_type(context, handle->ccache);
if (strcmp(type, "MEMORY") == 0) {
krb5_creds *creds;
+ krb5_data config_start_realm;
+ char *start_realm;
+
ret = krb5_store_uint32(sp, 0);
if (ret) {
krb5_storage_free(sp);
@@ -69,9 +72,25 @@ _gsskrb5_export_cred(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
- ret = _krb5_get_krbtgt(context, handle->ccache,
- handle->principal->realm,
- &creds);
+ ret = krb5_cc_get_config(context, handle->ccache, NULL, "start_realm",
+ &config_start_realm);
+ if (ret == 0) {
+ start_realm = strndup(config_start_realm.data,
+ config_start_realm.length);
+ krb5_data_free(&config_start_realm);
+ } else {
+ start_realm = strdup(krb5_principal_get_realm(context,
+ handle->principal));
+ }
+ if (start_realm == NULL) {
+ *minor_status = krb5_enomem(context);
+ krb5_storage_free(sp);
+ return GSS_S_FAILURE;
+ }
+
+ ret = _krb5_get_krbtgt(context, handle->ccache, start_realm, &creds);
+ free(start_realm);
+ start_realm = NULL;
if (ret) {
krb5_storage_free(sp);
*minor_status = ret;
@@ -210,6 +229,10 @@ _gsskrb5_import_cred(OM_uint32 * minor_status,
ret = krb5_cc_store_cred(context, id, &creds);
krb5_free_cred_contents(context, &creds);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
diff --git a/lib/gssapi/krb5/decapsulate.c b/lib/gssapi/krb5/decapsulate.c
index 640c064d0bf1..86085f569501 100644
--- a/lib/gssapi/krb5/decapsulate.c
+++ b/lib/gssapi/krb5/decapsulate.c
@@ -190,6 +190,9 @@ _gssapi_verify_pad(gss_buffer_t wrapped_token,
size_t padlength;
int i;
+ if (wrapped_token->length < 1)
+ return GSS_S_BAD_MECH;
+
pad = (u_char *)wrapped_token->value + wrapped_token->length - 1;
padlength = *pad;
diff --git a/lib/gssapi/krb5/display_name.c b/lib/gssapi/krb5/display_name.c
index a296399cecad..67cb61e7cb81 100644
--- a/lib/gssapi/krb5/display_name.c
+++ b/lib/gssapi/krb5/display_name.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_name
(OM_uint32 * minor_status,
- const gss_name_t input_name,
+ gss_const_name_t input_name,
gss_buffer_t output_name_buffer,
gss_OID * output_name_type
)
diff --git a/lib/gssapi/krb5/duplicate_name.c b/lib/gssapi/krb5/duplicate_name.c
index 0bc57e8a03ed..43519d6a2d53 100644
--- a/lib/gssapi/krb5/duplicate_name.c
+++ b/lib/gssapi/krb5/duplicate_name.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_duplicate_name (
OM_uint32 * minor_status,
- const gss_name_t src_name,
+ gss_const_name_t src_name,
gss_name_t * dest_name
)
{
diff --git a/lib/gssapi/krb5/export_name.c b/lib/gssapi/krb5/export_name.c
index 32368d3ccefd..1686a6570af5 100644
--- a/lib/gssapi/krb5/export_name.c
+++ b/lib/gssapi/krb5/export_name.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_export_name
(OM_uint32 * minor_status,
- const gss_name_t input_name,
+ gss_const_name_t input_name,
gss_buffer_t exported_name
)
{
diff --git a/lib/gssapi/krb5/export_sec_context.c b/lib/gssapi/krb5/export_sec_context.c
index eeb2743b4322..b500f4230cd3 100644
--- a/lib/gssapi/krb5/export_sec_context.c
+++ b/lib/gssapi/krb5/export_sec_context.c
@@ -34,9 +34,9 @@
#include "gsskrb5_locl.h"
OM_uint32 GSSAPI_CALLCONV
-_gsskrb5_export_sec_context (
- OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
+_gsskrb5_export_sec_context(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
gss_buffer_t interprocess_token
)
{
@@ -204,7 +204,11 @@ _gsskrb5_export_sec_context (
*minor_status = kret;
goto failure;
}
- kret = krb5_store_int32 (sp, ctx->lifetime);
+ /*
+ * XXX We should put a 64-bit int here, but we don't have a
+ * krb5_store_int64() yet.
+ */
+ kret = krb5_store_int32 (sp, ctx->endtime);
if (kret) {
*minor_status = kret;
goto failure;
diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c
index 26ede2487d30..deae016bc96b 100644
--- a/lib/gssapi/krb5/external.c
+++ b/lib/gssapi/krb5/external.c
@@ -202,67 +202,131 @@ static gss_mo_desc krb5_mo[] = {
},
{
GSS_C_MA_MECH_CONCRETE,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_ITOK_FRAMED,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_AUTH_INIT,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_AUTH_TARG,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_AUTH_INIT_ANON,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_DELEG_CRED,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_INTEG_PROT,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_CONF_PROT,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_MIC,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_WRAP,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_PROT_READY,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_REPLAY_DET,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_OOS_DET,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_CBINDINGS,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_PFS,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
},
{
GSS_C_MA_CTX_TRANS,
- GSS_MO_MA
+ GSS_MO_MA,
+ NULL,
+ NULL,
+ NULL,
+ NULL
}
};
@@ -324,7 +388,7 @@ static gssapi_mech_interface_desc krb5_mech = {
NULL,
krb5_mo,
sizeof(krb5_mo) / sizeof(krb5_mo[0]),
- _gsskrb5_pname_to_uid,
+ _gsskrb5_localname,
_gsskrb5_authorize_localname,
NULL,
NULL,
diff --git a/lib/gssapi/krb5/get_mic.c b/lib/gssapi/krb5/get_mic.c
index 0109ca7c6e76..643385d9e892 100644
--- a/lib/gssapi/krb5/get_mic.c
+++ b/lib/gssapi/krb5/get_mic.c
@@ -275,7 +275,7 @@ mic_des3
OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token
@@ -285,7 +285,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_keyblock *key;
OM_uint32 ret;
- krb5_keytype keytype;
GSSAPI_KRB5_INIT (&context);
@@ -300,10 +299,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (context, key->keytype, &keytype);
- switch (keytype) {
- case KEYTYPE_DES :
+ switch (key->keytype) {
+ case KRB5_ENCTYPE_DES_CBC_CRC :
+ case KRB5_ENCTYPE_DES_CBC_MD4 :
+ case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
ret = mic_des (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
@@ -311,12 +311,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
ret = GSS_S_FAILURE;
#endif
break;
- case KEYTYPE_DES3 :
+ case KRB5_ENCTYPE_DES3_CBC_MD5 :
+ case KRB5_ENCTYPE_DES3_CBC_SHA1 :
ret = mic_des3 (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
break;
- case KEYTYPE_ARCFOUR:
- case KEYTYPE_ARCFOUR_56:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
break;
diff --git a/lib/gssapi/krb5/gsskrb5-private.h b/lib/gssapi/krb5/gsskrb5-private.h
index 2a669d867f16..e05d4a6b6da6 100644
--- a/lib/gssapi/krb5/gsskrb5-private.h
+++ b/lib/gssapi/krb5/gsskrb5-private.h
@@ -179,6 +179,17 @@ _gssapi_unwrap_cfx_iov (
int /*iov_count*/);
OM_uint32
+_gssapi_unwrap_iov_arcfour (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int */*pconf_state*/,
+ gss_qop_t */*pqop_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
_gssapi_verify_mech_header (
u_char **/*str*/,
size_t /*total_len*/,
@@ -243,6 +254,28 @@ _gssapi_wrap_cfx_iov (
int /*iov_count*/);
OM_uint32
+_gssapi_wrap_iov_arcfour (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_iov_length_arcfour (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
_gssapi_wrap_iov_length_cfx (
OM_uint32 */*minor_status*/,
gsskrb5_ctx /*ctx*/,
@@ -278,7 +311,7 @@ OM_uint32 GSSAPI_CALLCONV
_gsskrb5_accept_sec_context (
OM_uint32 * /*minor_status*/,
gss_ctx_id_t * /*context_handle*/,
- const gss_cred_id_t /*acceptor_cred_handle*/,
+ gss_const_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*/,
@@ -291,7 +324,7 @@ _gsskrb5_accept_sec_context (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_acquire_cred (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*desired_name*/,
+ gss_const_name_t /*desired_name*/,
OM_uint32 /*time_req*/,
const gss_OID_set /*desired_mechs*/,
gss_cred_usage_t /*cred_usage*/,
@@ -302,7 +335,7 @@ _gsskrb5_acquire_cred (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_acquire_cred_ext (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*desired_name*/,
+ gss_const_name_t /*desired_name*/,
gss_const_OID /*credential_type*/,
const void */*credential_data*/,
OM_uint32 /*time_req*/,
@@ -313,8 +346,8 @@ _gsskrb5_acquire_cred_ext (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_add_cred (
OM_uint32 */*minor_status*/,
- const gss_cred_id_t /*input_cred_handle*/,
- const gss_name_t /*desired_name*/,
+ gss_const_cred_id_t /*input_cred_handle*/,
+ gss_const_name_t /*desired_name*/,
const gss_OID /*desired_mech*/,
gss_cred_usage_t /*cred_usage*/,
OM_uint32 /*initiator_time_req*/,
@@ -327,7 +360,7 @@ _gsskrb5_add_cred (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_authorize_localname (
OM_uint32 */*minor_status*/,
- const gss_name_t /*input_name*/,
+ gss_const_name_t /*input_name*/,
gss_const_buffer_t /*user_name*/,
gss_const_OID /*user_name_type*/);
@@ -335,15 +368,13 @@ OM_uint32
_gsskrb5_canon_name (
OM_uint32 */*minor_status*/,
krb5_context /*context*/,
- int /*use_dns*/,
- krb5_const_principal /*sourcename*/,
- gss_name_t /*targetname*/,
+ gss_const_name_t /*targetname*/,
krb5_principal */*out*/);
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_canonicalize_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
+ gss_const_name_t /*input_name*/,
const gss_OID /*mech_type*/,
gss_name_t * output_name );
@@ -353,14 +384,14 @@ _gsskrb5_clear_status (void);
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_compare_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*name1*/,
- const gss_name_t /*name2*/,
+ gss_const_name_t /*name1*/,
+ gss_const_name_t /*name2*/,
int * name_equal );
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_context_time (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
OM_uint32 * time_rec );
OM_uint32
@@ -406,7 +437,7 @@ _gsskrb5_delete_sec_context (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_display_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
+ gss_const_name_t /*input_name*/,
gss_buffer_t /*output_name_buffer*/,
gss_OID * output_name_type );
@@ -422,7 +453,7 @@ _gsskrb5_display_status (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_duplicate_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*src_name*/,
+ gss_const_name_t /*src_name*/,
gss_name_t * dest_name );
void
@@ -459,13 +490,13 @@ _gsskrb5_export_cred (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
+ gss_const_name_t /*input_name*/,
gss_buffer_t exported_name );
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_sec_context (
- OM_uint32 * /*minor_status*/,
- gss_ctx_id_t * /*context_handle*/,
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
gss_buffer_t interprocess_token );
ssize_t
@@ -477,7 +508,7 @@ _gsskrb5_get_mech (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_get_mic (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
gss_qop_t /*qop_req*/,
const gss_buffer_t /*message_buffer*/,
gss_buffer_t message_token );
@@ -518,9 +549,9 @@ _gsskrb5_init (krb5_context */*context*/);
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_init_sec_context (
OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
+ gss_const_cred_id_t /*cred_handle*/,
gss_ctx_id_t * /*context_handle*/,
- const gss_name_t /*target_name*/,
+ gss_const_name_t /*target_name*/,
const gss_OID /*mech_type*/,
OM_uint32 /*req_flags*/,
OM_uint32 /*time_req*/,
@@ -534,7 +565,7 @@ _gsskrb5_init_sec_context (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_context (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
gss_name_t * /*src_name*/,
gss_name_t * /*targ_name*/,
OM_uint32 * /*lifetime_rec*/,
@@ -546,7 +577,7 @@ _gsskrb5_inquire_context (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_cred (
OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
+ gss_const_cred_id_t /*cred_handle*/,
gss_name_t * /*output_name*/,
OM_uint32 * /*lifetime*/,
gss_cred_usage_t * /*cred_usage*/,
@@ -555,7 +586,7 @@ _gsskrb5_inquire_cred (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_cred_by_mech (
OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
+ gss_const_cred_id_t /*cred_handle*/,
const gss_OID /*mech_type*/,
gss_name_t * /*name*/,
OM_uint32 * /*initiator_lifetime*/,
@@ -565,14 +596,14 @@ _gsskrb5_inquire_cred_by_mech (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_cred_by_oid (
OM_uint32 * /*minor_status*/,
- const gss_cred_id_t /*cred_handle*/,
+ gss_const_cred_id_t /*cred_handle*/,
const gss_OID /*desired_object*/,
gss_buffer_set_t */*data_set*/);
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_mechs_for_name (
OM_uint32 * /*minor_status*/,
- const gss_name_t /*input_name*/,
+ gss_const_name_t /*input_name*/,
gss_OID_set * mech_types );
OM_uint32 GSSAPI_CALLCONV
@@ -584,7 +615,7 @@ _gsskrb5_inquire_names_for_mech (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_inquire_sec_context_by_oid (
OM_uint32 */*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
const gss_OID /*desired_object*/,
gss_buffer_set_t */*data_set*/);
@@ -606,9 +637,16 @@ OM_uint32
_gsskrb5_lifetime_left (
OM_uint32 */*minor_status*/,
krb5_context /*context*/,
- OM_uint32 /*lifetime*/,
+ OM_uint32 /*endtime*/,
OM_uint32 */*lifetime_rec*/);
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_localname (
+ OM_uint32 */*minor_status*/,
+ gss_const_name_t /*pname*/,
+ const gss_OID /*mech_type*/,
+ gss_buffer_t /*localname*/);
+
void *
_gsskrb5_make_header (
void */*ptr*/,
@@ -617,16 +655,9 @@ _gsskrb5_make_header (
const gss_OID /*mech*/);
OM_uint32 GSSAPI_CALLCONV
-_gsskrb5_pname_to_uid (
- OM_uint32 */*minor_status*/,
- const gss_name_t /*pname*/,
- const gss_OID /*mech_type*/,
- uid_t */*uidp*/);
-
-OM_uint32 GSSAPI_CALLCONV
_gsskrb5_process_context_token (
OM_uint32 */*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
const gss_buffer_t token_buffer );
OM_uint32 GSSAPI_CALLCONV
@@ -692,7 +723,7 @@ _gsskrb5_store_cred (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_unwrap (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
const gss_buffer_t /*input_message_buffer*/,
gss_buffer_t /*output_message_buffer*/,
int * /*conf_state*/,
@@ -716,7 +747,7 @@ _gsskrb5_verify_header (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_verify_mic (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
const gss_buffer_t /*message_buffer*/,
const gss_buffer_t /*token_buffer*/,
gss_qop_t * qop_state );
@@ -734,7 +765,7 @@ _gsskrb5_verify_mic_internal (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_wrap (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
gss_qop_t /*qop_req*/,
const gss_buffer_t /*input_message_buffer*/,
@@ -744,7 +775,7 @@ _gsskrb5_wrap (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_wrap_size_limit (
OM_uint32 * /*minor_status*/,
- const gss_ctx_id_t /*context_handle*/,
+ gss_const_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
gss_qop_t /*qop_req*/,
OM_uint32 /*req_output_size*/,
diff --git a/lib/gssapi/krb5/gsskrb5_locl.h b/lib/gssapi/krb5/gsskrb5_locl.h
index 6b9b03f34908..4119730576fc 100644
--- a/lib/gssapi/krb5/gsskrb5_locl.h
+++ b/lib/gssapi/krb5/gsskrb5_locl.h
@@ -81,7 +81,7 @@ typedef struct gsskrb5_ctx {
krb5_creds *kcred;
krb5_ccache ccache;
struct krb5_ticket *ticket;
- OM_uint32 lifetime;
+ time_t endtime;
HEIMDAL_MUTEX ctx_id_mutex;
struct gss_msg_order *order;
krb5_keyblock *service_keyblock;
@@ -95,7 +95,7 @@ typedef struct {
#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
#define GSS_CF_NO_CI_FLAGS 2
struct krb5_keytab_data *keytab;
- OM_uint32 lifetime;
+ time_t endtime;
gss_cred_usage_t usage;
gss_OID_set mechanisms;
struct krb5_ccache_data *ccache;
@@ -134,7 +134,4 @@ extern HEIMDAL_MUTEX gssapi_keytab_mutex;
#define SC_LOCAL_SUBKEY 0x08
#define SC_REMOTE_SUBKEY 0x10
-/* type to signal that that dns canon maybe should be done */
-#define MAGIC_HOSTBASED_NAME_TYPE 4711
-
#endif
diff --git a/lib/gssapi/krb5/import_name.c b/lib/gssapi/krb5/import_name.c
index 5fe512672f95..6a362640b6fe 100644
--- a/lib/gssapi/krb5/import_name.c
+++ b/lib/gssapi/krb5/import_name.c
@@ -83,26 +83,21 @@ import_krb5_name (OM_uint32 *minor_status,
OM_uint32
_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
- int use_dns, krb5_const_principal sourcename, gss_name_t targetname,
- krb5_principal *out)
+ gss_const_name_t targetname, krb5_principal *out)
{
- krb5_principal p = (krb5_principal)targetname;
+ krb5_const_principal p = (krb5_const_principal)targetname;
krb5_error_code ret;
char *hostname = NULL, *service;
+ int type;
+ const char *comp;
*minor_status = 0;
/* If its not a hostname */
- if (krb5_principal_get_type(context, p) != MAGIC_HOSTBASED_NAME_TYPE) {
- ret = krb5_copy_principal(context, p, out);
- } else if (!use_dns) {
- ret = krb5_copy_principal(context, p, out);
- if (ret)
- goto out;
- krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
- if (sourcename)
- ret = krb5_principal_set_realm(context, *out, sourcename->realm);
- } else {
+ type = krb5_principal_get_type(context, p);
+ comp = krb5_principal_get_comp_string(context, p, 0);
+ if (type == KRB5_NT_SRV_HST || type == KRB5_NT_SRV_HST_NEEDS_CANON ||
+ (type == KRB5_NT_UNKNOWN && comp != NULL && strcmp(comp, "host") == 0)) {
if (p->name.name_string.len == 0)
return GSS_S_BAD_NAME;
else if (p->name.name_string.len > 1)
@@ -115,9 +110,10 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
service,
KRB5_NT_SRV_HST,
out);
+ } else {
+ ret = krb5_copy_principal(context, p, out);
}
- out:
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
@@ -128,10 +124,10 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
static OM_uint32
-import_hostbased_name (OM_uint32 *minor_status,
- krb5_context context,
- const gss_buffer_t input_name_buffer,
- gss_name_t *output_name)
+import_hostbased_name(OM_uint32 *minor_status,
+ krb5_context context,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
{
krb5_principal princ = NULL;
krb5_error_code kerr;
@@ -153,7 +149,7 @@ import_hostbased_name (OM_uint32 *minor_status,
host = p + 1;
}
- kerr = krb5_make_principal(context, &princ, NULL, tmp, host, NULL);
+ kerr = krb5_make_principal(context, &princ, "", tmp, host, NULL);
free (tmp);
*minor_status = kerr;
if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
@@ -161,7 +157,7 @@ import_hostbased_name (OM_uint32 *minor_status,
else if (kerr)
return GSS_S_FAILURE;
- krb5_principal_set_type(context, princ, MAGIC_HOSTBASED_NAME_TYPE);
+ krb5_principal_set_type(context, princ, KRB5_NT_SRV_HST);
*output_name = (gss_name_t)princ;
return 0;
diff --git a/lib/gssapi/krb5/import_sec_context.c b/lib/gssapi/krb5/import_sec_context.c
index 3bab1802b3c9..e34e07115a5f 100644
--- a/lib/gssapi/krb5/import_sec_context.c
+++ b/lib/gssapi/krb5/import_sec_context.c
@@ -192,9 +192,13 @@ _gsskrb5_import_sec_context (
if (krb5_ret_int32 (sp, &tmp))
goto failure;
ctx->more_flags = tmp;
+ /*
+ * XXX endtime should be a 64-bit int, but we don't have
+ * krb5_ret_int64() yet.
+ */
if (krb5_ret_int32 (sp, &tmp))
goto failure;
- ctx->lifetime = tmp;
+ ctx->endtime = tmp;
ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
if (ret)
diff --git a/lib/gssapi/krb5/init_sec_context.c b/lib/gssapi/krb5/init_sec_context.c
index 5f8b01b72707..4ef5c9c7123a 100644
--- a/lib/gssapi/krb5/init_sec_context.c
+++ b/lib/gssapi/krb5/init_sec_context.c
@@ -128,7 +128,7 @@ _gsskrb5_create_ctx(
ctx->service_keyblock = NULL;
ctx->ticket = NULL;
krb5_data_zero(&ctx->fwd_data);
- ctx->lifetime = GSS_C_INDEFINITE;
+ ctx->endtime = 0;
ctx->order = NULL;
ctx->crypto = NULL;
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
@@ -137,6 +137,7 @@ _gsskrb5_create_ctx(
if (kret) {
*minor_status = kret;
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ free(ctx);
return GSS_S_FAILURE;
}
@@ -145,6 +146,7 @@ _gsskrb5_create_ctx(
*minor_status = kret;
krb5_auth_con_free(context, ctx->auth_context);
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ free(ctx);
return GSS_S_FAILURE;
}
@@ -156,7 +158,7 @@ _gsskrb5_create_ctx(
krb5_auth_con_free(context, ctx->deleg_auth_context);
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
-
+ free(ctx);
return GSS_S_BAD_BINDINGS;
}
@@ -168,7 +170,7 @@ _gsskrb5_create_ctx(
krb5_auth_con_free(context, ctx->deleg_auth_context);
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
-
+ free(ctx);
return GSS_S_BAD_BINDINGS;
}
@@ -204,8 +206,7 @@ gsskrb5_get_creds(
krb5_context context,
krb5_ccache ccache,
gsskrb5_ctx ctx,
- const gss_name_t target_name,
- int use_dns,
+ gss_const_name_t target_name,
OM_uint32 time_req,
OM_uint32 * time_rec)
{
@@ -223,8 +224,8 @@ gsskrb5_get_creds(
ctx->kcred = NULL;
}
- ret = _gsskrb5_canon_name(minor_status, context, use_dns,
- ctx->source, target_name, &ctx->target);
+ ret = _gsskrb5_canon_name(minor_status, context, target_name,
+ &ctx->target);
if (ret)
return ret;
@@ -253,10 +254,10 @@ gsskrb5_get_creds(
return GSS_S_FAILURE;
}
- ctx->lifetime = ctx->kcred->times.endtime;
+ ctx->endtime = ctx->kcred->times.endtime;
ret = _gsskrb5_lifetime_left(minor_status, context,
- ctx->lifetime, &lifetime_rec);
+ ctx->endtime, &lifetime_rec);
if (ret) return ret;
if (lifetime_rec == 0) {
@@ -344,8 +345,7 @@ do_delegation (krb5_context context,
fwd_flags.forwarded = 1;
fwd_flags.forwardable = 1;
- if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
- name->name.name_string.len < 2)
+ if (name->name.name_string.len < 2)
goto out;
kret = krb5_get_forwarded_creds(context,
@@ -378,7 +378,7 @@ init_auth
gsskrb5_cred cred,
gsskrb5_ctx ctx,
krb5_context context,
- gss_name_t name,
+ gss_const_name_t name,
const gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
@@ -391,12 +391,9 @@ init_auth
{
OM_uint32 ret = GSS_S_FAILURE;
krb5_error_code kret;
- krb5_data outbuf;
krb5_data fwd_data;
OM_uint32 lifetime_rec;
- int allow_dns = 1;
- krb5_data_zero(&outbuf);
krb5_data_zero(&fwd_data);
*minor_status = 0;
@@ -425,44 +422,17 @@ init_auth
/*
* This is hideous glue for (NFS) clients that wants to limit the
* available enctypes to what it can support (encryption in
- * kernel). If there is no enctypes selected for this credential,
- * reset it to the default set of enctypes.
+ * kernel).
*/
- {
- krb5_enctype *enctypes = NULL;
+ if (cred && cred->enctypes)
+ krb5_set_default_in_tkt_etypes(context, cred->enctypes);
- if (cred && cred->enctypes)
- enctypes = cred->enctypes;
- krb5_set_default_in_tkt_etypes(context, enctypes);
- }
-
- /* canon name if needed for client + target realm */
- kret = krb5_cc_get_config(context, ctx->ccache, NULL,
- "realm-config", &outbuf);
- if (kret == 0) {
- /* XXX 2 is no server canon */
- if (outbuf.length < 1 || ((((unsigned char *)outbuf.data)[0]) & 2))
- allow_dns = 0;
- krb5_data_free(&outbuf);
- }
-
- /*
- * First we try w/o dns, hope that the KDC have register alias
- * (and referrals if cross realm) for this principal. If that
- * fails and if we are allowed to using this realm try again with
- * DNS canonicalizion.
- */
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
- ctx, name, 0, time_req,
- time_rec);
- if (ret && allow_dns)
- ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
- ctx, name, 1, time_req,
- time_rec);
+ ctx, name, time_req, time_rec);
if (ret)
goto failure;
- ctx->lifetime = ctx->kcred->times.endtime;
+ ctx->endtime = ctx->kcred->times.endtime;
ret = _gss_DES3_get_mic_compat(minor_status, ctx, context);
if (ret)
@@ -470,7 +440,7 @@ init_auth
ret = _gsskrb5_lifetime_left(minor_status,
context,
- ctx->lifetime,
+ ctx->endtime,
&lifetime_rec);
if (ret)
goto failure;
@@ -817,14 +787,11 @@ repl_mutual
repl);
*minor_status = 0;
- if (time_rec) {
- ret = _gsskrb5_lifetime_left(minor_status,
- context,
- ctx->lifetime,
- time_rec);
- } else {
- ret = GSS_S_COMPLETE;
- }
+ if (time_rec)
+ _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->endtime,
+ time_rec);
if (ret_flags)
*ret_flags = ctx->flags;
@@ -865,9 +832,9 @@ repl_mutual
OM_uint32 GSSAPI_CALLCONV _gsskrb5_init_sec_context
(OM_uint32 * minor_status,
- const gss_cred_id_t cred_handle,
+ gss_const_cred_id_t cred_handle,
gss_ctx_id_t * context_handle,
- const gss_name_t target_name,
+ gss_const_name_t target_name,
const gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
diff --git a/lib/gssapi/krb5/inquire_context.c b/lib/gssapi/krb5/inquire_context.c
index ade8ec4b9cb6..e225c33ba2be 100644
--- a/lib/gssapi/krb5/inquire_context.c
+++ b/lib/gssapi/krb5/inquire_context.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
gss_name_t * src_name,
gss_name_t * targ_name,
OM_uint32 * lifetime_rec,
@@ -76,7 +76,7 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
if (lifetime_rec) {
ret = _gsskrb5_lifetime_left(minor_status,
context,
- ctx->lifetime,
+ ctx->endtime,
lifetime_rec);
if (ret)
goto failed;
diff --git a/lib/gssapi/krb5/inquire_cred.c b/lib/gssapi/krb5/inquire_cred.c
index f88199692cd7..1770fec76eab 100644
--- a/lib/gssapi/krb5/inquire_cred.c
+++ b/lib/gssapi/krb5/inquire_cred.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
(OM_uint32 * minor_status,
- const gss_cred_id_t cred_handle,
+ gss_const_cred_id_t cred_handle,
gss_name_t * output_name,
OM_uint32 * lifetime,
gss_cred_usage_t * cred_usage,
@@ -45,136 +45,179 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
krb5_context context;
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;
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
+ gss_OID_set amechs = GSS_C_NO_OID_SET;
+ gss_OID_set imechs = GSS_C_NO_OID_SET;
+ OM_uint32 junk;
+ OM_uint32 aminor;
OM_uint32 ret;
+ OM_uint32 aret;
+ OM_uint32 alife = GSS_C_INDEFINITE;
+ OM_uint32 ilife = GSS_C_INDEFINITE;
+
+ /*
+ * XXX This function is more complex than it has to be. It should call
+ * _gsskrb5_inquire_cred_by_mech() twice and merge the results in the
+ * cred_handle == GSS_C_NO_CREDENTIAL case, but since
+ * _gsskrb5_inquire_cred_by_mech() is implemented in terms of this
+ * function, first we must fix _gsskrb5_inquire_cred_by_mech().
+ */
*minor_status = 0;
if (output_name)
- *output_name = NULL;
+ *output_name = GSS_C_NO_NAME;
+ if (cred_usage)
+ *cred_usage = GSS_C_BOTH; /* There's no NONE */
if (mechanisms)
- *mechanisms = GSS_C_NO_OID_SET;
+ *mechanisms = GSS_C_NO_OID_SET;
GSSAPI_KRB5_INIT (&context);
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)
- icred = (gsskrb5_cred)aqcred_init;
-
- if (icred == NULL && acred == NULL) {
- *minor_status = 0;
- return GSS_S_NO_CRED;
- }
- } else
- acred = (gsskrb5_cred)cred_handle;
+ /*
+ * From here to the end of this if we should refactor into a separate
+ * function.
+ */
+ /* Get the info for the default ACCEPT credential */
+ aret = _gsskrb5_acquire_cred(&aminor,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_ACCEPT,
+ &aqcred_accept,
+ NULL,
+ NULL);
+ if (aret == GSS_S_COMPLETE) {
+ aret = _gsskrb5_inquire_cred(&aminor,
+ aqcred_accept,
+ output_name,
+ &alife,
+ NULL,
+ &amechs);
+ (void) _gsskrb5_release_cred(&junk, &aqcred_accept);
+ if (aret == GSS_S_COMPLETE) {
+ output_name = NULL; /* Can't merge names; output only one */
+ if (cred_usage)
+ *cred_usage = GSS_C_ACCEPT;
+ if (lifetime)
+ *lifetime = alife;
+ if (mechanisms) {
+ *mechanisms = amechs;
+ amechs = GSS_C_NO_OID_SET;
+ }
+ (void) gss_release_oid_set(&junk, &amechs);
+ } else if (aret != GSS_S_NO_CRED) {
+ *minor_status = aminor;
+ return aret;
+ } else {
+ alife = GSS_C_INDEFINITE;
+ }
+ }
+
+ /* Get the info for the default INITIATE credential */
+ 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) {
+ ret = _gsskrb5_inquire_cred(minor_status,
+ aqcred_init,
+ output_name,
+ &ilife,
+ NULL,
+ &imechs);
+ (void) _gsskrb5_release_cred(&junk, &aqcred_init);
+ if (ret == GSS_S_COMPLETE) {
+ /*
+ * Merge results for INITIATE with ACCEPT if we had ACCEPT and
+ * for those outputs that are desired.
+ */
+ if (cred_usage) {
+ *cred_usage = (*cred_usage == GSS_C_ACCEPT) ?
+ GSS_C_BOTH : GSS_C_INITIATE;
+ }
+ if (lifetime)
+ *lifetime = min(alife, ilife);
+ if (mechanisms) {
+ /*
+ * This is just one mechanism (IAKERB and such would live
+ * elsewhere). imechs will be equal to amechs, though not
+ * ==.
+ */
+ if (aret != GSS_S_COMPLETE) {
+ *mechanisms = imechs;
+ imechs = GSS_C_NO_OID_SET;
+ }
+ }
+ (void) gss_release_oid_set(&junk, &amechs);
+ } else if (ret != GSS_S_NO_CRED) {
+ *minor_status = aminor;
+ return aret;
+ }
+ }
+
+ if (aret != GSS_S_COMPLETE && ret != GSS_S_COMPLETE) {
+ *minor_status = aminor;
+ return aret;
+ }
+ *minor_status = 0; /* Even though 0 is not specified to be special */
+ return GSS_S_COMPLETE;
+ }
- if (acred)
- HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
- if (icred)
- HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
if (output_name != NULL) {
- if (icred && icred->principal != NULL) {
- gss_name_t name;
-
- if (acred && acred->principal)
- name = (gss_name_t)acred->principal;
- else
- name = (gss_name_t)icred->principal;
-
+ if (cred->principal != NULL) {
+ gss_name_t name = (gss_name_t)cred->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(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(context,
- &princ);
- if (*minor_status) {
- ret = GSS_S_FAILURE;
- goto out;
- }
- *output_name = (gss_name_t)princ;
- }
+ goto out;
+ } else if (cred->usage == GSS_C_ACCEPT) {
+ /*
+ * Keytab case, princ may not be set (yet, ever, whatever).
+ *
+ * We used to unconditionally output the krb5_sname_to_principal()
+ * of the host service for the hostname, but we didn't know if we
+ * had keytab entries for it, so it was incorrect. We can't be
+ * breaking anything in tree by outputting GSS_C_NO_NAME, but we
+ * might be breaking other callers.
+ */
+ *output_name = GSS_C_NO_NAME;
+ } else {
+ /* This shouldn't happen */
+ *minor_status = KRB5_NOCREDS_SUPPLIED; /* XXX */
+ ret = GSS_S_NO_CRED;
+ goto out;
+ }
}
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,
- context,
- 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();
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ cred->endtime,
+ lifetime);
+ if (ret)
+ goto out;
}
-
+ if (cred_usage != NULL)
+ *cred_usage = cred->usage;
if (mechanisms != NULL) {
ret = gss_create_empty_oid_set(minor_status, mechanisms);
if (ret)
- goto out;
- if (acred)
- ret = gss_add_oid_set_member(minor_status,
- &acred->mechanisms->elements[0],
- mechanisms);
- if (ret == GSS_S_COMPLETE && icred)
- ret = gss_add_oid_set_member(minor_status,
- &icred->mechanisms->elements[0],
- mechanisms);
+ goto out;
+ ret = gss_add_oid_set_member(minor_status,
+ &cred->mechanisms->elements[0],
+ mechanisms);
if (ret)
- goto out;
+ 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);
+out:
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
return ret;
}
diff --git a/lib/gssapi/krb5/inquire_cred_by_mech.c b/lib/gssapi/krb5/inquire_cred_by_mech.c
index 7bd9c11c6056..6ce4994ebe08 100644
--- a/lib/gssapi/krb5/inquire_cred_by_mech.c
+++ b/lib/gssapi/krb5/inquire_cred_by_mech.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_mech (
OM_uint32 * minor_status,
- const gss_cred_id_t cred_handle,
+ gss_const_cred_id_t cred_handle,
const gss_OID mech_type,
gss_name_t * name,
OM_uint32 * initiator_lifetime,
@@ -47,6 +47,10 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_mech (
OM_uint32 maj_stat;
OM_uint32 lifetime;
+ /*
+ * XXX This is busted. _gsskrb5_inquire_cred() should be implemented in
+ * terms of _gsskrb5_inquire_cred_by_mech(), NOT the other way around.
+ */
maj_stat =
_gsskrb5_inquire_cred (minor_status, cred_handle,
name, &lifetime, &usage, NULL);
diff --git a/lib/gssapi/krb5/inquire_cred_by_oid.c b/lib/gssapi/krb5/inquire_cred_by_oid.c
index d560ed4ba1c6..7dae3d25c4ff 100644
--- a/lib/gssapi/krb5/inquire_cred_by_oid.c
+++ b/lib/gssapi/krb5/inquire_cred_by_oid.c
@@ -34,7 +34,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid
(OM_uint32 * minor_status,
- const gss_cred_id_t cred_handle,
+ gss_const_cred_id_t cred_handle,
const gss_OID desired_object,
gss_buffer_set_t *data_set)
{
diff --git a/lib/gssapi/krb5/inquire_mechs_for_name.c b/lib/gssapi/krb5/inquire_mechs_for_name.c
index 6197a81b40a7..c6c67464fc55 100644
--- a/lib/gssapi/krb5/inquire_mechs_for_name.c
+++ b/lib/gssapi/krb5/inquire_mechs_for_name.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
OM_uint32 * minor_status,
- const gss_name_t input_name,
+ gss_const_name_t input_name,
gss_OID_set * mech_types
)
{
diff --git a/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/lib/gssapi/krb5/inquire_sec_context_by_oid.c
index b57217a4e830..f1ed99320975 100644
--- a/lib/gssapi/krb5/inquire_sec_context_by_oid.c
+++ b/lib/gssapi/krb5/inquire_sec_context_by_oid.c
@@ -149,7 +149,6 @@ static OM_uint32 inquire_sec_context_get_subkey
}
ret = krb5_store_keyblock(sp, *key);
- krb5_free_keyblock (context, key);
if (ret)
goto out;
@@ -169,6 +168,7 @@ static OM_uint32 inquire_sec_context_get_subkey
}
out:
+ krb5_free_keyblock(context, key);
krb5_data_free(&data);
if (sp)
krb5_storage_free(sp);
@@ -333,7 +333,8 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status,
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);
+ /* XXX need krb5_store_int64() */
+ ret = krb5_store_int32(sp, context_handle->endtime);
if (ret) goto out;
krb5_auth_con_getlocalseqnumber (context,
context_handle->auth_context,
@@ -529,7 +530,7 @@ out:
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid
(OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
const gss_OID desired_object,
gss_buffer_set_t *data_set)
{
diff --git a/lib/gssapi/krb5/pname_to_uid.c b/lib/gssapi/krb5/pname_to_uid.c
index ff754e779813..dca74645de6d 100644
--- a/lib/gssapi/krb5/pname_to_uid.c
+++ b/lib/gssapi/krb5/pname_to_uid.c
@@ -33,53 +33,38 @@
#include "gsskrb5_locl.h"
OM_uint32 GSSAPI_CALLCONV
-_gsskrb5_pname_to_uid(OM_uint32 *minor_status,
- const gss_name_t pname,
- const gss_OID mech_type,
- uid_t *uidp)
+_gsskrb5_localname(OM_uint32 *minor_status,
+ gss_const_name_t pname,
+ const gss_OID mech_type,
+ gss_buffer_t localname)
{
-#ifdef NO_LOCALNAME
- *minor_status = KRB5_NO_LOCALNAME;
- return GSS_S_FAILURE;
-#else
krb5_error_code ret;
krb5_context context;
krb5_const_principal princ = (krb5_const_principal)pname;
- char localname[256];
-#ifdef POSIX_GETPWNAM_R
- char pwbuf[2048];
- struct passwd pw, *pwd;
-#else
- struct passwd *pwd;
-#endif
+ char lnamebuf[256];
GSSAPI_KRB5_INIT(&context);
*minor_status = 0;
ret = krb5_aname_to_localname(context, princ,
- sizeof(localname), localname);
+ sizeof(lnamebuf), lnamebuf);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
-#ifdef POSIX_GETPWNAM_R
- if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) {
- *minor_status = KRB5_NO_LOCALNAME;
- return GSS_S_FAILURE;
- }
-#else
- pwd = getpwnam(localname);
-#endif
+ localname->length = strlen(lnamebuf);
- if (pwd == NULL) {
- *minor_status = KRB5_NO_LOCALNAME;
+ localname->value = malloc(localname->length + 1);
+ if (localname->value == NULL) {
+ localname->length = 0;
+ *minor_status = ENOMEM;
return GSS_S_FAILURE;
}
- *uidp = pwd->pw_uid;
+ memcpy(localname->value, lnamebuf, localname->length + 1);
+ *minor_status = 0;
return GSS_S_COMPLETE;
-#endif /* NO_LOCALNAME */
}
diff --git a/lib/gssapi/krb5/prf.c b/lib/gssapi/krb5/prf.c
index 162a3097099f..671ab2c6d982 100644
--- a/lib/gssapi/krb5/prf.c
+++ b/lib/gssapi/krb5/prf.c
@@ -119,7 +119,7 @@ _gsskrb5_pseudo_random(OM_uint32 *minor_status,
while(dol > 0) {
size_t tsize;
- _gsskrb5_encode_om_uint32(num, input.data);
+ _gsskrb5_encode_be_om_uint32(num, input.data);
ret = krb5_crypto_prf(context, crypto, &input, &output);
if (ret) {
@@ -133,7 +133,7 @@ _gsskrb5_pseudo_random(OM_uint32 *minor_status,
tsize = min(dol, output.length);
memcpy(p, output.data, tsize);
- p += output.length;
+ p += tsize;
dol -= tsize;
krb5_data_free(&output);
num++;
diff --git a/lib/gssapi/krb5/process_context_token.c b/lib/gssapi/krb5/process_context_token.c
index 0cc1c07cfbe9..601b0e8a5a8a 100644
--- a/lib/gssapi/krb5/process_context_token.c
+++ b/lib/gssapi/krb5/process_context_token.c
@@ -35,7 +35,7 @@
OM_uint32 GSSAPI_CALLCONV _gsskrb5_process_context_token (
OM_uint32 *minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
const gss_buffer_t token_buffer
)
{
diff --git a/lib/gssapi/krb5/set_sec_context_option.c b/lib/gssapi/krb5/set_sec_context_option.c
index 141ff722fb64..a0e6fd02c59a 100644
--- a/lib/gssapi/krb5/set_sec_context_option.c
+++ b/lib/gssapi/krb5/set_sec_context_option.c
@@ -178,23 +178,9 @@ _gsskrb5_set_sec_context_option
} 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(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(context,
- (krb5_send_to_kdc_func)c.func,
- c.ptr);
- }
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
- *minor_status = 0;
- return GSS_S_COMPLETE;
} else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
char *str;
diff --git a/lib/gssapi/krb5/store_cred.c b/lib/gssapi/krb5/store_cred.c
index a3aa2fb83e71..40b75771dd17 100644
--- a/lib/gssapi/krb5/store_cred.c
+++ b/lib/gssapi/krb5/store_cred.c
@@ -46,8 +46,11 @@ _gsskrb5_store_cred(OM_uint32 *minor_status,
krb5_context context;
krb5_error_code ret;
gsskrb5_cred cred;
- krb5_ccache id;
- int destroy = 0;
+ krb5_ccache id = NULL;
+ krb5_ccache def_ccache = NULL;
+ const char *def_type = NULL;
+ time_t exp_current;
+ time_t exp_new;
*minor_status = 0;
@@ -56,7 +59,8 @@ _gsskrb5_store_cred(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
- if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0)
+ if (desired_mech != GSS_C_NO_OID &&
+ gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0)
return GSS_S_BAD_MECH;
cred = (gsskrb5_cred)input_cred_handle;
@@ -69,48 +73,87 @@ _gsskrb5_store_cred(OM_uint32 *minor_status,
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);
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_get_lifetime(context, cred->ccache, &exp_new);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return GSS_S_NO_CRED;
}
if (cred->principal == NULL) {
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = GSS_KRB5_S_KG_TGT_MISSING;
- return(GSS_S_FAILURE);
+ return GSS_S_FAILURE;
}
- /* write out cred to credential cache */
+ ret = krb5_cc_default(context, &def_ccache);
+ if (ret == 0) {
+ def_type = krb5_cc_get_type(context, def_ccache);
+ krb5_cc_close(context, def_ccache);
+ }
+ def_ccache = NULL;
+ /* write out cred to credential cache */
ret = krb5_cc_cache_match(context, cred->principal, &id);
if (ret) {
- ret = krb5_cc_new_unique(context, NULL, NULL, &id);
- if (ret) {
- HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
- *minor_status = ret;
- return(GSS_S_FAILURE);
- }
- destroy = 1;
+ if (default_cred) {
+ ret = krb5_cc_default(context, &id);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ if (def_type == NULL ||
+ !krb5_cc_support_switch(context, def_type)) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0; /* XXX */
+ return GSS_S_NO_CRED; /* XXX */
+ }
+ ret = krb5_cc_new_unique(context, def_type, NULL, &id);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ overwrite_cred = 1;
+ }
+ }
+
+ if (!overwrite_cred) {
+ /* If current creds are expired or near it, overwrite */
+ ret = krb5_cc_get_lifetime(context, id, &exp_current);
+ if (ret != 0 || exp_new > exp_current)
+ overwrite_cred = 1;
+ }
+
+ if (!overwrite_cred) {
+ /* Nothing to do */
+ krb5_cc_close(context, id);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0;
+ return GSS_S_DUPLICATE_ELEMENT;
}
ret = krb5_cc_initialize(context, id, cred->principal);
if (ret == 0)
ret = krb5_cc_copy_match_f(context, cred->ccache, id, NULL, NULL, NULL);
if (ret) {
- if (destroy)
- krb5_cc_destroy(context, id);
- else
- krb5_cc_close(context, id);
+ krb5_cc_close(context, id);
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
*minor_status = ret;
return(GSS_S_FAILURE);
}
- if (default_cred)
+ if (default_cred && def_type != NULL &&
+ krb5_cc_support_switch(context, def_type))
krb5_cc_switch(context, id);
krb5_cc_close(context, id);
-
HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
-
*minor_status = 0;
return GSS_S_COMPLETE;
}
diff --git a/lib/gssapi/krb5/test_acquire_cred.c b/lib/gssapi/krb5/test_acquire_cred.c
new file mode 100644
index 000000000000..9f7c9ef4e430
--- /dev/null
+++ b/lib/gssapi/krb5/test_acquire_cred.c
@@ -0,0 +1,162 @@
+/*
+ * 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "gsskrb5_locl.h"
+#include <err.h>
+
+static void
+print_time(OM_uint32 time_rec)
+{
+ if (time_rec == GSS_C_INDEFINITE) {
+ printf("cred never expire\n");
+ } else {
+ time_t t = time_rec + time(NULL);
+ printf("expiration time: %s", ctime(&t));
+ }
+}
+
+static void
+test_add(gss_cred_id_t cred_handle)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t copy_cred;
+ OM_uint32 time_rec;
+
+ major_status = gss_add_cred (&minor_status,
+ cred_handle,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ GSS_C_INITIATE,
+ 0,
+ 0,
+ &copy_cred,
+ NULL,
+ &time_rec,
+ NULL);
+
+ if (GSS_ERROR(major_status))
+ errx(1, "add_cred failed");
+
+ print_time(time_rec);
+
+ major_status = gss_release_cred(&minor_status,
+ &copy_cred);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_cred failed");
+}
+
+static void
+copy_cred(void)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t cred_handle;
+ OM_uint32 time_rec;
+
+ major_status = gss_acquire_cred(&minor_status,
+ GSS_C_NO_NAME,
+ 0,
+ NULL,
+ GSS_C_INITIATE,
+ &cred_handle,
+ NULL,
+ &time_rec);
+ if (GSS_ERROR(major_status))
+ errx(1, "acquire_cred failed");
+
+ print_time(time_rec);
+
+ test_add(cred_handle);
+ test_add(cred_handle);
+ test_add(cred_handle);
+
+ major_status = gss_release_cred(&minor_status,
+ &cred_handle);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_cred failed");
+}
+
+static void
+acquire_cred_service(const char *service)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t cred_handle;
+ OM_uint32 time_rec;
+ gss_buffer_desc name_buffer;
+ gss_name_t name;
+
+ name_buffer.value = rk_UNCONST(service);
+ name_buffer.length = strlen(service);
+
+ major_status = gss_import_name(&minor_status,
+ &name_buffer,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &name);
+ if (GSS_ERROR(major_status))
+ errx(1, "import_name failed");
+
+
+ major_status = gss_acquire_cred(&minor_status,
+ name,
+ 0,
+ NULL,
+ GSS_C_ACCEPT,
+ &cred_handle,
+ NULL,
+ &time_rec);
+ if (GSS_ERROR(major_status))
+ errx(1, "acquire_cred failed");
+
+ print_time(time_rec);
+
+ major_status = gss_release_cred(&minor_status,
+ &cred_handle);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_cred failed");
+
+
+ major_status = gss_release_name(&minor_status,
+ &name);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_name failed");
+
+}
+
+int
+main(int argc, char **argv)
+{
+ copy_cred();
+
+ acquire_cred_service("host@xen2-heimdal-linux.lab.it.su.se");
+
+ return 0;
+}
diff --git a/lib/gssapi/krb5/test_cfx.c b/lib/gssapi/krb5/test_cfx.c
index 0b196fcad24d..15f853c6b602 100644
--- a/lib/gssapi/krb5/test_cfx.c
+++ b/lib/gssapi/krb5/test_cfx.c
@@ -148,7 +148,7 @@ main(int argc, char **argv)
errx(1, "krb5_context_init: %d", ret);
ret = krb5_generate_random_keyblock(context,
- ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
&keyblock);
if (ret)
krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
diff --git a/lib/gssapi/krb5/test_cred.c b/lib/gssapi/krb5/test_cred.c
new file mode 100644
index 000000000000..06dd6632d0be
--- /dev/null
+++ b/lib/gssapi/krb5/test_cred.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2003-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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "gsskrb5_locl.h"
+#include <err.h>
+#include <getarg.h>
+
+static void
+gss_print_errors (int min_stat)
+{
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ OM_uint32 ret;
+
+ do {
+ ret = gss_display_status (&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ fprintf (stderr, "%.*s\n", (int)status_string.length,
+ (char *)status_string.value);
+ gss_release_buffer (&new_stat, &status_string);
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+}
+
+static void
+gss_err(int exitval, int status, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vwarnx (fmt, args);
+ gss_print_errors (status);
+ va_end(args);
+ exit (exitval);
+}
+
+static void
+acquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_cred_id_t cred;
+ int i;
+
+ for (i = 0; i < counter; i++) {
+ maj_stat = gss_acquire_cred(&min_stat, name,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ usage,
+ &cred,
+ NULL,
+ NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE",
+ i, (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE",
+ i, (int)maj_stat);
+ }
+}
+
+
+static void
+acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_cred_id_t cred, cred2, cred3;
+
+ maj_stat = gss_acquire_cred(&min_stat, name,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ usage,
+ &cred,
+ NULL,
+ NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_add_cred(&min_stat,
+ cred,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ usage,
+ GSS_C_INDEFINITE,
+ GSS_C_INDEFINITE,
+ &cred2,
+ NULL,
+ NULL,
+ NULL);
+
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_add_cred(&min_stat,
+ cred2,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ GSS_C_BOTH,
+ GSS_C_INDEFINITE,
+ GSS_C_INDEFINITE,
+ &cred3,
+ NULL,
+ NULL,
+ NULL);
+
+ maj_stat = gss_release_cred(&min_stat, &cred2);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred3);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
+}
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "service@host");
+ exit (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct gss_buffer_desc_struct name_buffer;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name;
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc < 1)
+ errx(1, "argc < 1");
+
+ name_buffer.value = argv[0];
+ name_buffer.length = strlen(argv[0]);
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &name);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "import name error");
+
+ acquire_release_loop(name, 100, GSS_C_ACCEPT);
+ acquire_release_loop(name, 100, GSS_C_INITIATE);
+ acquire_release_loop(name, 100, GSS_C_BOTH);
+
+ acquire_add_release_add(name, GSS_C_ACCEPT);
+ acquire_add_release_add(name, GSS_C_INITIATE);
+ acquire_add_release_add(name, GSS_C_BOTH);
+
+ gss_release_name(&min_stat, &name);
+
+ return 0;
+}
diff --git a/lib/gssapi/krb5/test_kcred.c b/lib/gssapi/krb5/test_kcred.c
new file mode 100644
index 000000000000..f53ce783bb07
--- /dev/null
+++ b/lib/gssapi/krb5/test_kcred.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2003-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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "gsskrb5_locl.h"
+#include <err.h>
+#include <getarg.h>
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static void
+copy_import(void)
+{
+ gss_cred_id_t cred1, cred2;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name1, name2;
+ OM_uint32 lifetime1, lifetime2;
+ gss_cred_usage_t usage1, usage2;
+ gss_OID_set mechs1, mechs2;
+ krb5_ccache id;
+ krb5_error_code ret;
+ krb5_context context;
+ int equal;
+
+ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_INITIATE,
+ &cred1, NULL, NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_acquire_cred");
+
+ maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1,
+ &usage1, &mechs1);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_inquire_cred");
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ errx(1, "krb5_init_context");
+
+ ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_new_unique");
+
+ maj_stat = gss_krb5_copy_ccache(&min_stat, context, cred1, id);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_copy_ccache");
+
+ maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_import_cred");
+
+ maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2,
+ &usage2, &mechs2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_inquire_cred 2");
+
+ maj_stat = gss_compare_name(&min_stat, name1, name2, &equal);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_compare_name");
+ if (!equal)
+ errx(1, "names not equal");
+
+ if (lifetime1 != lifetime1)
+ errx(1, "lifetime not equal");
+
+ if (usage1 != usage1)
+ errx(1, "usage not equal");
+
+ gss_release_cred(&min_stat, &cred1);
+ gss_release_cred(&min_stat, &cred2);
+
+ gss_release_name(&min_stat, &name1);
+ gss_release_name(&min_stat, &name2);
+
+#if 0
+ compare(mechs1, mechs2);
+#endif
+
+ gss_release_oid_set(&min_stat, &mechs1);
+ gss_release_oid_set(&min_stat, &mechs2);
+
+ krb5_cc_destroy(context, id);
+ krb5_free_context(context);
+}
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ copy_import();
+
+ return 0;
+}
diff --git a/lib/gssapi/krb5/test_oid.c b/lib/gssapi/krb5/test_oid.c
new file mode 100644
index 000000000000..00219b91e066
--- /dev/null
+++ b/lib/gssapi/krb5/test_oid.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "gsskrb5_locl.h"
+
+int
+main(int argc, char **argv)
+{
+ OM_uint32 minor_status, maj_stat;
+ gss_buffer_desc data;
+ int ret;
+
+ maj_stat = gss_oid_to_str(&minor_status, GSS_KRB5_MECHANISM, &data);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_oid_to_str failed");
+ ret = strncmp(data.value, "1 2 840 113554 1 2 2", data.length);
+ gss_release_buffer(&maj_stat, &data);
+ if (ret)
+ return 1;
+ return 0;
+}
diff --git a/lib/gssapi/krb5/unwrap.c b/lib/gssapi/krb5/unwrap.c
index d6bc20477787..da939c052930 100644
--- a/lib/gssapi/krb5/unwrap.c
+++ b/lib/gssapi/krb5/unwrap.c
@@ -382,7 +382,7 @@ unwrap_des3
OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
@@ -392,7 +392,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
krb5_keyblock *key;
krb5_context context;
OM_uint32 ret;
- krb5_keytype keytype;
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
output_message_buffer->value = NULL;
@@ -414,12 +413,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (context, key->keytype, &keytype);
*minor_status = 0;
- switch (keytype) {
- case KEYTYPE_DES :
+ switch (key->keytype) {
+ case KRB5_ENCTYPE_DES_CBC_CRC :
+ case KRB5_ENCTYPE_DES_CBC_MD4 :
+ case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
ret = unwrap_des (minor_status, ctx,
input_message_buffer, output_message_buffer,
@@ -428,13 +428,14 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
ret = GSS_S_FAILURE;
#endif
break;
- case KEYTYPE_DES3 :
+ case KRB5_ENCTYPE_DES3_CBC_MD5 :
+ case KRB5_ENCTYPE_DES3_CBC_SHA1 :
ret = unwrap_des3 (minor_status, ctx, context,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
break;
- case KEYTYPE_ARCFOUR:
- case KEYTYPE_ARCFOUR_56:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
ret = _gssapi_unwrap_arcfour (minor_status, ctx, context,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
diff --git a/lib/gssapi/krb5/verify_mic.c b/lib/gssapi/krb5/verify_mic.c
index 3814ef7062c1..9968ce403ef7 100644
--- a/lib/gssapi/krb5/verify_mic.c
+++ b/lib/gssapi/krb5/verify_mic.c
@@ -254,15 +254,11 @@ retry:
krb5_crypto_destroy (context, crypto);
ret = krb5_crypto_init(context, key,
ETYPE_DES3_CBC_SHA1, &crypto);
- if (ret){
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- ret = krb5_verify_checksum (context, crypto,
- KRB5_KU_USAGE_SIGN,
- tmp, message_buffer->length + 8,
- &csum);
+ if (ret == 0)
+ ret = krb5_verify_checksum(context, crypto,
+ KRB5_KU_USAGE_SIGN,
+ tmp, message_buffer->length + 8,
+ &csum);
free (tmp);
if (ret) {
krb5_crypto_destroy (context, crypto);
@@ -289,7 +285,6 @@ _gsskrb5_verify_mic_internal
{
krb5_keyblock *key;
OM_uint32 ret;
- krb5_keytype keytype;
if (ctx->more_flags & IS_CFX)
return _gssapi_verify_mic_cfx (minor_status, ctx,
@@ -304,9 +299,11 @@ _gsskrb5_verify_mic_internal
return GSS_S_FAILURE;
}
*minor_status = 0;
- krb5_enctype_to_keytype (context, key->keytype, &keytype);
- switch (keytype) {
- case KEYTYPE_DES :
+
+ switch (key->keytype) {
+ case KRB5_ENCTYPE_DES_CBC_CRC :
+ case KRB5_ENCTYPE_DES_CBC_MD4 :
+ case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
ret = verify_mic_des (minor_status, ctx, context,
message_buffer, token_buffer, qop_state, key,
@@ -315,13 +312,14 @@ _gsskrb5_verify_mic_internal
ret = GSS_S_FAILURE;
#endif
break;
- case KEYTYPE_DES3 :
+ case KRB5_ENCTYPE_DES3_CBC_MD5 :
+ case KRB5_ENCTYPE_DES3_CBC_SHA1 :
ret = verify_mic_des3 (minor_status, ctx, context,
message_buffer, token_buffer, qop_state, key,
type);
break;
- case KEYTYPE_ARCFOUR :
- case KEYTYPE_ARCFOUR_56 :
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
context,
message_buffer, token_buffer,
@@ -338,7 +336,7 @@ _gsskrb5_verify_mic_internal
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_verify_mic
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state
diff --git a/lib/gssapi/krb5/wrap.c b/lib/gssapi/krb5/wrap.c
index 1026e41914e9..481e30375a44 100644
--- a/lib/gssapi/krb5/wrap.c
+++ b/lib/gssapi/krb5/wrap.c
@@ -137,7 +137,7 @@ sub_wrap_size (
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_wrap_size_limit (
OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
OM_uint32 req_output_size,
@@ -147,7 +147,6 @@ _gsskrb5_wrap_size_limit (
krb5_context context;
krb5_keyblock *key;
OM_uint32 ret;
- krb5_keytype keytype;
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
GSSAPI_KRB5_INIT (&context);
@@ -164,23 +163,25 @@ _gsskrb5_wrap_size_limit (
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (context, key->keytype, &keytype);
- switch (keytype) {
- case KEYTYPE_DES :
+ switch (key->keytype) {
+ case KRB5_ENCTYPE_DES_CBC_CRC :
+ case KRB5_ENCTYPE_DES_CBC_MD4 :
+ case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
#else
ret = GSS_S_FAILURE;
#endif
break;
- case ENCTYPE_ARCFOUR_HMAC_MD5:
- case ENCTYPE_ARCFOUR_HMAC_MD5_56:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
ret = _gssapi_wrap_size_arcfour(minor_status, ctx, context,
conf_req_flag, qop_req,
req_output_size, max_input_size, key);
break;
- case KEYTYPE_DES3 :
+ case KRB5_ENCTYPE_DES3_CBC_MD5 :
+ case KRB5_ENCTYPE_DES3_CBC_SHA1 :
ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
break;
default :
@@ -527,7 +528,7 @@ wrap_des3
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_wrap
(OM_uint32 * minor_status,
- const gss_ctx_id_t context_handle,
+ gss_const_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
@@ -538,7 +539,6 @@ _gsskrb5_wrap
krb5_context context;
krb5_keyblock *key;
OM_uint32 ret;
- krb5_keytype keytype;
const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
output_message_buffer->value = NULL;
@@ -558,10 +558,11 @@ _gsskrb5_wrap
*minor_status = ret;
return GSS_S_FAILURE;
}
- krb5_enctype_to_keytype (context, key->keytype, &keytype);
- switch (keytype) {
- case KEYTYPE_DES :
+ switch (key->keytype) {
+ case KRB5_ENCTYPE_DES_CBC_CRC :
+ case KRB5_ENCTYPE_DES_CBC_MD4 :
+ case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
ret = wrap_des (minor_status, ctx, context, conf_req_flag,
qop_req, input_message_buffer, conf_state,
@@ -570,13 +571,14 @@ _gsskrb5_wrap
ret = GSS_S_FAILURE;
#endif
break;
- case KEYTYPE_DES3 :
+ case KRB5_ENCTYPE_DES3_CBC_MD5 :
+ case KRB5_ENCTYPE_DES3_CBC_SHA1 :
ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
break;
- case KEYTYPE_ARCFOUR:
- case KEYTYPE_ARCFOUR_56:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+ case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
ret = _gssapi_wrap_arcfour (minor_status, ctx, context, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);