/* -*- 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>
/*
* It is possible to support sending a request that includes both a
* FAST and normal version. This would complicate the
* pre-authentication logic significantly. You would need to maintain
* two contexts, one for FAST and one for normal use. In adition, you
* would need to manage the security issues surrounding downgrades.
* However trying FAST at all requires an armor key. Generally in
* obtaining the armor key, the client learns enough to know that FAST
* is supported. If not, the client can see FAST in the
* preauth_required error's padata and retry with FAST. So, this
* implementation does not support FAST+normal.
*
* We store the outer version of the request to use . The caller
* stores the inner version. We handle the encoding of the request
* body (and request) and provide encoded request bodies for the
* caller to use as these may be used for checksums. In the AS case
* we also evaluate whether to continue a conversation as one of the
* important questions there is the presence of a cookie.
*/
#include "fast.h"
#include "int-proto.h"
static krb5_error_code
struct krb5int_fast_request_state *state,
{
if (retval == 0)
if (retval == 0)
if (retval == 0)
if (retval == 0)
if (retval == 0) {
}
if (retval == 0) {
}
if (out_creds)
/* target_principal is owned by caller. */
return retval;
}
{
}
if (retval == 0)
if (retval == 0) {
}
if (local_encoded_request_body != NULL)
return retval;
}
struct krb5int_fast_request_state *state,
{
&ccache);
if (retval == 0) {
}
if (retval == 0) {
retval = 0;
}
}
if (retval != 0) {
const char * errmsg;
if (errmsg) {
}
}
}
if (ccache)
if (target_principal)
return retval;
}
struct krb5int_fast_request_state *state,
const krb5_data *to_be_checksummed,
{
}
/* Fill in a fresh random nonce for each inner request*/
if (retval == 0) {
}
}
if (retval == 0)
if (retval == 0) {
if (armored_req == NULL)
}
if (retval == 0)
if (retval == 0)
&cksumtype);
/* DES enctypes have unkeyed mandatory checksums; need a keyed one. */
if (retval ==0)
if (retval == 0)
&armored_req->enc_part);
if (retval == 0)
if (retval==0) {
}
if(retval == 0)
if (retval == 0) {
}
if (encoded_armored_req)
if (armored_req) {
}
if (encoded_fast_req)
if (local_encoded_result)
return retval;
}
static krb5_error_code
struct krb5int_fast_request_state *state,
{
if (retval == 0) {
}
if (retval == 0) {
}
if (retval == 0)
if (retval != 0) {
const char * errmsg;
}
if (retval == 0)
if (retval == 0) {
}
}
if (retval == 0) {
*response = local_resp;
local_resp = NULL;
}
if (encrypted_response)
if (local_resp)
return retval;
}
/*
* FAST separates two concepts: the set of padata we're using to
* decide what pre-auth mechanisms to use and the set of padata we're
* making available to mechanisms in order for them to respond to an
* error. The plugin interface in March 2009 does not permit
* separating these concepts for the plugins. This function makes
* both available for future revisions to the plugin interface. It
* also re-encodes the padata from the current error as a encoded
* typed-data and puts that in the e_data field. That will allow
* existing plugins with the old interface to find the error data.
* The output parameter out_padata contains the padata from the error
* whenever padata is available (all the time with fast).
*/
struct krb5int_fast_request_state *state,
{
*out_padata = NULL;
*retry = 0;
if (retval == 0)
if (retval) {
/*This can happen if the KDC does not understand FAST. We
* don't expect that, but treating it as the fatal error
* indicated by the KDC seems reasonable.
*/
*retry = 0;
return 0;
}
if (retval == 0) {
if (fx_error_pa == NULL) {
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, "Expecting FX_ERROR pa-data inside FAST container");
}
}
if (retval == 0) {
}
/*
* krb5_pa_data and krb5_typed_data are safe to cast between:
* they have the same type fields in the same order.
* (krb5_preauthtype is a krb5_int32). If krb5_typed_data is
* ever changed then this will need to be a copy not a cast.
*/
if (retval == 0)
&encoded_td);
if (retval == 0) {
encoded_td = NULL;
*err_replyptr = fx_error;
/*
* If there is more than the fx_error padata, then we want
* to retry the error if a cookie is present
*/
*retry = 0;
}
if (fx_error)
} else { /*not FAST*/
if (retval == 0)
if (retval == 0) {
*out_padata = result;
return 0;
}
"Error decoding padata in error reply");
return retval;
}
}
return retval;
}
struct krb5int_fast_request_state *state,
{
*strengthen_key = NULL;
return 0;
if (retval == 0) {
if (fast_response->finished == 0) {
}
}
if (retval == 0)
if (retval == 0)
&cksum_valid);
if (retval == 0 && cksum_valid == 0) {
}
if (retval == 0) {
}
if (fast_response)
if (encoded_ticket)
return retval;
}
{
if (strengthen_key) {
if (retval == 0) {
}
} else {
}
return retval;
}
{
if (local_state == NULL)
return ENOMEM;
*state = local_state;
return 0;
}
void
{
return;
/*We are responsible for none of the store in the fast_outer_req*/
}
{
return NULL;
break;
}
return *tmppa;
}
struct krb5int_fast_request_state *state,
{
*fast_avail = FALSE;
else {
}
if (retval == 0)
if (retval == 0)
if (retval == 0) {
}
}
if (checksum)
return retval;
}
struct krb5int_fast_request_state *state,
{
return 0; /*already using FAST*/
return 0;
return 1;
}
return 0;
}