/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
*
* Copyright (C) 2009 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*
*
*/
#include "k5-int.h"
#include "int-proto.h"
/* Convert ticket flags to necessary KDC options */
/*
* Implements S4U2Self, by which a service can request a ticket to
* itself on behalf of an arbitrary principal.
*/
static krb5_error_code
void *prompter_data,
void *gak_data)
{
/* force a hard error, we don't actually have the key */
return KDC_ERR_PREAUTH_FAILED;
}
static krb5_error_code
{
int use_master = 0;
*canon_user = NULL;
return EINVAL;
}
/* we already know the realm of the user */
if (subject_cert != NULL)
if (code != 0)
goto cleanup;
else {
/* should this be NULL, empty or a fixed string? XXX */
client_data.length = 0;
client = &client_data;
}
&use_master, NULL);
if (code == 0 ||
code == KDC_ERR_PREAUTH_REQUIRED ||
code == KDC_ERR_PREAUTH_FAILED) {
code = 0;
}
return code;
}
static krb5_error_code
{
int i;
char *p;
}
return ENOMEM;
p[0] = (name_type >> 0 ) & 0xFF;
p += 4;
}
if (code != 0) {
return code;
}
cksum);
return code;
}
static krb5_error_code
{
return EINVAL;
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
goto cleanup;
}
*out_padata = padata;
return code;
}
/*
* This function is invoked by krb5int_send_tgs() just before
* the request is encoded; it gives us access to the nonce and
* subkey without requiring them to be generated by the caller.
*/
static krb5_error_code
void *gcvt_data)
{
int i;
if (code != 0)
goto cleanup;
/* [MS-SFU] 2.2.2: unusual to say the least, but enc_padata secures it */
} else {
&cksumtype);
}
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
;
(i + 2) * sizeof(krb5_pa_data *));
goto cleanup;
}
goto cleanup;
}
}
return code;
}
static krb5_error_code
{
case ENCTYPE_DES_CBC_CRC:
case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_MD5:
case ENCTYPE_DES3_CBC_SHA1:
case ENCTYPE_DES3_CBC_RAW:
case ENCTYPE_ARCFOUR_HMAC:
case ENCTYPE_ARCFOUR_HMAC_EXP :
break;
default:
break;
}
/* XXX this will break newer enctypes with a MIT 1.7 KDC */
if (rep_s4u_padata == NULL) {
return KRB5_KDCREP_MODIFIED;
else
return 0;
}
if (code != 0)
goto cleanup;
goto cleanup;
}
if (code != 0)
goto cleanup;
else
if (code != 0)
goto cleanup;
goto cleanup;
}
/*
* KDCs that support KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE also return
* S4U enc_padata for older (pre-AES) encryption types only.
*/
if (not_newer) {
if (enc_s4u_padata == NULL) {
goto cleanup;
}
} else {
if (enc_s4u_padata->length !=
goto cleanup;
}
goto cleanup;
}
}
goto cleanup;
}
return code;
}
static krb5_error_code
{
int referral_count = 0, i;
{
0);
if (code != 0)
goto cleanup;
} else {
if (code != 0)
goto cleanup;
}
} else {
user_realm->data);
if (code != 0)
goto cleanup;
}
if (subject_cert != NULL)
/* First, acquire a TGT to the user's realm. */
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
}
if (code != 0)
goto cleanup;
/* Then, walk back the referral path to S4U2Self for user */
kdcopt = 0;
if (options & KRB5_GC_CANONICALIZE)
if (options & KRB5_GC_FORWARDABLE)
if (options & KRB5_GC_NO_TRANSIT_CHECK)
for (referral_count = 0;
{
goto cleanup;
}
if (code != 0) {
goto cleanup;
}
}
/* Rewrite server realm to match TGS realm */
if (code != 0) {
goto cleanup;
}
&out_padata, &enc_padata,
if (code != 0) {
goto cleanup;
}
if (code != 0)
goto cleanup;
code = 0;
goto cleanup;
break;
}
for (i = 0; i < referral_count; i++) {
referral_tgts[i]->server)) {
goto cleanup;
}
}
} else {
break;
}
}
for (i = 0; i < KRB5_REFERRAL_MAXHOPS; i++) {
if (referral_tgts[i] != NULL)
}
return code;
}
{
if (options & KRB5_GC_CONSTRAINED_DELEGATION) {
goto cleanup;
}
/* Uncanonicalised check */
goto cleanup;
goto cleanup;
}
if (code != 0)
goto cleanup;
|| options & KRB5_GC_CACHED)
goto cleanup;
if (code != 0)
goto cleanup;
if ((options & KRB5_GC_NO_STORE) == 0) {
if (code != 0)
goto cleanup;
}
}
return code;
}
/*
* Exported API for constrained delegation (S4U2Proxy).
*
* This is preferable to using krb5_get_credentials directly because
* it can perform some additional checks.
*/
{
goto cleanup;
}
/*
* Caller should have set in_creds->client to match evidence
* ticket client
*/
goto cleanup;
}
goto cleanup;
}
if (code != 0)
goto cleanup;
goto cleanup;
}
if (code != 0) {
} else {
}
|| options & KRB5_GC_CACHED)
goto cleanup;
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
/*
* Check client name because we couldn't compare that inside
* krb5_get_credentials() (enc_part2 is unavailable in clear)
*/
goto cleanup;
}
}
if (evidence_tkt_data != NULL)
return code;
}