⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkinit.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	ret = pk_mk_pa_reply_enckey(context,				    config,				    client_params,				    req,				    req_buffer,				    &client_params->reply_key,				    &info);	if (ret) {	    free_PA_PK_AS_REP_Win2k(&rep);	    goto out;	}	ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data, 			   rep.u.encKeyPack.length, &info, &size, 			   ret);	free_ContentInfo(&info);	if (ret) {	    krb5_set_error_string(context, "encoding of Key ContentInfo "				  "failed %d", ret);	    free_PA_PK_AS_REP_Win2k(&rep);	    goto out;	}	if (rep.u.encKeyPack.length != size)	    krb5_abortx(context, "Internal ASN.1 encoder error");	ASN1_MALLOC_ENCODE(PA_PK_AS_REP_Win2k, buf, len, &rep, &size, ret);	free_PA_PK_AS_REP_Win2k(&rep);	if (ret) {	    krb5_set_error_string(context, 				  "encode PA-PK-AS-REP-Win2k failed %d", ret);	    goto out;	}	if (len != size)	    krb5_abortx(context, "Internal ASN.1 encoder error");    } else	krb5_abortx(context, "PK-INIT internal error");    ret = krb5_padata_add(context, md, pa_type, buf, len);    if (ret) {	krb5_set_error_string(context, "failed adding PA-PK-AS-REP %d", ret);	free(buf);	goto out;    }    if (config->pkinit_kdc_ocsp_file) {	if (ocsp.expire == 0 && ocsp.next_update > kdc_time) {	    struct stat sb;	    int fd;	    krb5_data_free(&ocsp.data);	    ocsp.expire = 0;	    ocsp.next_update = kdc_time + 60 * 5;	    fd = open(config->pkinit_kdc_ocsp_file, O_RDONLY);	    if (fd < 0) {		kdc_log(context, config, 0, 			"PK-INIT failed to open ocsp data file %d", errno);		goto out_ocsp;	    }	    ret = fstat(fd, &sb);	    if (ret) {		ret = errno;		close(fd);		kdc_log(context, config, 0, 			"PK-INIT failed to stat ocsp data %d", ret);		goto out_ocsp;	    }	    	    ret = krb5_data_alloc(&ocsp.data, sb.st_size);	    if (ret) {		close(fd);		kdc_log(context, config, 0, 			"PK-INIT failed to stat ocsp data %d", ret);		goto out_ocsp;	    }	    ocsp.data.length = sb.st_size;	    ret = read(fd, ocsp.data.data, sb.st_size);	    close(fd);	    if (ret != sb.st_size) {		kdc_log(context, config, 0, 			"PK-INIT failed to read ocsp data %d", errno);		goto out_ocsp;	    }	    ret = hx509_ocsp_verify(kdc_identity->hx509ctx,				    kdc_time,				    kdc_cert,				    0,				    ocsp.data.data, ocsp.data.length,				    &ocsp.expire);	    if (ret) {		kdc_log(context, config, 0, 			"PK-INIT failed to verify ocsp data %d", ret);		krb5_data_free(&ocsp.data);		ocsp.expire = 0;	    } else if (ocsp.expire > 180) {		ocsp.expire -= 180; /* refetch the ocsp before it expire */		ocsp.next_update = ocsp.expire;	    } else {		ocsp.next_update = kdc_time;	    }	out_ocsp:	    ret = 0;	}	if (ocsp.expire != 0 && ocsp.expire > kdc_time) {	    ret = krb5_padata_add(context, md, 				  KRB5_PADATA_PA_PK_OCSP_RESPONSE,				  ocsp.data.data, ocsp.data.length);	    if (ret) {		krb5_set_error_string(context, 				      "Failed adding OCSP response %d", ret);		goto out;	    }	}    }out:    if (kdc_cert)	hx509_cert_free(kdc_cert);    if (ret == 0)	*reply_key = &client_params->reply_key;    return ret;}static intmatch_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, i, found = 0;    memset(&list, 0 , sizeof(list));    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,						   client_cert,						   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) {	    kdc_log(context, config, 0,		    "Decoding kerberos name in certificate failed: %s",		    krb5_get_err_text(context, ret));	    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;	}	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;}static intmatch_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;}krb5_error_code_kdc_pk_check_client(krb5_context context,		     krb5_kdc_configuration *config,		     const hdb_entry_ex *client,		     pk_client_params *client_params,		     char **subject_name){    const HDB_Ext_PKINIT_acl *acl;    krb5_error_code ret;    hx509_name name;    int i;    ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,				      client_params->cert,				      &name);    if (ret)	return ret;    ret = hx509_name_to_string(name, subject_name);    hx509_name_free(&name);    if (ret)	return ret;    kdc_log(context, config, 0,	    "Trying to authorize PK-INIT subject DN %s", 	    *subject_name);    if (config->pkinit_princ_in_cert) {	ret = match_rfc_san(context, config,			    kdc_identity->hx509ctx,			    client_params->cert,			    client->entry.principal);	if (ret == 0) {	    kdc_log(context, config, 5,		    "Found matching PK-INIT SAN in certificate");	    return 0;	}	ret = match_ms_upn_san(context, config,			       kdc_identity->hx509ctx,			       client_params->cert,			       client->entry.principal);	if (ret == 0) {	    kdc_log(context, config, 5,		    "Found matching MS UPN SAN in certificate");	    return 0;	}    }    ret = hdb_entry_get_pkinit_acl(&client->entry, &acl);    if (ret == 0 && acl != NULL) {	/*	 * Cheat here and compare the generated name with the string	 * and not the reverse.	 */	for (i = 0; i < acl->len; i++) {	    if (strcmp(*subject_name, acl->val[0].subject) != 0)		continue;	    /* Don't support isser and anchor checking right now */	    if (acl->val[0].issuer)		continue;	    if (acl->val[0].anchor)		continue;	    kdc_log(context, config, 5,		    "Found matching PK-INIT database ACL");	    return 0;	}    }    for (i = 0; i < principal_mappings.len; i++) {	krb5_boolean b;	b = krb5_principal_compare(context,				   client->entry.principal,				   principal_mappings.val[i].principal);	if (b == FALSE)	    continue;	if (strcmp(principal_mappings.val[i].subject, *subject_name) != 0)	    continue;	kdc_log(context, config, 5,		"Found matching PK-INIT FILE ACL");	return 0;    }    krb5_set_error_string(context,			  "PKINIT no matching principals for %s",			  *subject_name);    kdc_log(context, config, 5,	    "PKINIT no matching principals for %s",	    *subject_name);    free(*subject_name);    *subject_name = NULL;    return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;}static krb5_error_codeadd_principal_mapping(krb5_context context, 		      const char *principal_name,		      const char * subject){   struct pk_allowed_princ *tmp;   krb5_principal principal;   krb5_error_code ret;   tmp = realloc(principal_mappings.val,	         (principal_mappings.len + 1) * sizeof(*tmp));   if (tmp == NULL)       return ENOMEM;   principal_mappings.val = tmp;   ret = krb5_parse_name(context, principal_name, &principal);   if (ret)       return ret;   principal_mappings.val[principal_mappings.len].principal = principal;   principal_mappings.val[principal_mappings.len].subject = strdup(subject);   if (principal_mappings.val[principal_mappings.len].subject == NULL) {       krb5_free_principal(context, principal);       return ENOMEM;   }   principal_mappings.len++;   return 0;}krb5_error_code_kdc_add_inital_verified_cas(krb5_context context,			     krb5_kdc_configuration *config,			     pk_client_params *params,			     EncTicketPart *tkt){    AD_INITIAL_VERIFIED_CAS cas;    krb5_error_code ret;    krb5_data data;    size_t size;    memset(&cas, 0, sizeof(cas));        /* XXX add CAs to cas here */    ASN1_MALLOC_ENCODE(AD_INITIAL_VERIFIED_CAS, data.data, data.length,		       &cas, &size, ret);    if (ret)	return ret;    if (data.length != size)	krb5_abortx(context, "internal asn.1 encoder error");    ret = _kdc_tkt_add_if_relevant_ad(context, tkt, 				      KRB5_AUTHDATA_INITIAL_VERIFIED_CAS,				      &data);    krb5_data_free(&data);    return ret;}/* * */static voidload_mappings(krb5_context context, const char *fn){    krb5_error_code ret;    char buf[1024];    unsigned long lineno = 0;    FILE *f;    f = fopen(fn, "r");    if (f == NULL)	return;    while (fgets(buf, sizeof(buf), f) != NULL) {	char *subject_name, *p;    	buf[strcspn(buf, "\n")] = '\0';	lineno++;	p = buf + strspn(buf, " \t");	if (*p == '#' || *p == '\0')	    continue;	subject_name = strchr(p, ':');	if (subject_name == NULL) {	    krb5_warnx(context, "pkinit mapping file line %lu "		       "missing \":\" :%s",		       lineno, buf);	    continue;	}	*subject_name++ = '\0';	ret = add_principal_mapping(context, p, subject_name);	if (ret) {	    krb5_warn(context, ret, "failed to add line %lu \":\" :%s\n",		      lineno, buf);	    continue;	}    }     fclose(f);}		   /* * */krb5_error_code_kdc_pk_initialize(krb5_context context,		   krb5_kdc_configuration *config,		   const char *user_id,		   const char *anchors,		   char **pool,		   char **revoke_list){    const char *file;    char *fn = NULL;    krb5_error_code ret;    file = krb5_config_get_string(context, NULL,				  "libdefaults", "moduli", NULL);    ret = _krb5_parse_moduli(context, file, &moduli);    if (ret)	krb5_err(context, 1, ret, "PKINIT: failed to load modidi file");    principal_mappings.len = 0;    principal_mappings.val = NULL;    ret = _krb5_pk_load_id(context,			   &kdc_identity,			   user_id,			   anchors,			   pool,			   revoke_list,			   NULL,			   NULL,			   NULL);    if (ret) {	krb5_warn(context, ret, "PKINIT: ");	config->enable_pkinit = 0;	return ret;    }    {	hx509_query *q;	hx509_cert cert;		ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);	if (ret) {	    krb5_warnx(context, "PKINIT: out of memory");	    return ENOMEM;	}		hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);	hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);		ret = hx509_certs_find(kdc_identity->hx509ctx,			       kdc_identity->certs,			       q,			       &cert);	hx509_query_free(kdc_identity->hx509ctx, q);	if (ret == 0) {	    if (hx509_cert_check_eku(kdc_identity->hx509ctx, cert,				     oid_id_pkkdcekuoid(), 0))		krb5_warnx(context, "WARNING Found KDC certificate "			   "is missing the PK-INIT KDC EKU, this is bad for "			   "interoperability.");	    hx509_cert_free(cert);	} else	    krb5_warnx(context, "PKINIT: failed to find a signing "		       "certifiate with a public key");    }    ret = krb5_config_get_bool_default(context, 				       NULL,				       FALSE,				       "kdc",				       "pkinit_allow_proxy_certificate",				       NULL);    _krb5_pk_allow_proxy_certificate(kdc_identity, ret);    file = krb5_config_get_string(context, 				  NULL,				  "kdc",				  "pkinit_mappings_file",				  NULL);    if (file == NULL) {	asprintf(&fn, "%s/pki-mapping", hdb_db_dir(context));	file = fn;    }    load_mappings(context, file);    if (fn)	free(fn);    return 0;}#endif /* PKINIT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -