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

📄 kerberos5.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1997-2007 Kungliga Tekniska H鰃skolan * (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 "kdc_locl.h"RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $");#define MAX_TIME ((time_t)((1U << 31) - 1))void_kdc_fix_time(time_t **t){    if(*t == NULL){	ALLOC(*t);	**t = MAX_TIME;    }    if(**t == 0) **t = MAX_TIME; /* fix for old clients */}static intrealloc_method_data(METHOD_DATA *md){    PA_DATA *pa;    pa = realloc(md->val, (md->len + 1) * sizeof(*md->val));    if(pa == NULL)	return ENOMEM;    md->val = pa;    md->len++;    return 0;}static voidset_salt_padata (METHOD_DATA *md, Salt *salt){    if (salt) {	realloc_method_data(md);	md->val[md->len - 1].padata_type = salt->type;	der_copy_octet_string(&salt->salt,			      &md->val[md->len - 1].padata_value);    }}const PA_DATA*_kdc_find_padata(const KDC_REQ *req, int *start, int type){    if (req->padata == NULL)	return NULL;    while(*start < req->padata->len){	(*start)++;	if(req->padata->val[*start - 1].padata_type == type)	    return &req->padata->val[*start - 1];    }    return NULL;}/* * Detect if `key' is the using the the precomputed `default_salt'. */static krb5_booleanis_default_salt_p(const krb5_salt *default_salt, const Key *key){    if (key->salt == NULL)	return TRUE;    if (default_salt->salttype != key->salt->type)	return FALSE;    if (krb5_data_cmp(&default_salt->saltvalue, &key->salt->salt))	return FALSE;    return TRUE;}/* * return the first appropriate key of `princ' in `ret_key'.  Look for * all the etypes in (`etypes', `len'), stopping as soon as we find * one, but preferring one that has default salt */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)	    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;}krb5_error_code_kdc_make_anonymous_principalname (PrincipalName *pn){    pn->name_type = KRB5_NT_PRINCIPAL;    pn->name_string.len = 1;    pn->name_string.val = malloc(sizeof(*pn->name_string.val));    if (pn->name_string.val == NULL)	return ENOMEM;    pn->name_string.val[0] = strdup("anonymous");    if (pn->name_string.val[0] == NULL) {	free(pn->name_string.val);	pn->name_string.val = NULL;	return ENOMEM;    }    return 0;}void_kdc_log_timestamp(krb5_context context, 		   krb5_kdc_configuration *config,		   const char *type,		   KerberosTime authtime, KerberosTime *starttime, 		   KerberosTime endtime, KerberosTime *renew_till){    char authtime_str[100], starttime_str[100], 	endtime_str[100], renewtime_str[100];        krb5_format_time(context, authtime, 		     authtime_str, sizeof(authtime_str), TRUE);     if (starttime)	krb5_format_time(context, *starttime, 			 starttime_str, sizeof(starttime_str), TRUE);     else	strlcpy(starttime_str, "unset", sizeof(starttime_str));    krb5_format_time(context, endtime, 		     endtime_str, sizeof(endtime_str), TRUE);     if (renew_till)	krb5_format_time(context, *renew_till, 			 renewtime_str, sizeof(renewtime_str), TRUE);     else	strlcpy(renewtime_str, "unset", sizeof(renewtime_str));        kdc_log(context, config, 5,	    "%s authtime: %s starttime: %s endtime: %s renew till: %s",	    type, authtime_str, starttime_str, endtime_str, renewtime_str);}static voidlog_patypes(krb5_context context, 	    krb5_kdc_configuration *config,	    METHOD_DATA *padata){    struct rk_strpool *p = NULL;    char *str;    int i;	        for (i = 0; i < padata->len; i++) {	switch(padata->val[i].padata_type) {	case KRB5_PADATA_PK_AS_REQ:	    p = rk_strpoolprintf(p, "PK-INIT(ietf)");	    break;	case KRB5_PADATA_PK_AS_REQ_WIN:	    p = rk_strpoolprintf(p, "PK-INIT(win2k)");	    break;	case KRB5_PADATA_PA_PK_OCSP_RESPONSE:	    p = rk_strpoolprintf(p, "OCSP");	    break;	case KRB5_PADATA_ENC_TIMESTAMP:	    p = rk_strpoolprintf(p, "encrypted-timestamp");	    break;	default:	    p = rk_strpoolprintf(p, "%d", padata->val[i].padata_type);	    break;	}	if (p && i + 1 < padata->len)	    p = rk_strpoolprintf(p, ", ");	if (p == NULL) {	    kdc_log(context, config, 0, "out of memory");	    return;	}    }    if (p == NULL)	p = rk_strpoolprintf(p, "none");	    str = rk_strpoolcollect(p);    kdc_log(context, config, 0, "Client sent patypes: %s", str);    free(str);}/* * */krb5_error_code_kdc_encode_reply(krb5_context context,		  krb5_kdc_configuration *config,		  KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek, 		  krb5_enctype etype, 		  int skvno, const EncryptionKey *skey,		  int ckvno, const EncryptionKey *ckey,		  const char **e_text,		  krb5_data *reply){    unsigned char *buf;    size_t buf_size;    size_t len;    krb5_error_code ret;    krb5_crypto crypto;    ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);    if(ret) {	kdc_log(context, config, 0, "Failed to encode ticket: %s", 		krb5_get_err_text(context, ret));	return ret;    }    if(buf_size != len) {	free(buf);	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");	*e_text = "KDC internal error";	return KRB5KRB_ERR_GENERIC;    }    ret = krb5_crypto_init(context, skey, etype, &crypto);    if (ret) {	free(buf);	kdc_log(context, config, 0, "krb5_crypto_init failed: %s",		krb5_get_err_text(context, ret));	return ret;    }    ret = krb5_encrypt_EncryptedData(context, 				     crypto,				     KRB5_KU_TICKET,				     buf,				     len,				     skvno,				     &rep->ticket.enc_part);    free(buf);    krb5_crypto_destroy(context, crypto);    if(ret) {	kdc_log(context, config, 0, "Failed to encrypt data: %s",		krb5_get_err_text(context, ret));	return ret;    }        if(rep->msg_type == krb_as_rep && !config->encode_as_rep_as_tgs_rep)	ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);    else	ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);    if(ret) {	kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", 		krb5_get_err_text(context, ret));	return ret;    }    if(buf_size != len) {	free(buf);	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");	*e_text = "KDC internal error";	return KRB5KRB_ERR_GENERIC;    }    ret = krb5_crypto_init(context, ckey, 0, &crypto);    if (ret) {	free(buf);	kdc_log(context, config, 0, "krb5_crypto_init failed: %s",		krb5_get_err_text(context, ret));	return ret;    }    if(rep->msg_type == krb_as_rep) {	krb5_encrypt_EncryptedData(context,				   crypto,				   KRB5_KU_AS_REP_ENC_PART,				   buf,				   len,				   ckvno,				   &rep->enc_part);	free(buf);	ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);    } else {	krb5_encrypt_EncryptedData(context,				   crypto,				   KRB5_KU_TGS_REP_ENC_PART_SESSION,				   buf,				   len,				   ckvno,				   &rep->enc_part);	free(buf);	ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);    }    krb5_crypto_destroy(context, crypto);    if(ret) {	kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", 		krb5_get_err_text(context, ret));	return ret;    }    if(buf_size != len) {	free(buf);	kdc_log(context, config, 0, "Internal error in ASN.1 encoder");	*e_text = "KDC internal error";	return KRB5KRB_ERR_GENERIC;    }    reply->data = buf;    reply->length = buf_size;    return 0;}/* * Return 1 if the client have only older enctypes, this is for * determining if the server should send ETYPE_INFO2 or not. */static intolder_enctype(krb5_enctype enctype){    switch (enctype) {    case ETYPE_DES_CBC_CRC:    case ETYPE_DES_CBC_MD4:    case ETYPE_DES_CBC_MD5:    case ETYPE_DES3_CBC_SHA1:    case ETYPE_ARCFOUR_HMAC_MD5:    case ETYPE_ARCFOUR_HMAC_MD5_56:    /*      * The following three is "old" windows enctypes and is needed for     * windows 2000 hosts.     */    case ETYPE_ARCFOUR_MD4:    case ETYPE_ARCFOUR_HMAC_OLD:    case ETYPE_ARCFOUR_HMAC_OLD_EXP:	return 1;    default:	return 0;    }}static intonly_older_enctype_p(const KDC_REQ *req){    int i;    for(i = 0; i < req->req_body.etype.len; i++) {	if (!older_enctype(req->req_body.etype.val[i]))	    return 0;    }    return 1;}/* * */static krb5_error_codemake_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key){    ent->etype = key->key.keytype;    if(key->salt){#if 0	ALLOC(ent->salttype);	if(key->salt->type == hdb_pw_salt)	    *ent->salttype = 0; /* or 1? or NULL? */	else if(key->salt->type == hdb_afs3_salt)	    *ent->salttype = 2;	else {	    kdc_log(context, config, 0, "unknown salt-type: %d", 		    key->salt->type);	    return KRB5KRB_ERR_GENERIC;	}	/* according to `the specs', we can't send a salt if	   we have AFS3 salted key, but that requires that you	   *know* what cell you are using (e.g by assuming	   that the cell is the same as the realm in lower	   case) */#elif 0	ALLOC(ent->salttype);	*ent->salttype = key->salt->type;#else	/* 	 * We shouldn't sent salttype since it is incompatible with the	 * specification and it breaks windows clients.  The afs	 * salting problem is solved by using KRB5-PADATA-AFS3-SALT	 * implemented in Heimdal 0.7 and later.	 */	ent->salttype = NULL;#endif	krb5_copy_data(context, &key->salt->salt,		       &ent->salt);    } else {	/* we return no salt type at all, as that should indicate	 * the default salt type and make everybody happy.  some	 * systems (like w2k) dislike being told the salt type	 * here. */	ent->salttype = NULL;	ent->salt = NULL;    }    return 0;}static krb5_error_codeget_pa_etype_info(krb5_context context, 		  krb5_kdc_configuration *config,		  METHOD_DATA *md, hdb_entry *client, 		  ENCTYPE *etypes, unsigned int etypes_len){    krb5_error_code ret = 0;    int i, j;

⌨️ 快捷键说明

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