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

📄 kerberos5.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
    if(only_netbios)	return config->allow_null_ticket_addresses;    ret = krb5_sockaddr2address (context, from, &addr);    if(ret)	return FALSE;    result = krb5_address_search(context, &addr, addresses);    krb5_free_address (context, &addr);    return result;}/* * */static krb5_booleansend_pac_p(krb5_context context, KDC_REQ *req){    krb5_error_code ret;    PA_PAC_REQUEST pacreq;    const PA_DATA *pa;    int i = 0;        pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);    if (pa == NULL)	return TRUE;    ret = decode_PA_PAC_REQUEST(pa->padata_value.data,				pa->padata_value.length,				&pacreq,				NULL);    if (ret)	return TRUE;    i = pacreq.include_pac;    free_PA_PAC_REQUEST(&pacreq);    if (i == 0)	return FALSE;    return TRUE;}/* * */krb5_error_code_kdc_as_rep(krb5_context context, 	    krb5_kdc_configuration *config,	    KDC_REQ *req, 	    const krb5_data *req_buffer, 	    krb5_data *reply,	    const char *from,	    struct sockaddr *from_addr,	    int datagram_reply){    KDC_REQ_BODY *b = &req->req_body;    AS_REP rep;    KDCOptions f = b->kdc_options;    hdb_entry_ex *client = NULL, *server = NULL;    krb5_enctype cetype, setype, sessionetype;    krb5_data e_data;    EncTicketPart et;    EncKDCRepPart ek;    krb5_principal client_princ = NULL, server_princ = NULL;    char *client_name = NULL, *server_name = NULL;    krb5_error_code ret = 0;    const char *e_text = NULL;    krb5_crypto crypto;    Key *ckey, *skey;    EncryptionKey *reply_key;    int flags = 0;#ifdef PKINIT    pk_client_params *pkp = NULL;#endif    memset(&rep, 0, sizeof(rep));    krb5_data_zero(&e_data);    if (f.canonicalize)	flags |= HDB_F_CANON;    if(b->sname == NULL){	ret = KRB5KRB_ERR_GENERIC;	e_text = "No server in request";    } else{	ret = _krb5_principalname2krb5_principal (context,						  &server_princ,						  *(b->sname),						  b->realm);	if (ret == 0)	    ret = krb5_unparse_name(context, server_princ, &server_name);    }    if (ret) {	kdc_log(context, config, 0, 		"AS-REQ malformed server name from %s", from);	goto out;    }        if(b->cname == NULL){	ret = KRB5KRB_ERR_GENERIC;	e_text = "No client in request";    } else {	if (b->cname->name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {	    if (b->cname->name_string.len != 1) {		kdc_log(context, config, 0,			"AS-REQ malformed canon request from %s, "			"enterprise name with %d name components", 			from, b->cname->name_string.len);		ret = KRB5_PARSE_MALFORMED;		goto out;	    }	    ret = krb5_parse_name(context, b->cname->name_string.val[0],				  &client_princ);	    if (ret)		goto out;	} else {	    ret = _krb5_principalname2krb5_principal (context,						      &client_princ,						      *(b->cname),						      b->realm);	    if (ret)		goto out;	}	ret = krb5_unparse_name(context, client_princ, &client_name);    }    if (ret) {	kdc_log(context, config, 0,		"AS-REQ malformed client name from %s", from);	goto out;    }    kdc_log(context, config, 0, "AS-REQ %s from %s for %s", 	    client_name, from, server_name);    ret = _kdc_db_fetch(context, config, client_princ, 			HDB_F_GET_CLIENT | flags, NULL, &client);    if(ret){	kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,		krb5_get_err_text(context, ret));	ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;	goto out;    }    ret = _kdc_db_fetch(context, config, server_princ,			HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,			NULL, &server);    if(ret){	kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name,		krb5_get_err_text(context, ret));	ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;	goto out;    }    ret = _kdc_windc_client_access(context, client, req, &e_data);    if(ret)	goto out;    ret = _kdc_check_flags(context, config, 			   client, client_name,			   server, server_name,			   TRUE);    if(ret)	goto out;    memset(&et, 0, sizeof(et));    memset(&ek, 0, sizeof(ek));    if(req->padata){	int i;	const PA_DATA *pa;	int found_pa = 0;	log_patypes(context, config, req->padata);#ifdef PKINIT	kdc_log(context, config, 5, 		"Looking for PKINIT pa-data -- %s", client_name);	e_text = "No PKINIT PA found";	i = 0;	if ((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))	    ;	if (pa == NULL) {	    i = 0;	    if((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))		;	}	if (pa) {	    char *client_cert = NULL;	    ret = _kdc_pk_rd_padata(context, config, req, pa, &pkp);	    if (ret) {		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;		kdc_log(context, config, 5, 			"Failed to decode PKINIT PA-DATA -- %s", 			client_name);		goto ts_enc;	    }	    if (ret == 0 && pkp == NULL)		goto ts_enc;	    ret = _kdc_pk_check_client(context,				       config,				       client,				       pkp,				       &client_cert);	    if (ret) {		e_text = "PKINIT certificate not allowed to "		    "impersonate principal";		_kdc_pk_free_client_param(context, pkp);		kdc_log(context, config, 0, "%s", e_text);		pkp = NULL;		goto out;	    }	    found_pa = 1;	    et.flags.pre_authent = 1;	    kdc_log(context, config, 0,		    "PKINIT pre-authentication succeeded -- %s using %s", 		    client_name, client_cert);	    free(client_cert);	    if (pkp)		goto preauth_done;	}    ts_enc:#endif	kdc_log(context, config, 5, "Looking for ENC-TS pa-data -- %s", 		client_name);	i = 0;	e_text = "No ENC-TS found";	while((pa = _kdc_find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){	    krb5_data ts_data;	    PA_ENC_TS_ENC p;	    size_t len;	    EncryptedData enc_data;	    Key *pa_key;	    char *str;	    	    found_pa = 1;	    	    ret = decode_EncryptedData(pa->padata_value.data,				       pa->padata_value.length,				       &enc_data,				       &len);	    if (ret) {		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;		kdc_log(context, config, 5, "Failed to decode PA-DATA -- %s", 			client_name);		goto out;	    }	    	    ret = hdb_enctype2key(context, &client->entry, 				  enc_data.etype, &pa_key);	    if(ret){		char *estr;		e_text = "No key matches pa-data";		ret = KRB5KDC_ERR_ETYPE_NOSUPP;		if(krb5_enctype_to_string(context, enc_data.etype, &estr))		    estr = NULL;		if(estr == NULL)		    kdc_log(context, config, 5, 			    "No client key matching pa-data (%d) -- %s", 			    enc_data.etype, client_name);		else		    kdc_log(context, config, 5,			    "No client key matching pa-data (%s) -- %s", 			    estr, client_name);		free(estr);		    		free_EncryptedData(&enc_data);		continue;	    }	try_next_key:	    ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);	    if (ret) {		kdc_log(context, config, 0, "krb5_crypto_init failed: %s",			krb5_get_err_text(context, ret));		free_EncryptedData(&enc_data);		continue;	    }	    ret = krb5_decrypt_EncryptedData (context,					      crypto,					      KRB5_KU_PA_ENC_TIMESTAMP,					      &enc_data,					      &ts_data);	    krb5_crypto_destroy(context, crypto);	    if(ret){		krb5_error_code ret2;		ret2 = krb5_enctype_to_string(context, 					      pa_key->key.keytype, &str);		if (ret2)		    str = NULL;		kdc_log(context, config, 5, 			"Failed to decrypt PA-DATA -- %s "			"(enctype %s) error %s",			client_name,			str ? str : "unknown enctype", 			krb5_get_err_text(context, ret));		free(str);		if(hdb_next_enctype2key(context, &client->entry, 					enc_data.etype, &pa_key) == 0)		    goto try_next_key;		e_text = "Failed to decrypt PA-DATA";		free_EncryptedData(&enc_data);		ret = KRB5KDC_ERR_PREAUTH_FAILED;		continue;	    }	    free_EncryptedData(&enc_data);	    ret = decode_PA_ENC_TS_ENC(ts_data.data,				       ts_data.length,				       &p,				       &len);	    krb5_data_free(&ts_data);	    if(ret){		e_text = "Failed to decode PA-ENC-TS-ENC";		ret = KRB5KDC_ERR_PREAUTH_FAILED;		kdc_log(context, config, 			5, "Failed to decode PA-ENC-TS_ENC -- %s",			client_name);		continue;	    }	    free_PA_ENC_TS_ENC(&p);	    if (abs(kdc_time - p.patimestamp) > context->max_skew) {		char client_time[100];				krb5_format_time(context, p.patimestamp, 				 client_time, sizeof(client_time), TRUE);  		ret = KRB5KRB_AP_ERR_SKEW; 		kdc_log(context, config, 0,			"Too large time skew, "			"client time %s is out by %u > %u seconds -- %s", 			client_time, 			(unsigned)abs(kdc_time - p.patimestamp), 			context->max_skew,			client_name);#if 1		/* This code is from samba, needs testing */		/* 		 * the following is needed to make windows clients		 * to retry using the timestamp in the error message		 *		 * this is maybe a bug in windows to not trying when e_text		 * is present...		 */		e_text = NULL;#else		e_text = "Too large time skew";#endif		goto out;	    }	    et.flags.pre_authent = 1;	    ret = krb5_enctype_to_string(context,pa_key->key.keytype, &str);	    if (ret)		str = NULL;	    kdc_log(context, config, 2,		    "ENC-TS Pre-authentication succeeded -- %s using %s", 		    client_name, str ? str : "unknown enctype");	    free(str);	    break;	}#ifdef PKINIT    preauth_done:#endif	if(found_pa == 0 && config->require_preauth)	    goto use_pa;	/* We come here if we found a pa-enc-timestamp, but if there           was some problem with it, other than too large skew */	if(found_pa && et.flags.pre_authent == 0){	    kdc_log(context, config, 0, "%s -- %s", e_text, client_name);	    e_text = NULL;	    goto out;	}    }else if (config->require_preauth	      || client->entry.flags.require_preauth	      || server->entry.flags.require_preauth) {	METHOD_DATA method_data;	PA_DATA *pa;	unsigned char *buf;	size_t len;    use_pa: 	method_data.len = 0;	method_data.val = NULL;	ret = realloc_method_data(&method_data);	pa = &method_data.val[method_data.len-1];	pa->padata_type		= KRB5_PADATA_ENC_TIMESTAMP;	pa->padata_value.length	= 0;	pa->padata_value.data	= NULL;#ifdef PKINIT	ret = realloc_method_data(&method_data);	pa = &method_data.val[method_data.len-1];	pa->padata_type		= KRB5_PADATA_PK_AS_REQ;	pa->padata_value.length	= 0;	pa->padata_value.data	= NULL;	ret = realloc_method_data(&method_data);	pa = &method_data.val[method_data.len-1];	pa->padata_type		= KRB5_PADATA_PK_AS_REQ_WIN;	pa->padata_value.length	= 0;	pa->padata_value.data	= NULL;#endif	/* 	 * RFC4120 requires: 	 * - If the client only knows about old enctypes, then send	 *   both info replies (we send 'info' first in the list).	 * - If the client is 'modern', because it knows about 'new'	 *   enctype types, then only send the 'info2' reply.	 */	/* XXX check ret */	if (only_older_enctype_p(req))	    ret = get_pa_etype_info(context, config,				    &method_data, &client->entry, 				    b->etype.val, b->etype.len); 	/* XXX check ret */	ret = get_pa_etype_info2(context, config, &method_data, 				 &client->entry, b->etype.val, b->etype.len);		ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);	free_METHOD_DATA(&method_data);	e_data.data   = buf;	e_data.length = len;	e_text ="Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",	ret = KRB5KDC_ERR_PREAUTH_REQUIRED;	kdc_log(context, config, 0,		"No preauth found, returning PREAUTH-REQUIRED -- %s",		client_name);	goto out;    }        /*     * Find the client key (for preauth ENC-TS verification and reply

⌨️ 快捷键说明

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