accept_sec_context.c revision ab9b2e153c3a9a2b1141fefa87925b1a9beb1236
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Use is subject to license terms.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#pragma ident "%Z%%M% %I% %E% SMI"
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright 2000, 2004 by the Massachusetts Institute of Technology.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * All Rights Reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Export of this software from the United States of America may
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * require a specific license from the United States Government.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * It is the responsibility of any person or organization contemplating
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * export to obtain such a license before exporting.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * distribute this software and its documentation for any purpose and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * without fee is hereby granted, provided that the above copyright
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * notice appear in all copies and that both that copyright notice and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * this permission notice appear in supporting documentation, and that
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * the name of M.I.T. not be used in advertising or publicity pertaining
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * to distribution of the software without specific, written prior
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * permission. Furthermore if you modify this software you must label
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * your software as modified software and not distribute it in such a
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fashion that it might be confused with the original M.I.T. software.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * M.I.T. makes no representations about the suitability of
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * this software for any purpose. It is provided "as is" without express
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * or implied warranty.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright 1993 by OpenVision Technologies, Inc.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Permission to use, copy, modify, distribute, and sell this software
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and its documentation for any purpose is hereby granted without fee,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * provided that the above copyright notice appears in all copies and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * that both that copyright notice and this permission notice appear in
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * supporting documentation, and that the name of OpenVision not be used
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * in advertising or publicity pertaining to distribution of the software
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * without specific, written prior permission. OpenVision makes no
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * representations about the suitability of this software for any
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * purpose. It is provided "as is" without express or implied warranty.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * PERFORMANCE OF THIS SOFTWARE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (C) 1998 by the FundsXpress, INC.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Export of this software from the United States of America may require
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * a specific license from the United States Government. It is the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * responsibility of any person or organization contemplating export to
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * obtain such a license before exporting.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * distribute this software and its documentation for any purpose and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * without fee is hereby granted, provided that the above copyright
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * notice appear in all copies and that both that copyright notice and
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * this permission notice appear in supporting documentation, and that
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * the name of FundsXpress. not be used in advertising or publicity pertaining
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * to distribution of the software without specific, written prior
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * permission. FundsXpress makes no representations about the suitability of
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * this software for any purpose. It is provided "as is" without express
d2b539e744e90927cf7a57df3475145c279d68f9agiri * or implied warranty.
d2b539e744e90927cf7a57df3475145c279d68f9agiri * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* Solaris kerberos: XXX kludgy but there is no include file for the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * krb5_fcc_ops extern declaration.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Decode, decrypt and store the forwarded creds in the local ccache.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and populate the callers delegated credential handle if it
d2b539e744e90927cf7a57df3475145c279d68f9agiri * was provided.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otard_and_store_for_creds(context, auth_context, inbuf, out_cred)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG0(KRB5_INFO, "rd_and_store_for_creds() start");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_auth_con_getflags(context, auth_context, &flags_org)))
d2b539e744e90927cf7a57df3475145c279d68f9agiri * By the time krb5_rd_cred is called here (after krb5_rd_req has been
d2b539e744e90927cf7a57df3475145c279d68f9agiri * called in krb5_gss_accept_sec_context), the "keyblock" field of
d2b539e744e90927cf7a57df3475145c279d68f9agiri * auth_context contains a pointer to the session key, and the
d2b539e744e90927cf7a57df3475145c279d68f9agiri * "recv_subkey" field might contain a session subkey. Either of
d2b539e744e90927cf7a57df3475145c279d68f9agiri * these (the "recv_subkey" if it isn't NULL, otherwise the
d2b539e744e90927cf7a57df3475145c279d68f9agiri * "keyblock") might have been used to encrypt the encrypted part of
d2b539e744e90927cf7a57df3475145c279d68f9agiri * the KRB_CRED message that contains the forwarded credentials. (The
d2b539e744e90927cf7a57df3475145c279d68f9agiri * Java Crypto and Security Implementation from the DSTC in Australia
d2b539e744e90927cf7a57df3475145c279d68f9agiri * always uses the session key. But apparently it never negotiates a
d2b539e744e90927cf7a57df3475145c279d68f9agiri * subkey, so this code works fine against a JCSI client.) Up to the
d2b539e744e90927cf7a57df3475145c279d68f9agiri * present, though, GSSAPI clients linked against the MIT code (which
d2b539e744e90927cf7a57df3475145c279d68f9agiri * is almost all GSSAPI clients) don't encrypt the KRB_CRED message at
d2b539e744e90927cf7a57df3475145c279d68f9agiri * all -- at this level. So if the first call to krb5_rd_cred fails,
d2b539e744e90927cf7a57df3475145c279d68f9agiri * we should call it a second time with another auth context freshly
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * created by krb5_auth_con_init. All of its keyblock fields will be
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * NULL, so krb5_rd_cred will assume that the KRB_CRED message is
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * unencrypted. (The MIT code doesn't actually send the KRB_CRED
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * message in the clear -- the "authenticator" whose "checksum" ends up
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * containing the KRB_CRED message does get encrypted.)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If the client is using non-DES enctypes it really ought to
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * send encrypted KRB-CREDs...
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* NOTREACHED */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* Try to krb5_rd_cred() likely unencrypted KRB-CRED */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_auth_con_init(context, &new_auth_ctx)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_rd_cred(context, new_auth_ctx, inbuf,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* Lots of kludging going on here... Some day the ccache interface
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota will be rewritten though */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &template_ccache);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota retval = krb5_cc_initialize(context, ccache, creds[0]->client);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota retval = krb5_cc_store_cred(context, ccache, creds[0]);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* generate a delegated credential handle */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* allocate memory for a cred_t... */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* zero it out... */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (void) memset(cred, 0, sizeof(krb5_gss_cred_id_rec));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* copy the client principle into it... */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_copy_principal(context, creds[0]->client,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cred->usage = GSS_C_INITIATE; /* we can't accept with this */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* cred->princ already set */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cred->prerfc_mech = 1; /* this cred will work with all three mechs */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cred->keytab = NULL; /* no keytab associated with this... */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* The cred expires when the original cred was set to expire */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cred->ccache = ccache; /* the ccache containing the credential */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ccache = NULL; /* cred takes ownership so don't destroy */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* If there were errors, there might have been a memory leak
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((retval = krb5_cc_close(context, ccache)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto cleanup;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * SUNW15resync
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Added this cc_destroy for template_cache, w/out it causes memory
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * leak via "ssh -o gssapidelegatecredentials=yes ..."
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota krb5_auth_con_setflags(context, auth_context, flags_org);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG(KRB5_INFO, "rd_and_store_for_creds() end retval %d", retval);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * SUNW15resync
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Most of the logic here left "as is" because of lots of fixes MIT
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * does not have yet
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otakrb5_gss_accept_sec_context(minor_status, context_handle,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG0(KRB5_INFO,"krb5_gss_accept_sec_context() start");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* set up returns to be freeable */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* initialize the delegated cred handle to NO_CREDENTIAL for now */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Context handle must be unspecified. Actually, it must be
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota * non-established, but currently, accept_sec_context never returns
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * a non-established context handle.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*SUPPRESS 29*/
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* Solaris kerberos: the original Solaris code returned GSS_S_NO_CONTEXT
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * for this error. This conflicts somewhat with RFC2743 which states
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * GSS_S_NO_CONTEXT should be returned only for sucessor calls following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * GSS_S_CONTINUE_NEEDED status returns. Note the MIT code doesn't
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * return GSS_S_NO_CONTEXT at all.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota KRB5_LOG0(KRB5_ERR,"krb5_gss_accept_sec_context() "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "error GSS_S_NO_CONTEXT");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* verify the token's integrity, and leave the token in ap_req.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota figure out which mech oid was used, and save it */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Previous versions of this library used the old mech_id
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and some broken behavior (wrong IV on checksum
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * encryption). We support the old mech_id for
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * compatibility, and use it to decide when to use the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * old behavior.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Solaris Kerberos:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * We need to decode the request now so that we can get the
goto fail;
goto fail;
&princ))) {
goto fail;
goto fail;
goto fail;
goto fail;
code = 0;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
&md5len)) {
goto fail;
code = 0;
goto fail;
bigend = 0;
goto fail;
goto fail;
goto fail;
code = 0;
goto fail;
goto fail;
goto fail;
if (code) {
goto fail;
== NULL) {
goto fail;
ctx = 0;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
case ENCTYPE_DES_CBC_MD5:
case ENCTYPE_DES_CBC_CRC:
goto fail;
goto copy_subkey_to_seq;
case ENCTYPE_DES3_CBC_SHA1:
goto fail;
goto fail;
case ENCTYPE_ARCFOUR_HMAC:
goto copy_subkey;
if (code)
goto fail;
if (code)
goto fail;
goto copy_subkey;
goto fail;
code = 0;
goto fail;
unsigned char * ptr3;
int cfx_generate_subkey;
cfx_generate_subkey = 0;
if (cfx_generate_subkey) {
if (code == 0) {
if (code) {
goto fail;
goto fail;
if (cfx_generate_subkey) {
if (code != 0) {
goto fail;
if (code) {
goto fail;
== NULL) {
goto fail;
if (src_name) {
goto fail;
goto fail;
if (mech_type)
if (time_rec)
if (ret_flags)
if (src_name)
goto fail;
*minor_status = 0;
fail:
if (authdat)
if (cred_rcache)
if (ctx)
return(major_status);
if (ctx)
if (name) {
unsigned int tmsglen;
int toktype;
if (code)
goto cleanup;
goto cleanup;
return (major_status);