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

📄 krb5tgs.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
    ret = krb5_crypto_init(context, key, 0, &crypto);    if (ret) {	free(buf);	kdc_log(context, config, 0, "krb5_crypto_init failed: %s",		krb5_get_err_text(context, ret));	goto out;    }    ret = krb5_verify_checksum(context,			       crypto,			       KRB5_KU_TGS_REQ_AUTH_CKSUM,			       buf, 			       len,			       auth->cksum);    free(buf);    krb5_crypto_destroy(context, crypto);    if(ret){	kdc_log(context, config, 0,		"Failed to verify authenticator checksum: %s", 		krb5_get_err_text(context, ret));    }out:    free_Authenticator(auth);    free(auth);    return ret;}/* * */static const char *find_rpath(krb5_context context, Realm crealm, Realm srealm){    const char *new_realm = krb5_config_get_string(context,						   NULL,						   "capaths", 						   crealm,						   srealm,						   NULL);    return new_realm;}	    static krb5_booleanneed_referral(krb5_context context, krb5_principal server, krb5_realm **realms){    if(server->name.name_type != KRB5_NT_SRV_INST ||       server->name.name_string.len != 2)	return FALSE;     return _krb5_get_host_realm_int(context, server->name.name_string.val[1],				    FALSE, realms) == 0;}static krb5_error_codetgs_parse_request(krb5_context context, 		  krb5_kdc_configuration *config,		  KDC_REQ_BODY *b,		  const PA_DATA *tgs_req,		  hdb_entry_ex **krbtgt,		  krb5_enctype *krbtgt_etype,		  krb5_ticket **ticket,		  const char **e_text,		  const char *from,		  const struct sockaddr *from_addr,		  time_t **csec,		  int **cusec,		  AuthorizationData **auth_data){    krb5_ap_req ap_req;    krb5_error_code ret;    krb5_principal princ;    krb5_auth_context ac = NULL;    krb5_flags ap_req_options;    krb5_flags verify_ap_req_flags;    krb5_crypto crypto;    Key *tkey;    *auth_data = NULL;    *csec  = NULL;    *cusec = NULL;    memset(&ap_req, 0, sizeof(ap_req));    ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);    if(ret){	kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", 		krb5_get_err_text(context, ret));	goto out;    }    if(!get_krbtgt_realm(&ap_req.ticket.sname)){	/* XXX check for ticket.sname == req.sname */	kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket");	ret = KRB5KDC_ERR_POLICY; /* ? */	goto out;    }        _krb5_principalname2krb5_principal(context,				       &princ,				       ap_req.ticket.sname,				       ap_req.ticket.realm);        ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt);    if(ret) {	char *p;	ret = krb5_unparse_name(context, princ, &p);	if (ret != 0)	    p = "<unparse_name failed>";	krb5_free_principal(context, princ);	kdc_log(context, config, 0,		"Ticket-granting ticket not found in database: %s: %s",		p, krb5_get_err_text(context, ret));	if (ret == 0)	    free(p);	ret = KRB5KRB_AP_ERR_NOT_US;	goto out;    }        if(ap_req.ticket.enc_part.kvno &&        *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){	char *p;	ret = krb5_unparse_name (context, princ, &p);	krb5_free_principal(context, princ);	if (ret != 0)	    p = "<unparse_name failed>";	kdc_log(context, config, 0,		"Ticket kvno = %d, DB kvno = %d (%s)", 		*ap_req.ticket.enc_part.kvno,		(*krbtgt)->entry.kvno,		p);	if (ret == 0)	    free (p);	ret = KRB5KRB_AP_ERR_BADKEYVER;	goto out;    }    *krbtgt_etype = ap_req.ticket.enc_part.etype;    ret = hdb_enctype2key(context, &(*krbtgt)->entry, 			  ap_req.ticket.enc_part.etype, &tkey);    if(ret){	char *str = NULL, *p = NULL;	krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);	krb5_unparse_name(context, princ, &p); 	kdc_log(context, config, 0,		"No server key with enctype %s found for %s",		str ? str : "<unknown enctype>",		p ? p : "<unparse_name failed>");	free(str);	free(p);	ret = KRB5KRB_AP_ERR_BADKEYVER;	goto out;    }        if (b->kdc_options.validate)	verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;    else	verify_ap_req_flags = 0;    ret = krb5_verify_ap_req2(context,			      &ac,			      &ap_req,			      princ,			      &tkey->key,			      verify_ap_req_flags,			      &ap_req_options,			      ticket,			      KRB5_KU_TGS_REQ_AUTH);			         krb5_free_principal(context, princ);    if(ret) {	kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", 		krb5_get_err_text(context, ret));	goto out;    }    {	krb5_authenticator auth;	ret = krb5_auth_con_getauthenticator(context, ac, &auth);	if (ret == 0) {	    *csec   = malloc(sizeof(**csec));	    if (*csec == NULL) {		krb5_free_authenticator(context, &auth);		kdc_log(context, config, 0, "malloc failed");		goto out;	    }	    **csec  = auth->ctime;	    *cusec  = malloc(sizeof(**cusec));	    if (*cusec == NULL) {		krb5_free_authenticator(context, &auth);		kdc_log(context, config, 0, "malloc failed");		goto out;	    }	    **cusec  = auth->cusec;	    krb5_free_authenticator(context, &auth);	}    }    ret = tgs_check_authenticator(context, config, 				  ac, b, e_text, &(*ticket)->ticket.key);    if (ret) {	krb5_auth_con_free(context, ac);	goto out;    }    if (b->enc_authorization_data) {	unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;	krb5_keyblock *subkey;	krb5_data ad;	ret = krb5_auth_con_getremotesubkey(context,					    ac,					    &subkey);	if(ret){	    krb5_auth_con_free(context, ac);	    kdc_log(context, config, 0, "Failed to get remote subkey: %s", 		    krb5_get_err_text(context, ret));	    goto out;	}	if(subkey == NULL){	    usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;	    ret = krb5_auth_con_getkey(context, ac, &subkey);	    if(ret) {		krb5_auth_con_free(context, ac);		kdc_log(context, config, 0, "Failed to get session key: %s", 			krb5_get_err_text(context, ret));		goto out;	    }	}	if(subkey == NULL){	    krb5_auth_con_free(context, ac);	    kdc_log(context, config, 0,		    "Failed to get key for enc-authorization-data");	    ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */	    goto out;	}	ret = krb5_crypto_init(context, subkey, 0, &crypto);	if (ret) {	    krb5_auth_con_free(context, ac);	    kdc_log(context, config, 0, "krb5_crypto_init failed: %s",		    krb5_get_err_text(context, ret));	    goto out;	}	ret = krb5_decrypt_EncryptedData (context,					  crypto,					  usage,					  b->enc_authorization_data,					  &ad);	krb5_crypto_destroy(context, crypto);	if(ret){	    krb5_auth_con_free(context, ac);	    kdc_log(context, config, 0, 		    "Failed to decrypt enc-authorization-data");	    ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */	    goto out;	}	krb5_free_keyblock(context, subkey);	ALLOC(*auth_data);	if (*auth_data == NULL) {	    krb5_auth_con_free(context, ac);	    ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */	    goto out;	}	ret = decode_AuthorizationData(ad.data, ad.length, *auth_data, NULL);	if(ret){	    krb5_auth_con_free(context, ac);	    free(*auth_data);	    *auth_data = NULL;	    kdc_log(context, config, 0, "Failed to decode authorization data");	    ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */	    goto out;	}    }    krb5_auth_con_free(context, ac);    out:    free_AP_REQ(&ap_req);        return ret;}static krb5_error_codetgs_build_reply(krb5_context context, 		krb5_kdc_configuration *config,		KDC_REQ *req, 		KDC_REQ_BODY *b,		hdb_entry_ex *krbtgt,		krb5_enctype krbtgt_etype,		krb5_ticket *ticket,		krb5_data *reply,		const char *from,		const char **e_text,		AuthorizationData *auth_data,		const struct sockaddr *from_addr,		int datagram_reply){    krb5_error_code ret;    krb5_principal cp = NULL, sp = NULL;    krb5_principal client_principal = NULL;    char *spn = NULL, *cpn = NULL;    hdb_entry_ex *server = NULL, *client = NULL;    EncTicketPart *tgt = &ticket->ticket;    KRB5SignedPathPrincipals *spp = NULL;    const EncryptionKey *ekey;    krb5_keyblock sessionkey;    krb5_kvno kvno;    krb5_data rspac;    int cross_realm = 0;    PrincipalName *s;    Realm r;    int nloop = 0;    EncTicketPart adtkt;    char opt_str[128];    int require_signedpath = 0;    memset(&sessionkey, 0, sizeof(sessionkey));    memset(&adtkt, 0, sizeof(adtkt));    krb5_data_zero(&rspac);    s = b->sname;    r = b->realm;    if(b->kdc_options.enc_tkt_in_skey){	Ticket *t;	hdb_entry_ex *uu;	krb5_principal p;	Key *uukey;	    	if(b->additional_tickets == NULL || 	   b->additional_tickets->len == 0){	    ret = KRB5KDC_ERR_BADOPTION; /* ? */	    kdc_log(context, config, 0,		    "No second ticket present in request");	    goto out;	}	t = &b->additional_tickets->val[0];	if(!get_krbtgt_realm(&t->sname)){	    kdc_log(context, config, 0,		    "Additional ticket is not a ticket-granting ticket");	    ret = KRB5KDC_ERR_POLICY;	    goto out;	}	_krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);	ret = _kdc_db_fetch(context, config, p, 			    HDB_F_GET_CLIENT|HDB_F_GET_SERVER, 			    NULL, &uu);	krb5_free_principal(context, p);	if(ret){	    if (ret == HDB_ERR_NOENTRY)		ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;	    goto out;	}	ret = hdb_enctype2key(context, &uu->entry, 			      t->enc_part.etype, &uukey);	if(ret){	    _kdc_free_ent(context, uu);	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */	    goto out;	}	ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0);	_kdc_free_ent(context, uu);	if(ret)	    goto out;	ret = verify_flags(context, config, &adtkt, spn);	if (ret)	    goto out;	s = &adtkt.cname;	r = adtkt.crealm;    }    _krb5_principalname2krb5_principal(context, &sp, *s, r);    ret = krb5_unparse_name(context, sp, &spn);	    if (ret)	goto out;    _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);    ret = krb5_unparse_name(context, cp, &cpn);    if (ret)	goto out;    unparse_flags (KDCOptions2int(b->kdc_options),		   asn1_KDCOptions_units(),		   opt_str, sizeof(opt_str));    if(*opt_str)	kdc_log(context, config, 0,		"TGS-REQ %s from %s for %s [%s]", 		cpn, from, spn, opt_str);    else	kdc_log(context, config, 0,		"TGS-REQ %s from %s for %s", cpn, from, spn);    /*     * Fetch server     */server_lookup:    ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER, NULL, &server);    if(ret){	const char *new_rlm;	Realm req_rlm;	krb5_realm *realms;	if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {	    if(nloop++ < 2) {		new_rlm = find_rpath(context, tgt->crealm, req_rlm);		if(new_rlm) {		    kdc_log(context, config, 5, "krbtgt for realm %s "			    "not found, trying %s", 			    req_rlm, new_rlm);		    krb5_free_principal(context, sp);		    free(spn);		    krb5_make_principal(context, &sp, r, 					KRB5_TGS_NAME, new_rlm, NULL);		    ret = krb5_unparse_name(context, sp, &spn);			    if (ret)			goto out;		    auth_data = NULL; /* ms don't handle AD in referals */		    goto server_lookup;		}	    }	} else if(need_referral(context, sp, &realms)) {	    if (strcmp(realms[0], sp->realm) != 0) {		kdc_log(context, config, 5,			"Returning a referral to realm %s for "			"server %s that was not found",			realms[0], spn);		krb5_free_principal(context, sp);		free(spn);		krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,				    realms[0], NULL);		ret = krb5_unparse_name(context, sp, &spn);		if (ret)		    goto out;		krb5_free_host_realm(context, realms);		auth_data = NULL; /* ms don't handle AD in referals */		goto server_lookup;	    }	    krb5_free_host_realm(context, realms);	}	kdc_log(context, config, 0,		"Server not found in database: %s: %s", spn,		krb5_get_err_text(context, ret));	if (ret == HDB_ERR_NOENTRY)	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;	goto out;    }    ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client);    if(ret) {	const char *krbtgt_realm; 	/*	 * If the client belongs to the same realm as our krbtgt, it	 * should exist in the local database.	 *	 */	krbtgt_realm = 	    krb5_principal_get_comp_string(context, 					   krbtgt->entry.principal, 1);	if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {	    if (ret == HDB_ERR_NOENTRY)		ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;	    kdc_log(context, config, 1, "Client no longer in database: %s",		    cpn);	    goto out;	}		kdc_log(context, config, 1, "Client not found in database: %s: %s",		cpn, krb5_get_err_text(context, ret));

⌨️ 快捷键说明

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