Home | History | Annotate | Download | only in mech
      1 /*
      2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 /* -*- mode: c; indent-tabs-mode: nil -*- */
      6 /*
      7  * Copyright 1993 by OpenVision Technologies, Inc.
      8  *
      9  * Permission to use, copy, modify, distribute, and sell this software
     10  * and its documentation for any purpose is hereby granted without fee,
     11  * provided that the above copyright notice appears in all copies and
     12  * that both that copyright notice and this permission notice appear in
     13  * supporting documentation, and that the name of OpenVision not be used
     14  * in advertising or publicity pertaining to distribution of the software
     15  * without specific, written prior permission. OpenVision makes no
     16  * representations about the suitability of this software for any
     17  * purpose.  It is provided "as is" without express or implied warranty.
     18  *
     19  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     20  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     21  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     22  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     23  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     24  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     25  * PERFORMANCE OF THIS SOFTWARE.
     26  */
     27 /*
     28  * Copyright (c) 2006-2008, Novell, Inc.
     29  * All rights reserved.
     30  *
     31  * Redistribution and use in source and binary forms, with or without
     32  * modification, are permitted provided that the following conditions are met:
     33  *
     34  *   * Redistributions of source code must retain the above copyright notice,
     35  *       this list of conditions and the following disclaimer.
     36  *   * Redistributions in binary form must reproduce the above copyright
     37  *       notice, this list of conditions and the following disclaimer in the
     38  *       documentation and/or other materials provided with the distribution.
     39  *   * The copyright holder's name is not used to endorse or promote products
     40  *       derived from this software without specific prior written permission.
     41  *
     42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     43  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     45  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     46  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     47  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     48  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     49  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     50  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     51  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     52  * POSSIBILITY OF SUCH DAMAGE.
     53  */
     54 /*
     55  * Copyright (c) 2006-2008, Novell, Inc.
     56  * All rights reserved.
     57  *
     58  * Redistribution and use in source and binary forms, with or without
     59  * modification, are permitted provided that the following conditions are met:
     60  *
     61  *   * Redistributions of source code must retain the above copyright notice,
     62  *       this list of conditions and the following disclaimer.
     63  *   * Redistributions in binary form must reproduce the above copyright
     64  *       notice, this list of conditions and the following disclaimer in the
     65  *       documentation and/or other materials provided with the distribution.
     66  *   * The copyright holder's name is not used to endorse or promote products
     67  *       derived from this software without specific prior written permission.
     68  *
     69  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     70  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     71  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     72  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     73  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     74  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     75  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     76  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     77  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     78  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     79  * POSSIBILITY OF SUCH DAMAGE.
     80  */
     81 
     82 #include "gssapiP_krb5.h"
     83 #include "mechglueP.h" /* SUNW17PACresync */
     84 
     85 OM_uint32
     86 krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
     87                          acceptor_name, lifetime_rec, mech_type, ret_flags,
     88                          locally_initiated, opened)
     89     OM_uint32 *minor_status;
     90     gss_ctx_id_t context_handle;
     91     gss_name_t *initiator_name;
     92     gss_name_t *acceptor_name;
     93     OM_uint32 *lifetime_rec;
     94     gss_OID *mech_type;
     95     OM_uint32 *ret_flags;
     96     int *locally_initiated;
     97     int *opened;
     98 {
     99     krb5_context context;
    100     krb5_error_code code;
    101     krb5_gss_ctx_id_rec *ctx;
    102     krb5_principal initiator, acceptor;
    103     krb5_timestamp now;
    104     krb5_deltat lifetime;
    105 
    106     if (initiator_name)
    107         *initiator_name = (gss_name_t) NULL;
    108     if (acceptor_name)
    109         *acceptor_name = (gss_name_t) NULL;
    110 
    111     /* validate the context handle */
    112     if (! kg_validate_ctx_id(context_handle)) {
    113         *minor_status = (OM_uint32) G_VALIDATE_FAILED;
    114         return(GSS_S_NO_CONTEXT);
    115     }
    116 
    117     ctx = (krb5_gss_ctx_id_rec *) context_handle;
    118 
    119     if (! ctx->established) {
    120         *minor_status = KG_CTX_INCOMPLETE;
    121         return(GSS_S_NO_CONTEXT);
    122     }
    123 
    124     initiator = NULL;
    125     acceptor = NULL;
    126     context = ctx->k5_context;
    127 
    128     if ((code = krb5_timeofday(context, &now))) {
    129         *minor_status = code;
    130         save_error_info(*minor_status, context);
    131         return(GSS_S_FAILURE);
    132     }
    133 
    134 
    135     /* SUNW17PACresync - should be krb_times.endtime (revisit) */
    136     if ((lifetime = ctx->endtime - now) < 0)
    137         lifetime = 0;
    138 
    139     if (initiator_name) {
    140         if ((code = krb5_copy_principal(context,
    141                                         ctx->initiate?ctx->here:ctx->there,
    142                                         &initiator))) {
    143             *minor_status = code;
    144             save_error_info(*minor_status, context);
    145             return(GSS_S_FAILURE);
    146         }
    147         if (! kg_save_name((gss_name_t) initiator)) {
    148             krb5_free_principal(context, initiator);
    149             *minor_status = (OM_uint32) G_VALIDATE_FAILED;
    150             return(GSS_S_FAILURE);
    151         }
    152     }
    153 
    154     if (acceptor_name) {
    155         if ((code = krb5_copy_principal(context,
    156                                         ctx->initiate?ctx->there:ctx->here,
    157                                         &acceptor))) {
    158             if (initiator) krb5_free_principal(context, initiator);
    159             *minor_status = code;
    160             save_error_info(*minor_status, context);
    161             return(GSS_S_FAILURE);
    162         }
    163         if (! kg_save_name((gss_name_t) acceptor)) {
    164             krb5_free_principal(context, acceptor);
    165             if (initiator) {
    166                 kg_delete_name((gss_name_t) initiator);
    167                 krb5_free_principal(context, initiator);
    168             }
    169             *minor_status = (OM_uint32) G_VALIDATE_FAILED;
    170             return(GSS_S_FAILURE);
    171         }
    172     }
    173 
    174     if (initiator_name)
    175         *initiator_name = (gss_name_t) initiator;
    176 
    177     if (acceptor_name)
    178         *acceptor_name = (gss_name_t) acceptor;
    179 
    180     if (lifetime_rec)
    181         *lifetime_rec = lifetime;
    182 
    183     if (mech_type)
    184         *mech_type = (gss_OID) ctx->mech_used;
    185 
    186     if (ret_flags)
    187         *ret_flags = ctx->gss_flags;
    188 
    189     if (locally_initiated)
    190         *locally_initiated = ctx->initiate;
    191 
    192     if (opened)
    193         *opened = ctx->established;
    194 
    195     *minor_status = 0;
    196 
    197     return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
    198 }
    199 
    200 OM_uint32
    201 gss_krb5int_inq_session_key(
    202     OM_uint32 *minor_status,
    203     const gss_ctx_id_t context_handle,
    204     const gss_OID desired_object,
    205     gss_buffer_set_t *data_set)
    206 {
    207     krb5_gss_ctx_id_rec *ctx;
    208     krb5_keyblock *key;
    209     gss_buffer_desc keyvalue, keyinfo;
    210     OM_uint32 major_status, minor;
    211     unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6];
    212     gss_OID_desc oid;
    213 
    214     ctx = (krb5_gss_ctx_id_rec *) context_handle;
    215     key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey;
    216 
    217     keyvalue.value = key->contents;
    218     keyvalue.length = key->length;
    219 
    220     major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set);
    221     if (GSS_ERROR(major_status))
    222         goto cleanup;
    223 
    224     oid.elements = oid_buf;
    225     oid.length = sizeof(oid_buf);
    226 
    227     major_status = generic_gss_oid_compose(minor_status,
    228                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID,
    229                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,
    230                                            key->enctype,
    231                                            &oid);
    232     if (GSS_ERROR(major_status))
    233         goto cleanup;
    234 
    235     keyinfo.value = oid.elements;
    236     keyinfo.length = oid.length;
    237 
    238     major_status = generic_gss_add_buffer_set_member(minor_status, &keyinfo, data_set);
    239     if (GSS_ERROR(major_status))
    240         goto cleanup;
    241 
    242     return GSS_S_COMPLETE;
    243 
    244 cleanup:
    245     if (*data_set != GSS_C_NO_BUFFER_SET) {
    246         if ((*data_set)->count != 0)
    247             memset((*data_set)->elements[0].value, 0, (*data_set)->elements[0].length);
    248         gss_release_buffer_set(&minor, data_set);
    249     }
    250 
    251     return major_status;
    252 }
    253 
    254 OM_uint32
    255 gss_krb5int_extract_authz_data_from_sec_context(
    256    OM_uint32 *minor_status,
    257    const gss_ctx_id_t context_handle,
    258    const gss_OID desired_object,
    259    gss_buffer_set_t *data_set)
    260 {
    261     OM_uint32 major_status;
    262     krb5_gss_ctx_id_rec *ctx;
    263     int ad_type = 0;
    264     size_t i;
    265 
    266     *data_set = GSS_C_NO_BUFFER_SET;
    267 
    268     ctx = (krb5_gss_ctx_id_rec *) context_handle;
    269 
    270     major_status = generic_gss_oid_decompose(minor_status,
    271                                              GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID,
    272                                              GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH,
    273                                              desired_object,
    274                                              &ad_type);
    275     if (major_status != GSS_S_COMPLETE || ad_type == 0) {
    276         *minor_status = ENOENT;
    277         return major_status; /* SUNW17PACresync */
    278     }
    279 
    280     if (ctx->authdata != NULL) {
    281         for (i = 0; ctx->authdata[i] != NULL; i++) {
    282             if (ctx->authdata[i]->ad_type == ad_type) {
    283                 gss_buffer_desc ad_data;
    284 
    285                 ad_data.length = ctx->authdata[i]->length;
    286                 ad_data.value = ctx->authdata[i]->contents;
    287 
    288                 major_status = generic_gss_add_buffer_set_member(minor_status,
    289                                                                  &ad_data, data_set);
    290                 if (GSS_ERROR(major_status))
    291                     break;
    292             }
    293         }
    294     }
    295 
    296     if (GSS_ERROR(major_status)) {
    297         OM_uint32 tmp;
    298 
    299         generic_gss_release_buffer_set(&tmp, data_set);
    300     }
    301 
    302     return major_status;
    303 }
    304 
    305 OM_uint32
    306 gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status,
    307                                               const gss_ctx_id_t context_handle,
    308                                               const gss_OID desired_oid,
    309                                               gss_buffer_set_t *data_set)
    310 {
    311     krb5_gss_ctx_id_rec *ctx;
    312     gss_buffer_desc rep;
    313 
    314     ctx = (krb5_gss_ctx_id_rec *) context_handle;
    315 
    316     rep.value = &ctx->krb_times.authtime;
    317     rep.length = sizeof(ctx->krb_times.authtime);
    318 
    319     return generic_gss_add_buffer_set_member(minor_status, &rep, data_set);
    320 }
    321 
    322