Esempio n. 1
0
krb5_error_code
_kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
		krb5_enctype *etypes, unsigned len,
		Key **ret_key, krb5_enctype *ret_etype)
{
    int i;
    krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
    krb5_salt def_salt;

    krb5_get_pw_salt (context, princ->entry.principal, &def_salt);

    for(i = 0; ret != 0 && i < len ; i++) {
	Key *key = NULL;

	if (krb5_enctype_valid(context, etypes[i]) != 0 &&
	    !_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
	    continue;

	while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
	    if (key->key.keyvalue.length == 0) {
		ret = KRB5KDC_ERR_NULL_KEY;
		continue;
	    }
	    *ret_key   = key;
	    *ret_etype = etypes[i];
	    ret = 0;
	    if (is_default_salt_p(&def_salt, key)) {
		krb5_free_salt (context, def_salt);
		return ret;
	    }
	}
    }
    krb5_free_salt (context, def_salt);
    return ret;
}
Esempio n. 2
0
krb5_error_code
_kdc_get_preferred_key(krb5_context context,
		       krb5_kdc_configuration *config,
		       hdb_entry_ex *h,
		       const char *name,
		       krb5_enctype *enctype,
		       Key **key)
{
    krb5_error_code ret;
    int i;

    if (config->use_strongest_server_key) {
	const krb5_enctype *p = krb5_kerberos_enctypes(context);

	for (i = 0; p[i] != (krb5_enctype)ETYPE_NULL; i++) {
	    if (krb5_enctype_valid(context, p[i]) != 0 &&
		!_kdc_is_weak_exception(h->entry.principal, p[i]))
		continue;
	    ret = hdb_enctype2key(context, &h->entry, NULL, p[i], key);
	    if (ret != 0)
		continue;
	    if (enctype != NULL)
		*enctype = p[i];
	    return 0;
	}
    } else {
	*key = NULL;

	for (i = 0; i < h->entry.keys.len; i++) {
	    if (krb5_enctype_valid(context, h->entry.keys.val[i].key.keytype) != 0 &&
		!_kdc_is_weak_exception(h->entry.principal, h->entry.keys.val[i].key.keytype))
		continue;
	    ret = hdb_enctype2key(context, &h->entry, NULL,
				  h->entry.keys.val[i].key.keytype, key);
	    if (ret != 0)
		continue;
	    if (enctype != NULL)
		*enctype = (*key)->key.keytype;
	    return 0;
	}
    }

    krb5_set_error_message(context, EINVAL,
			   "No valid kerberos key found for %s", name);
    return EINVAL; /* XXX */
}
Esempio n. 3
0
krb5_error_code
_kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
		krb5_boolean is_preauth, hdb_entry_ex *princ,
		krb5_enctype *etypes, unsigned len,
		krb5_enctype *ret_enctype, Key **ret_key)
{
    krb5_error_code ret;
    krb5_salt def_salt;
    krb5_enctype enctype = ETYPE_NULL;
    Key *key;
    int i;

    /* We'll want to avoid keys with v4 salted keys in the pre-auth case... */
    ret = krb5_get_pw_salt(context, princ->entry.principal, &def_salt);
    if (ret)
	return ret;

    ret = KRB5KDC_ERR_ETYPE_NOSUPP;

    if (use_strongest_session_key) {
	const krb5_enctype *p;
	krb5_enctype clientbest = ETYPE_NULL;
	int j;

	/*
	 * Pick the strongest key that the KDC, target service, and
	 * client all support, using the local cryptosystem enctype
	 * list in strongest-to-weakest order to drive the search.
	 *
	 * This is not what RFC4120 says to do, but it encourages
	 * adoption of stronger enctypes.  This doesn't play well with
	 * clients that have multiple Kerberos client implementations
	 * available with different supported enctype lists.
	 */

	/* drive the search with local supported enctypes list */
	p = krb5_kerberos_enctypes(context);
	for (i = 0; p[i] != ETYPE_NULL && enctype == ETYPE_NULL; i++) {
	    if (krb5_enctype_valid(context, p[i]) != 0)
		continue;

	    /* check that the client supports it too */
	    for (j = 0; j < len && enctype == ETYPE_NULL; j++) {
		if (p[i] != etypes[j])
		    continue;
		/* save best of union of { client, crypto system } */
		if (clientbest == ETYPE_NULL)
		    clientbest = p[i];
		/* check target princ support */
		ret = hdb_enctype2key(context, &princ->entry, p[i], &key);
		if (ret)
		    continue;
		if (is_preauth && !is_default_salt_p(&def_salt, key))
		    continue;
		enctype = p[i];
	    }
	}
	if (clientbest != ETYPE_NULL && enctype == ETYPE_NULL)
	    enctype = clientbest;
	else if (enctype == ETYPE_NULL)
	    ret = KRB5KDC_ERR_ETYPE_NOSUPP;
	if (ret == 0 && ret_enctype != NULL)
	    *ret_enctype = enctype;
	if (ret == 0 && ret_key != NULL)
	    *ret_key = key;
    } else {
	/*
	 * Pick the first key from the client's enctype list that is
	 * supported by the cryptosystem and by the given principal.
	 *
	 * RFC4120 says we SHOULD pick the first _strong_ key from the
	 * client's list... not the first key...  If the admin disallows
	 * weak enctypes in krb5.conf and selects this key selection
	 * algorithm, then we get exactly what RFC4120 says.
	 */
	for(key = NULL, i = 0; ret != 0 && i < len; i++, key = NULL) {

	    if (krb5_enctype_valid(context, etypes[i]) != 0 &&
		!_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
		continue;

	    while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
		if (key->key.keyvalue.length == 0) {
		    ret = KRB5KDC_ERR_NULL_KEY;
		    continue;
		}
		if (ret_key != NULL)
		    *ret_key = key;
		if (ret_enctype != NULL)
		    *ret_enctype = etypes[i];
		ret = 0;
		if (is_preauth && is_default_salt_p(&def_salt, key))
		    goto out;
	    }
	}
    }

out:
    krb5_free_salt (context, def_salt);
    return ret;
}