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

📄 krb5tgs.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: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $");/* * return the realm of a krbtgt-ticket or NULL */static Realm get_krbtgt_realm(const PrincipalName *p){    if(p->name_string.len == 2       && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)	return p->name_string.val[1];    else	return NULL;}/* * The KDC might add a signed path to the ticket authorization data * field. This is to avoid server impersonating clients and the * request constrained delegation. * * This is done by storing a KRB5_AUTHDATA_IF_RELEVANT with a single * entry of type KRB5SignedPath. */static krb5_error_codefind_KRB5SignedPath(krb5_context context,		    const AuthorizationData *ad,		    krb5_data *data){    AuthorizationData child;    krb5_error_code ret;    int pos;	    if (ad == NULL || ad->len == 0)	return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;    pos = ad->len - 1;    if (ad->val[pos].ad_type != KRB5_AUTHDATA_IF_RELEVANT)	return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;    ret = decode_AuthorizationData(ad->val[pos].ad_data.data,				   ad->val[pos].ad_data.length,				   &child,				   NULL);    if (ret) {	krb5_set_error_string(context, "Failed to decode "			      "IF_RELEVANT with %d", ret);	return ret;    }    if (child.len != 1) {	free_AuthorizationData(&child);	return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;    }    if (child.val[0].ad_type != KRB5_AUTHDATA_SIGNTICKET) {	free_AuthorizationData(&child);	return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;    }    if (data)	ret = der_copy_octet_string(&child.val[0].ad_data, data);    free_AuthorizationData(&child);    return ret;}krb5_error_code_kdc_add_KRB5SignedPath(krb5_context context,			krb5_kdc_configuration *config,			hdb_entry_ex *krbtgt,			krb5_enctype enctype,			krb5_const_principal server,			KRB5SignedPathPrincipals *principals,			EncTicketPart *tkt){    krb5_error_code ret;    KRB5SignedPath sp;    krb5_data data;    krb5_crypto crypto = NULL;    size_t size;    if (server && principals) {	ret = add_KRB5SignedPathPrincipals(principals, server);	if (ret)	    return ret;    }    {	KRB5SignedPathData spd;		spd.encticket = *tkt;	spd.delegated = principals;		ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,			   &spd, &size, ret);	if (ret)	    return ret;	if (data.length != size)	    krb5_abortx(context, "internal asn.1 encoder error");    }    {	Key *key;	ret = hdb_enctype2key(context, &krbtgt->entry, enctype, &key);	if (ret == 0)	    ret = krb5_crypto_init(context, &key->key, 0, &crypto);	if (ret) {	    free(data.data);	    return ret;	}    }    /*     * Fill in KRB5SignedPath     */    sp.etype = enctype;    sp.delegated = principals;    ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,			       data.data, data.length, &sp.cksum);    krb5_crypto_destroy(context, crypto);    free(data.data);    if (ret)	return ret;    ASN1_MALLOC_ENCODE(KRB5SignedPath, data.data, data.length, &sp, &size, ret);    free_Checksum(&sp.cksum);    if (ret)	return ret;    if (data.length != size)	krb5_abortx(context, "internal asn.1 encoder error");        /*     * Add IF-RELEVANT(KRB5SignedPath) to the last slot in     * authorization data field.     */    ret = _kdc_tkt_add_if_relevant_ad(context, tkt,				      KRB5_AUTHDATA_SIGNTICKET, &data);    krb5_data_free(&data);    return ret;}static krb5_error_codecheck_KRB5SignedPath(krb5_context context,		     krb5_kdc_configuration *config,		     hdb_entry_ex *krbtgt,		     EncTicketPart *tkt,		     KRB5SignedPathPrincipals **delegated,		     int require_signedpath){    krb5_error_code ret;    krb5_data data;    krb5_crypto crypto = NULL;    *delegated = NULL;    ret = find_KRB5SignedPath(context, tkt->authorization_data, &data);    if (ret == 0) {	KRB5SignedPathData spd;	KRB5SignedPath sp;	AuthorizationData *ad;	size_t size;	ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL);	krb5_data_free(&data);	if (ret)	    return ret;	spd.encticket = *tkt;	/* the KRB5SignedPath is the last entry */	ad = spd.encticket.authorization_data;	if (--ad->len == 0)	    spd.encticket.authorization_data = NULL;	spd.delegated = sp.delegated;	ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,			   &spd, &size, ret);	ad->len++;	spd.encticket.authorization_data = ad;	if (ret) {	    free_KRB5SignedPath(&sp);	    return ret;	}	if (data.length != size)	    krb5_abortx(context, "internal asn.1 encoder error");	{	    Key *key;	    ret = hdb_enctype2key(context, &krbtgt->entry, sp.etype, &key);	    if (ret == 0)		ret = krb5_crypto_init(context, &key->key, 0, &crypto);	    if (ret) {		free(data.data);		free_KRB5SignedPath(&sp);		return ret;	    }	}	ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 				   data.data, data.length, 				   &sp.cksum);	krb5_crypto_destroy(context, crypto);	free(data.data);	if (ret) {	    free_KRB5SignedPath(&sp);	    return ret;	}	if (sp.delegated) {	    *delegated = malloc(sizeof(*sp.delegated));	    if (*delegated == NULL) {		free_KRB5SignedPath(&sp);		return ENOMEM;	    }	    ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);	    if (ret) {		free_KRB5SignedPath(&sp);		free(*delegated);		*delegated = NULL;		return ret;	    }	}	free_KRB5SignedPath(&sp);	    } else {	if (require_signedpath)	    return KRB5KDC_ERR_BADOPTION;    }    return 0;}/* * */static krb5_error_codecheck_PAC(krb5_context context,	  krb5_kdc_configuration *config,	  const krb5_principal client_principal,	  hdb_entry_ex *client,	  hdb_entry_ex *server,	  const EncryptionKey *server_key,	  const EncryptionKey *krbtgt_key,	  EncTicketPart *tkt,	  krb5_data *rspac,	  int *require_signedpath){    AuthorizationData *ad = tkt->authorization_data;    unsigned i, j;    krb5_error_code ret;    if (ad == NULL || ad->len == 0)	return 0;    for (i = 0; i < ad->len; i++) {	AuthorizationData child;	if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT)	    continue;	ret = decode_AuthorizationData(ad->val[i].ad_data.data,				       ad->val[i].ad_data.length,				       &child,				       NULL);	if (ret) {	    krb5_set_error_string(context, "Failed to decode "				  "IF_RELEVANT with %d", ret);	    return ret;	}	for (j = 0; j < child.len; j++) {	    if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) {		krb5_pac pac;		/* Found PAC */		ret = krb5_pac_parse(context,				     child.val[j].ad_data.data,				     child.val[j].ad_data.length,				     &pac);		free_AuthorizationData(&child);		if (ret)		    return ret;		ret = krb5_pac_verify(context, pac, tkt->authtime, 				      client_principal,				      krbtgt_key, NULL);		if (ret) {		    krb5_pac_free(context, pac);		    return ret;		}		ret = _kdc_pac_verify(context, client_principal, 				      client, server, &pac);		if (ret) {		    krb5_pac_free(context, pac);		    return ret;		}		*require_signedpath = 0;		ret = _krb5_pac_sign(context, pac, tkt->authtime,				     client_principal,				     server_key, krbtgt_key, rspac);		krb5_pac_free(context, pac);		return ret;	    }	}	free_AuthorizationData(&child);    }    return 0;}/* * */static krb5_error_codecheck_tgs_flags(krb5_context context,        		krb5_kdc_configuration *config,		KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et){    KDCOptions f = b->kdc_options;	    if(f.validate){	if(!tgt->flags.invalid || tgt->starttime == NULL){	    kdc_log(context, config, 0,		    "Bad request to validate ticket");	    return KRB5KDC_ERR_BADOPTION;	}	if(*tgt->starttime > kdc_time){	    kdc_log(context, config, 0,		    "Early request to validate ticket");	    return KRB5KRB_AP_ERR_TKT_NYV;	}	/* XXX  tkt = tgt */	et->flags.invalid = 0;    }else if(tgt->flags.invalid){	kdc_log(context, config, 0, 		"Ticket-granting ticket has INVALID flag set");	return KRB5KRB_AP_ERR_TKT_INVALID;    }    if(f.forwardable){	if(!tgt->flags.forwardable){	    kdc_log(context, config, 0,		    "Bad request for forwardable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.forwardable = 1;    }    if(f.forwarded){	if(!tgt->flags.forwardable){	    kdc_log(context, config, 0,		    "Request to forward non-forwardable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.forwarded = 1;	et->caddr = b->addresses;    }    if(tgt->flags.forwarded)	et->flags.forwarded = 1;	    if(f.proxiable){	if(!tgt->flags.proxiable){	    kdc_log(context, config, 0,		    "Bad request for proxiable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.proxiable = 1;    }    if(f.proxy){	if(!tgt->flags.proxiable){	    kdc_log(context, config, 0,		    "Request to proxy non-proxiable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.proxy = 1;	et->caddr = b->addresses;    }    if(tgt->flags.proxy)	et->flags.proxy = 1;    if(f.allow_postdate){	if(!tgt->flags.may_postdate){	    kdc_log(context, config, 0,		    "Bad request for post-datable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.may_postdate = 1;    }    if(f.postdated){	if(!tgt->flags.may_postdate){	    kdc_log(context, config, 0,		    "Bad request for postdated ticket");	    return KRB5KDC_ERR_BADOPTION;	}	if(b->from)	    *et->starttime = *b->from;	et->flags.postdated = 1;	et->flags.invalid = 1;    }else if(b->from && *b->from > kdc_time + context->max_skew){	kdc_log(context, config, 0, "Ticket cannot be postdated");	return KRB5KDC_ERR_CANNOT_POSTDATE;    }    if(f.renewable){	if(!tgt->flags.renewable){	    kdc_log(context, config, 0,		    "Bad request for renewable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	et->flags.renewable = 1;	ALLOC(et->renew_till);	_kdc_fix_time(&b->rtime);	*et->renew_till = *b->rtime;    }    if(f.renew){	time_t old_life;	if(!tgt->flags.renewable || tgt->renew_till == NULL){	    kdc_log(context, config, 0,		    "Request to renew non-renewable ticket");	    return KRB5KDC_ERR_BADOPTION;	}	old_life = tgt->endtime;	if(tgt->starttime)	    old_life -= *tgt->starttime;	else	    old_life -= tgt->authtime;	et->endtime = *et->starttime + old_life;	if (et->renew_till != NULL)	    et->endtime = min(*et->renew_till, et->endtime);    }	        #if 0    /* checks for excess flags */

⌨️ 快捷键说明

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