Esempio n. 1
0
static int
match_rfc_san(krb5_context context,
	      krb5_kdc_configuration *config,
	      hx509_context hx509ctx,
	      hx509_cert client_cert,
	      krb5_const_principal match)
{
    hx509_octet_string_list list;
    int ret, found = 0;
    size_t i;

    memset(&list, 0 , sizeof(list));

    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
						   client_cert,
						   &asn1_oid_id_pkinit_san,
						   &list);
    if (ret)
	goto out;

    for (i = 0; !found && i < list.len; i++) {
	krb5_principal_data principal;
	KRB5PrincipalName kn;
	size_t size;

	ret = decode_KRB5PrincipalName(list.val[i].data,
				       list.val[i].length,
				       &kn, &size);
	if (ret) {
	    const char *msg = krb5_get_error_message(context, ret);
	    kdc_log(context, config, 0,
		    "Decoding kerberos name in certificate failed: %s", msg);
	    krb5_free_error_message(context, msg);
	    break;
	}
	if (size != list.val[i].length) {
	    kdc_log(context, config, 0,
		    "Decoding kerberos name have extra bits on the end");
	    return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
	}

	memset(&principal, 0, sizeof (principal));
	principal.name = kn.principalName;
	principal.realm = kn.realm;

	if (krb5_principal_compare(context, &principal, match) == TRUE)
	    found = 1;
	free_KRB5PrincipalName(&kn);
    }

out:
    hx509_free_octet_string_list(&list);
    if (ret)
	return ret;

    if (!found)
	return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;

    return 0;
}
Esempio n. 2
0
static int
match_ms_upn_san(krb5_context context,
		 krb5_kdc_configuration *config,
		 hx509_context hx509ctx,
		 hx509_cert client_cert,
		 HDB *clientdb,
		 hdb_entry_ex *client)
{
    hx509_octet_string_list list;
    krb5_principal principal = NULL;
    int ret;
    MS_UPN_SAN upn;
    size_t size;

    memset(&list, 0 , sizeof(list));

    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
						   client_cert,
						   &asn1_oid_id_pkinit_ms_san,
						   &list);
    if (ret)
	goto out;

    if (list.len != 1) {
	kdc_log(context, config, 0,
		"More then one PK-INIT MS UPN SAN");
	ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
	goto out;
    }

    ret = decode_MS_UPN_SAN(list.val[0].data, list.val[0].length, &upn, &size);
    if (ret) {
	kdc_log(context, config, 0, "Decode of MS-UPN-SAN failed");
	goto out;
    }
    if (size != list.val[0].length) {
	free_MS_UPN_SAN(&upn);
	kdc_log(context, config, 0, "Trailing data in ");
	ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
	goto out;
    }

    kdc_log(context, config, 0, "found MS UPN SAN: %s", upn);

    ret = krb5_parse_name(context, upn, &principal);
    free_MS_UPN_SAN(&upn);
    if (ret) {
	kdc_log(context, config, 0, "Failed to parse principal in MS UPN SAN");
	goto out;
    }

    if (clientdb->hdb_check_pkinit_ms_upn_match) {
	ret = clientdb->hdb_check_pkinit_ms_upn_match(context, clientdb, client, principal);
    } else {

	/*
	 * This is very wrong, but will do for a fallback
	 */
	strupr(principal->realm);

	if (krb5_principal_compare(context, principal, client->entry.principal) == FALSE)
	    ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
    }

out:
    if (principal)
	krb5_free_principal(context, principal);
    hx509_free_octet_string_list(&list);

    return ret;
}
krb5_error_code
_gsspku2u_principal(krb5_context context,
		    struct hx509_cert_data *cert,
		    krb5_principal *principal)
{
    hx509_octet_string_list list;
    krb5_error_code ret;
    int found = 0;
    unsigned i;
    char *name;

    *principal = NULL;

    /*
     * First try to map PKINIT SAN to a Kerberos principal
     */

    ret = hx509_cert_find_subjectAltName_otherName(context->hx509ctx, cert,
						   &asn1_oid_id_pkinit_san,
						   &list);
    if (ret == 0) {
	for (i = 0; !found && i < list.len; i++) {
	    KRB5PrincipalName r;

	    ret = decode_KRB5PrincipalName(list.val[i].data,
					   list.val[i].length,
					   &r, NULL);
	    if (ret)
		continue;
	    
	    ret = _krb5_principalname2krb5_principal(context, principal,
						     r.principalName,
						     KRB5_PKU2U_REALM_NAME);
	    free_KRB5PrincipalName(&r);
	    if (ret == 0)
		found = 1;
	}
	hx509_free_octet_string_list(&list);
    }
    if (found)
	return 0;

    /*
     *
     */

    ret = hx509_cert_get_appleid(context->hx509ctx, cert, &name);
    if (ret == 0) {
	ret = krb5_make_principal(context, principal,
				  KRB5_PKU2U_REALM_NAME,
				  name, NULL);
	hx509_xfree(name);
	if (ret == 0) {
	    (*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL;
	    return 0;
	}
    }
    
    /*
     * Give up and just WELLKNOWN and assertion instead
     */

    ret = krb5_make_principal(context, principal, KRB5_PKU2U_REALM_NAME,
			      KRB5_WELLKNOWN_NAME, KRB5_NULL_NAME, NULL);
    if (ret == 0)
	(*principal)->name.name_type = KRB5_NT_WELLKNOWN;
    return ret;
}
Esempio n. 4
0
static int
match_ms_upn_san(krb5_context context,
		 krb5_kdc_configuration *config,
		 hx509_context hx509ctx,
		 hx509_cert client_cert,
		 krb5_const_principal match)
{
    hx509_octet_string_list list;
    krb5_principal principal = NULL;
    int ret, found = 0;
    MS_UPN_SAN upn;
    size_t size;

    memset(&list, 0 , sizeof(list));

    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
						   client_cert,
						   oid_id_pkinit_ms_san(),
						   &list);
    if (ret)
	goto out;

    if (list.len != 1) {
	kdc_log(context, config, 0,
		"More then one PK-INIT MS UPN SAN");
	goto out;
    }

    ret = decode_MS_UPN_SAN(list.val[0].data, list.val[0].length, &upn, &size);
    if (ret) {
	kdc_log(context, config, 0, "Decode of MS-UPN-SAN failed");
	goto out;
    }

    kdc_log(context, config, 0, "found MS UPN SAN: %s", upn);

    ret = krb5_parse_name(context, upn, &principal);
    free_MS_UPN_SAN(&upn);
    if (ret) {
	kdc_log(context, config, 0, "Failed to parse principal in MS UPN SAN");
	goto out;
    }

    /*
     * This is very wrong, but will do for now, should really and a
     * plugin to the windc layer to very this ACL.
    */
    strupr(principal->realm);

    if (krb5_principal_compare(context, principal, match) == TRUE)
	found = 1;

out:
    if (principal)
	krb5_free_principal(context, principal);
    hx509_free_octet_string_list(&list);
    if (ret)
	return ret;

    if (!found)
	return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;

    return 0;
}