diff options
Diffstat (limited to 'source4/heimdal/lib/gssapi')
130 files changed, 16207 insertions, 4915 deletions
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c deleted file mode 100644 index 41a54bdab1..0000000000 --- a/source4/heimdal/lib/gssapi/accept_sec_context.c +++ /dev/null @@ -1,1176 +0,0 @@ -/* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "gssapi_locl.h" - -RCSID("$Id: accept_sec_context.c,v 1.55 2005/11/25 15:57:35 lha Exp $"); - -HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; -krb5_keytab gssapi_krb5_keytab; - -OM_uint32 -gsskrb5_register_acceptor_identity (const char *identity) -{ - krb5_error_code ret; - - ret = gssapi_krb5_init(); - if(ret) - return GSS_S_FAILURE; - - HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); - - if(gssapi_krb5_keytab != NULL) { - krb5_kt_close(gssapi_krb5_context, gssapi_krb5_keytab); - gssapi_krb5_keytab = NULL; - } - if (identity == NULL) { - ret = krb5_kt_default(gssapi_krb5_context, &gssapi_krb5_keytab); - } else { - char *p; - - asprintf(&p, "FILE:%s", identity); - if(p == NULL) { - HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); - return GSS_S_FAILURE; - } - ret = krb5_kt_resolve(gssapi_krb5_context, p, &gssapi_krb5_keytab); - free(p); - } - HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); - if(ret) - return GSS_S_FAILURE; - return GSS_S_COMPLETE; -} - -void -gsskrb5_is_cfx(gss_ctx_id_t context_handle, int *is_cfx) -{ - krb5_keyblock *key; - int acceptor = (context_handle->more_flags & LOCAL) == 0; - *is_cfx = 0; - - if (acceptor) { - if (context_handle->auth_context->local_subkey) - key = context_handle->auth_context->local_subkey; - else - key = context_handle->auth_context->remote_subkey; - } else { - if (context_handle->auth_context->remote_subkey) - key = context_handle->auth_context->remote_subkey; - else - key = context_handle->auth_context->local_subkey; - } - if (key == NULL) - key = context_handle->auth_context->keyblock; - - if (key == NULL) - return; - - switch (key->keytype) { - case ETYPE_DES_CBC_CRC: - case ETYPE_DES_CBC_MD4: - case ETYPE_DES_CBC_MD5: - case ETYPE_DES3_CBC_MD5: - case ETYPE_DES3_CBC_SHA1: - case ETYPE_ARCFOUR_HMAC_MD5: - case ETYPE_ARCFOUR_HMAC_MD5_56: - break; - default : - *is_cfx = 1; - if ((acceptor && context_handle->auth_context->local_subkey) || - (!acceptor && context_handle->auth_context->remote_subkey)) - context_handle->more_flags |= ACCEPTOR_SUBKEY; - break; - } -} - - -static OM_uint32 -gsskrb5_accept_delegated_token - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - gss_cred_id_t * delegated_cred_handle) -{ - krb5_data *fwd_data = &(*context_handle)->fwd_data; - OM_uint32 *flags = &(*context_handle)->flags; - krb5_principal principal = (*context_handle)->source; - krb5_ccache ccache = NULL; - krb5_error_code kret; - int32_t ac_flags, ret = GSS_S_COMPLETE; - - *minor_status = 0; - - /* XXX Create a new delegated_cred_handle? */ - if (delegated_cred_handle == NULL) - kret = krb5_cc_default (gssapi_krb5_context, &ccache); - else - kret = krb5_cc_gen_new (gssapi_krb5_context, &krb5_mcc_ops, &ccache); - if (kret) { - *flags &= ~GSS_C_DELEG_FLAG; - goto out; - } - - kret = krb5_cc_initialize(gssapi_krb5_context, ccache, principal); - if (kret) { - *flags &= ~GSS_C_DELEG_FLAG; - goto out; - } - - krb5_auth_con_removeflags(gssapi_krb5_context, - (*context_handle)->auth_context, - KRB5_AUTH_CONTEXT_DO_TIME, - &ac_flags); - kret = krb5_rd_cred2(gssapi_krb5_context, - (*context_handle)->auth_context, - ccache, - fwd_data); - if (kret) - gssapi_krb5_set_error_string(); - krb5_auth_con_setflags(gssapi_krb5_context, - (*context_handle)->auth_context, - ac_flags); - if (kret) { - *flags &= ~GSS_C_DELEG_FLAG; - ret = GSS_S_FAILURE; - *minor_status = kret; - goto out; - } - - if (delegated_cred_handle) { - ret = gss_krb5_import_cred(minor_status, - ccache, - NULL, - NULL, - delegated_cred_handle); - if (ret != GSS_S_COMPLETE) - goto out; - - (*delegated_cred_handle)->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; - ccache = NULL; - } - -out: - if (ccache) { - if (delegated_cred_handle == NULL) - krb5_cc_close(gssapi_krb5_context, ccache); - else - krb5_cc_destroy(gssapi_krb5_context, ccache); - } - return ret; -} - -static OM_uint32 -gsskrb5_acceptor_ready( - OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - gss_cred_id_t * delegated_cred_handle) -{ - OM_uint32 ret; - int32_t seq_number; - int is_cfx = 0; - OM_uint32 *flags = &(*context_handle)->flags; - - krb5_auth_getremoteseqnumber (gssapi_krb5_context, - (*context_handle)->auth_context, - &seq_number); - - gsskrb5_is_cfx(*context_handle, &is_cfx); - - ret = _gssapi_msg_order_create(minor_status, - &(*context_handle)->order, - _gssapi_msg_order_f(*flags), - seq_number, 0, is_cfx); - if (ret) return ret; - - if (!(*flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(*flags)) { - krb5_auth_con_setlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - seq_number); - } - - /* - * We should handle the delegation ticket, in case it's there - */ - if ((*context_handle)->fwd_data.length > 0 && (*flags & GSS_C_DELEG_FLAG)) { - ret = gsskrb5_accept_delegated_token(minor_status, - context_handle, - delegated_cred_handle); - if (ret) return ret; - } else { - /* Well, looks like it wasn't there after all */ - *flags &= ~GSS_C_DELEG_FLAG; - } - - (*context_handle)->state = ACCEPTOR_READY; - (*context_handle)->more_flags |= OPEN; - - return GSS_S_COMPLETE; -} -static OM_uint32 -gsskrb5_acceptor_start - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t * src_name, - gss_OID * mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec, - gss_cred_id_t * delegated_cred_handle - ) -{ - krb5_error_code kret; - OM_uint32 ret = GSS_S_COMPLETE; - krb5_data indata; - krb5_flags ap_options; - OM_uint32 flags; - krb5_ticket *ticket = NULL; - krb5_keytab keytab = NULL; - krb5_keyblock *keyblock = NULL; - int is_cfx = 0; - - krb5_data_zero (&(*context_handle)->fwd_data); - - /* - * We may, or may not, have an escapsulation. - */ - ret = gssapi_krb5_decapsulate (minor_status, - input_token_buffer, - &indata, - "\x01\x00", - GSS_KRB5_MECHANISM); - - if (ret) { - /* No OID wrapping apparently available. */ - indata.length = input_token_buffer->length; - indata.data = input_token_buffer->value; - } - - /* - * We need to get our keytab - */ - if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) { - if (gssapi_krb5_keytab != NULL) { - keytab = gssapi_krb5_keytab; - } - } else if (acceptor_cred_handle->keytab != NULL) { - keytab = acceptor_cred_handle->keytab; - } - - /* - * We need to check the ticket and create the AP-REP packet - */ - kret = krb5_rd_req_return_keyblock(gssapi_krb5_context, - &(*context_handle)->auth_context, - &indata, - (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred_handle->principal, - keytab, - &ap_options, - &ticket, - &keyblock); - if (kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - - /* - * We need to remember some data on the context_handle - */ - (*context_handle)->ticket = ticket; - (*context_handle)->service_keyblock = keyblock; - (*context_handle)->lifetime = ticket->ticket.endtime; - - /* - * We need to copy the principal names to the context and the calling layer - */ - kret = krb5_copy_principal(gssapi_krb5_context, - ticket->client, - &(*context_handle)->source); - if (kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - } - - kret = krb5_copy_principal (gssapi_krb5_context, - ticket->server, - &(*context_handle)->target); - if (kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - - /* - * We need to setup some compat stuff, this assumes that context_handle->target is already set - */ - ret = _gss_DES3_get_mic_compat(minor_status, *context_handle); - if (ret) { - return ret; - } - - if (src_name != NULL) { - kret = krb5_copy_principal (gssapi_krb5_context, - ticket->client, - src_name); - if (kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - } - - /* - * We need to get the flags out of the 8003 checksum - */ - { - krb5_authenticator authenticator; - - kret = krb5_auth_con_getauthenticator(gssapi_krb5_context, - (*context_handle)->auth_context, - &authenticator); - if(kret) { - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - - if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) { - ret = gssapi_krb5_verify_8003_checksum(minor_status, - input_chan_bindings, - authenticator->cksum, - &flags, - &(*context_handle)->fwd_data); - - krb5_free_authenticator(gssapi_krb5_context, &authenticator); - if (ret) { - return ret; - } - } else { - krb5_crypto crypto; - - kret = krb5_crypto_init(gssapi_krb5_context, - (*context_handle)->auth_context->keyblock, - 0, &crypto); - if(kret) { - krb5_free_authenticator(gssapi_krb5_context, &authenticator); - - ret = GSS_S_FAILURE; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - - /* Windows accepts Samba3's use of a kerberos, - rather than GSSAPI checksum here */ - kret = krb5_verify_checksum(gssapi_krb5_context, - crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0, - authenticator->cksum); - krb5_free_authenticator(gssapi_krb5_context, &authenticator); - krb5_crypto_destroy(gssapi_krb5_context, crypto); - - if(kret) { - ret = GSS_S_BAD_SIG; - *minor_status = kret; - gssapi_krb5_set_error_string (); - return ret; - } - - flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; - } - } - - if(flags & GSS_C_MUTUAL_FLAG) { - krb5_data outbuf; - - gsskrb5_is_cfx(*context_handle, &is_cfx); - - if (is_cfx != 0 - || (ap_options & AP_OPTS_USE_SUBKEY)) { - kret = krb5_auth_con_addflags(gssapi_krb5_context, - (*context_handle)->auth_context, - KRB5_AUTH_CONTEXT_USE_SUBKEY, - NULL); - (*context_handle)->more_flags |= ACCEPTOR_SUBKEY; - } - - kret = krb5_mk_rep(gssapi_krb5_context, - (*context_handle)->auth_context, - &outbuf); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); - return GSS_S_FAILURE; - } - - if (!(flags & GSS_C_DCE_STYLE)) { - ret = gssapi_krb5_encapsulate(minor_status, - &outbuf, - output_token, - "\x02\x00", - GSS_KRB5_MECHANISM); - krb5_data_free (&outbuf); - if (ret) { - return ret; - } - } else { - output_token->length = outbuf.length; - output_token->value = outbuf.data; - } - } - - flags |= GSS_C_TRANS_FLAG; - - /* Remember the flags */ - - (*context_handle)->lifetime = ticket->ticket.endtime; - (*context_handle)->flags = flags; - (*context_handle)->more_flags |= OPEN; - - if (mech_type) - *mech_type = GSS_KRB5_MECHANISM; - - if (time_rec) { - ret = gssapi_lifetime_left(minor_status, - (*context_handle)->lifetime, - time_rec); - if (ret) { - return ret; - } - } - - /* - * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from the client - */ - if (flags & GSS_C_DCE_STYLE) { - if (ret_flags) { - /* Return flags to caller, but we haven't processed delgations yet */ - *ret_flags = flags & ~GSS_C_DELEG_FLAG; - } - - (*context_handle)->state = ACCEPTOR_WAIT_FOR_DCESTYLE; - return GSS_S_CONTINUE_NEEDED; - } - - ret = gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle); - - /* - * We need to send the flags back to the caller - */ - - *ret_flags = (*context_handle)->flags; - return ret; -} - -static OM_uint32 -gsskrb5_acceptor_wait_for_dcestyle( - OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t * src_name, - gss_OID * mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec, - gss_cred_id_t * delegated_cred_handle) -{ - OM_uint32 ret; - krb5_error_code kret; - krb5_data inbuf; - OM_uint32 r_seq_number; - OM_uint32 l_seq_number; - - /* We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP */ - inbuf.length = input_token_buffer->length; - inbuf.data = input_token_buffer->value; - - /* - * We need to remeber the old remote seq_number, then check if the client has replied with our local seq_number, - * and then reset the remote seq_number to the old value - */ - { - kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &l_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &r_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_con_setremoteseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - l_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to verify the AP_REP, but we need to flag that this - is DCE_STYLE, so don't check the timestamps this time - */ - { - krb5_ap_rep_enc_part *repl; - int32_t auth_flags; - - kret = krb5_auth_con_removeflags(gssapi_krb5_context, - (*context_handle)->auth_context, - KRB5_AUTH_CONTEXT_DO_TIME, &auth_flags); - if (kret) { /* Can't happen */ - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_rd_rep(gssapi_krb5_context, - (*context_handle)->auth_context, - &inbuf, - &repl); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - /* Because the inbuf above is a final leg from client - * to server, we don't have a use for a 'reply' - * here */ - krb5_free_ap_rep_enc_part(gssapi_krb5_context, repl); - - /* Do no harm, put the flags back */ - kret = krb5_auth_con_setflags(gssapi_krb5_context, - (*context_handle)->auth_context, - auth_flags); - if (kret) { /* Can't happen */ - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to check the liftime */ - { - OM_uint32 lifetime_rec; - - ret = gssapi_lifetime_left(minor_status, - (*context_handle)->lifetime, - &lifetime_rec); - if (ret) { - return ret; - } - if (lifetime_rec == 0) { - return GSS_S_CONTEXT_EXPIRED; - } - - if (time_rec) *time_rec = lifetime_rec; - } - - /* We need to give the caller the flags which are in use */ - if (ret_flags) *ret_flags = (*context_handle)->flags; - - if (src_name) { - kret = krb5_copy_principal(gssapi_krb5_context, - (*context_handle)->source, - src_name); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); - return GSS_S_FAILURE; - } - } - - /* - * After the krb5_rd_rep() the remote and local seq_number should be the same, - * because the client just replies the seq_number from our AP-REP in its AP-REP, - * but then the client uses the seq_number from its AP-REQ for GSS_wrap() - */ - { - OM_uint32 tmp_r_seq_number; - OM_uint32 tmp_l_seq_number; - - kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &tmp_r_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &tmp_l_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - /* - * Here we check if the client has responsed with our local seq_number, - */ - if (tmp_r_seq_number != tmp_l_seq_number) { - return GSS_S_UNSEQ_TOKEN; - } - } - - /* - * We need to reset the remote seq_number, because the client will use, - * the old one for the GSS_wrap() calls - */ - { - kret = krb5_auth_con_setremoteseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - r_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - return gsskrb5_acceptor_ready(minor_status, context_handle, delegated_cred_handle); -} - -static OM_uint32 -gsskrb5_accept_sec_context - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t * src_name, - gss_OID * mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec, - gss_cred_id_t * delegated_cred_handle - ) -{ - OM_uint32 ret = GSS_S_COMPLETE; - krb5_data fwd_data; - gss_ctx_id_t local_context; - OM_uint32 minor_status2; - GSSAPI_KRB5_INIT(); - - krb5_data_zero (&fwd_data); - output_token->length = 0; - output_token->value = NULL; - - if (src_name != NULL) - *src_name = NULL; - if (mech_type) - *mech_type = GSS_KRB5_MECHANISM; - - if (*context_handle == GSS_C_NO_CONTEXT) { - ret = _gsskrb5_create_ctx(minor_status, - &local_context, - input_chan_bindings, - ACCEPTOR_START); - if (ret) return ret; - } else { - local_context = *context_handle; - } - - /* - * TODO: check the channel_bindings - * (above just sets them to krb5 layer) - */ - - HEIMDAL_MUTEX_lock(&(local_context)->ctx_id_mutex); - - switch ((local_context)->state) { - case ACCEPTOR_START: - ret = gsskrb5_acceptor_start(minor_status, - &local_context, - acceptor_cred_handle, - input_token_buffer, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle); - break; - case ACCEPTOR_WAIT_FOR_DCESTYLE: - ret = gsskrb5_acceptor_wait_for_dcestyle(minor_status, - &local_context, - acceptor_cred_handle, - input_token_buffer, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle); - break; - case ACCEPTOR_READY: - /* this function should not be called after it has returned GSS_S_COMPLETE */ - ret = GSS_S_BAD_STATUS; - break; - default: - /* TODO: is this correct here? --metze */ - ret = GSS_S_BAD_STATUS; - break; - } - - HEIMDAL_MUTEX_unlock(&(local_context)->ctx_id_mutex); - - if (*context_handle == GSS_C_NO_CONTEXT) { - if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - *context_handle = local_context; - } else { - gss_delete_sec_context(&minor_status2, - &local_context, - NULL); - } - } - - return ret; -} - -static OM_uint32 -code_NegTokenArg(OM_uint32 *minor_status, - const NegTokenTarg *targ, - krb5_data *data, - u_char **ret_buf) -{ - OM_uint32 ret; - u_char *buf; - size_t buf_size, buf_len; - - buf_size = 1024; - buf = malloc(buf_size); - if (buf == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - do { - ret = encode_NegTokenTarg(buf + buf_size - 1, - buf_size, - targ, &buf_len); - if (ret == 0) { - size_t tmp; - - ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, - buf_size - buf_len, - buf_len, - ASN1_C_CONTEXT, - CONS, - 1, - &tmp); - if (ret == 0) - buf_len += tmp; - } - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc (buf, buf_size); - if (tmp == NULL) { - *minor_status = ENOMEM; - free(buf); - return GSS_S_FAILURE; - } - buf = tmp; - } else { - *minor_status = ret; - free(buf); - return GSS_S_FAILURE; - } - } - } while (ret == ASN1_OVERFLOW); - - data->data = buf + buf_size - buf_len; - data->length = buf_len; - *ret_buf = buf; - return GSS_S_COMPLETE; -} - -static OM_uint32 -send_reject (OM_uint32 *minor_status, - gss_buffer_t output_token) -{ - NegTokenTarg targ; - krb5_data data; - u_char *buf; - OM_uint32 ret; - - ALLOC(targ.negResult, 1); - if (targ.negResult == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - *(targ.negResult) = reject; - targ.supportedMech = NULL; - targ.responseToken = NULL; - targ.mechListMIC = NULL; - - ret = code_NegTokenArg (minor_status, &targ, &data, &buf); - free_NegTokenTarg(&targ); - if (ret) - return ret; - -#if 0 - ret = _gssapi_encapsulate(minor_status, - &data, - output_token, - GSS_SPNEGO_MECHANISM); -#else - output_token->value = malloc(data.length); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - } else { - output_token->length = data.length; - memcpy(output_token->value, data.data, output_token->length); - } -#endif - free(buf); - if (ret) - return ret; - return GSS_S_BAD_MECH; -} - -static OM_uint32 -send_accept (OM_uint32 *minor_status, - OM_uint32 major_status, - gss_buffer_t output_token, - gss_buffer_t mech_token, - gss_ctx_id_t context_handle, - const MechTypeList *mechtypelist) -{ - NegTokenTarg targ; - krb5_data data; - u_char *buf; - OM_uint32 ret; - gss_buffer_desc mech_buf, mech_mic_buf; - krb5_boolean require_mic; - - memset(&targ, 0, sizeof(targ)); - ALLOC(targ.negResult, 1); - if (targ.negResult == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - *(targ.negResult) = accept_completed; - - ALLOC(targ.supportedMech, 1); - if (targ.supportedMech == NULL) { - free_NegTokenTarg(&targ); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - ret = der_get_oid(GSS_KRB5_MECHANISM->elements, - GSS_KRB5_MECHANISM->length, - targ.supportedMech, - NULL); - if (ret) { - free_NegTokenTarg(&targ); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - if (mech_token != NULL && mech_token->length != 0) { - ALLOC(targ.responseToken, 1); - if (targ.responseToken == NULL) { - free_NegTokenTarg(&targ); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - targ.responseToken->length = mech_token->length; - targ.responseToken->data = mech_token->value; - mech_token->length = 0; - mech_token->value = NULL; - } else { - targ.responseToken = NULL; - } - - ret = _gss_spnego_require_mechlist_mic(minor_status, context_handle, - &require_mic); - if (ret) { - free_NegTokenTarg(&targ); - return ret; - } - - if (major_status == GSS_S_COMPLETE && require_mic) { - size_t buf_len; - - ALLOC(targ.mechListMIC, 1); - if (targ.mechListMIC == NULL) { - free_NegTokenTarg(&targ); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length, - mechtypelist, &buf_len, ret); - if (ret) { - free_NegTokenTarg(&targ); - return ret; - } - if (mech_buf.length != buf_len) - abort(); - - ret = gss_get_mic(minor_status, context_handle, 0, &mech_buf, - &mech_mic_buf); - free (mech_buf.value); - if (ret) { - free_NegTokenTarg(&targ); - return ret; - } - - targ.mechListMIC->length = mech_mic_buf.length; - targ.mechListMIC->data = mech_mic_buf.value; - } else - targ.mechListMIC = NULL; - - ret = code_NegTokenArg (minor_status, &targ, &data, &buf); - free_NegTokenTarg(&targ); - if (ret) - return ret; - -#if 0 - ret = _gssapi_encapsulate(minor_status, - &data, - output_token, - GSS_SPNEGO_MECHANISM); -#else - output_token->value = malloc(data.length); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - } else { - output_token->length = data.length; - memcpy(output_token->value, data.data, output_token->length); - } -#endif - free(buf); - if (ret) - return ret; - return GSS_S_COMPLETE; -} - -static OM_uint32 -spnego_accept_sec_context - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t * src_name, - gss_OID * mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec, - gss_cred_id_t * delegated_cred_handle - ) -{ - OM_uint32 ret, ret2; - NegTokenInit ni; - size_t ni_len; - int i; - int found = 0; - krb5_data data; - size_t len, taglen; - - output_token->length = 0; - output_token->value = NULL; - - ret = _gssapi_decapsulate (minor_status, - input_token_buffer, - &data, - GSS_SPNEGO_MECHANISM); - if (ret) - return ret; - - ret = der_match_tag_and_length(data.data, data.length, - ASN1_C_CONTEXT, CONS, 0, &len, &taglen); - if (ret) - return ret; - - if(len > data.length - taglen) - return ASN1_OVERRUN; - - ret = decode_NegTokenInit((const unsigned char *)data.data + taglen, len, - &ni, &ni_len); - if (ret) - return GSS_S_DEFECTIVE_TOKEN; - - if (ni.mechTypes == NULL) { - free_NegTokenInit(&ni); - return send_reject (minor_status, output_token); - } - - for (i = 0; !found && i < ni.mechTypes->len; ++i) { - unsigned char mechbuf[17]; - size_t mech_len; - - ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1, - sizeof(mechbuf), - &ni.mechTypes->val[i], - &mech_len); - if (ret) { - free_NegTokenInit(&ni); - return GSS_S_DEFECTIVE_TOKEN; - } - if (mech_len == GSS_KRB5_MECHANISM->length - && memcmp(GSS_KRB5_MECHANISM->elements, - mechbuf + sizeof(mechbuf) - mech_len, - mech_len) == 0) - found = 1; - } - if (found) { - gss_buffer_desc ibuf, obuf; - gss_buffer_t ot = NULL; - OM_uint32 minor; - - if (ni.mechToken != NULL) { - ibuf.length = ni.mechToken->length; - ibuf.value = ni.mechToken->data; - - ret = gsskrb5_accept_sec_context(&minor, - context_handle, - acceptor_cred_handle, - &ibuf, - input_chan_bindings, - src_name, - mech_type, - &obuf, - ret_flags, - time_rec, - delegated_cred_handle); - if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - ot = &obuf; - } else { - free_NegTokenInit(&ni); - send_reject (minor_status, output_token); - return ret; - } - } - ret2 = send_accept (minor_status, ret, output_token, ot, - *context_handle, ni.mechTypes); - if (ret2 != GSS_S_COMPLETE) - ret = ret2; - if (ot != NULL) - gss_release_buffer(&minor, ot); - free_NegTokenInit(&ni); - return ret; - } else { - free_NegTokenInit(&ni); - return send_reject (minor_status, output_token); - } -} - -OM_uint32 -gss_accept_sec_context - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_cred_id_t acceptor_cred_handle, - const gss_buffer_t input_token_buffer, - const gss_channel_bindings_t input_chan_bindings, - gss_name_t * src_name, - gss_OID * mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec, - gss_cred_id_t * delegated_cred_handle - ) -{ - OM_uint32 ret; - ssize_t mech_len; - const u_char *p; - - *minor_status = 0; - - mech_len = gssapi_krb5_get_mech (input_token_buffer->value, - input_token_buffer->length, - &p); - - /* This could be 'dce style' kerberos, where the OID is missing :-( */ - if ((mech_len < 0) || ((mech_len == GSS_KRB5_MECHANISM->length) - && memcmp(p, GSS_KRB5_MECHANISM->elements, mech_len) == 0)) - ret = gsskrb5_accept_sec_context(minor_status, - context_handle, - acceptor_cred_handle, - input_token_buffer, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle); - else if (mech_len == GSS_SPNEGO_MECHANISM->length - && memcmp(p, GSS_SPNEGO_MECHANISM->elements, mech_len) == 0) - ret = spnego_accept_sec_context(minor_status, - context_handle, - acceptor_cred_handle, - input_token_buffer, - input_chan_bindings, - src_name, - mech_type, - output_token, - ret_flags, - time_rec, - delegated_cred_handle); - else - return GSS_S_BAD_MECH; - - return ret; -} diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi.h index eac2737f43..340b35377d 100644 --- a/source4/heimdal/lib/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,802 +31,11 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h,v 1.40 2006/05/05 11:08:29 lha Exp $ */ +/* $Id: gssapi.h,v 1.50 2006/10/07 20:57:15 lha Exp $ */ #ifndef GSSAPI_H_ #define GSSAPI_H_ -/* - * First, include stddef.h to get size_t defined. - */ -#include <stddef.h> - -#include <krb5-types.h> - -/* - * Now define the three implementation-dependent types. - */ - -typedef uint32_t OM_uint32; - -typedef uint32_t gss_uint32; - -/* - * This is to avoid having to include <krb5.h> - */ - -struct krb5_auth_context_data; - -struct Principal; - -/* typedef void *gss_name_t; */ - -typedef struct Principal *gss_name_t; - -struct gss_ctx_id_t_desc_struct; -typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t; - -typedef struct gss_OID_desc_struct { - OM_uint32 length; - void *elements; -} gss_OID_desc, *gss_OID; - -typedef struct gss_OID_set_desc_struct { - size_t count; - gss_OID elements; -} gss_OID_set_desc, *gss_OID_set; - -struct krb5_keytab_data; - -struct krb5_ccache_data; - -typedef int gss_cred_usage_t; - -struct gss_cred_id_t_desc_struct; -typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t; - -typedef struct gss_buffer_desc_struct { - size_t length; - void *value; -} gss_buffer_desc, *gss_buffer_t; - -typedef struct gss_channel_bindings_struct { - OM_uint32 initiator_addrtype; - gss_buffer_desc initiator_address; - OM_uint32 acceptor_addrtype; - gss_buffer_desc acceptor_address; - gss_buffer_desc application_data; -} *gss_channel_bindings_t; - -/* - * For now, define a QOP-type as an OM_uint32 - */ -typedef OM_uint32 gss_qop_t; - -/* - * Flag bits for context-level services. - */ -#define GSS_C_DELEG_FLAG 1 /* 0x00000001 */ -#define GSS_C_MUTUAL_FLAG 2 /* 0x00000002 */ -#define GSS_C_REPLAY_FLAG 4 /* 0x00000004 */ -#define GSS_C_SEQUENCE_FLAG 8 /* 0x00000008 */ -#define GSS_C_CONF_FLAG 16 /* 0x00000010 */ -#define GSS_C_INTEG_FLAG 32 /* 0x00000020 */ -#define GSS_C_ANON_FLAG 64 /* 0x00000040 */ -#define GSS_C_PROT_READY_FLAG 128 /* 0x00000080 */ -#define GSS_C_TRANS_FLAG 256 /* 0x00000100 */ - -/* these are from draft-brezak-win2k-krb-rc4-hmac-04.txt */ -#define GSS_C_DCE_STYLE 4096 /* 0x00001000 */ -#define GSS_C_IDENTIFY_FLAG 8192 /* 0x00002000 */ -#define GSS_C_EXTENDED_ERROR_FLAG 16384 /* 0x00004000 */ - -/* - * Credential usage options - */ -#define GSS_C_BOTH 0 -#define GSS_C_INITIATE 1 -#define GSS_C_ACCEPT 2 - -/* - * Status code types for gss_display_status - */ -#define GSS_C_GSS_CODE 1 -#define GSS_C_MECH_CODE 2 - -/* - * The constant definitions for channel-bindings address families - */ -#define GSS_C_AF_UNSPEC 0 -#define GSS_C_AF_LOCAL 1 -#define GSS_C_AF_INET 2 -#define GSS_C_AF_IMPLINK 3 -#define GSS_C_AF_PUP 4 -#define GSS_C_AF_CHAOS 5 -#define GSS_C_AF_NS 6 -#define GSS_C_AF_NBS 7 -#define GSS_C_AF_ECMA 8 -#define GSS_C_AF_DATAKIT 9 -#define GSS_C_AF_CCITT 10 -#define GSS_C_AF_SNA 11 -#define GSS_C_AF_DECnet 12 -#define GSS_C_AF_DLI 13 -#define GSS_C_AF_LAT 14 -#define GSS_C_AF_HYLINK 15 -#define GSS_C_AF_APPLETALK 16 -#define GSS_C_AF_BSC 17 -#define GSS_C_AF_DSS 18 -#define GSS_C_AF_OSI 19 -#define GSS_C_AF_X25 21 -#define GSS_C_AF_INET6 24 - -#define GSS_C_AF_NULLADDR 255 - -/* - * Various Null values - */ -#define GSS_C_NO_NAME ((gss_name_t) 0) -#define GSS_C_NO_BUFFER ((gss_buffer_t) 0) -#define GSS_C_NO_OID ((gss_OID) 0) -#define GSS_C_NO_OID_SET ((gss_OID_set) 0) -#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0) -#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0) -#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0) -#define GSS_C_EMPTY_BUFFER {0, NULL} - -/* - * Some alternate names for a couple of the above - * values. These are defined for V1 compatibility. - */ -#define GSS_C_NULL_OID GSS_C_NO_OID -#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET - -/* - * Define the default Quality of Protection for per-message - * services. Note that an implementation that offers multiple - * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero - * (as done here) to mean "default protection", or to a specific - * explicit QOP value. However, a value of 0 should always be - * interpreted by a GSSAPI implementation as a request for the - * default protection level. - */ -#define GSS_C_QOP_DEFAULT 0 - -#define GSS_KRB5_CONF_C_QOP_DES 0x0100 -#define GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200 - -/* - * Expiration time of 2^32-1 seconds means infinite lifetime for a - * credential or security context - */ -#define GSS_C_INDEFINITE 0xfffffffful - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" - * "\x01\x02\x01\x01"}, - * corresponding to an object-identifier value of - * {iso(1) member-body(2) United States(840) mit(113554) - * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant - * GSS_C_NT_USER_NAME should be initialized to point - * to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_USER_NAME; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" - * "\x01\x02\x01\x02"}, - * corresponding to an object-identifier value of - * {iso(1) member-body(2) United States(840) mit(113554) - * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. - * The constant GSS_C_NT_MACHINE_UID_NAME should be - * initialized to point to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_MACHINE_UID_NAME; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" - * "\x01\x02\x01\x03"}, - * corresponding to an object-identifier value of - * {iso(1) member-body(2) United States(840) mit(113554) - * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. - * The constant GSS_C_NT_STRING_UID_NAME should be - * initialized to point to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_STRING_UID_NAME; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, - * corresponding to an object-identifier value of - * {iso(1) org(3) dod(6) internet(1) security(5) - * nametypes(6) gss-host-based-services(2)). The constant - * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point - * to that gss_OID_desc. This is a deprecated OID value, and - * implementations wishing to support hostbased-service names - * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID, - * defined below, to identify such names; - * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym - * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input - * parameter, but should not be emitted by GSS-API - * implementations - */ -extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" - * "\x01\x02\x01\x04"}, corresponding to an - * object-identifier value of {iso(1) member-body(2) - * Unites States(840) mit(113554) infosys(1) gssapi(2) - * generic(1) service_name(4)}. The constant - * GSS_C_NT_HOSTBASED_SERVICE should be initialized - * to point to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_HOSTBASED_SERVICE; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {6, (void *)"\x2b\x06\01\x05\x06\x03"}, - * corresponding to an object identifier value of - * {1(iso), 3(org), 6(dod), 1(internet), 5(security), - * 6(nametypes), 3(gss-anonymous-name)}. The constant - * and GSS_C_NT_ANONYMOUS should be initialized to point - * to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_ANONYMOUS; - -/* - * The implementation must reserve static storage for a - * gss_OID_desc object containing the value - * {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, - * corresponding to an object-identifier value of - * {1(iso), 3(org), 6(dod), 1(internet), 5(security), - * 6(nametypes), 4(gss-api-exported-name)}. The constant - * GSS_C_NT_EXPORT_NAME should be initialized to point - * to that gss_OID_desc. - */ -extern gss_OID GSS_C_NT_EXPORT_NAME; - -/* - * RFC2478, SPNEGO: - * The security mechanism of the initial - * negotiation token is identified by the Object Identifier - * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2). - */ -extern gss_OID GSS_SPNEGO_MECHANISM; - -/* - * This if for kerberos5 names. - */ - -extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME; -extern gss_OID GSS_KRB5_NT_USER_NAME; -extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME; -extern gss_OID GSS_KRB5_NT_STRING_UID_NAME; - -extern gss_OID GSS_KRB5_MECHANISM; - -/* for compatibility with MIT api */ - -#define gss_mech_krb5 GSS_KRB5_MECHANISM -#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME +#include <gssapi/gssapi.h> -/* Major status codes */ - -#define GSS_S_COMPLETE 0 - -/* - * Some "helper" definitions to make the status code macros obvious. - */ -#define GSS_C_CALLING_ERROR_OFFSET 24 -#define GSS_C_ROUTINE_ERROR_OFFSET 16 -#define GSS_C_SUPPLEMENTARY_OFFSET 0 -#define GSS_C_CALLING_ERROR_MASK 0377ul -#define GSS_C_ROUTINE_ERROR_MASK 0377ul -#define GSS_C_SUPPLEMENTARY_MASK 0177777ul - -/* - * The macros that test status codes for error conditions. - * Note that the GSS_ERROR() macro has changed slightly from - * the V1 GSSAPI so that it now evaluates its argument - * only once. - */ -#define GSS_CALLING_ERROR(x) \ - (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) -#define GSS_ROUTINE_ERROR(x) \ - (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) -#define GSS_SUPPLEMENTARY_INFO(x) \ - (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) -#define GSS_ERROR(x) \ - (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ - (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) - -/* - * Now the actual status code definitions - */ - -/* - * Calling errors: - */ -#define GSS_S_CALL_INACCESSIBLE_READ \ - (1ul << GSS_C_CALLING_ERROR_OFFSET) -#define GSS_S_CALL_INACCESSIBLE_WRITE \ - (2ul << GSS_C_CALLING_ERROR_OFFSET) -#define GSS_S_CALL_BAD_STRUCTURE \ - (3ul << GSS_C_CALLING_ERROR_OFFSET) - -/* - * Routine errors: - */ -#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET) - -#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_MIC GSS_S_BAD_SIG -#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET) -#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET) - -/* - * Supplementary info bits: - */ -#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) -#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) -#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) -#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) -#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) - -/* - * From RFC1964: - * - * 4.1.1. Non-Kerberos-specific codes - */ - -#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1 - /* "No @ in SERVICE-NAME name string" */ -#define GSS_KRB5_S_G_BAD_STRING_UID 2 - /* "STRING-UID-NAME contains nondigits" */ -#define GSS_KRB5_S_G_NOUSER 3 - /* "UID does not resolve to username" */ -#define GSS_KRB5_S_G_VALIDATE_FAILED 4 - /* "Validation error" */ -#define GSS_KRB5_S_G_BUFFER_ALLOC 5 - /* "Couldn't allocate gss_buffer_t data" */ -#define GSS_KRB5_S_G_BAD_MSG_CTX 6 - /* "Message context invalid" */ -#define GSS_KRB5_S_G_WRONG_SIZE 7 - /* "Buffer is the wrong size" */ -#define GSS_KRB5_S_G_BAD_USAGE 8 - /* "Credential usage type is unknown" */ -#define GSS_KRB5_S_G_UNKNOWN_QOP 9 - /* "Unknown quality of protection specified" */ - - /* - * 4.1.2. Kerberos-specific-codes - */ - -#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10 - /* "Principal in credential cache does not match desired name" */ -#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11 - /* "No principal in keytab matches desired name" */ -#define GSS_KRB5_S_KG_TGT_MISSING 12 - /* "Credential cache has no TGT" */ -#define GSS_KRB5_S_KG_NO_SUBKEY 13 - /* "Authenticator has no subkey" */ -#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14 - /* "Context is already fully established" */ -#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15 - /* "Unknown signature type in token" */ -#define GSS_KRB5_S_KG_BAD_LENGTH 16 - /* "Invalid field length in token" */ -#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17 - /* "Attempt to use incomplete security context" */ - -/* - * Finally, function prototypes for the GSS-API routines. - */ - - -OM_uint32 gss_acquire_cred - (OM_uint32 * /*minor_status*/, - const gss_name_t /*desired_name*/, - OM_uint32 /*time_req*/, - const gss_OID_set /*desired_mechs*/, - gss_cred_usage_t /*cred_usage*/, - gss_cred_id_t * /*output_cred_handle*/, - gss_OID_set * /*actual_mechs*/, - OM_uint32 * /*time_rec*/ - ); - -OM_uint32 gss_release_cred - (OM_uint32 * /*minor_status*/, - gss_cred_id_t * /*cred_handle*/ - ); - -OM_uint32 gss_init_sec_context - (OM_uint32 * /*minor_status*/, - const gss_cred_id_t /*initiator_cred_handle*/, - gss_ctx_id_t * /*context_handle*/, - const gss_name_t /*target_name*/, - const gss_OID /*mech_type*/, - OM_uint32 /*req_flags*/, - OM_uint32 /*time_req*/, - const gss_channel_bindings_t /*input_chan_bindings*/, - const gss_buffer_t /*input_token*/, - gss_OID * /*actual_mech_type*/, - gss_buffer_t /*output_token*/, - OM_uint32 * /*ret_flags*/, - OM_uint32 * /*time_rec*/ - ); - -OM_uint32 gss_accept_sec_context - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t * /*context_handle*/, - const gss_cred_id_t /*acceptor_cred_handle*/, - const gss_buffer_t /*input_token_buffer*/, - const gss_channel_bindings_t /*input_chan_bindings*/, - gss_name_t * /*src_name*/, - gss_OID * /*mech_type*/, - gss_buffer_t /*output_token*/, - OM_uint32 * /*ret_flags*/, - OM_uint32 * /*time_rec*/, - gss_cred_id_t * /*delegated_cred_handle*/ - ); - -OM_uint32 gss_process_context_token - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - const gss_buffer_t /*token_buffer*/ - ); - -OM_uint32 gss_delete_sec_context - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t * /*context_handle*/, - gss_buffer_t /*output_token*/ - ); - -OM_uint32 gss_context_time - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - OM_uint32 * /*time_rec*/ - ); - -OM_uint32 gss_get_mic - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - gss_qop_t /*qop_req*/, - const gss_buffer_t /*message_buffer*/, - gss_buffer_t /*message_token*/ - ); - -OM_uint32 gss_verify_mic - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - const gss_buffer_t /*message_buffer*/, - const gss_buffer_t /*token_buffer*/, - gss_qop_t * /*qop_state*/ - ); - -OM_uint32 gss_wrap - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - int /*conf_req_flag*/, - gss_qop_t /*qop_req*/, - const gss_buffer_t /*input_message_buffer*/, - int * /*conf_state*/, - gss_buffer_t /*output_message_buffer*/ - ); - -OM_uint32 gss_unwrap - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - const gss_buffer_t /*input_message_buffer*/, - gss_buffer_t /*output_message_buffer*/, - int * /*conf_state*/, - gss_qop_t * /*qop_state*/ - ); - -OM_uint32 gss_display_status - (OM_uint32 * /*minor_status*/, - OM_uint32 /*status_value*/, - int /*status_type*/, - const gss_OID /*mech_type*/, - OM_uint32 * /*message_context*/, - gss_buffer_t /*status_string*/ - ); - -OM_uint32 gss_indicate_mechs - (OM_uint32 * /*minor_status*/, - gss_OID_set * /*mech_set*/ - ); - -OM_uint32 gss_compare_name - (OM_uint32 * /*minor_status*/, - const gss_name_t /*name1*/, - const gss_name_t /*name2*/, - int * /*name_equal*/ - ); - -OM_uint32 gss_display_name - (OM_uint32 * /*minor_status*/, - const gss_name_t /*input_name*/, - gss_buffer_t /*output_name_buffer*/, - gss_OID * /*output_name_type*/ - ); - -OM_uint32 gss_import_name - (OM_uint32 * /*minor_status*/, - const gss_buffer_t /*input_name_buffer*/, - const gss_OID /*input_name_type*/, - gss_name_t * /*output_name*/ - ); - -OM_uint32 gss_export_name - (OM_uint32 * /*minor_status*/, - const gss_name_t /*input_name*/, - gss_buffer_t /*exported_name*/ - ); - -OM_uint32 gss_release_name - (OM_uint32 * /*minor_status*/, - gss_name_t * /*input_name*/ - ); - -OM_uint32 gss_release_buffer - (OM_uint32 * /*minor_status*/, - gss_buffer_t /*buffer*/ - ); - -OM_uint32 gss_release_oid_set - (OM_uint32 * /*minor_status*/, - gss_OID_set * /*set*/ - ); - -OM_uint32 gss_inquire_cred - (OM_uint32 * /*minor_status*/, - const gss_cred_id_t /*cred_handle*/, - gss_name_t * /*name*/, - OM_uint32 * /*lifetime*/, - gss_cred_usage_t * /*cred_usage*/, - gss_OID_set * /*mechanisms*/ - ); - -OM_uint32 gss_inquire_context ( - OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - gss_name_t * /*src_name*/, - gss_name_t * /*targ_name*/, - OM_uint32 * /*lifetime_rec*/, - gss_OID * /*mech_type*/, - OM_uint32 * /*ctx_flags*/, - int * /*locally_initiated*/, - int * /*open_context*/ - ); - -OM_uint32 gsskrb5_wrap_size ( - OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - int /*conf_req_flag*/, - gss_qop_t /*qop_req*/, - OM_uint32 /*req_input_size*/, - OM_uint32 * /*output_size*/ - ); - -OM_uint32 gss_wrap_size_limit ( - OM_uint32 * /*minor_status*/, - const gss_ctx_id_t /*context_handle*/, - int /*conf_req_flag*/, - gss_qop_t /*qop_req*/, - OM_uint32 /*req_output_size*/, - OM_uint32 * /*max_input_size*/ - ); - -OM_uint32 gss_add_cred ( - OM_uint32 * /*minor_status*/, - const gss_cred_id_t /*input_cred_handle*/, - const gss_name_t /*desired_name*/, - const gss_OID /*desired_mech*/, - gss_cred_usage_t /*cred_usage*/, - OM_uint32 /*initiator_time_req*/, - OM_uint32 /*acceptor_time_req*/, - gss_cred_id_t * /*output_cred_handle*/, - gss_OID_set * /*actual_mechs*/, - OM_uint32 * /*initiator_time_rec*/, - OM_uint32 * /*acceptor_time_rec*/ - ); - -OM_uint32 gss_inquire_cred_by_mech ( - OM_uint32 * /*minor_status*/, - const gss_cred_id_t /*cred_handle*/, - const gss_OID /*mech_type*/, - gss_name_t * /*name*/, - OM_uint32 * /*initiator_lifetime*/, - OM_uint32 * /*acceptor_lifetime*/, - gss_cred_usage_t * /*cred_usage*/ - ); - -OM_uint32 gss_export_sec_context ( - OM_uint32 * /*minor_status*/, - gss_ctx_id_t * /*context_handle*/, - gss_buffer_t /*interprocess_token*/ - ); - -OM_uint32 gss_import_sec_context ( - OM_uint32 * /*minor_status*/, - const gss_buffer_t /*interprocess_token*/, - gss_ctx_id_t * /*context_handle*/ - ); - -OM_uint32 gss_create_empty_oid_set ( - OM_uint32 * /*minor_status*/, - gss_OID_set * /*oid_set*/ - ); - -OM_uint32 gss_add_oid_set_member ( - OM_uint32 * /*minor_status*/, - const gss_OID /*member_oid*/, - gss_OID_set * /*oid_set*/ - ); - -OM_uint32 gss_test_oid_set_member ( - OM_uint32 * /*minor_status*/, - const gss_OID /*member*/, - const gss_OID_set /*set*/, - int * /*present*/ - ); - -OM_uint32 gss_inquire_names_for_mech ( - OM_uint32 * /*minor_status*/, - const gss_OID /*mechanism*/, - gss_OID_set * /*name_types*/ - ); - -OM_uint32 gss_inquire_mechs_for_name ( - OM_uint32 * /*minor_status*/, - const gss_name_t /*input_name*/, - gss_OID_set * /*mech_types*/ - ); - -OM_uint32 gss_canonicalize_name ( - OM_uint32 * /*minor_status*/, - const gss_name_t /*input_name*/, - const gss_OID /*mech_type*/, - gss_name_t * /*output_name*/ - ); - -OM_uint32 gss_duplicate_name ( - OM_uint32 * /*minor_status*/, - const gss_name_t /*src_name*/, - gss_name_t * /*dest_name*/ - ); - -/* - * The following routines are obsolete variants of gss_get_mic, - * gss_verify_mic, gss_wrap and gss_unwrap. They should be - * provided by GSSAPI V2 implementations for backwards - * compatibility with V1 applications. Distinct entrypoints - * (as opposed to #defines) should be provided, both to allow - * GSSAPI V1 applications to link against GSSAPI V2 implementations, - * and to retain the slight parameter type differences between the - * obsolete versions of these routines and their current forms. - */ - -OM_uint32 gss_sign - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t /*context_handle*/, - int /*qop_req*/, - gss_buffer_t /*message_buffer*/, - gss_buffer_t /*message_token*/ - ); - -OM_uint32 gss_verify - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t /*context_handle*/, - gss_buffer_t /*message_buffer*/, - gss_buffer_t /*token_buffer*/, - int * /*qop_state*/ - ); - -OM_uint32 gss_seal - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t /*context_handle*/, - int /*conf_req_flag*/, - int /*qop_req*/, - gss_buffer_t /*input_message_buffer*/, - int * /*conf_state*/, - gss_buffer_t /*output_message_buffer*/ - ); - -OM_uint32 gss_unseal - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t /*context_handle*/, - gss_buffer_t /*input_message_buffer*/, - gss_buffer_t /*output_message_buffer*/, - int * /*conf_state*/, - int * /*qop_state*/ - ); - -/* - * kerberos mechanism specific functions - */ - -OM_uint32 -gss_krb5_ccache_name(OM_uint32 * /*minor_status*/, - const char * /*name */, - const char ** /*out_name */); - -OM_uint32 gsskrb5_register_acceptor_identity - (const char */*identity*/); - -OM_uint32 gss_krb5_copy_ccache - (OM_uint32 */*minor*/, - gss_cred_id_t /*cred*/, - struct krb5_ccache_data */*out*/); - -OM_uint32 gss_krb5_copy_service_keyblock - (OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - struct EncryptionKey **out); - -OM_uint32 gss_krb5_import_cred(OM_uint32 *minor_status, - struct krb5_ccache_data * /* id */, - struct Principal * /* keytab_principal */, - struct krb5_keytab_data * /* keytab */, - gss_cred_id_t */* cred */); - -OM_uint32 gss_krb5_get_tkt_flags - (OM_uint32 */*minor*/, - gss_ctx_id_t /*context_handle*/, - OM_uint32 */*tkt_flags*/); - -OM_uint32 -gsskrb5_extract_authz_data_from_sec_context - (OM_uint32 * /*minor_status*/, - gss_ctx_id_t /*context_handle*/, - int /*ad_type*/, - gss_buffer_t /*ad_data*/); -OM_uint32 -gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - time_t *authtime); -OM_uint32 -gsskrb5_get_initiator_subkey - (OM_uint32 * /*minor_status*/, - const gss_ctx_id_t context_handle, - gss_buffer_t /* subkey */); - -#define GSS_C_KRB5_COMPAT_DES3_MIC 1 - -OM_uint32 -gss_krb5_compat_des3_mic(OM_uint32 *, gss_ctx_id_t, int); - -#ifdef __cplusplus -} #endif - -#endif /* GSSAPI_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h new file mode 100644 index 0000000000..238907653e --- /dev/null +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -0,0 +1,837 @@ +/* + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: gssapi.h,v 1.5 2006/10/19 07:11:14 lha Exp $ */ + +#ifndef GSSAPI_GSSAPI_H_ +#define GSSAPI_GSSAPI_H_ + +/* + * First, include stddef.h to get size_t defined. + */ +#include <stddef.h> + +#include <krb5-types.h> + +/* + * Now define the three implementation-dependent types. + */ + +typedef uint32_t OM_uint32; +typedef uint64_t OM_uint64; + +typedef uint32_t gss_uint32; + +struct gss_name_t_desc_struct; +typedef struct gss_name_t_desc_struct *gss_name_t; + +struct gss_ctx_id_t_desc_struct; +typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t; + +typedef struct gss_OID_desc_struct { + OM_uint32 length; + void *elements; +} gss_OID_desc, *gss_OID; + +typedef struct gss_OID_set_desc_struct { + size_t count; + gss_OID elements; +} gss_OID_set_desc, *gss_OID_set; + +typedef int gss_cred_usage_t; + +struct gss_cred_id_t_desc_struct; +typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t; + +typedef struct gss_buffer_desc_struct { + size_t length; + void *value; +} gss_buffer_desc, *gss_buffer_t; + +typedef struct gss_channel_bindings_struct { + OM_uint32 initiator_addrtype; + gss_buffer_desc initiator_address; + OM_uint32 acceptor_addrtype; + gss_buffer_desc acceptor_address; + gss_buffer_desc application_data; +} *gss_channel_bindings_t; + +/* GGF extension data types */ +typedef struct gss_buffer_set_desc_struct { + size_t count; + gss_buffer_desc *elements; +} gss_buffer_set_desc, *gss_buffer_set_t; + +/* + * For now, define a QOP-type as an OM_uint32 + */ +typedef OM_uint32 gss_qop_t; + +/* + * Flag bits for context-level services. + */ +#define GSS_C_DELEG_FLAG 1 +#define GSS_C_MUTUAL_FLAG 2 +#define GSS_C_REPLAY_FLAG 4 +#define GSS_C_SEQUENCE_FLAG 8 +#define GSS_C_CONF_FLAG 16 +#define GSS_C_INTEG_FLAG 32 +#define GSS_C_ANON_FLAG 64 +#define GSS_C_PROT_READY_FLAG 128 +#define GSS_C_TRANS_FLAG 256 + +#define GSS_C_DCE_STYLE 4096 +#define GSS_C_IDENTIFY_FLAG 8192 +#define GSS_C_EXTENDED_ERROR_FLAG 16384 + +/* + * Credential usage options + */ +#define GSS_C_BOTH 0 +#define GSS_C_INITIATE 1 +#define GSS_C_ACCEPT 2 + +/* + * Status code types for gss_display_status + */ +#define GSS_C_GSS_CODE 1 +#define GSS_C_MECH_CODE 2 + +/* + * The constant definitions for channel-bindings address families + */ +#define GSS_C_AF_UNSPEC 0 +#define GSS_C_AF_LOCAL 1 +#define GSS_C_AF_INET 2 +#define GSS_C_AF_IMPLINK 3 +#define GSS_C_AF_PUP 4 +#define GSS_C_AF_CHAOS 5 +#define GSS_C_AF_NS 6 +#define GSS_C_AF_NBS 7 +#define GSS_C_AF_ECMA 8 +#define GSS_C_AF_DATAKIT 9 +#define GSS_C_AF_CCITT 10 +#define GSS_C_AF_SNA 11 +#define GSS_C_AF_DECnet 12 +#define GSS_C_AF_DLI 13 +#define GSS_C_AF_LAT 14 +#define GSS_C_AF_HYLINK 15 +#define GSS_C_AF_APPLETALK 16 +#define GSS_C_AF_BSC 17 +#define GSS_C_AF_DSS 18 +#define GSS_C_AF_OSI 19 +#define GSS_C_AF_X25 21 +#define GSS_C_AF_INET6 24 + +#define GSS_C_AF_NULLADDR 255 + +/* + * Various Null values + */ +#define GSS_C_NO_NAME ((gss_name_t) 0) +#define GSS_C_NO_BUFFER ((gss_buffer_t) 0) +#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t) 0) +#define GSS_C_NO_OID ((gss_OID) 0) +#define GSS_C_NO_OID_SET ((gss_OID_set) 0) +#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0) +#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0) +#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0) +#define GSS_C_EMPTY_BUFFER {0, NULL} + +/* + * Some alternate names for a couple of the above + * values. These are defined for V1 compatibility. + */ +#define GSS_C_NULL_OID GSS_C_NO_OID +#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET + +/* + * Define the default Quality of Protection for per-message + * services. Note that an implementation that offers multiple + * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero + * (as done here) to mean "default protection", or to a specific + * explicit QOP value. However, a value of 0 should always be + * interpreted by a GSSAPI implementation as a request for the + * default protection level. + */ +#define GSS_C_QOP_DEFAULT 0 + +#define GSS_KRB5_CONF_C_QOP_DES 0x0100 +#define GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200 + +/* + * Expiration time of 2^32-1 seconds means infinite lifetime for a + * credential or security context + */ +#define GSS_C_INDEFINITE 0xfffffffful + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x01"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant + * GSS_C_NT_USER_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_USER_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x02"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. + * The constant GSS_C_NT_MACHINE_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_MACHINE_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x03"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. + * The constant GSS_C_NT_STRING_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_STRING_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, + * corresponding to an object-identifier value of + * {iso(1) org(3) dod(6) internet(1) security(5) + * nametypes(6) gss-host-based-services(2)). The constant + * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point + * to that gss_OID_desc. This is a deprecated OID value, and + * implementations wishing to support hostbased-service names + * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID, + * defined below, to identify such names; + * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym + * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input + * parameter, but should not be emitted by GSS-API + * implementations + */ +extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x04"}, corresponding to an + * object-identifier value of {iso(1) member-body(2) + * Unites States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4)}. The constant + * GSS_C_NT_HOSTBASED_SERVICE should be initialized + * to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_HOSTBASED_SERVICE; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\01\x05\x06\x03"}, + * corresponding to an object identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 3(gss-anonymous-name)}. The constant + * and GSS_C_NT_ANONYMOUS should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_ANONYMOUS; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, + * corresponding to an object-identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 4(gss-api-exported-name)}. The constant + * GSS_C_NT_EXPORT_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_EXPORT_NAME; + +/* + * Digest mechanism + */ + +extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM; + +/* Major status codes */ + +#define GSS_S_COMPLETE 0 + +/* + * Some "helper" definitions to make the status code macros obvious. + */ +#define GSS_C_CALLING_ERROR_OFFSET 24 +#define GSS_C_ROUTINE_ERROR_OFFSET 16 +#define GSS_C_SUPPLEMENTARY_OFFSET 0 +#define GSS_C_CALLING_ERROR_MASK 0377ul +#define GSS_C_ROUTINE_ERROR_MASK 0377ul +#define GSS_C_SUPPLEMENTARY_MASK 0177777ul + +/* + * The macros that test status codes for error conditions. + * Note that the GSS_ERROR() macro has changed slightly from + * the V1 GSSAPI so that it now evaluates its argument + * only once. + */ +#define GSS_CALLING_ERROR(x) \ + (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) +#define GSS_ROUTINE_ERROR(x) \ + (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) +#define GSS_SUPPLEMENTARY_INFO(x) \ + (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) +#define GSS_ERROR(x) \ + (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ + (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) + +/* + * Now the actual status code definitions + */ + +/* + * Calling errors: + */ +#define GSS_S_CALL_INACCESSIBLE_READ \ + (1ul << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_INACCESSIBLE_WRITE \ + (2ul << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_BAD_STRUCTURE \ + (3ul << GSS_C_CALLING_ERROR_OFFSET) + +/* + * Routine errors: + */ +#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET) + +#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_MIC GSS_S_BAD_SIG +#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET) + +/* + * Supplementary info bits: + */ +#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) +#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) +#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) +#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) +#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) + +/* + * From RFC1964: + * + * 4.1.1. Non-Kerberos-specific codes + */ + +#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1 + /* "No @ in SERVICE-NAME name string" */ +#define GSS_KRB5_S_G_BAD_STRING_UID 2 + /* "STRING-UID-NAME contains nondigits" */ +#define GSS_KRB5_S_G_NOUSER 3 + /* "UID does not resolve to username" */ +#define GSS_KRB5_S_G_VALIDATE_FAILED 4 + /* "Validation error" */ +#define GSS_KRB5_S_G_BUFFER_ALLOC 5 + /* "Couldn't allocate gss_buffer_t data" */ +#define GSS_KRB5_S_G_BAD_MSG_CTX 6 + /* "Message context invalid" */ +#define GSS_KRB5_S_G_WRONG_SIZE 7 + /* "Buffer is the wrong size" */ +#define GSS_KRB5_S_G_BAD_USAGE 8 + /* "Credential usage type is unknown" */ +#define GSS_KRB5_S_G_UNKNOWN_QOP 9 + /* "Unknown quality of protection specified" */ + + /* + * 4.1.2. Kerberos-specific-codes + */ + +#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10 + /* "Principal in credential cache does not match desired name" */ +#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11 + /* "No principal in keytab matches desired name" */ +#define GSS_KRB5_S_KG_TGT_MISSING 12 + /* "Credential cache has no TGT" */ +#define GSS_KRB5_S_KG_NO_SUBKEY 13 + /* "Authenticator has no subkey" */ +#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14 + /* "Context is already fully established" */ +#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15 + /* "Unknown signature type in token" */ +#define GSS_KRB5_S_KG_BAD_LENGTH 16 + /* "Invalid field length in token" */ +#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17 + /* "Attempt to use incomplete security context" */ + +/* + * This is used to make sure mechs that don't want to have external + * references don't get any prototypes, and thus can get warnings. + */ + +/* + * Finally, function prototypes for the GSS-API routines. + */ + +OM_uint32 gss_acquire_cred + (OM_uint32 * /*minor_status*/, + const gss_name_t /*desired_name*/, + OM_uint32 /*time_req*/, + const gss_OID_set /*desired_mechs*/, + gss_cred_usage_t /*cred_usage*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * /*time_rec*/ + ); + +OM_uint32 gss_release_cred + (OM_uint32 * /*minor_status*/, + gss_cred_id_t * /*cred_handle*/ + ); + +OM_uint32 gss_init_sec_context + (OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*initiator_cred_handle*/, + gss_ctx_id_t * /*context_handle*/, + const gss_name_t /*target_name*/, + const gss_OID /*mech_type*/, + OM_uint32 /*req_flags*/, + OM_uint32 /*time_req*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + const gss_buffer_t /*input_token*/, + gss_OID * /*actual_mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * /*time_rec*/ + ); + +OM_uint32 gss_accept_sec_context + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + const gss_cred_id_t /*acceptor_cred_handle*/, + const gss_buffer_t /*input_token_buffer*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + gss_name_t * /*src_name*/, + gss_OID * /*mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * /*time_rec*/, + gss_cred_id_t * /*delegated_cred_handle*/ + ); + +OM_uint32 gss_process_context_token + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*token_buffer*/ + ); + +OM_uint32 gss_delete_sec_context + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + gss_buffer_t /*output_token*/ + ); + +OM_uint32 gss_context_time + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + OM_uint32 * /*time_rec*/ + ); + +OM_uint32 gss_get_mic + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*message_buffer*/, + gss_buffer_t /*message_token*/ + ); + +OM_uint32 gss_verify_mic + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t * /*qop_state*/ + ); + +OM_uint32 gss_wrap + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t /*output_message_buffer*/ + ); + +OM_uint32 gss_unwrap + (OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + gss_qop_t * /*qop_state*/ + ); + +OM_uint32 gss_display_status + (OM_uint32 * /*minor_status*/, + OM_uint32 /*status_value*/, + int /*status_type*/, + const gss_OID /*mech_type*/, + OM_uint32 * /*message_context*/, + gss_buffer_t /*status_string*/ + ); + +OM_uint32 gss_indicate_mechs + (OM_uint32 * /*minor_status*/, + gss_OID_set * /*mech_set*/ + ); + +OM_uint32 gss_compare_name + (OM_uint32 * /*minor_status*/, + const gss_name_t /*name1*/, + const gss_name_t /*name2*/, + int * /*name_equal*/ + ); + +OM_uint32 gss_display_name + (OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t /*output_name_buffer*/, + gss_OID * /*output_name_type*/ + ); + +OM_uint32 gss_import_name + (OM_uint32 * /*minor_status*/, + const gss_buffer_t /*input_name_buffer*/, + const gss_OID /*input_name_type*/, + gss_name_t * /*output_name*/ + ); + +OM_uint32 gss_export_name + (OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t /*exported_name*/ + ); + +OM_uint32 gss_release_name + (OM_uint32 * /*minor_status*/, + gss_name_t * /*input_name*/ + ); + +OM_uint32 gss_release_buffer + (OM_uint32 * /*minor_status*/, + gss_buffer_t /*buffer*/ + ); + +OM_uint32 gss_release_oid_set + (OM_uint32 * /*minor_status*/, + gss_OID_set * /*set*/ + ); + +OM_uint32 gss_inquire_cred + (OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + gss_name_t * /*name*/, + OM_uint32 * /*lifetime*/, + gss_cred_usage_t * /*cred_usage*/, + gss_OID_set * /*mechanisms*/ + ); + +OM_uint32 gss_inquire_context ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_name_t * /*src_name*/, + gss_name_t * /*targ_name*/, + OM_uint32 * /*lifetime_rec*/, + gss_OID * /*mech_type*/, + OM_uint32 * /*ctx_flags*/, + int * /*locally_initiated*/, + int * /*open_context*/ + ); + +OM_uint32 gss_wrap_size_limit ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + OM_uint32 /*req_output_size*/, + OM_uint32 * /*max_input_size*/ + ); + +OM_uint32 gss_add_cred ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*input_cred_handle*/, + const gss_name_t /*desired_name*/, + const gss_OID /*desired_mech*/, + gss_cred_usage_t /*cred_usage*/, + OM_uint32 /*initiator_time_req*/, + OM_uint32 /*acceptor_time_req*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * /*initiator_time_rec*/, + OM_uint32 * /*acceptor_time_rec*/ + ); + +OM_uint32 gss_inquire_cred_by_mech ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + const gss_OID /*mech_type*/, + gss_name_t * /*name*/, + OM_uint32 * /*initiator_lifetime*/, + OM_uint32 * /*acceptor_lifetime*/, + gss_cred_usage_t * /*cred_usage*/ + ); + +OM_uint32 gss_export_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + gss_buffer_t /*interprocess_token*/ + ); + +OM_uint32 gss_import_sec_context ( + OM_uint32 * /*minor_status*/, + const gss_buffer_t /*interprocess_token*/, + gss_ctx_id_t * /*context_handle*/ + ); + +OM_uint32 gss_create_empty_oid_set ( + OM_uint32 * /*minor_status*/, + gss_OID_set * /*oid_set*/ + ); + +OM_uint32 gss_add_oid_set_member ( + OM_uint32 * /*minor_status*/, + const gss_OID /*member_oid*/, + gss_OID_set * /*oid_set*/ + ); + +OM_uint32 gss_test_oid_set_member ( + OM_uint32 * /*minor_status*/, + const gss_OID /*member*/, + const gss_OID_set /*set*/, + int * /*present*/ + ); + +OM_uint32 gss_inquire_names_for_mech ( + OM_uint32 * /*minor_status*/, + const gss_OID /*mechanism*/, + gss_OID_set * /*name_types*/ + ); + +OM_uint32 gss_inquire_mechs_for_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_OID_set * /*mech_types*/ + ); + +OM_uint32 gss_canonicalize_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + const gss_OID /*mech_type*/, + gss_name_t * /*output_name*/ + ); + +OM_uint32 gss_duplicate_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*src_name*/, + gss_name_t * /*dest_name*/ + ); + +OM_uint32 gss_duplicate_oid ( + OM_uint32 * /* minor_status */, + gss_OID /* src_oid */, + gss_OID * /* dest_oid */ + ); +OM_uint32 +gss_release_oid + (OM_uint32 * /*minor_status*/, + gss_OID * /* oid */ + ); + +OM_uint32 +gss_oid_to_str( + OM_uint32 * /*minor_status*/, + gss_OID /* oid */, + gss_buffer_t /* str */ + ); + +OM_uint32 +gss_inquire_sec_context_by_oid( + OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set + ); + +OM_uint32 +gss_set_sec_context_option (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value); + +OM_uint32 +gss_set_cred_option (OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID object, + const gss_buffer_t value); + +int +gss_oid_equal(const gss_OID a, const gss_OID b); + +OM_uint32 +gss_create_empty_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set); + +OM_uint32 +gss_add_buffer_set_member + (OM_uint32 * minor_status, + const gss_buffer_t member_buffer, + gss_buffer_set_t *buffer_set); + +OM_uint32 +gss_release_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set); + +OM_uint32 +gss_inquire_cred_by_oid(OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set); + +/* + * The following routines are obsolete variants of gss_get_mic, + * gss_verify_mic, gss_wrap and gss_unwrap. They should be + * provided by GSSAPI V2 implementations for backwards + * compatibility with V1 applications. Distinct entrypoints + * (as opposed to #defines) should be provided, both to allow + * GSSAPI V1 applications to link against GSSAPI V2 implementations, + * and to retain the slight parameter type differences between the + * obsolete versions of these routines and their current forms. + */ + +OM_uint32 gss_sign + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*qop_req*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t /*message_token*/ + ); + +OM_uint32 gss_verify + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t /*token_buffer*/, + int * /*qop_state*/ + ); + +OM_uint32 gss_seal + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + int /*qop_req*/, + gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t /*output_message_buffer*/ + ); + +OM_uint32 gss_unseal + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + int * /*qop_state*/ + ); + +/* + * + */ + +OM_uint32 +gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set); + +OM_uint32 +gss_encapsulate_token(gss_buffer_t /* input_token */, + gss_OID /* oid */, + gss_buffer_t /* output_token */); + +OM_uint32 +gss_decapsulate_token(gss_buffer_t /* input_token */, + gss_OID /* oid */, + gss_buffer_t /* output_token */); + + + +#ifdef __cplusplus +} +#endif + +#include <gssapi/gssapi_krb5.h> +#include <gssapi/gssapi_spnego.h> + +#endif /* GSSAPI_GSSAPI_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h new file mode 100644 index 0000000000..8c025c8366 --- /dev/null +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: gssapi_krb5.h,v 1.10 2006/10/20 22:04:03 lha Exp $ */ + +#ifndef GSSAPI_KRB5_H_ +#define GSSAPI_KRB5_H_ + +#include <gssapi/gssapi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This is for kerberos5 names. + */ + +extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME; +extern gss_OID GSS_KRB5_NT_USER_NAME; +extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME; +extern gss_OID GSS_KRB5_NT_STRING_UID_NAME; + +extern gss_OID GSS_KRB5_MECHANISM; + +/* for compatibility with MIT api */ + +#define gss_mech_krb5 GSS_KRB5_MECHANISM +#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME + +/* Extensions set contexts options */ +extern gss_OID GSS_KRB5_COPY_CCACHE_X; +extern gss_OID GSS_KRB5_COMPAT_DES3_MIC_X; +extern gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X; +extern gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X; +extern gss_OID GSS_KRB5_SEND_TO_KDC_X; +/* Extensions inquire context */ +extern gss_OID GSS_KRB5_GET_TKT_FLAGS_X; +extern gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X; +extern gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO; +extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X; +extern gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X; +extern gss_OID GSS_KRB5_GET_SUBKEY_X; +extern gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X; +extern gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X; +extern gss_OID GSS_KRB5_GET_AUTHTIME_X; +extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X; +/* Extensions creds */ +extern gss_OID GSS_KRB5_IMPORT_CRED_X; + +/* + * kerberos mechanism specific functions + */ + +struct krb5_keytab_data; +struct krb5_ccache_data; +struct Principal; + +OM_uint32 +gss_krb5_ccache_name(OM_uint32 * /*minor_status*/, + const char * /*name */, + const char ** /*out_name */); + +OM_uint32 gsskrb5_register_acceptor_identity + (const char */*identity*/); + +OM_uint32 gss_krb5_copy_ccache + (OM_uint32 */*minor*/, + gss_cred_id_t /*cred*/, + struct krb5_ccache_data */*out*/); + +OM_uint32 +gss_krb5_import_cred(OM_uint32 */*minor*/, + struct krb5_ccache_data * /*in*/, + struct Principal * /*keytab_principal*/, + struct krb5_keytab_data * /*keytab*/, + gss_cred_id_t */*out*/); + +OM_uint32 gss_krb5_get_tkt_flags + (OM_uint32 */*minor*/, + gss_ctx_id_t /*context_handle*/, + OM_uint32 */*tkt_flags*/); + +OM_uint32 +gsskrb5_extract_authz_data_from_sec_context + (OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*ad_type*/, + gss_buffer_t /*ad_data*/); + +OM_uint32 +gsskrb5_set_dns_canonicalize(int); + +struct gsskrb5_send_to_kdc { + void *func; + void *ptr; +}; + +OM_uint32 +gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *); + +OM_uint32 +gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *); + +struct EncryptionKey; + +OM_uint32 +gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + struct EncryptionKey **out); +OM_uint32 +gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + struct EncryptionKey **out); +OM_uint32 +gsskrb5_get_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + struct EncryptionKey **out); + +/* + * Lucid - NFSv4 interface to GSS-API KRB5 to expose key material to + * do GSS content token handling in-kernel. + */ + +typedef struct gss_krb5_lucid_key { + OM_uint32 type; + OM_uint32 length; + void * data; +} gss_krb5_lucid_key_t; + +typedef struct gss_krb5_rfc1964_keydata { + OM_uint32 sign_alg; + OM_uint32 seal_alg; + gss_krb5_lucid_key_t ctx_key; +} gss_krb5_rfc1964_keydata_t; + +typedef struct gss_krb5_cfx_keydata { + OM_uint32 have_acceptor_subkey; + gss_krb5_lucid_key_t ctx_key; + gss_krb5_lucid_key_t acceptor_subkey; +} gss_krb5_cfx_keydata_t; + +typedef struct gss_krb5_lucid_context_v1 { + OM_uint32 version; + OM_uint32 initiate; + OM_uint32 endtime; + OM_uint64 send_seq; + OM_uint64 recv_seq; + OM_uint32 protocol; + gss_krb5_rfc1964_keydata_t rfc1964_kd; + gss_krb5_cfx_keydata_t cfx_kd; +} gss_krb5_lucid_context_v1_t; + +typedef struct gss_krb5_lucid_context_version { + OM_uint32 version; /* Structure version number */ +} gss_krb5_lucid_context_version_t; + +/* + * Function declarations + */ + +OM_uint32 +gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **kctx); + + +OM_uint32 +gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, + void *kctx); + + + +#ifdef __cplusplus +} +#endif + +#endif /* GSSAPI_SPNEGO_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h new file mode 100644 index 0000000000..0a856e39aa --- /dev/null +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: gssapi_spnego.h,v 1.1 2006/10/07 22:26:21 lha Exp $ */ + +#ifndef GSSAPI_SPNEGO_H_ +#define GSSAPI_SPNEGO_H_ + +#include <gssapi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * RFC2478, SPNEGO: + * The security mechanism of the initial + * negotiation token is identified by the Object Identifier + * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2). + */ +extern gss_OID GSS_SPNEGO_MECHANISM; +#define gss_mech_spnego GSS_SPNEGO_MECHANISM + +#ifdef __cplusplus +} +#endif + +#endif /* GSSAPI_SPNEGO_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi_locl.h b/source4/heimdal/lib/gssapi/gssapi_locl.h deleted file mode 100644 index 81169a8500..0000000000 --- a/source4/heimdal/lib/gssapi/gssapi_locl.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $Id: gssapi_locl.h,v 1.45 2006/05/04 11:56:14 lha Exp $ */ - -#ifndef GSSAPI_LOCL_H -#define GSSAPI_LOCL_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <krb5_locl.h> -#include <gssapi.h> -#include <assert.h> - -#include "cfx.h" -#include "arcfour.h" - -#include "spnego_asn1.h" - -/* - * - */ - -struct gss_msg_order; - -typedef struct gss_ctx_id_t_desc_struct { - struct krb5_auth_context_data *auth_context; - gss_name_t source, target; - enum gss_ctx_id_t_state { - INITIATOR_START = 1, INITIATOR_WAIT_FOR_MUTAL = 2, INITIATOR_READY= 3, - ACCEPTOR_START = 11, ACCEPTOR_WAIT_FOR_DCESTYLE = 12, ACCEPTOR_READY = 13 - } state; - OM_uint32 flags; - enum {LOCAL = 1, - OPEN = 2, - COMPAT_OLD_DES3 = 4, - COMPAT_OLD_DES3_SELECTED = 8, - ACCEPTOR_SUBKEY = 16 - } more_flags; - struct krb5_ticket *ticket; - krb5_keyblock *service_keyblock; - krb5_data fwd_data; - OM_uint32 lifetime; - HEIMDAL_MUTEX ctx_id_mutex; - struct gss_msg_order *order; -} gss_ctx_id_t_desc; - -typedef struct gss_cred_id_t_desc_struct { - gss_name_t principal; - int cred_flags; -#define GSS_CF_DESTROY_CRED_ON_RELEASE 1 - struct krb5_keytab_data *keytab; - OM_uint32 lifetime; - gss_cred_usage_t usage; - gss_OID_set mechanisms; - struct krb5_ccache_data *ccache; - HEIMDAL_MUTEX cred_id_mutex; -} gss_cred_id_t_desc; - -/* - * - */ - -extern krb5_context gssapi_krb5_context; - -extern krb5_keytab gssapi_krb5_keytab; -extern HEIMDAL_MUTEX gssapi_keytab_mutex; - -struct gssapi_thr_context { - HEIMDAL_MUTEX mutex; - char *error_string; -}; - -/* - * Prototypes - */ - -krb5_error_code gssapi_krb5_init (void); - -krb5_error_code gssapi_krb5_init_ev (void *); - -#define GSSAPI_KRB5_INIT() do { \ - krb5_error_code kret_gss_init; \ - if((kret_gss_init = gssapi_krb5_init ()) != 0) { \ - *minor_status = kret_gss_init; \ - return GSS_S_FAILURE; \ - } \ -} while (0) - -struct gssapi_thr_context * -gssapi_get_thread_context(int); - -OM_uint32 -_gsskrb5_create_ctx( - OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_channel_bindings_t input_chan_bindings, - enum gss_ctx_id_t_state state); - -void -gsskrb5_is_cfx(gss_ctx_id_t, int *); - -OM_uint32 -gssapi_krb5_create_8003_checksum ( - OM_uint32 *minor_status, - const gss_channel_bindings_t input_chan_bindings, - OM_uint32 flags, - const krb5_data *fwd_data, - Checksum *result); - -OM_uint32 -gssapi_krb5_verify_8003_checksum ( - OM_uint32 *minor_status, - const gss_channel_bindings_t input_chan_bindings, - const Checksum *cksum, - OM_uint32 *flags, - krb5_data *fwd_data); - -void -_gssapi_encap_length (size_t data_len, - size_t *len, - size_t *total_len, - const gss_OID mech); - -void -gssapi_krb5_encap_length (size_t data_len, - size_t *len, - size_t *total_len, - const gss_OID mech); - - - -OM_uint32 -_gssapi_encapsulate(OM_uint32 *minor_status, - const krb5_data *in_data, - gss_buffer_t output_token, - const gss_OID mech); - - -OM_uint32 -gssapi_krb5_encapsulate(OM_uint32 *minor_status, - const krb5_data *in_data, - gss_buffer_t output_token, - const u_char *type, - const gss_OID mech); - -OM_uint32 -gssapi_krb5_decapsulate(OM_uint32 *minor_status, - gss_buffer_t input_token_buffer, - krb5_data *out_data, - const char *type, - gss_OID oid); - -u_char * -gssapi_krb5_make_header (u_char *p, - size_t len, - const u_char *type, - const gss_OID mech); - -u_char * -_gssapi_make_mech_header(u_char *p, - size_t len, - const gss_OID mech); - -OM_uint32 -_gssapi_verify_mech_header(u_char **str, - size_t total_len, - gss_OID oid); - -OM_uint32 -gssapi_krb5_verify_header(u_char **str, - size_t total_len, - const u_char *type, - gss_OID oid); - -OM_uint32 -_gssapi_decapsulate(OM_uint32 *minor_status, - gss_buffer_t input_token_buffer, - krb5_data *out_data, - const gss_OID mech); - - -ssize_t -gssapi_krb5_get_mech (const u_char *, size_t, const u_char **); - -OM_uint32 -_gssapi_verify_pad(gss_buffer_t, size_t, size_t *); - -OM_uint32 -gss_verify_mic_internal(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, - const gss_buffer_t message_buffer, - const gss_buffer_t token_buffer, - gss_qop_t * qop_state, - char * type); - -OM_uint32 -gss_krb5_get_subkey(const gss_ctx_id_t context_handle, - krb5_keyblock **key); - -krb5_error_code -gss_address_to_krb5addr(OM_uint32 gss_addr_type, - gss_buffer_desc *gss_addr, - int16_t port, - krb5_address *address); - -/* sec_context flags */ - -#define SC_LOCAL_ADDRESS 0x01 -#define SC_REMOTE_ADDRESS 0x02 -#define SC_KEYBLOCK 0x04 -#define SC_LOCAL_SUBKEY 0x08 -#define SC_REMOTE_SUBKEY 0x10 - -int -gss_oid_equal(const gss_OID a, const gss_OID b); - -void -gssapi_krb5_clear_status (void); - -void -gssapi_krb5_set_status (const char *fmt, ...); - -void -gssapi_krb5_set_error_string (void); - -char * -gssapi_krb5_get_error_string (void); - -OM_uint32 -_gss_DES3_get_mic_compat(OM_uint32 *, gss_ctx_id_t); - -OM_uint32 -_gss_spnego_require_mechlist_mic(OM_uint32 *, gss_ctx_id_t, krb5_boolean *); - -krb5_error_code -_gss_check_compat(OM_uint32 *, gss_name_t, const char *, - krb5_boolean *, krb5_boolean); - -OM_uint32 -gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *); - -OM_uint32 -_gssapi_krb5_ccache_lifetime(OM_uint32 *, krb5_ccache, - krb5_principal, OM_uint32 *); - -/* sequence */ - -OM_uint32 -_gssapi_msg_order_create(OM_uint32 *, struct gss_msg_order **, - OM_uint32, OM_uint32, OM_uint32, int); -OM_uint32 -_gssapi_msg_order_destroy(struct gss_msg_order **); - -OM_uint32 -_gssapi_msg_order_check(struct gss_msg_order *, OM_uint32); - -OM_uint32 -_gssapi_msg_order_f(OM_uint32); - -OM_uint32 -_gssapi_msg_order_import(OM_uint32 *, krb5_storage *, - struct gss_msg_order **); - -krb5_error_code -_gssapi_msg_order_export(krb5_storage *, struct gss_msg_order *); - - -/* 8003 */ - -krb5_error_code -gssapi_encode_om_uint32(OM_uint32, u_char *); - -krb5_error_code -gssapi_encode_be_om_uint32(OM_uint32, u_char *); - -krb5_error_code -gssapi_decode_om_uint32(const void *, OM_uint32 *); - -krb5_error_code -gssapi_decode_be_om_uint32(const void *, OM_uint32 *); - -#endif diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h new file mode 100644 index 0000000000..a05919b510 --- /dev/null +++ b/source4/heimdal/lib/gssapi/gssapi_mech.h @@ -0,0 +1,348 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#ifndef GSSAPI_MECH_H +#define GSSAPI_MECH_H 1 + +#include <gssapi.h> + +typedef OM_uint32 _gss_acquire_cred_t + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + const gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 * /* time_rec */ + ); + +typedef OM_uint32 _gss_release_cred_t + (OM_uint32 *, /* minor_status */ + gss_cred_id_t * /* cred_handle */ + ); + +typedef OM_uint32 _gss_init_sec_context_t + (OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* initiator_cred_handle */ + gss_ctx_id_t *, /* context_handle */ + const gss_name_t, /* target_name */ + const gss_OID, /* mech_type */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + const gss_channel_bindings_t, + /* input_chan_bindings */ + const gss_buffer_t, /* input_token */ + gss_OID *, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 *, /* ret_flags */ + OM_uint32 * /* time_rec */ + ); + +typedef OM_uint32 _gss_accept_sec_context_t + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + const gss_cred_id_t, /* acceptor_cred_handle */ + const gss_buffer_t, /* input_token_buffer */ + const gss_channel_bindings_t, + /* input_chan_bindings */ + gss_name_t *, /* src_name */ + gss_OID *, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 *, /* ret_flags */ + OM_uint32 *, /* time_rec */ + gss_cred_id_t * /* delegated_cred_handle */ + ); + +typedef OM_uint32 _gss_process_context_token_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t /* token_buffer */ + ); + +typedef OM_uint32 _gss_delete_sec_context_t + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* output_token */ + ); + +typedef OM_uint32 _gss_context_time_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + OM_uint32 * /* time_rec */ + ); + +typedef OM_uint32 _gss_get_mic_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + gss_qop_t, /* qop_req */ + const gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +typedef OM_uint32 _gss_verify_mic_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t, /* message_buffer */ + const gss_buffer_t, /* token_buffer */ + gss_qop_t * /* qop_state */ + ); + +typedef OM_uint32 _gss_wrap_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + const gss_buffer_t, /* input_message_buffer */ + int *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +typedef OM_uint32 _gss_unwrap_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int *, /* conf_state */ + gss_qop_t * /* qop_state */ + ); + +typedef OM_uint32 _gss_display_status_t + (OM_uint32 *, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + const gss_OID, /* mech_type */ + OM_uint32 *, /* message_context */ + gss_buffer_t /* status_string */ + ); + +typedef OM_uint32 _gss_indicate_mechs_t + (OM_uint32 *, /* minor_status */ + gss_OID_set * /* mech_set */ + ); + +typedef OM_uint32 _gss_compare_name_t + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* name1 */ + const gss_name_t, /* name2 */ + int * /* name_equal */ + ); + +typedef OM_uint32 _gss_display_name_t + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID * /* output_name_type */ + ); + +typedef OM_uint32 _gss_import_name_t + (OM_uint32 *, /* minor_status */ + const gss_buffer_t, /* input_name_buffer */ + const gss_OID, /* input_name_type */ + gss_name_t * /* output_name */ + ); + +typedef OM_uint32 _gss_export_name_t + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t /* exported_name */ + ); + +typedef OM_uint32 _gss_release_name_t + (OM_uint32 *, /* minor_status */ + gss_name_t * /* input_name */ + ); + +typedef OM_uint32 _gss_inquire_cred_t + (OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + gss_cred_usage_t *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + +typedef OM_uint32 _gss_inquire_context_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + gss_name_t *, /* src_name */ + gss_name_t *, /* targ_name */ + OM_uint32 *, /* lifetime_rec */ + gss_OID *, /* mech_type */ + OM_uint32 *, /* ctx_flags */ + int *, /* locally_initiated */ + int * /* open */ + ); + +typedef OM_uint32 _gss_wrap_size_limit_t + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + ); + +typedef OM_uint32 _gss_add_cred_t ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred_handle */ + const gss_name_t, /* desired_name */ + const gss_OID, /* desired_mech */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); + +typedef OM_uint32 _gss_inquire_cred_by_mech_t ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + const gss_OID, /* mech_type */ + gss_name_t *, /* name */ + OM_uint32 *, /* initiator_lifetime */ + OM_uint32 *, /* acceptor_lifetime */ + gss_cred_usage_t * /* cred_usage */ + ); + +typedef OM_uint32 _gss_export_sec_context_t ( + OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + ); + +typedef OM_uint32 _gss_import_sec_context_t ( + OM_uint32 *, /* minor_status */ + const gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + ); + +typedef OM_uint32 _gss_inquire_names_for_mech_t ( + OM_uint32 *, /* minor_status */ + const gss_OID, /* mechanism */ + gss_OID_set * /* name_types */ + ); + +typedef OM_uint32 _gss_inquire_mechs_for_name_t ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_OID_set * /* mech_types */ + ); + +typedef OM_uint32 _gss_canonicalize_name_t ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + const gss_OID, /* mech_type */ + gss_name_t * /* output_name */ + ); + +typedef OM_uint32 _gss_duplicate_name_t ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* src_name */ + gss_name_t * /* dest_name */ + ); + +typedef OM_uint32 _gss_inquire_sec_context_by_oid ( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set + ); + +typedef OM_uint32 _gss_inquire_cred_by_oid ( + OM_uint32 *minor_status, + const gss_cred_id_t cred, + const gss_OID desired_object, + gss_buffer_set_t *data_set + ); + +typedef OM_uint32 _gss_set_sec_context_option ( + OM_uint32 *minor_status, + gss_ctx_id_t *cred_handle, + const gss_OID desired_object, + const gss_buffer_t value + ); + +typedef OM_uint32 _gss_set_cred_option ( + OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID desired_object, + const gss_buffer_t value + ); + + +#define GMI_VERSION 1 + +typedef struct gssapi_mech_interface_desc { + unsigned gm_version; + const char *gm_name; + gss_OID_desc gm_mech_oid; + _gss_acquire_cred_t *gm_acquire_cred; + _gss_release_cred_t *gm_release_cred; + _gss_init_sec_context_t *gm_init_sec_context; + _gss_accept_sec_context_t *gm_accept_sec_context; + _gss_process_context_token_t *gm_process_context_token; + _gss_delete_sec_context_t *gm_delete_sec_context; + _gss_context_time_t *gm_context_time; + _gss_get_mic_t *gm_get_mic; + _gss_verify_mic_t *gm_verify_mic; + _gss_wrap_t *gm_wrap; + _gss_unwrap_t *gm_unwrap; + _gss_display_status_t *gm_display_status; + _gss_indicate_mechs_t *gm_indicate_mechs; + _gss_compare_name_t *gm_compare_name; + _gss_display_name_t *gm_display_name; + _gss_import_name_t *gm_import_name; + _gss_export_name_t *gm_export_name; + _gss_release_name_t *gm_release_name; + _gss_inquire_cred_t *gm_inquire_cred; + _gss_inquire_context_t *gm_inquire_context; + _gss_wrap_size_limit_t *gm_wrap_size_limit; + _gss_add_cred_t *gm_add_cred; + _gss_inquire_cred_by_mech_t *gm_inquire_cred_by_mech; + _gss_export_sec_context_t *gm_export_sec_context; + _gss_import_sec_context_t *gm_import_sec_context; + _gss_inquire_names_for_mech_t *gm_inquire_names_for_mech; + _gss_inquire_mechs_for_name_t *gm_inquire_mechs_for_name; + _gss_canonicalize_name_t *gm_canonicalize_name; + _gss_duplicate_name_t *gm_duplicate_name; + _gss_inquire_sec_context_by_oid *gm_inquire_sec_context_by_oid; + _gss_inquire_cred_by_oid *gm_inquire_cred_by_oid; + _gss_set_sec_context_option *gm_set_sec_context_option; + _gss_set_cred_option *gm_set_cred_option; +} gssapi_mech_interface_desc, *gssapi_mech_interface; + +gssapi_mech_interface +__gss_get_mechanism(gss_OID /* oid */); + +gssapi_mech_interface __gss_spnego_initialize(void); +gssapi_mech_interface __gss_krb5_initialize(void); + +#endif /* GSSAPI_MECH_H */ diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c deleted file mode 100644 index 4f0d237241..0000000000 --- a/source4/heimdal/lib/gssapi/init_sec_context.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "gssapi_locl.h" - -RCSID("$Id: init_sec_context.c,v 1.63 2006/05/05 10:27:13 lha Exp $"); - -/* - * copy the addresses from `input_chan_bindings' (if any) to - * the auth context `ac' - */ - -static OM_uint32 -set_addresses (krb5_auth_context ac, - const gss_channel_bindings_t input_chan_bindings) -{ - /* Port numbers are expected to be in application_data.value, - * initator's port first */ - - krb5_address initiator_addr, acceptor_addr; - krb5_error_code kret; - - if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS - || input_chan_bindings->application_data.length != - 2 * sizeof(ac->local_port)) - return 0; - - memset(&initiator_addr, 0, sizeof(initiator_addr)); - memset(&acceptor_addr, 0, sizeof(acceptor_addr)); - - ac->local_port = - *(int16_t *) input_chan_bindings->application_data.value; - - ac->remote_port = - *((int16_t *) input_chan_bindings->application_data.value + 1); - - kret = gss_address_to_krb5addr(input_chan_bindings->acceptor_addrtype, - &input_chan_bindings->acceptor_address, - ac->remote_port, - &acceptor_addr); - if (kret) - return kret; - - kret = gss_address_to_krb5addr(input_chan_bindings->initiator_addrtype, - &input_chan_bindings->initiator_address, - ac->local_port, - &initiator_addr); - if (kret) { - krb5_free_address (gssapi_krb5_context, &acceptor_addr); - return kret; - } - - kret = krb5_auth_con_setaddrs(gssapi_krb5_context, - ac, - &initiator_addr, /* local address */ - &acceptor_addr); /* remote address */ - - krb5_free_address (gssapi_krb5_context, &initiator_addr); - krb5_free_address (gssapi_krb5_context, &acceptor_addr); - -#if 0 - free(input_chan_bindings->application_data.value); - input_chan_bindings->application_data.value = NULL; - input_chan_bindings->application_data.length = 0; -#endif - - return kret; -} - -OM_uint32 -_gsskrb5_create_ctx( - OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - const gss_channel_bindings_t input_chan_bindings, - enum gss_ctx_id_t_state state) -{ - krb5_error_code kret; - - *context_handle = malloc(sizeof(**context_handle)); - if (*context_handle == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - (*context_handle)->auth_context = NULL; - (*context_handle)->source = NULL; - (*context_handle)->target = NULL; - (*context_handle)->state = state; - (*context_handle)->flags = 0; - (*context_handle)->more_flags = 0; - (*context_handle)->service_keyblock = NULL; - (*context_handle)->ticket = NULL; - krb5_data_zero(&(*context_handle)->fwd_data); - (*context_handle)->lifetime = GSS_C_INDEFINITE; - (*context_handle)->order = NULL; - HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); - - kret = krb5_auth_con_init (gssapi_krb5_context, - &(*context_handle)->auth_context); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); - - HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); - - return GSS_S_FAILURE; - } - - kret = set_addresses((*context_handle)->auth_context, - input_chan_bindings); - if (kret) { - *minor_status = kret; - - HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); - - krb5_auth_con_free(gssapi_krb5_context, (*context_handle)->auth_context); - - return GSS_S_BAD_BINDINGS; - } - - /* - * We need a sequence number - */ - - krb5_auth_con_addflags(gssapi_krb5_context, - (*context_handle)->auth_context, - KRB5_AUTH_CONTEXT_DO_SEQUENCE, - NULL); - - return GSS_S_COMPLETE; -} - -static OM_uint32 -gsskrb5_get_creds( - OM_uint32 * minor_status, - krb5_ccache ccache, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - OM_uint32 time_req, - OM_uint32 * time_rec, - krb5_creds ** cred) -{ - OM_uint32 ret; - krb5_error_code kret; - krb5_creds this_cred; - OM_uint32 lifetime_rec; - - *cred = NULL; - - kret = krb5_cc_get_principal(gssapi_krb5_context, - ccache, - &(*context_handle)->source); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_copy_principal(gssapi_krb5_context, - target_name, - &(*context_handle)->target); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - memset(&this_cred, 0, sizeof(this_cred)); - this_cred.client = (*context_handle)->source; - this_cred.server = (*context_handle)->target; - - if (time_req && time_req != GSS_C_INDEFINITE) { - krb5_timestamp ts; - - krb5_timeofday (gssapi_krb5_context, &ts); - this_cred.times.endtime = ts + time_req; - } else { - this_cred.times.endtime = 0; - } - - this_cred.session.keytype = KEYTYPE_NULL; - - kret = krb5_get_credentials(gssapi_krb5_context, - 0, - ccache, - &this_cred, - cred); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - (*context_handle)->lifetime = (*cred)->times.endtime; - - ret = gssapi_lifetime_left(minor_status, - (*context_handle)->lifetime, - &lifetime_rec); - if (ret) return ret; - - if (lifetime_rec == 0) { - *minor_status = 0; - return GSS_S_CONTEXT_EXPIRED; - } - - if (time_rec) *time_rec = lifetime_rec; - - return GSS_S_COMPLETE; -} - -static OM_uint32 -gsskrb5_initiator_ready( - OM_uint32 * minor_status, - gss_ctx_id_t * context_handle) -{ - OM_uint32 ret; - int32_t seq_number; - int is_cfx = 0; - OM_uint32 flags = (*context_handle)->flags; - - krb5_auth_getremoteseqnumber (gssapi_krb5_context, - (*context_handle)->auth_context, - &seq_number); - - gsskrb5_is_cfx(*context_handle, &is_cfx); - - ret = _gssapi_msg_order_create(minor_status, - &(*context_handle)->order, - _gssapi_msg_order_f(flags), - seq_number, 0, is_cfx); - if (ret) return ret; - - (*context_handle)->state = INITIATOR_READY; - (*context_handle)->more_flags |= OPEN; - - return GSS_S_COMPLETE; -} - -/* - * handle delegated creds in init-sec-context - */ - -static void -do_delegation (krb5_auth_context ac, - krb5_ccache ccache, - krb5_creds *cred, - const gss_name_t target_name, - krb5_data *fwd_data, - OM_uint32 *flags) -{ - krb5_creds creds; - krb5_kdc_flags fwd_flags; - krb5_error_code kret; - - memset (&creds, 0, sizeof(creds)); - krb5_data_zero (fwd_data); - - kret = krb5_cc_get_principal(gssapi_krb5_context, ccache, &creds.client); - if (kret) - goto out; - - kret = krb5_build_principal(gssapi_krb5_context, - &creds.server, - strlen(creds.client->realm), - creds.client->realm, - KRB5_TGS_NAME, - creds.client->realm, - NULL); - if (kret) - goto out; - - creds.times.endtime = 0; - - fwd_flags.i = 0; - fwd_flags.b.forwarded = 1; - fwd_flags.b.forwardable = 1; - - if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/ - target_name->name.name_string.len < 2) - goto out; - - kret = krb5_get_forwarded_creds(gssapi_krb5_context, - ac, - ccache, - fwd_flags.i, - target_name->name.name_string.val[1], - &creds, - fwd_data); - - out: - if (kret) - *flags &= ~GSS_C_DELEG_FLAG; - else - *flags |= GSS_C_DELEG_FLAG; - - if (creds.client) - krb5_free_principal(gssapi_krb5_context, creds.client); - if (creds.server) - krb5_free_principal(gssapi_krb5_context, creds.server); -} - -/* - * first stage of init-sec-context - */ - -static OM_uint32 -gsskrb5_initiator_start -(OM_uint32 * minor_status, - krb5_ccache ccache, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - OM_uint32 ret = GSS_S_FAILURE; - krb5_error_code kret; - krb5_flags ap_options; - krb5_creds *cred = NULL; - krb5_data outbuf; - OM_uint32 flags; - krb5_data authenticator; - Checksum cksum; - krb5_enctype enctype; - krb5_data fwd_data; - int is_cfx; - - krb5_data_zero(&outbuf); - krb5_data_zero(&fwd_data); - - (*context_handle)->more_flags |= LOCAL; - - /* We need to get the credentials for the requested target */ - ret = gsskrb5_get_creds(minor_status, - ccache, - context_handle, - target_name, - time_req, - time_rec, - &cred); - if (ret) return ret; - - /* - * We need to setup some compat stuff, this assumes that context_handle->target is already set - */ - ret = _gss_DES3_get_mic_compat(minor_status, *context_handle); - if (ret) return ret; - - /* We need the key and a random local subkey */ - { - kret = krb5_auth_con_setkey(gssapi_krb5_context, - (*context_handle)->auth_context, - &cred->session); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_con_generatelocalsubkey(gssapi_krb5_context, - (*context_handle)->auth_context, - &cred->session); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to prepare the flags used for this context */ - { - flags = 0; - ap_options = 0; - - /* - * The KDC may have issued us a service ticket marked NOT - * ok-as-delegate. We may still wish to force the matter, and to - * allow this we check a per-realm gssapi [appdefaults] config - * option. If ok-as-delegate in the config file is set to TRUE - * (default FALSE) and our caller has so requested, we will still - * attempt to forward the ticket. - * - * Otherwise, strip the GSS_C_DELEG_FLAG (so we don't attempt a - * delegation) - */ - if (!cred->flags.b.ok_as_delegate) { - krb5_boolean delegate; - - krb5_appdefault_boolean(gssapi_krb5_context, - "gssapi", target_name->realm, - "ok-as-delegate", FALSE, &delegate); - if (!delegate) - req_flags &= ~GSS_C_DELEG_FLAG; - } - - if (req_flags & GSS_C_DELEG_FLAG) { - do_delegation((*context_handle)->auth_context, - ccache, cred, target_name, &fwd_data, &flags); - } - - if (req_flags & GSS_C_MUTUAL_FLAG) { - flags |= GSS_C_MUTUAL_FLAG; - ap_options |= AP_OPTS_MUTUAL_REQUIRED; - } - - if (req_flags & GSS_C_REPLAY_FLAG) { - flags |= GSS_C_REPLAY_FLAG; - } - - if (req_flags & GSS_C_SEQUENCE_FLAG) { - flags |= GSS_C_SEQUENCE_FLAG; - } - - if (req_flags & GSS_C_ANON_FLAG) { - ;/* XXX */ - } - - if (req_flags & GSS_C_DCE_STYLE) { - flags |= GSS_C_DCE_STYLE; - /* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */ - flags |= GSS_C_MUTUAL_FLAG; - ap_options |= AP_OPTS_MUTUAL_REQUIRED; - } - - if (req_flags & GSS_C_IDENTIFY_FLAG) { - flags |= GSS_C_IDENTIFY_FLAG; - } - - if (req_flags & GSS_C_EXTENDED_ERROR_FLAG) { - flags |= GSS_C_EXTENDED_ERROR_FLAG; - } - - /* TODO: why are this always there? --metze */ - flags |= GSS_C_CONF_FLAG; - flags |= GSS_C_INTEG_FLAG; - flags |= GSS_C_TRANS_FLAG; - - if (ret_flags) *ret_flags = flags; - (*context_handle)->flags = flags; - } - - /* We need to generate the 8003 checksum */ - { - ret = gssapi_krb5_create_8003_checksum(minor_status, - input_chan_bindings, - flags, - &fwd_data, - &cksum); - krb5_data_free (&fwd_data); - if (ret) return ret; - } - - enctype = (*context_handle)->auth_context->keyblock->keytype; - - gsskrb5_is_cfx(*context_handle, &is_cfx); - - if (is_cfx != 0) { - kret = krb5_auth_con_addflags(gssapi_krb5_context, - (*context_handle)->auth_context, - KRB5_AUTH_CONTEXT_USE_SUBKEY, - NULL); - (*context_handle)->more_flags |= ACCEPTOR_SUBKEY; - } - - /* We need to create an Authenticator */ - { - kret = krb5_build_authenticator (gssapi_krb5_context, - (*context_handle)->auth_context, - enctype, - cred, - &cksum, - NULL, - &authenticator, - KRB5_KU_AP_REQ_AUTH); - free_Checksum(&cksum); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to create the AP_REQ */ - { - kret = krb5_build_ap_req(gssapi_krb5_context, - enctype, - cred, - ap_options, - authenticator, - &outbuf); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to encapsulate the AP_REQ if GSS_C_DCE_STYLE isn't in use */ - { - if (!(flags & GSS_C_DCE_STYLE)) { - ret = gssapi_krb5_encapsulate(minor_status, &outbuf, output_token, - "\x01\x00", GSS_KRB5_MECHANISM); - krb5_data_free (&outbuf); - if (ret) return ret; - } else { - output_token->length = outbuf.length; - output_token->value = outbuf.data; - } - } - - /* We no longer need the creds */ - krb5_free_creds(gssapi_krb5_context, cred); - - /* We are done if GSS_C_MUTUAL_FLAG is in use */ - if (flags & GSS_C_MUTUAL_FLAG) { - (*context_handle)->state = INITIATOR_WAIT_FOR_MUTAL; - return GSS_S_CONTINUE_NEEDED; - } - - return gsskrb5_initiator_ready(minor_status, context_handle); -} - -static OM_uint32 -gsskrb5_initiator_wait_for_mutual( - OM_uint32 * minor_status, - krb5_ccache ccache, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec) -{ - OM_uint32 ret; - krb5_error_code kret; - krb5_data inbuf; - OM_uint32 flags = (*context_handle)->flags; - int32_t l_seq_number; - int32_t r_seq_number; - - /* We need to decapsulate the AP_REP if GSS_C_DCE_STYLE isn't in use */ - { - if (!(flags & GSS_C_DCE_STYLE)) { - ret = gssapi_krb5_decapsulate(minor_status, input_token, &inbuf, - "\x02\x00", GSS_KRB5_MECHANISM); - if (ret) return ret; - } else { - inbuf.length = input_token->length; - inbuf.data = input_token->value; - } - } - - /* We need to verify the AP_REP */ - { - krb5_ap_rep_enc_part *repl; - - kret = krb5_rd_rep(gssapi_krb5_context, - (*context_handle)->auth_context, - &inbuf, - &repl); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - krb5_free_ap_rep_enc_part(gssapi_krb5_context, repl); - } - - /* We need to check the liftime */ - { - OM_uint32 lifetime_rec; - - ret = gssapi_lifetime_left(minor_status, - (*context_handle)->lifetime, - &lifetime_rec); - if (ret) return ret; - - if (lifetime_rec == 0) { - return GSS_S_CONTEXT_EXPIRED; - } - - if (time_rec) *time_rec = lifetime_rec; - } - - /* We need to give the caller the flags which are in use */ - if (ret_flags) *ret_flags = (*context_handle)->flags; - - /* We are done here if GSS_C_DCE_STYLE isn't in use */ - if (!(flags & GSS_C_DCE_STYLE)) { - return gsskrb5_initiator_ready(minor_status, context_handle); - } - - /* - * We need to set the local seq_number to the remote one just for the krb5_mk_rep(), - * and then we need to use the old local seq_number again for the GSS_Wrap() messages - */ - { - kret = krb5_auth_getremoteseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &r_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_con_getlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - &l_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - kret = krb5_auth_con_setlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - r_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - /* We need to create an AP_REP */ - { - krb5_data outbuf; - - kret = krb5_mk_rep(gssapi_krb5_context, - (*context_handle)->auth_context, - &outbuf); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - - output_token->length = outbuf.length; - output_token->value = outbuf.data; - } - - /* We need to reset the local seq_number */ - { - kret = krb5_auth_con_setlocalseqnumber(gssapi_krb5_context, - (*context_handle)->auth_context, - l_seq_number); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } - - return gsskrb5_initiator_ready(minor_status, context_handle); -} - -static OM_uint32 -gsskrb5_init_sec_context - (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - OM_uint32 ret; - krb5_error_code kret; - krb5_ccache ccache = NULL; - - if (*context_handle == GSS_C_NO_CONTEXT) { - ret = _gsskrb5_create_ctx(minor_status, - context_handle, - input_chan_bindings, - INITIATOR_START); - if (ret) return ret; - } - - if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; - - if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) { - kret = krb5_cc_default (gssapi_krb5_context, &ccache); - if (kret) { - gssapi_krb5_set_error_string (); - *minor_status = kret; - return GSS_S_FAILURE; - } - } else { - ccache = initiator_cred_handle->ccache; - } - - HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); - - switch ((*context_handle)->state) { - case INITIATOR_START: - ret = gsskrb5_initiator_start(minor_status, - ccache, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - output_token, - ret_flags, - time_rec); - break; - case INITIATOR_WAIT_FOR_MUTAL: - ret = gsskrb5_initiator_wait_for_mutual(minor_status, - ccache, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - output_token, - ret_flags, - time_rec); - break; - case INITIATOR_READY: - /* should this be GSS_S_BAD_STATUS ? --metze */ - - /* We need to check the liftime */ - { - OM_uint32 lifetime_rec; - - ret = gssapi_lifetime_left(minor_status, - (*context_handle)->lifetime, - &lifetime_rec); - if (ret) break; - - if (lifetime_rec == 0) { - *minor_status = 0; - ret = GSS_S_CONTEXT_EXPIRED; - break; - } - - if (time_rec) *time_rec = lifetime_rec; - } - - /* We need to give the caller the flags which are in use */ - if (ret_flags) *ret_flags = (*context_handle)->flags; - - ret = GSS_S_COMPLETE; - break; - default: - /* TODO: is this correct here? --metze */ - ret = GSS_S_BAD_STATUS; - break; - } - - if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) { - krb5_cc_close(gssapi_krb5_context, ccache); - } - - HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); - - return ret; -} - -static OM_uint32 -spnego_reply - (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - OM_uint32 ret; - krb5_data indata; - NegTokenTarg targ; - u_char oidbuf[17]; - size_t oidlen; - gss_buffer_desc sub_token; - ssize_t mech_len; - const u_char *p; - size_t len, taglen; - krb5_boolean require_mic; - - output_token->length = 0; - output_token->value = NULL; - - /* - * SPNEGO doesn't include gss wrapping on SubsequentContextToken - * like the Kerberos 5 mech does. But lets check for it anyway. - */ - - mech_len = gssapi_krb5_get_mech (input_token->value, - input_token->length, - &p); - - if (mech_len < 0) { - indata.data = input_token->value; - indata.length = input_token->length; - } else if (mech_len == GSS_KRB5_MECHANISM->length - && memcmp(GSS_KRB5_MECHANISM->elements, p, mech_len) == 0) - return gsskrb5_init_sec_context (minor_status, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECHANISM, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - else if (mech_len == GSS_SPNEGO_MECHANISM->length - && memcmp(GSS_SPNEGO_MECHANISM->elements, p, mech_len) == 0){ - ret = _gssapi_decapsulate (minor_status, - input_token, - &indata, - GSS_SPNEGO_MECHANISM); - if (ret) - return ret; - } else - return GSS_S_BAD_MECH; - - ret = der_match_tag_and_length((const char *)indata.data, - indata.length, - ASN1_C_CONTEXT, CONS, 1, &len, &taglen); - if (ret) { - gssapi_krb5_set_status("Failed to decode NegToken choice"); - *minor_status = ret; - return GSS_S_FAILURE; - } - - if(len > indata.length - taglen) { - gssapi_krb5_set_status("Buffer overrun in NegToken choice"); - *minor_status = ASN1_OVERRUN; - return GSS_S_FAILURE; - } - - ret = decode_NegTokenTarg((const char *)indata.data + taglen, - len, &targ, NULL); - if (ret) { - gssapi_krb5_set_status("Failed to decode NegTokenTarg"); - *minor_status = ret; - return GSS_S_FAILURE; - } - - if (targ.negResult == NULL - || *(targ.negResult) == reject - || targ.supportedMech == NULL) { - free_NegTokenTarg(&targ); - return GSS_S_BAD_MECH; - } - - ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1, - sizeof(oidbuf), - targ.supportedMech, - &oidlen); - if (ret || oidlen != GSS_KRB5_MECHANISM->length - || memcmp(oidbuf + sizeof(oidbuf) - oidlen, - GSS_KRB5_MECHANISM->elements, - oidlen) != 0) { - free_NegTokenTarg(&targ); - return GSS_S_BAD_MECH; - } - - if (targ.responseToken != NULL) { - sub_token.length = targ.responseToken->length; - sub_token.value = targ.responseToken->data; - } else { - sub_token.length = 0; - sub_token.value = NULL; - } - - ret = gsskrb5_init_sec_context(minor_status, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECHANISM, - req_flags, - time_req, - input_chan_bindings, - &sub_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - if (ret) { - free_NegTokenTarg(&targ); - return ret; - } - - /* - * Verify the mechListMIC if CFX was used; or if local policy - * dictated so. - */ - ret = _gss_spnego_require_mechlist_mic(minor_status, *context_handle, - &require_mic); - if (ret) { - free_NegTokenTarg(&targ); - return ret; - } - - if (require_mic) { - MechTypeList mechlist; - MechType m0; - size_t buf_len; - gss_buffer_desc mic_buf, mech_buf; - - if (targ.mechListMIC == NULL) { - free_NegTokenTarg(&targ); - *minor_status = 0; - return GSS_S_BAD_MIC; - } - - mechlist.len = 1; - mechlist.val = &m0; - - ret = der_get_oid(GSS_KRB5_MECHANISM->elements, - GSS_KRB5_MECHANISM->length, - &m0, - NULL); - if (ret) { - free_NegTokenTarg(&targ); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length, - &mechlist, &buf_len, ret); - if (ret) { - free_NegTokenTarg(&targ); - free_oid(&m0); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - if (mech_buf.length != buf_len) - abort(); - - mic_buf.length = targ.mechListMIC->length; - mic_buf.value = targ.mechListMIC->data; - - ret = gss_verify_mic(minor_status, *context_handle, - &mech_buf, &mic_buf, NULL); - free(mech_buf.value); - free_oid(&m0); - } - free_NegTokenTarg(&targ); - return ret; -} - -static OM_uint32 -spnego_initial - (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - NegTokenInit ni; - int ret; - OM_uint32 sub, minor; - gss_buffer_desc mech_token; - u_char *buf; - size_t buf_size, buf_len; - krb5_data data; - - memset (&ni, 0, sizeof(ni)); - - ALLOC(ni.mechTypes, 1); - if (ni.mechTypes == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - ALLOC_SEQ(ni.mechTypes, 1); - if (ni.mechTypes->val == NULL) { - free_NegTokenInit(&ni); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - ret = der_get_oid(GSS_KRB5_MECHANISM->elements, - GSS_KRB5_MECHANISM->length, - &ni.mechTypes->val[0], - NULL); - if (ret) { - free_NegTokenInit(&ni); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - -#if 0 - ALLOC(ni.reqFlags, 1); - if (ni.reqFlags == NULL) { - free_NegTokenInit(&ni); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - ni.reqFlags->delegFlag = req_flags & GSS_C_DELEG_FLAG; - ni.reqFlags->mutualFlag = req_flags & GSS_C_MUTUAL_FLAG; - ni.reqFlags->replayFlag = req_flags & GSS_C_REPLAY_FLAG; - ni.reqFlags->sequenceFlag = req_flags & GSS_C_SEQUENCE_FLAG; - ni.reqFlags->anonFlag = req_flags & GSS_C_ANON_FLAG; - ni.reqFlags->confFlag = req_flags & GSS_C_CONF_FLAG; - ni.reqFlags->integFlag = req_flags & GSS_C_INTEG_FLAG; -#else - ni.reqFlags = NULL; -#endif - - sub = gsskrb5_init_sec_context(&minor, - initiator_cred_handle, - context_handle, - target_name, - GSS_KRB5_MECHANISM, - req_flags, - time_req, - input_chan_bindings, - GSS_C_NO_BUFFER, - actual_mech_type, - &mech_token, - ret_flags, - time_rec); - if (GSS_ERROR(sub)) { - free_NegTokenInit(&ni); - return sub; - } - if (mech_token.length != 0) { - ALLOC(ni.mechToken, 1); - if (ni.mechToken == NULL) { - free_NegTokenInit(&ni); - gss_release_buffer(&minor, &mech_token); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - ni.mechToken->length = mech_token.length; - ni.mechToken->data = malloc(mech_token.length); - if (ni.mechToken->data == NULL && mech_token.length != 0) { - free_NegTokenInit(&ni); - gss_release_buffer(&minor, &mech_token); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - memcpy(ni.mechToken->data, mech_token.value, mech_token.length); - gss_release_buffer(&minor, &mech_token); - } else - ni.mechToken = NULL; - - /* XXX ignore mech list mic for now */ - ni.mechListMIC = NULL; - - - { - NegotiationToken nt; - - nt.element = choice_NegotiationToken_negTokenInit; - nt.u.negTokenInit = ni; - - ASN1_MALLOC_ENCODE(NegotiationToken, buf, buf_size, - &nt, &buf_len, ret); - if (ret == 0 && buf_size != buf_len) - abort(); - } - - data.data = buf; - data.length = buf_size; - - free_NegTokenInit(&ni); - if (ret) - return ret; - - sub = _gssapi_encapsulate(minor_status, - &data, - output_token, - GSS_SPNEGO_MECHANISM); - free (buf); - - if (sub) - return sub; - - return GSS_S_CONTINUE_NEEDED; -} - -static OM_uint32 -spnego_init_sec_context - (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) - return spnego_initial (minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - else - return spnego_reply (minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); -} - -/* - * gss_init_sec_context - */ - -OM_uint32 gss_init_sec_context - (OM_uint32 * minor_status, - const gss_cred_id_t initiator_cred_handle, - gss_ctx_id_t * context_handle, - const gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - const gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - OM_uint32 * ret_flags, - OM_uint32 * time_rec - ) -{ - GSSAPI_KRB5_INIT (); - - output_token->length = 0; - output_token->value = NULL; - - if (ret_flags) - *ret_flags = 0; - if (time_rec) - *time_rec = 0; - - if (target_name == GSS_C_NO_NAME) { - if (actual_mech_type) - *actual_mech_type = GSS_C_NO_OID; - *minor_status = 0; - return GSS_S_BAD_NAME; - } - - if (mech_type == GSS_C_NO_OID || - gss_oid_equal(mech_type, GSS_KRB5_MECHANISM)) - return gsskrb5_init_sec_context(minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - else if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM)) - return spnego_init_sec_context (minor_status, - initiator_cred_handle, - context_handle, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - actual_mech_type, - output_token, - ret_flags, - time_rec); - else - return GSS_S_BAD_MECH; -} diff --git a/source4/heimdal/lib/gssapi/inquire_cred.c b/source4/heimdal/lib/gssapi/inquire_cred.c deleted file mode 100644 index 9ed1ff4cc4..0000000000 --- a/source4/heimdal/lib/gssapi/inquire_cred.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "gssapi_locl.h" - -RCSID("$Id: inquire_cred.c,v 1.7 2004/11/30 19:27:11 lha Exp $"); - -OM_uint32 gss_inquire_cred - (OM_uint32 * minor_status, - const gss_cred_id_t cred_handle, - gss_name_t * name, - OM_uint32 * lifetime, - gss_cred_usage_t * cred_usage, - gss_OID_set * mechanisms - ) -{ - gss_cred_id_t cred; - OM_uint32 ret; - - *minor_status = 0; - - if (name) - *name = NULL; - if (mechanisms) - *mechanisms = GSS_C_NO_OID_SET; - - if (cred_handle == GSS_C_NO_CREDENTIAL) { - ret = gss_acquire_cred(minor_status, - GSS_C_NO_NAME, - GSS_C_INDEFINITE, - GSS_C_NO_OID_SET, - GSS_C_BOTH, - &cred, - NULL, - NULL); - if (ret) - return ret; - } else - cred = (gss_cred_id_t)cred_handle; - - HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); - - if (name != NULL) { - if (cred->principal != NULL) { - ret = gss_duplicate_name(minor_status, cred->principal, - name); - if (ret) - goto out; - } else if (cred->usage == GSS_C_ACCEPT) { - *minor_status = krb5_sname_to_principal(gssapi_krb5_context, NULL, - NULL, KRB5_NT_SRV_HST, name); - if (*minor_status) { - ret = GSS_S_FAILURE; - goto out; - } - } else { - *minor_status = krb5_get_default_principal(gssapi_krb5_context, - name); - if (*minor_status) { - ret = GSS_S_FAILURE; - goto out; - } - } - } - if (lifetime != NULL) { - ret = gssapi_lifetime_left(minor_status, - cred->lifetime, - lifetime); - if (ret) - goto out; - } - if (cred_usage != NULL) - *cred_usage = cred->usage; - - if (mechanisms != NULL) { - ret = gss_create_empty_oid_set(minor_status, mechanisms); - if (ret) - goto out; - ret = gss_add_oid_set_member(minor_status, - &cred->mechanisms->elements[0], - mechanisms); - if (ret) - goto out; - } - ret = GSS_S_COMPLETE; - out: - HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); - - if (cred_handle == GSS_C_NO_CREDENTIAL) - ret = gss_release_cred(minor_status, &cred); - - return ret; -} diff --git a/source4/heimdal/lib/gssapi/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c index 359bb6e715..0123f67e09 100644 --- a/source4/heimdal/lib/gssapi/8003.c +++ b/source4/heimdal/lib/gssapi/krb5/8003.c @@ -31,12 +31,12 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: 8003.c,v 1.18 2006/05/04 11:55:40 lha Exp $"); +RCSID("$Id: 8003.c,v 1.20 2006/10/07 22:13:51 lha Exp $"); krb5_error_code -gssapi_encode_om_uint32(OM_uint32 n, u_char *p) +_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p) { p[0] = (n >> 0) & 0xFF; p[1] = (n >> 8) & 0xFF; @@ -46,7 +46,7 @@ gssapi_encode_om_uint32(OM_uint32 n, u_char *p) } krb5_error_code -gssapi_encode_be_om_uint32(OM_uint32 n, u_char *p) +_gsskrb5_encode_be_om_uint32(OM_uint32 n, u_char *p) { p[0] = (n >> 24) & 0xFF; p[1] = (n >> 16) & 0xFF; @@ -56,7 +56,7 @@ gssapi_encode_be_om_uint32(OM_uint32 n, u_char *p) } krb5_error_code -gssapi_decode_om_uint32(const void *ptr, OM_uint32 *n) +_gsskrb5_decode_om_uint32(const void *ptr, OM_uint32 *n) { const u_char *p = ptr; *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); @@ -64,7 +64,7 @@ gssapi_decode_om_uint32(const void *ptr, OM_uint32 *n) } krb5_error_code -gssapi_decode_be_om_uint32(const void *ptr, OM_uint32 *n) +_gsskrb5_decode_be_om_uint32(const void *ptr, OM_uint32 *n) { const u_char *p = ptr; *n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); @@ -79,23 +79,23 @@ hash_input_chan_bindings (const gss_channel_bindings_t b, MD5_CTX md5; MD5_Init(&md5); - gssapi_encode_om_uint32 (b->initiator_addrtype, num); + _gsskrb5_encode_om_uint32 (b->initiator_addrtype, num); MD5_Update (&md5, num, sizeof(num)); - gssapi_encode_om_uint32 (b->initiator_address.length, num); + _gsskrb5_encode_om_uint32 (b->initiator_address.length, num); MD5_Update (&md5, num, sizeof(num)); if (b->initiator_address.length) MD5_Update (&md5, b->initiator_address.value, b->initiator_address.length); - gssapi_encode_om_uint32 (b->acceptor_addrtype, num); + _gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num); MD5_Update (&md5, num, sizeof(num)); - gssapi_encode_om_uint32 (b->acceptor_address.length, num); + _gsskrb5_encode_om_uint32 (b->acceptor_address.length, num); MD5_Update (&md5, num, sizeof(num)); if (b->acceptor_address.length) MD5_Update (&md5, b->acceptor_address.value, b->acceptor_address.length); - gssapi_encode_om_uint32 (b->application_data.length, num); + _gsskrb5_encode_om_uint32 (b->application_data.length, num); MD5_Update (&md5, num, sizeof(num)); if (b->application_data.length) MD5_Update (&md5, @@ -112,7 +112,7 @@ hash_input_chan_bindings (const gss_channel_bindings_t b, */ OM_uint32 -gssapi_krb5_create_8003_checksum ( +_gsskrb5_create_8003_checksum ( OM_uint32 *minor_status, const gss_channel_bindings_t input_chan_bindings, OM_uint32 flags, @@ -136,7 +136,7 @@ gssapi_krb5_create_8003_checksum ( } p = result->checksum.data; - gssapi_encode_om_uint32 (16, p); + _gsskrb5_encode_om_uint32 (16, p); p += 4; if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) { memset (p, 0, 16); @@ -144,7 +144,7 @@ gssapi_krb5_create_8003_checksum ( hash_input_chan_bindings (input_chan_bindings, p); } p += 16; - gssapi_encode_om_uint32 (flags, p); + _gsskrb5_encode_om_uint32 (flags, p); p += 4; if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) { @@ -167,7 +167,7 @@ gssapi_krb5_create_8003_checksum ( */ OM_uint32 -gssapi_krb5_verify_8003_checksum( +_gsskrb5_verify_8003_checksum( OM_uint32 *minor_status, const gss_channel_bindings_t input_chan_bindings, const Checksum *cksum, @@ -192,7 +192,7 @@ gssapi_krb5_verify_8003_checksum( } p = cksum->checksum.data; - gssapi_decode_om_uint32(p, &length); + _gsskrb5_decode_om_uint32(p, &length); if(length != sizeof(hash)) { *minor_status = 0; return GSS_S_BAD_BINDINGS; @@ -214,7 +214,7 @@ gssapi_krb5_verify_8003_checksum( p += sizeof(hash); - gssapi_decode_om_uint32(p, flags); + _gsskrb5_decode_om_uint32(p, flags); p += 4; if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) { diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c new file mode 100644 index 0000000000..e42bb11b85 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -0,0 +1,774 @@ +/* + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: accept_sec_context.c,v 1.64 2006/10/25 04:19:45 lha Exp $"); + +HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; +krb5_keytab _gsskrb5_keytab; + +OM_uint32 +_gsskrb5_register_acceptor_identity (const char *identity) +{ + krb5_error_code ret; + + ret = _gsskrb5_init(); + if(ret) + return GSS_S_FAILURE; + + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + + if(_gsskrb5_keytab != NULL) { + krb5_kt_close(_gsskrb5_context, _gsskrb5_keytab); + _gsskrb5_keytab = NULL; + } + if (identity == NULL) { + ret = krb5_kt_default(_gsskrb5_context, &_gsskrb5_keytab); + } else { + char *p; + + asprintf(&p, "FILE:%s", identity); + if(p == NULL) { + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + return GSS_S_FAILURE; + } + ret = krb5_kt_resolve(_gsskrb5_context, p, &_gsskrb5_keytab); + free(p); + } + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + if(ret) + return GSS_S_FAILURE; + return GSS_S_COMPLETE; +} + +void +_gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx) +{ + krb5_keyblock *key; + int acceptor = (ctx->more_flags & LOCAL) == 0; + + *is_cfx = 0; + + if (acceptor) { + if (ctx->auth_context->local_subkey) + key = ctx->auth_context->local_subkey; + else + key = ctx->auth_context->remote_subkey; + } else { + if (ctx->auth_context->remote_subkey) + key = ctx->auth_context->remote_subkey; + else + key = ctx->auth_context->local_subkey; + } + if (key == NULL) + key = ctx->auth_context->keyblock; + + if (key == NULL) + return; + + switch (key->keytype) { + case ETYPE_DES_CBC_CRC: + case ETYPE_DES_CBC_MD4: + case ETYPE_DES_CBC_MD5: + case ETYPE_DES3_CBC_MD5: + case ETYPE_DES3_CBC_SHA1: + case ETYPE_ARCFOUR_HMAC_MD5: + case ETYPE_ARCFOUR_HMAC_MD5_56: + break; + default : + *is_cfx = 1; + if ((acceptor && ctx->auth_context->local_subkey) || + (!acceptor && ctx->auth_context->remote_subkey)) + ctx->more_flags |= ACCEPTOR_SUBKEY; + break; + } +} + + +static OM_uint32 +gsskrb5_accept_delegated_token +(OM_uint32 * minor_status, + gsskrb5_ctx ctx, + gss_cred_id_t * delegated_cred_handle + ) +{ + krb5_ccache ccache = NULL; + krb5_error_code kret; + int32_t ac_flags, ret = GSS_S_COMPLETE; + + *minor_status = 0; + + /* XXX Create a new delegated_cred_handle? */ + if (delegated_cred_handle == NULL) { + kret = krb5_cc_default (_gsskrb5_context, &ccache); + } else { + *delegated_cred_handle = NULL; + kret = krb5_cc_gen_new (_gsskrb5_context, &krb5_mcc_ops, &ccache); + } + if (kret) { + ctx->flags &= ~GSS_C_DELEG_FLAG; + goto out; + } + + kret = krb5_cc_initialize(_gsskrb5_context, ccache, ctx->source); + if (kret) { + ctx->flags &= ~GSS_C_DELEG_FLAG; + goto out; + } + + krb5_auth_con_removeflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_TIME, + &ac_flags); + kret = krb5_rd_cred2(_gsskrb5_context, + ctx->auth_context, + ccache, + &ctx->fwd_data); + if (kret) + _gsskrb5_set_error_string(); + krb5_auth_con_setflags(_gsskrb5_context, + ctx->auth_context, + ac_flags); + if (kret) { + ctx->flags &= ~GSS_C_DELEG_FLAG; + ret = GSS_S_FAILURE; + *minor_status = kret; + goto out; + } + + if (delegated_cred_handle) { + gsskrb5_cred handle; + + ret = _gsskrb5_import_cred(minor_status, + ccache, + NULL, + NULL, + delegated_cred_handle); + if (ret != GSS_S_COMPLETE) + goto out; + + handle = (gsskrb5_cred) *delegated_cred_handle; + + handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; + krb5_cc_close(_gsskrb5_context, ccache); + ccache = NULL; + } + +out: + if (ccache) { + if (delegated_cred_handle == NULL) + krb5_cc_close(_gsskrb5_context, ccache); + else + krb5_cc_destroy(_gsskrb5_context, ccache); + } + return ret; +} + +static OM_uint32 +gsskrb5_acceptor_ready(OM_uint32 * minor_status, + gsskrb5_ctx ctx, + gss_cred_id_t *delegated_cred_handle) +{ + OM_uint32 ret; + int32_t seq_number; + int is_cfx = 0; + + krb5_auth_getremoteseqnumber (_gsskrb5_context, + ctx->auth_context, + &seq_number); + + _gsskrb5i_is_cfx(ctx, &is_cfx); + + ret = _gssapi_msg_order_create(minor_status, + &ctx->order, + _gssapi_msg_order_f(ctx->flags), + seq_number, 0, is_cfx); + if (ret) + return ret; + + /* + * If requested, set local sequence num to remote sequence if this + * isn't a mutual authentication context + */ + if (!(ctx->flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(ctx->flags)) { + krb5_auth_con_setlocalseqnumber(_gsskrb5_context, + ctx->auth_context, + seq_number); + } + + /* + * We should handle the delegation ticket, in case it's there + */ + if (ctx->fwd_data.length > 0 && (ctx->flags & GSS_C_DELEG_FLAG)) { + ret = gsskrb5_accept_delegated_token(minor_status, + ctx, + delegated_cred_handle); + if (ret) + return ret; + } else { + /* Well, looks like it wasn't there after all */ + ctx->flags &= ~GSS_C_DELEG_FLAG; + } + + ctx->state = ACCEPTOR_READY; + ctx->more_flags |= OPEN; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +gsskrb5_acceptor_start(OM_uint32 * minor_status, + gsskrb5_ctx ctx, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t * delegated_cred_handle) +{ + krb5_error_code kret; + OM_uint32 ret = GSS_S_COMPLETE; + krb5_data indata; + krb5_flags ap_options; + krb5_ticket *ticket = NULL; + krb5_keytab keytab = NULL; + krb5_keyblock *keyblock = NULL; + int is_cfx = 0; + const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle; + + /* + * We may, or may not, have an escapsulation. + */ + ret = _gsskrb5_decapsulate (minor_status, + input_token_buffer, + &indata, + "\x01\x00", + GSS_KRB5_MECHANISM); + + if (ret) { + /* Assume that there is no OID wrapping. */ + indata.length = input_token_buffer->length; + indata.data = input_token_buffer->value; + } + + /* + * We need to get our keytab + */ + if (acceptor_cred == NULL) { + if (_gsskrb5_keytab != NULL) + keytab = _gsskrb5_keytab; + } else if (acceptor_cred->keytab != NULL) { + keytab = acceptor_cred->keytab; + } + + /* + * We need to check the ticket and create the AP-REP packet + */ + kret = krb5_rd_req_return_keyblock(_gsskrb5_context, + &ctx->auth_context, + &indata, + (acceptor_cred == NULL) ? NULL : acceptor_cred->principal, + keytab, + &ap_options, + &ticket, + &keyblock); + if (kret) { + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + + /* + * We need to remember some data on the context_handle. + */ + ctx->ticket = ticket; + ctx->service_keyblock = keyblock; + ctx->lifetime = ticket->ticket.endtime; + + /* + * We need to copy the principal names to the context and the + * calling layer. + */ + kret = krb5_copy_principal(_gsskrb5_context, + ticket->client, + &ctx->source); + if (kret) { + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + } + + kret = krb5_copy_principal(_gsskrb5_context, ticket->server, &ctx->target); + if (kret) { + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + + /* + * We need to setup some compat stuff, this assumes that + * context_handle->target is already set. + */ + ret = _gss_DES3_get_mic_compat(minor_status, ctx); + if (ret) + return ret; + + if (src_name != NULL) { + kret = krb5_copy_principal (_gsskrb5_context, + ticket->client, + (gsskrb5_name*)src_name); + if (kret) { + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + } + + /* + * We need to get the flags out of the 8003 checksum. + */ + { + krb5_authenticator authenticator; + + kret = krb5_auth_con_getauthenticator(_gsskrb5_context, + ctx->auth_context, + &authenticator); + if(kret) { + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + + if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) { + ret = _gsskrb5_verify_8003_checksum(minor_status, + input_chan_bindings, + authenticator->cksum, + &ctx->flags, + &ctx->fwd_data); + + krb5_free_authenticator(_gsskrb5_context, &authenticator); + if (ret) { + return ret; + } + } else { + krb5_crypto crypto; + + kret = krb5_crypto_init(_gsskrb5_context, + ctx->auth_context->keyblock, + 0, &crypto); + if(kret) { + krb5_free_authenticator(_gsskrb5_context, &authenticator); + + ret = GSS_S_FAILURE; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + + /* + * Windows accepts Samba3's use of a kerberos, rather than + * GSSAPI checksum here + */ + + kret = krb5_verify_checksum(_gsskrb5_context, + crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0, + authenticator->cksum); + krb5_free_authenticator(_gsskrb5_context, &authenticator); + krb5_crypto_destroy(_gsskrb5_context, crypto); + + if(kret) { + ret = GSS_S_BAD_SIG; + *minor_status = kret; + _gsskrb5_set_error_string (); + return ret; + } + + /* + * Samba style get some flags (but not DCE-STYLE) + */ + ctx->flags = + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + } + } + + if(ctx->flags & GSS_C_MUTUAL_FLAG) { + krb5_data outbuf; + + _gsskrb5i_is_cfx(ctx, &is_cfx); + + if (is_cfx != 0 + || (ap_options & AP_OPTS_USE_SUBKEY)) { + kret = krb5_auth_con_addflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_USE_SUBKEY, + NULL); + ctx->more_flags |= ACCEPTOR_SUBKEY; + } + + kret = krb5_mk_rep(_gsskrb5_context, + ctx->auth_context, + &outbuf); + if (kret) { + *minor_status = kret; + _gsskrb5_set_error_string (); + return GSS_S_FAILURE; + } + + if (ctx->flags & GSS_C_DCE_STYLE) { + output_token->length = outbuf.length; + output_token->value = outbuf.data; + } else { + ret = _gsskrb5_encapsulate(minor_status, + &outbuf, + output_token, + "\x02\x00", + GSS_KRB5_MECHANISM); + krb5_data_free (&outbuf); + if (ret) + return ret; + } + } + + ctx->flags |= GSS_C_TRANS_FLAG; + + /* Remember the flags */ + + ctx->lifetime = ticket->ticket.endtime; + ctx->more_flags |= OPEN; + + if (mech_type) + *mech_type = GSS_KRB5_MECHANISM; + + if (time_rec) { + ret = _gsskrb5_lifetime_left(minor_status, + ctx->lifetime, + time_rec); + if (ret) { + return ret; + } + } + + /* + * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from + * the client. + */ + if (ctx->flags & GSS_C_DCE_STYLE) { + /* + * Return flags to caller, but we haven't processed + * delgations yet + */ + if (ret_flags) + *ret_flags = (ctx->flags & ~GSS_C_DELEG_FLAG); + + ctx->state = ACCEPTOR_WAIT_FOR_DCESTYLE; + return GSS_S_CONTINUE_NEEDED; + } + + ret = gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle); + + if (ret_flags) + *ret_flags = ctx->flags; + + return ret; +} + +static OM_uint32 +acceptor_wait_for_dcestyle(OM_uint32 * minor_status, + gsskrb5_ctx ctx, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t * delegated_cred_handle) +{ + OM_uint32 ret; + krb5_error_code kret; + krb5_data inbuf; + int32_t r_seq_number, l_seq_number; + + /* + * We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP + */ + + inbuf.length = input_token_buffer->length; + inbuf.data = input_token_buffer->value; + + /* + * We need to remeber the old remote seq_number, then check if the + * client has replied with our local seq_number, and then reset + * the remote seq_number to the old value + */ + { + kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + ctx->auth_context, + &l_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + kret = krb5_auth_getremoteseqnumber(_gsskrb5_context, + ctx->auth_context, + &r_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context, + ctx->auth_context, + l_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + } + + /* + * We need to verify the AP_REP, but we need to flag that this is + * DCE_STYLE, so don't check the timestamps this time, but put the + * flag DO_TIME back afterward. + */ + { + krb5_ap_rep_enc_part *repl; + int32_t auth_flags; + + krb5_auth_con_removeflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_TIME, + &auth_flags); + + kret = krb5_rd_rep(_gsskrb5_context, ctx->auth_context, &inbuf, &repl); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + krb5_free_ap_rep_enc_part(_gsskrb5_context, repl); + krb5_auth_con_setflags(_gsskrb5_context, ctx->auth_context, auth_flags); + } + + /* We need to check the liftime */ + { + OM_uint32 lifetime_rec; + + ret = _gsskrb5_lifetime_left(minor_status, + ctx->lifetime, + &lifetime_rec); + if (ret) { + return ret; + } + if (lifetime_rec == 0) { + return GSS_S_CONTEXT_EXPIRED; + } + + if (time_rec) *time_rec = lifetime_rec; + } + + /* We need to give the caller the flags which are in use */ + if (ret_flags) *ret_flags = ctx->flags; + + if (src_name) { + kret = krb5_copy_principal(_gsskrb5_context, + ctx->source, + (gsskrb5_name*)src_name); + if (kret) { + *minor_status = kret; + _gsskrb5_set_error_string (); + return GSS_S_FAILURE; + } + } + + /* + * After the krb5_rd_rep() the remote and local seq_number should + * be the same, because the client just replies the seq_number + * from our AP-REP in its AP-REP, but then the client uses the + * seq_number from its AP-REQ for GSS_wrap() + */ + { + int32_t tmp_r_seq_number, tmp_l_seq_number; + + kret = krb5_auth_getremoteseqnumber(_gsskrb5_context, + ctx->auth_context, + &tmp_r_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + ctx->auth_context, + &tmp_l_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + /* + * Here we check if the client has responsed with our local seq_number, + */ + if (tmp_r_seq_number != tmp_l_seq_number) { + return GSS_S_UNSEQ_TOKEN; + } + } + + /* + * We need to reset the remote seq_number, because the client will use, + * the old one for the GSS_wrap() calls + */ + { + kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context, + ctx->auth_context, + r_seq_number); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + } + + return gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle); +} + + +OM_uint32 +_gsskrb5_accept_sec_context(OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t * delegated_cred_handle) +{ + OM_uint32 ret; + gsskrb5_ctx ctx; + + GSSAPI_KRB5_INIT(); + + output_token->length = 0; + output_token->value = NULL; + + if (src_name != NULL) + *src_name = NULL; + if (mech_type) + *mech_type = GSS_KRB5_MECHANISM; + + if (*context_handle == GSS_C_NO_CONTEXT) { + ret = _gsskrb5_create_ctx(minor_status, + context_handle, + input_chan_bindings, + ACCEPTOR_START); + if (ret) + return ret; + } + + ctx = (gsskrb5_ctx)*context_handle; + + + /* + * TODO: check the channel_bindings + * (above just sets them to krb5 layer) + */ + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + switch (ctx->state) { + case ACCEPTOR_START: + ret = gsskrb5_acceptor_start(minor_status, + ctx, + acceptor_cred_handle, + input_token_buffer, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle); + break; + case ACCEPTOR_WAIT_FOR_DCESTYLE: + ret = acceptor_wait_for_dcestyle(minor_status, + ctx, + acceptor_cred_handle, + input_token_buffer, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle); + break; + case ACCEPTOR_READY: + /* + * If we get there, the caller have called + * gss_accept_sec_context() one time too many. + */ + ret = GSS_S_BAD_STATUS; + break; + default: + /* TODO: is this correct here? --metze */ + ret = GSS_S_BAD_STATUS; + break; + } + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + if (GSS_ERROR(ret)) { + OM_uint32 min2; + _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER); + } + + return ret; +} diff --git a/source4/heimdal/lib/gssapi/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index fa5d709a30..df6e137402 100644 --- a/source4/heimdal/lib/gssapi/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,12 +31,12 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: acquire_cred.c,v 1.27 2005/12/01 16:26:02 lha Exp $"); +RCSID("$Id: acquire_cred.c,v 1.31 2006/10/07 22:13:55 lha Exp $"); OM_uint32 -_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status, +__gsskrb5_ccache_lifetime(OM_uint32 *minor_status, krb5_ccache id, krb5_principal principal, OM_uint32 *lifetime) @@ -48,32 +48,32 @@ _gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status, memset(&in_cred, 0, sizeof(in_cred)); in_cred.client = principal; - realm = krb5_principal_get_realm(gssapi_krb5_context, principal); + realm = krb5_principal_get_realm(_gsskrb5_context, principal); if (realm == NULL) { - gssapi_krb5_clear_status (); + _gsskrb5_clear_status (); *minor_status = KRB5_PRINC_NOMATCH; /* XXX */ return GSS_S_FAILURE; } - kret = krb5_make_principal(gssapi_krb5_context, &in_cred.server, + kret = krb5_make_principal(_gsskrb5_context, &in_cred.server, realm, KRB5_TGS_NAME, realm, NULL); if (kret) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_get_credentials(gssapi_krb5_context, 0, + kret = krb5_get_credentials(_gsskrb5_context, 0, id, &in_cred, &out_cred); - krb5_free_principal(gssapi_krb5_context, in_cred.server); + krb5_free_principal(_gsskrb5_context, in_cred.server); if (kret) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = kret; return GSS_S_FAILURE; } *lifetime = out_cred->times.endtime; - krb5_free_creds(gssapi_krb5_context, out_cred); + krb5_free_creds(_gsskrb5_context, out_cred); return GSS_S_COMPLETE; } @@ -82,21 +82,21 @@ _gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status, static krb5_error_code -get_keytab(krb5_context context, krb5_keytab *keytab) +get_keytab(krb5_keytab *keytab) { char kt_name[256]; krb5_error_code kret; HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); - if (gssapi_krb5_keytab != NULL) { - kret = krb5_kt_get_name(context, - gssapi_krb5_keytab, + if (_gsskrb5_keytab != NULL) { + kret = krb5_kt_get_name(_gsskrb5_context, + _gsskrb5_keytab, kt_name, sizeof(kt_name)); if (kret == 0) - kret = krb5_kt_resolve(context, kt_name, keytab); + kret = krb5_kt_resolve(_gsskrb5_context, kt_name, keytab); } else - kret = krb5_kt_default(context, keytab); + kret = krb5_kt_default(_gsskrb5_context, keytab); HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); @@ -105,12 +105,11 @@ get_keytab(krb5_context context, krb5_keytab *keytab) static OM_uint32 acquire_initiator_cred (OM_uint32 * minor_status, - krb5_context context, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, - gss_cred_id_t handle, + gsskrb5_cred handle, gss_OID_set * actual_mechs, OM_uint32 * time_rec ) @@ -120,9 +119,10 @@ static OM_uint32 acquire_initiator_cred krb5_principal def_princ; krb5_get_init_creds_opt *opt; krb5_ccache ccache; - krb5_error_code kret; krb5_keytab keytab; + krb5_error_code kret; + keytab = NULL; ccache = NULL; def_princ = NULL; ret = GSS_S_FAILURE; @@ -132,33 +132,33 @@ static OM_uint32 acquire_initiator_cred * caches, otherwise, fall back to default cache. Ignore * errors. */ if (handle->principal) - kret = krb5_cc_cache_match (gssapi_krb5_context, + kret = krb5_cc_cache_match (_gsskrb5_context, handle->principal, NULL, &ccache); if (ccache == NULL) { - kret = krb5_cc_default(gssapi_krb5_context, &ccache); + kret = krb5_cc_default(_gsskrb5_context, &ccache); if (kret) goto end; } - kret = krb5_cc_get_principal(context, ccache, + kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &def_princ); if (kret != 0) { /* we'll try to use a keytab below */ - krb5_cc_destroy(context, ccache); + krb5_cc_destroy(_gsskrb5_context, ccache); ccache = NULL; kret = 0; } else if (handle->principal == NULL) { - kret = krb5_copy_principal(context, def_princ, + kret = krb5_copy_principal(_gsskrb5_context, def_princ, &handle->principal); if (kret) goto end; } else if (handle->principal != NULL && - krb5_principal_compare(context, handle->principal, + krb5_principal_compare(_gsskrb5_context, handle->principal, def_princ) == FALSE) { /* Before failing, lets check the keytab */ - krb5_free_principal(context, def_princ); + krb5_free_principal(_gsskrb5_context, def_princ); def_princ = NULL; } if (def_princ == NULL) { @@ -166,37 +166,37 @@ static OM_uint32 acquire_initiator_cred * so attempt to get a TGT using a keytab. */ if (handle->principal == NULL) { - kret = krb5_get_default_principal(context, + kret = krb5_get_default_principal(_gsskrb5_context, &handle->principal); if (kret) goto end; } - kret = get_keytab(context, &keytab); + kret = get_keytab(&keytab); if (kret) goto end; - kret = krb5_get_init_creds_opt_alloc(gssapi_krb5_context, &opt); + kret = krb5_get_init_creds_opt_alloc(_gsskrb5_context, &opt); if (kret) goto end; - kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred, + kret = krb5_get_init_creds_keytab(_gsskrb5_context, &cred, handle->principal, keytab, 0, NULL, opt); krb5_get_init_creds_opt_free(opt); if (kret) goto end; - kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops, + kret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops, &ccache); if (kret) goto end; - kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client); + kret = krb5_cc_initialize(_gsskrb5_context, ccache, cred.client); if (kret) goto end; - kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred); + kret = krb5_cc_store_cred(_gsskrb5_context, ccache, &cred); if (kret) goto end; handle->lifetime = cred.times.endtime; handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; } else { - ret = _gssapi_krb5_ccache_lifetime(minor_status, + ret = __gsskrb5_ccache_lifetime(minor_status, ccache, handle->principal, &handle->lifetime); @@ -210,17 +210,17 @@ static OM_uint32 acquire_initiator_cred end: if (cred.client != NULL) - krb5_free_cred_contents(context, &cred); + krb5_free_cred_contents(_gsskrb5_context, &cred); if (def_princ != NULL) - krb5_free_principal(context, def_princ); + krb5_free_principal(_gsskrb5_context, def_princ); if (keytab != NULL) - krb5_kt_close(context, keytab); + krb5_kt_close(_gsskrb5_context, keytab); if (ret != GSS_S_COMPLETE) { if (ccache != NULL) - krb5_cc_close(gssapi_krb5_context, ccache); + krb5_cc_close(_gsskrb5_context, ccache); if (kret != 0) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); } } return (ret); @@ -228,11 +228,11 @@ end: static OM_uint32 acquire_acceptor_cred (OM_uint32 * minor_status, - krb5_context context, + const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, - gss_cred_id_t handle, + gsskrb5_cred handle, gss_OID_set * actual_mechs, OM_uint32 * time_rec ) @@ -242,7 +242,7 @@ static OM_uint32 acquire_acceptor_cred kret = 0; ret = GSS_S_FAILURE; - kret = get_keytab(context, &handle->keytab); + kret = get_keytab(&handle->keytab); if (kret) goto end; @@ -250,37 +250,38 @@ static OM_uint32 acquire_acceptor_cred if (handle->principal) { krb5_keytab_entry entry; - kret = krb5_kt_get_entry(gssapi_krb5_context, handle->keytab, + kret = krb5_kt_get_entry(_gsskrb5_context, handle->keytab, handle->principal, 0, 0, &entry); if (kret) goto end; - krb5_kt_free_entry(gssapi_krb5_context, &entry); + krb5_kt_free_entry(_gsskrb5_context, &entry); } ret = GSS_S_COMPLETE; end: if (ret != GSS_S_COMPLETE) { - krb5_kt_close(context, handle->keytab); + if (handle->keytab != NULL) + krb5_kt_close(_gsskrb5_context, handle->keytab); if (kret != 0) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); } } return (ret); } -OM_uint32 gss_acquire_cred - (OM_uint32 * minor_status, - const gss_name_t desired_name, - OM_uint32 time_req, - const gss_OID_set desired_mechs, - gss_cred_usage_t cred_usage, - gss_cred_id_t * output_cred_handle, - gss_OID_set * actual_mechs, - OM_uint32 * time_rec - ) +OM_uint32 _gsskrb5_acquire_cred +(OM_uint32 * minor_status, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t * output_cred_handle, + gss_OID_set * actual_mechs, + OM_uint32 * time_rec + ) { - gss_cred_id_t handle; + gsskrb5_cred handle; OM_uint32 ret; if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) { @@ -299,8 +300,8 @@ OM_uint32 gss_acquire_cred if (desired_mechs) { int present = 0; - ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - desired_mechs, &present); + ret = _gsskrb5_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + desired_mechs, &present); if (ret) return ret; if (!present) { @@ -309,66 +310,63 @@ OM_uint32 gss_acquire_cred } } - handle = (gss_cred_id_t)malloc(sizeof(*handle)); - if (handle == GSS_C_NO_CREDENTIAL) { + handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } - memset(handle, 0, sizeof (*handle)); HEIMDAL_MUTEX_init(&handle->cred_id_mutex); if (desired_name != GSS_C_NO_NAME) { - ret = gss_duplicate_name(minor_status, desired_name, - &handle->principal); - if (ret != GSS_S_COMPLETE) { + krb5_principal name = (krb5_principal)desired_name; + ret = krb5_copy_principal(_gsskrb5_context, name, &handle->principal); + if (ret) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); + _gsskrb5_set_error_string(); + *minor_status = ret; free(handle); - return (ret); + return GSS_S_FAILURE; } } if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) { - ret = acquire_initiator_cred(minor_status, gssapi_krb5_context, - desired_name, time_req, - desired_mechs, cred_usage, - handle, actual_mechs, time_rec); + ret = acquire_initiator_cred(minor_status, desired_name, time_req, + desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); free(handle); return (ret); } } if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { - ret = acquire_acceptor_cred(minor_status, gssapi_krb5_context, - time_req, - desired_mechs, cred_usage, - handle, actual_mechs, time_rec); + ret = acquire_acceptor_cred(minor_status, desired_name, time_req, + desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); free(handle); return (ret); } } - ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); + ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) - ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - &handle->mechanisms); + ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); if (ret == GSS_S_COMPLETE) - ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL, - actual_mechs); + ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)handle, + NULL, time_rec, NULL, actual_mechs); if (ret != GSS_S_COMPLETE) { if (handle->mechanisms != NULL) - gss_release_oid_set(NULL, &handle->mechanisms); + _gsskrb5_release_oid_set(NULL, &handle->mechanisms); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); free(handle); return (ret); } *minor_status = 0; if (time_rec) { - ret = gssapi_lifetime_left(minor_status, + ret = _gsskrb5_lifetime_left(minor_status, handle->lifetime, time_rec); @@ -376,8 +374,6 @@ OM_uint32 gss_acquire_cred return ret; } handle->usage = cred_usage; - - *output_cred_handle = handle; + *output_cred_handle = (gss_cred_id_t)handle; return (GSS_S_COMPLETE); } - diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c new file mode 100644 index 0000000000..4892e84798 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: add_cred.c,v 1.9 2006/10/07 22:13:58 lha Exp $"); + +OM_uint32 _gsskrb5_add_cred ( + OM_uint32 *minor_status, + const gss_cred_id_t input_cred_handle, + const gss_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 ret, lifetime; + gsskrb5_cred cred, handle; + krb5_const_principal dname; + + handle = NULL; + cred = (gsskrb5_cred)input_cred_handle; + dname = (krb5_const_principal)desired_name; + + if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) { + *minor_status = 0; + return GSS_S_BAD_MECH; + } + + if (cred == NULL && output_cred_handle == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + if (cred == NULL) { /* XXX standard conformance failure */ + *minor_status = 0; + return GSS_S_NO_CRED; + } + + /* check if requested output usage is compatible with output usage */ + if (output_cred_handle != NULL) { + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return(GSS_S_FAILURE); + } + } + + /* check that we have the same name */ + if (dname != NULL && + krb5_principal_compare(_gsskrb5_context, dname, + cred->principal) != FALSE) { + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = 0; + return GSS_S_BAD_NAME; + } + + /* make a copy */ + if (output_cred_handle) { + krb5_error_code kret; + + handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + handle->usage = cred_usage; + handle->lifetime = cred->lifetime; + handle->principal = NULL; + handle->keytab = NULL; + handle->ccache = NULL; + handle->mechanisms = NULL; + HEIMDAL_MUTEX_init(&handle->cred_id_mutex); + + ret = GSS_S_FAILURE; + + kret = krb5_copy_principal(_gsskrb5_context, cred->principal, + &handle->principal); + if (kret) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + free(handle); + *minor_status = kret; + return GSS_S_FAILURE; + } + + if (cred->keytab) { + char name[KRB5_KT_PREFIX_MAX_LEN + MAXPATHLEN]; + int len; + + ret = GSS_S_FAILURE; + + kret = krb5_kt_get_type(_gsskrb5_context, cred->keytab, + name, KRB5_KT_PREFIX_MAX_LEN); + if (kret) { + *minor_status = kret; + goto failure; + } + len = strlen(name); + name[len++] = ':'; + + kret = krb5_kt_get_name(_gsskrb5_context, cred->keytab, + name + len, + sizeof(name) - len); + if (kret) { + *minor_status = kret; + goto failure; + } + + kret = krb5_kt_resolve(_gsskrb5_context, name, + &handle->keytab); + if (kret){ + *minor_status = kret; + goto failure; + } + } + + if (cred->ccache) { + const char *type, *name; + char *type_name; + + ret = GSS_S_FAILURE; + + type = krb5_cc_get_type(_gsskrb5_context, cred->ccache); + if (type == NULL){ + *minor_status = ENOMEM; + goto failure; + } + + if (strcmp(type, "MEMORY") == 0) { + ret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops, + &handle->ccache); + if (ret) { + *minor_status = ret; + goto failure; + } + + ret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache, + handle->ccache); + if (ret) { + *minor_status = ret; + goto failure; + } + + } else { + name = krb5_cc_get_name(_gsskrb5_context, cred->ccache); + if (name == NULL) { + *minor_status = ENOMEM; + goto failure; + } + + asprintf(&type_name, "%s:%s", type, name); + if (type_name == NULL) { + *minor_status = ENOMEM; + goto failure; + } + + kret = krb5_cc_resolve(_gsskrb5_context, type_name, + &handle->ccache); + free(type_name); + if (kret) { + *minor_status = kret; + goto failure; + } + } + } + ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); + if (ret) + goto failure; + + ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); + if (ret) + goto failure; + } + + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + + ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)cred, + NULL, &lifetime, NULL, actual_mechs); + if (ret) + goto failure; + + if (initiator_time_rec) + *initiator_time_rec = lifetime; + if (acceptor_time_rec) + *acceptor_time_rec = lifetime; + + if (output_cred_handle) { + *output_cred_handle = (gss_cred_id_t)handle; + } + + *minor_status = 0; + return ret; + + failure: + + if (handle) { + if (handle->principal) + krb5_free_principal(_gsskrb5_context, handle->principal); + if (handle->keytab) + krb5_kt_close(_gsskrb5_context, handle->keytab); + if (handle->ccache) + krb5_cc_destroy(_gsskrb5_context, handle->ccache); + if (handle->mechanisms) + _gsskrb5_release_oid_set(NULL, &handle->mechanisms); + free(handle); + } + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + return ret; +} diff --git a/source4/heimdal/lib/gssapi/add_oid_set_member.c b/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c index ed654fc8c5..b0ec2c60d8 100644 --- a/source4/heimdal/lib/gssapi/add_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/krb5/add_oid_set_member.c @@ -31,11 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: add_oid_set_member.c,v 1.8 2003/03/16 17:50:49 lha Exp $"); +RCSID("$Id: add_oid_set_member.c,v 1.10 2006/10/07 22:14:00 lha Exp $"); -OM_uint32 gss_add_oid_set_member ( +OM_uint32 _gsskrb5_add_oid_set_member ( OM_uint32 * minor_status, const gss_OID member_oid, gss_OID_set * oid_set @@ -46,7 +46,8 @@ OM_uint32 gss_add_oid_set_member ( OM_uint32 res; int present; - res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present); + res = _gsskrb5_test_oid_set_member(minor_status, member_oid, + *oid_set, &present); if (res != GSS_S_COMPLETE) return res; diff --git a/source4/heimdal/lib/gssapi/address_to_krb5addr.c b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c index 13a6825f55..9aec53faaa 100644 --- a/source4/heimdal/lib/gssapi/address_to_krb5addr.c +++ b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c @@ -31,15 +31,15 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" #include <roken.h> krb5_error_code -gss_address_to_krb5addr(OM_uint32 gss_addr_type, - gss_buffer_desc *gss_addr, - int16_t port, - krb5_address *address) +_gsskrb5i_address_to_krb5addr(OM_uint32 gss_addr_type, + gss_buffer_desc *gss_addr, + int16_t port, + krb5_address *address) { int addr_type; struct sockaddr sa; @@ -61,7 +61,7 @@ gss_address_to_krb5addr(OM_uint32 gss_addr_type, return GSS_S_FAILURE; } - problem = krb5_h_addr2sockaddr (gssapi_krb5_context, + problem = krb5_h_addr2sockaddr (_gsskrb5_context, addr_type, gss_addr->value, &sa, @@ -70,7 +70,7 @@ gss_address_to_krb5addr(OM_uint32 gss_addr_type, if (problem) return GSS_S_FAILURE; - problem = krb5_sockaddr2address (gssapi_krb5_context, &sa, address); + problem = krb5_sockaddr2address (_gsskrb5_context, &sa, address); return problem; } diff --git a/source4/heimdal/lib/gssapi/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 936a20d403..82851f5a78 100644 --- a/source4/heimdal/lib/gssapi/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,9 +31,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: arcfour.c,v 1.19 2006/05/04 11:56:50 lha Exp $"); +RCSID("$Id: arcfour.c,v 1.29 2006/10/07 22:14:05 lha Exp $"); /* * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt @@ -57,6 +57,17 @@ RCSID("$Id: arcfour.c,v 1.19 2006/05/04 11:56:50 lha Exp $"); * Confounder[8] */ +/* + * WRAP in DCE-style have a fixed size header, the oid and length over + * the WRAP header is a total of + * GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE + + * GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead, + * remember the 2 bytes from APPL [0] SEQ). + */ + +#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32 +#define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13 + static krb5_error_code arcfour_mic_key(krb5_context context, krb5_keyblock *key, @@ -127,13 +138,13 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, memcpy(ptr + l1, v2, l2); memcpy(ptr + l1 + l2, v3, l3); - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret) { free(ptr); return ret; } - ret = krb5_create_checksum(gssapi_krb5_context, + ret = krb5_create_checksum(_gsskrb5_context, crypto, usage, 0, @@ -144,7 +155,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz); free_Checksum(&CKSUM); } - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return ret; } @@ -152,7 +163,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -164,7 +175,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, u_char k6_data[16], *p0, *p; RC4_KEY rc4_key; - gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); message_token->length = total_len; message_token->value = malloc (total_len); @@ -195,28 +206,28 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, message_buffer->value, message_buffer->length, NULL, 0); if (ret) { - gss_release_buffer(minor_status, message_token); + _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } - ret = arcfour_mic_key(gssapi_krb5_context, key, + ret = arcfour_mic_key(_gsskrb5_context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { - gss_release_buffer(minor_status, message_token); + _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, context_handle->auth_context, &seq_number); p = p0 + 8; /* SND_SEQ */ - gssapi_encode_be_om_uint32(seq_number, p); + _gsskrb5_encode_be_om_uint32(seq_number, p); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -236,7 +247,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -244,7 +255,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, char *type) { krb5_error_code ret; - int32_t seq_number; + uint32_t seq_number; OM_uint32 omret; u_char SND_SEQ[8], cksum_data[8], *p; char k6_data[16]; @@ -254,7 +265,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, *qop_state = 0; p = token_buffer->value; - omret = gssapi_krb5_verify_header (&p, + omret = _gsskrb5_verify_header (&p, token_buffer->length, (u_char *)type, GSS_KRB5_MECHANISM); @@ -278,7 +289,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, return GSS_S_FAILURE; } - ret = arcfour_mic_key(gssapi_krb5_context, key, + ret = arcfour_mic_key(_gsskrb5_context, key, cksum_data, sizeof(cksum_data), k6_data, sizeof(k6_data)); if (ret) { @@ -302,7 +313,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, memset(k6_data, 0, sizeof(k6_data)); } - gssapi_decode_be_om_uint32(SND_SEQ, &seq_number); + _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); @@ -326,39 +337,8 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, } OM_uint32 -_gssapi_wrap_size_arcfour(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_input_size, - OM_uint32 * output_size, - OM_uint32 * padlen, - krb5_keyblock *key) -{ - size_t len, total_len, datalen; - *padlen = 0; - datalen = req_input_size; - len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; - /* if GSS_C_DCE_STYLE is in use: - * - we only need to encapsulate the WRAP token - * - we should not add padding - */ - if (!(context_handle->flags & GSS_C_DCE_STYLE)) { - datalen += 1 /* padding */; - len += datalen; - } - _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); - if (context_handle->flags & GSS_C_DCE_STYLE) { - total_len += datalen; - } - - *output_size = total_len; - return GSS_S_COMPLETE; -} - -OM_uint32 _gssapi_wrap_arcfour(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -375,19 +355,17 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, if (conf_state) *conf_state = 0; - datalen = input_message_buffer->length; - len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; - /* if GSS_C_DCE_STYLE is in use: - * - we only need to encapsulate the WRAP token - * - we should not add padding - */ - if (!(context_handle->flags & GSS_C_DCE_STYLE)) { - datalen += 1 /* padding */; - len += datalen; - } - _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); - if (context_handle->flags & GSS_C_DCE_STYLE) { - total_len += datalen; + if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) { + datalen = input_message_buffer->length + 1 /* padding */; + + len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE; + _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + } else { + datalen = input_message_buffer->length; + + len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; + _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + total_len += datalen; } output_message_buffer->length = total_len; @@ -419,13 +397,13 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, p = NULL; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, context_handle->auth_context, &seq_number); - gssapi_encode_be_om_uint32(seq_number, p0 + 8); + _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -439,9 +417,9 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, /* p points to data */ p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE; memcpy(p, input_message_buffer->value, input_message_buffer->length); - /* only add padding when GSS_C_DCE_STYLE is not in use */ - if (!(context_handle->flags & GSS_C_DCE_STYLE)) { - p[input_message_buffer->length] = 1; /* PADDING */ + + if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) { + p[input_message_buffer->length] = 1; /* PADDING */ } ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL, @@ -452,7 +430,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, datalen); if (ret) { *minor_status = ret; - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } @@ -466,12 +444,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } - ret = arcfour_mic_key(gssapi_krb5_context, &Klocal, + ret = arcfour_mic_key(_gsskrb5_context, &Klocal, p0 + 8, 4, /* SND_SEQ */ k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } @@ -487,11 +465,11 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, } memset(k6_data, 0, sizeof(k6_data)); - ret = arcfour_mic_key(gssapi_krb5_context, key, + ret = arcfour_mic_key(_gsskrb5_context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } @@ -513,7 +491,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, } OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, @@ -523,15 +501,15 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, u_char Klocaldata[16]; krb5_keyblock Klocal; krb5_error_code ret; - int32_t seq_number; - size_t len, datalen; + uint32_t seq_number; + size_t datalen; OM_uint32 omret; u_char k6_data[16], SND_SEQ[8], Confounder[8]; u_char cksum_data[8]; u_char *p, *p0; int cmp; int conf_flag; - size_t padlen = 0; + size_t padlen = 0, len; if (conf_state) *conf_state = 0; @@ -539,25 +517,34 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, *qop_state = 0; p0 = input_message_buffer->value; - len = input_message_buffer->length; - /* if we have GSS_C_DCE_STYLE in use, we only need to decapsulate the WRAP token */ - if (context_handle->flags & GSS_C_DCE_STYLE) { - if (input_message_buffer->length < (GSS_ARCFOUR_WRAP_TOKEN_OFFSET+GSS_ARCFOUR_WRAP_TOKEN_SIZE)) { - return GSS_S_BAD_MECH; - } - len = GSS_ARCFOUR_WRAP_TOKEN_OFFSET+GSS_ARCFOUR_WRAP_TOKEN_SIZE; + + if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) { + len = input_message_buffer->length; + } else { + len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + + GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE; + if (input_message_buffer->length < len) + return GSS_S_BAD_MECH; } + omret = _gssapi_verify_mech_header(&p0, len, GSS_KRB5_MECHANISM); if (omret) return omret; - p = p0; - datalen = input_message_buffer->length - - (p - ((u_char *)input_message_buffer->value)) - + /* length of mech header */ + len = (p0 - (u_char *)input_message_buffer->value) + GSS_ARCFOUR_WRAP_TOKEN_SIZE; + if (len > input_message_buffer->length) + return GSS_S_BAD_MECH; + + /* length of data */ + datalen = input_message_buffer->length - len; + + p = p0; + if (memcmp(p, "\x02\x01", 2) != 0) return GSS_S_BAD_SIG; p += 2; @@ -577,7 +564,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, return GSS_S_BAD_MIC; p = NULL; - ret = arcfour_mic_key(gssapi_krb5_context, key, + ret = arcfour_mic_key(_gsskrb5_context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { @@ -594,7 +581,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, memset(k6_data, 0, sizeof(k6_data)); } - gssapi_decode_be_om_uint32(SND_SEQ, &seq_number); + _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); @@ -616,7 +603,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } - ret = arcfour_mic_key(gssapi_krb5_context, &Klocal, + ret = arcfour_mic_key(_gsskrb5_context, &Klocal, SND_SEQ, 4, k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); @@ -648,14 +635,14 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, } memset(k6_data, 0, sizeof(k6_data)); - if (!(context_handle->flags & GSS_C_DCE_STYLE)) { - ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen); - if (ret) { - gss_release_buffer(minor_status, output_message_buffer); + if ((context_handle->flags & GSS_C_DCE_STYLE) == 0) { + ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen); + if (ret) { + _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return ret; - } - output_message_buffer->length -= padlen; + } + output_message_buffer->length -= padlen; } ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL, @@ -665,14 +652,14 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, output_message_buffer->value, output_message_buffer->length + padlen); if (ret) { - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ if (cmp) { - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return GSS_S_BAD_MIC; } @@ -689,3 +676,79 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, *minor_status = 0; return GSS_S_COMPLETE; } + +static OM_uint32 +max_wrap_length_arcfour(const gsskrb5_ctx ctx, + krb5_crypto crypto, + size_t input_length, + OM_uint32 *max_input_size) +{ + /* + * if GSS_C_DCE_STYLE is in use: + * - we only need to encapsulate the WRAP token + * However, since this is a fixed since, we just + */ + if (ctx->flags & GSS_C_DCE_STYLE) { + size_t len, total_len; + + len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; + _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + + if (input_length < len) + *max_input_size = 0; + else + *max_input_size = input_length - len; + + } else { + size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE; + size_t blocksize = 8; + size_t len, total_len; + + len = 8 + input_length + blocksize + extrasize; + + _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + + total_len -= input_length; /* token length */ + if (total_len < input_length) { + *max_input_size = (input_length - total_len); + (*max_input_size) &= (~(OM_uint32)(blocksize - 1)); + } else { + *max_input_size = 0; + } + } + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gssapi_wrap_size_arcfour(OM_uint32 *minor_status, + const gsskrb5_ctx ctx, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size, + krb5_keyblock *key) +{ + krb5_error_code ret; + krb5_crypto crypto; + + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + if (ret != 0) { + _gsskrb5_set_error_string(); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = max_wrap_length_arcfour(ctx, crypto, + req_output_size, max_input_size); + if (ret != 0) { + _gsskrb5_set_error_string(); + *minor_status = ret; + krb5_crypto_destroy(_gsskrb5_context, crypto); + return GSS_S_FAILURE; + } + + krb5_crypto_destroy(_gsskrb5_context, crypto); + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c new file mode 100644 index 0000000000..f69300b590 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: canonicalize_name.c,v 1.4 2006/10/07 22:14:08 lha Exp $"); + +OM_uint32 _gsskrb5_canonicalize_name ( + OM_uint32 * minor_status, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t * output_name + ) +{ + return _gsskrb5_duplicate_name (minor_status, input_name, output_name); +} diff --git a/source4/heimdal/lib/gssapi/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c index ef7907c0de..cb3f9ee5d3 100755 --- a/source4/heimdal/lib/gssapi/cfx.c +++ b/source4/heimdal/lib/gssapi/krb5/cfx.c @@ -30,9 +30,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: cfx.c,v 1.19 2006/05/05 10:26:43 lha Exp $"); +RCSID("$Id: cfx.c,v 1.24 2006/10/24 21:13:22 lha Exp $"); /* * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt @@ -42,14 +42,13 @@ RCSID("$Id: cfx.c,v 1.19 2006/05/05 10:26:43 lha Exp $"); #define CFXSealed (1 << 1) #define CFXAcceptorSubkey (1 << 2) -static krb5_error_code -wrap_length_cfx(krb5_crypto crypto, - int conf_req_flag, - size_t input_length, - size_t *output_length, - size_t *cksumsize, - uint16_t *padlength, - size_t *padsize) +krb5_error_code +_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, + int conf_req_flag, + size_t input_length, + size_t *output_length, + size_t *cksumsize, + uint16_t *padlength) { krb5_error_code ret; krb5_cksumtype type; @@ -58,39 +57,37 @@ wrap_length_cfx(krb5_crypto crypto, *output_length = sizeof(gss_cfx_wrap_token_desc); *padlength = 0; - ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto, &type); - if (ret) { + ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type); + if (ret) return ret; - } - ret = krb5_checksumsize(gssapi_krb5_context, type, cksumsize); - if (ret) { + ret = krb5_checksumsize(_gsskrb5_context, type, cksumsize); + if (ret) return ret; - } if (conf_req_flag) { + size_t padsize; /* Header is concatenated with data before encryption */ input_length += sizeof(gss_cfx_wrap_token_desc); - ret = krb5_crypto_getpadsize(gssapi_krb5_context, crypto, padsize); + ret = krb5_crypto_getpadsize(_gsskrb5_context, crypto, &padsize); if (ret) { return ret; } - if (*padsize > 1) { + if (padsize > 1) { /* XXX check this */ - *padlength = *padsize - (input_length % *padsize); - } + *padlength = padsize - (input_length % padsize); - /* We add the pad ourselves (noted here for completeness only) */ - input_length += *padlength; + /* We add the pad ourselves (noted here for completeness only) */ + input_length += *padlength; + } - *output_length += krb5_get_wrapped_length(gssapi_krb5_context, + *output_length += krb5_get_wrapped_length(_gsskrb5_context, crypto, input_length); } else { /* Checksum is concatenated with data */ *output_length += input_length + *cksumsize; - *padsize = 0; } assert(*output_length > input_length); @@ -98,42 +95,94 @@ wrap_length_cfx(krb5_crypto crypto, return 0; } +krb5_error_code +_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, + int conf_req_flag, + size_t input_length, + OM_uint32 *output_length) +{ + krb5_error_code ret; + + *output_length = 0; + + /* 16-byte header is always first */ + if (input_length < 16) + return 0; + input_length -= 16; + + if (conf_req_flag) { + size_t wrapped_size, sz; + + wrapped_size = input_length + 1; + do { + wrapped_size--; + sz = krb5_get_wrapped_length(_gsskrb5_context, + crypto, wrapped_size); + } while (wrapped_size && sz > input_length); + if (wrapped_size == 0) { + *output_length = 0; + return 0; + } + + /* inner header */ + if (wrapped_size < 16) { + *output_length = 0; + return 0; + } + wrapped_size -= 16; + + *output_length = wrapped_size; + } else { + krb5_cksumtype type; + size_t cksumsize; + + ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type); + if (ret) + return ret; + + ret = krb5_checksumsize(_gsskrb5_context, type, &cksumsize); + if (ret) + return ret; + + if (input_length < cksumsize) + return 0; + + /* Checksum is concatenated with data */ + *output_length = input_length - cksumsize; + } + + return 0; +} + + OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, int conf_req_flag, gss_qop_t qop_req, - OM_uint32 req_input_size, - OM_uint32 *output_len, - OM_uint32 *padsize, + OM_uint32 req_output_size, + OM_uint32 *max_input_size, krb5_keyblock *key) { krb5_error_code ret; krb5_crypto crypto; - uint16_t pad_length; - size_t pad_size; - size_t output_length, cksumsize; - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = wrap_length_cfx(crypto, conf_req_flag, - req_input_size, - &output_length, &cksumsize, &pad_length, &pad_size); + ret = _gsskrb5cfx_max_wrap_length_cfx(crypto, conf_req_flag, + req_output_size, max_input_size); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } - *output_len = output_length; - *padsize = pad_size; - - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_COMPLETE; } @@ -183,7 +232,7 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate) } OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -199,23 +248,22 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, size_t wrapped_len, cksumsize; uint16_t padlength, rrc = 0; int32_t seq_number; - size_t padsize; u_char *p; - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = wrap_length_cfx(crypto, conf_req_flag, - input_message_buffer->length, - &wrapped_len, &cksumsize, &padlength, &padsize); + ret = _gsskrb5cfx_wrap_length_cfx(crypto, conf_req_flag, + input_message_buffer->length, + &wrapped_len, &cksumsize, &padlength); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -226,7 +274,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, output_message_buffer->value = malloc(output_message_buffer->length); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -276,12 +324,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, token->RRC[1] = 0; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber(gssapi_krb5_context, + krb5_auth_con_getlocalseqnumber(_gsskrb5_context, context_handle->auth_context, &seq_number); - gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]); - gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); - krb5_auth_con_setlocalseqnumber(gssapi_krb5_context, + _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]); + _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); + krb5_auth_con_setlocalseqnumber(_gsskrb5_context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -316,16 +364,16 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, memcpy(p + input_message_buffer->length + padlength, token, sizeof(*token)); - ret = krb5_encrypt(gssapi_krb5_context, crypto, + ret = krb5_encrypt(_gsskrb5_context, crypto, usage, p, input_message_buffer->length + padlength + sizeof(*token), &cipher); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } assert(sizeof(*token) + cipher.length == wrapped_len); @@ -334,10 +382,10 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } memcpy(p, cipher.data, cipher.length); @@ -349,23 +397,23 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, buf = malloc(input_message_buffer->length + sizeof(*token)); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } memcpy(buf, input_message_buffer->value, input_message_buffer->length); memcpy(buf + input_message_buffer->length, token, sizeof(*token)); - ret = krb5_create_checksum(gssapi_krb5_context, crypto, + ret = krb5_create_checksum(_gsskrb5_context, crypto, usage, 0, buf, input_message_buffer->length + sizeof(*token), &cksum); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); free(buf); return GSS_S_FAILURE; } @@ -386,17 +434,17 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, ret = rrc_rotate(p, input_message_buffer->length + cksum.checksum.length, rrc, FALSE); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); free_Checksum(&cksum); return GSS_S_FAILURE; } free_Checksum(&cksum); } - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); if (conf_state != NULL) { *conf_state = conf_req_flag; @@ -407,7 +455,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, } OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, @@ -470,8 +518,8 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* * Check sequence number */ - gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi); - gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo); + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi); + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo); if (seq_number_hi) { /* no support for 64-bit sequence numbers */ *minor_status = ERANGE; @@ -483,7 +531,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, if (ret != 0) { *minor_status = 0; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - gss_release_buffer(minor_status, output_message_buffer); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return ret; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -491,9 +539,9 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* * Decrypt and/or verify checksum */ - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } @@ -511,23 +559,23 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Rotate by RRC; bogus to do this in-place XXX */ *minor_status = rrc_rotate(p, len, rrc, TRUE); if (*minor_status != 0) { - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } if (token_flags & CFXSealed) { - ret = krb5_decrypt(gssapi_krb5_context, crypto, usage, + ret = krb5_decrypt(_gsskrb5_context, crypto, usage, p, len, &data); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_BAD_MIC; } /* Check that there is room for the pad and token header */ if (data.length < ec + sizeof(*token)) { - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); krb5_data_free(&data); return GSS_S_DEFECTIVE_TOKEN; } @@ -540,7 +588,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Check the integrity of the header */ if (memcmp(p, token, sizeof(*token)) != 0) { - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); krb5_data_free(&data); return GSS_S_BAD_MIC; } @@ -551,12 +599,12 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, Checksum cksum; /* Determine checksum type */ - ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, + ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &cksum.cksumtype); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -565,7 +613,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Check we have at least as much data as the checksum */ if (len < cksum.checksum.length) { *minor_status = ERANGE; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_BAD_MIC; } @@ -577,7 +625,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, output_message_buffer->value = malloc(len + sizeof(*token)); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -594,21 +642,21 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, token->RRC[0] = 0; token->RRC[1] = 0; - ret = krb5_verify_checksum(gssapi_krb5_context, crypto, + ret = krb5_verify_checksum(_gsskrb5_context, crypto, usage, output_message_buffer->value, len + sizeof(*token), &cksum); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); - gss_release_buffer(minor_status, output_message_buffer); + krb5_crypto_destroy(_gsskrb5_context, crypto); + _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_BAD_MIC; } } - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); if (qop_state != NULL) { *qop_state = GSS_C_QOP_DEFAULT; @@ -619,7 +667,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, } OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -634,9 +682,9 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, size_t len; int32_t seq_number; - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } @@ -645,7 +693,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, buf = malloc(len); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -662,12 +710,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, memset(token->Filler, 0xFF, 5); HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber(gssapi_krb5_context, + krb5_auth_con_getlocalseqnumber(_gsskrb5_context, context_handle->auth_context, &seq_number); - gssapi_encode_be_om_uint32(0, &token->SND_SEQ[0]); - gssapi_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); - krb5_auth_con_setlocalseqnumber(gssapi_krb5_context, + _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]); + _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); + krb5_auth_con_setlocalseqnumber(_gsskrb5_context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -678,16 +726,16 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; } - ret = krb5_create_checksum(gssapi_krb5_context, crypto, + ret = krb5_create_checksum(_gsskrb5_context, crypto, usage, 0, buf, len, &cksum); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); free(buf); return GSS_S_FAILURE; } - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); /* Determine MIC length */ message_token->length = sizeof(*token) + cksum.checksum.length; @@ -712,7 +760,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, } OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t *qop_state, @@ -763,8 +811,8 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, /* * Check sequence number */ - gssapi_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi); - gssapi_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo); + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi); + _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo); if (seq_number_hi) { *minor_status = ERANGE; return GSS_S_UNSEQ_TOKEN; @@ -782,19 +830,19 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, /* * Verify checksum */ - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_crypto_get_checksum_type(gssapi_krb5_context, crypto, + ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &cksum.cksumtype); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } @@ -810,21 +858,21 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, buf = malloc(message_buffer->length + sizeof(*token)); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); return GSS_S_FAILURE; } memcpy(buf, message_buffer->value, message_buffer->length); memcpy(buf + message_buffer->length, token, sizeof(*token)); - ret = krb5_verify_checksum(gssapi_krb5_context, crypto, + ret = krb5_verify_checksum(_gsskrb5_context, crypto, usage, buf, sizeof(*token) + message_buffer->length, &cksum); + krb5_crypto_destroy(_gsskrb5_context, crypto); if (ret != 0) { - gssapi_krb5_set_error_string(); + _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(gssapi_krb5_context, crypto); free(buf); return GSS_S_BAD_MIC; } diff --git a/source4/heimdal/lib/gssapi/cfx.h b/source4/heimdal/lib/gssapi/krb5/cfx.h index d9bdd9da19..1120544fbe 100755 --- a/source4/heimdal/lib/gssapi/cfx.h +++ b/source4/heimdal/lib/gssapi/krb5/cfx.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: cfx.h,v 1.5 2003/09/22 21:48:35 lha Exp $ */ +/* $Id: cfx.h,v 1.7 2006/07/19 14:16:33 lha Exp $ */ #ifndef GSSAPI_CFX_H_ #define GSSAPI_CFX_H_ 1 @@ -62,44 +62,19 @@ typedef struct gss_cfx_delete_token_desc_struct { u_char SND_SEQ[8]; } gss_cfx_delete_token_desc, *gss_cfx_delete_token; -OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_input_size, - OM_uint32 *output_len, - OM_uint32 *padlen, - krb5_keyblock *key); - -OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - const gss_buffer_t input_message_buffer, - int *conf_state, - gss_buffer_t output_message_buffer, - krb5_keyblock *key); +krb5_error_code +_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, + int conf_req_flag, + size_t input_length, + size_t *output_length, + size_t *cksumsize, + uint16_t *padlength); -OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - const gss_buffer_t input_message_buffer, - gss_buffer_t output_message_buffer, - int *conf_state, - gss_qop_t *qop_state, - krb5_keyblock *key); - -OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - gss_qop_t qop_req, - const gss_buffer_t message_buffer, - gss_buffer_t message_token, - krb5_keyblock *key); +krb5_error_code +_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, + int conf_req_flag, + size_t input_length, + OM_uint32 *output_length); -OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - const gss_buffer_t message_buffer, - const gss_buffer_t token_buffer, - gss_qop_t *qop_state, - krb5_keyblock *key); #endif /* GSSAPI_CFX_H_ */ diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c new file mode 100644 index 0000000000..3e0f7edfee --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: compare_name.c,v 1.7 2006/10/07 22:14:15 lha Exp $"); + +OM_uint32 _gsskrb5_compare_name + (OM_uint32 * minor_status, + const gss_name_t name1, + const gss_name_t name2, + int * name_equal + ) +{ + krb5_const_principal princ1 = (krb5_const_principal)name1; + krb5_const_principal princ2 = (krb5_const_principal)name2; + + GSSAPI_KRB5_INIT(); + + *name_equal = krb5_principal_compare (_gsskrb5_context, + princ1, princ2); + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c index 5605c48023..0ea2fce0e8 100644 --- a/source4/heimdal/lib/gssapi/compat.c +++ b/source4/heimdal/lib/gssapi/krb5/compat.c @@ -31,42 +31,42 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: compat.c,v 1.10 2005/05/30 20:51:51 lha Exp $"); +RCSID("$Id: compat.c,v 1.13 2006/10/07 22:14:17 lha Exp $"); -krb5_error_code -_gss_check_compat(OM_uint32 *minor_status, gss_name_t name, - const char *option, krb5_boolean *compat, - krb5_boolean match_val) +static krb5_error_code +check_compat(OM_uint32 *minor_status, krb5_const_principal name, + const char *option, krb5_boolean *compat, + krb5_boolean match_val) { krb5_error_code ret = 0; char **p, **q; krb5_principal match; - p = krb5_config_get_strings(gssapi_krb5_context, NULL, "gssapi", + p = krb5_config_get_strings(_gsskrb5_context, NULL, "gssapi", option, NULL); if(p == NULL) return 0; match = NULL; for(q = p; *q; q++) { - ret = krb5_parse_name(gssapi_krb5_context, *q, &match); + ret = krb5_parse_name(_gsskrb5_context, *q, &match); if (ret) break; - if (krb5_principal_match(gssapi_krb5_context, name, match)) { + if (krb5_principal_match(_gsskrb5_context, name, match)) { *compat = match_val; break; } - krb5_free_principal(gssapi_krb5_context, match); + krb5_free_principal(_gsskrb5_context, match); match = NULL; } if (match) - krb5_free_principal(gssapi_krb5_context, match); + krb5_free_principal(_gsskrb5_context, match); krb5_config_free_strings(p); if (ret) { @@ -83,18 +83,18 @@ _gss_check_compat(OM_uint32 *minor_status, gss_name_t name, */ OM_uint32 -_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx) +_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gsskrb5_ctx ctx) { krb5_boolean use_compat = FALSE; OM_uint32 ret; if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) { - ret = _gss_check_compat(minor_status, ctx->target, - "broken_des3_mic", &use_compat, TRUE); + ret = check_compat(minor_status, ctx->target, + "broken_des3_mic", &use_compat, TRUE); if (ret) return ret; - ret = _gss_check_compat(minor_status, ctx->target, - "correct_des3_mic", &use_compat, FALSE); + ret = check_compat(minor_status, ctx->target, + "correct_des3_mic", &use_compat, FALSE); if (ret) return ret; @@ -105,6 +105,7 @@ _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx) return 0; } +#if 0 OM_uint32 gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on) { @@ -121,34 +122,4 @@ gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on) return 0; } - -/* - * For compatability with the Windows SPNEGO implementation, the - * default is to ignore the mechListMIC unless the initiator specified - * CFX or configured in krb5.conf with the option - * [gssapi]require_mechlist_mic=target-principal-pattern. - * The option is valid for both initiator and acceptor. - */ -OM_uint32 -_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status, - gss_ctx_id_t ctx, - krb5_boolean *require_mic) -{ - OM_uint32 ret; - int is_cfx = 0; - - gsskrb5_is_cfx(ctx, &is_cfx); - if (is_cfx) { - /* CFX session key was used */ - *require_mic = TRUE; - } else { - *require_mic = FALSE; - ret = _gss_check_compat(minor_status, ctx->target, - "require_mechlist_mic", - require_mic, TRUE); - if (ret) - return ret; - } - *minor_status = 0; - return GSS_S_COMPLETE; -} +#endif diff --git a/source4/heimdal/lib/gssapi/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c index ee1dc6fe93..4e9d9f5d1d 100644 --- a/source4/heimdal/lib/gssapi/context_time.c +++ b/source4/heimdal/lib/gssapi/krb5/context_time.c @@ -31,12 +31,12 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: context_time.c,v 1.11 2005/12/05 09:19:52 lha Exp $"); +RCSID("$Id: context_time.c,v 1.13 2006/10/07 22:14:19 lha Exp $"); OM_uint32 -gssapi_lifetime_left(OM_uint32 *minor_status, +_gsskrb5_lifetime_left(OM_uint32 *minor_status, OM_uint32 lifetime, OM_uint32 *lifetime_rec) { @@ -48,10 +48,10 @@ gssapi_lifetime_left(OM_uint32 *minor_status, return GSS_S_COMPLETE; } - kret = krb5_timeofday(gssapi_krb5_context, &timeret); + kret = krb5_timeofday(_gsskrb5_context, &timeret); if (kret) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); return GSS_S_FAILURE; } @@ -64,7 +64,7 @@ gssapi_lifetime_left(OM_uint32 *minor_status, } -OM_uint32 gss_context_time +OM_uint32 _gsskrb5_context_time (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, OM_uint32 * time_rec @@ -72,14 +72,15 @@ OM_uint32 gss_context_time { OM_uint32 lifetime; OM_uint32 major_status; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; GSSAPI_KRB5_INIT (); - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - lifetime = context_handle->lifetime; - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + lifetime = ctx->lifetime; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); - major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec); + major_status = _gsskrb5_lifetime_left(minor_status, lifetime, time_rec); if (major_status != GSS_S_COMPLETE) return major_status; diff --git a/source4/heimdal/lib/gssapi/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index 782b701e44..99aa2ccb43 100644 --- a/source4/heimdal/lib/gssapi/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -31,10 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: copy_ccache.c,v 1.13 2005/11/28 23:05:44 lha Exp $"); +RCSID("$Id: copy_ccache.c,v 1.15 2006/10/07 22:14:22 lha Exp $"); +#if 0 OM_uint32 gss_krb5_copy_ccache(OM_uint32 *minor_status, gss_cred_id_t cred, @@ -50,36 +51,37 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, return GSS_S_FAILURE; } - kret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache, out); + kret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache, out); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (kret) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); return GSS_S_FAILURE; } *minor_status = 0; return GSS_S_COMPLETE; } +#endif OM_uint32 -gss_krb5_import_cred(OM_uint32 *minor_status, +_gsskrb5_import_cred(OM_uint32 *minor_status, krb5_ccache id, krb5_principal keytab_principal, krb5_keytab keytab, gss_cred_id_t *cred) { krb5_error_code kret; - gss_cred_id_t handle; + gsskrb5_cred handle; OM_uint32 ret; *cred = NULL; GSSAPI_KRB5_INIT (); - handle = (gss_cred_id_t)calloc(1, sizeof(*handle)); - if (handle == GSS_C_NO_CREDENTIAL) { - gssapi_krb5_clear_status (); + handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { + _gsskrb5_clear_status (); *minor_status = ENOMEM; return (GSS_S_FAILURE); } @@ -92,11 +94,11 @@ gss_krb5_import_cred(OM_uint32 *minor_status, handle->usage |= GSS_C_INITIATE; - kret = krb5_cc_get_principal(gssapi_krb5_context, id, + kret = krb5_cc_get_principal(_gsskrb5_context, id, &handle->principal); if (kret) { free(handle); - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -104,34 +106,34 @@ gss_krb5_import_cred(OM_uint32 *minor_status, if (keytab_principal) { krb5_boolean match; - match = krb5_principal_compare(gssapi_krb5_context, + match = krb5_principal_compare(_gsskrb5_context, handle->principal, keytab_principal); if (match == FALSE) { - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); free(handle); - gssapi_krb5_clear_status (); + _gsskrb5_clear_status (); *minor_status = EINVAL; return GSS_S_FAILURE; } } - ret = _gssapi_krb5_ccache_lifetime(minor_status, + ret = __gsskrb5_ccache_lifetime(minor_status, id, handle->principal, &handle->lifetime); if (ret != GSS_S_COMPLETE) { - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); free(handle); return ret; } - kret = krb5_cc_get_full_name(gssapi_krb5_context, id, &str); + kret = krb5_cc_get_full_name(_gsskrb5_context, id, &str); if (kret) goto out; - kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache); + kret = krb5_cc_resolve(_gsskrb5_context, str, &handle->ccache); free(str); if (kret) goto out; @@ -144,18 +146,18 @@ gss_krb5_import_cred(OM_uint32 *minor_status, handle->usage |= GSS_C_ACCEPT; if (keytab_principal && handle->principal == NULL) { - kret = krb5_copy_principal(gssapi_krb5_context, + kret = krb5_copy_principal(_gsskrb5_context, keytab_principal, &handle->principal); if (kret) goto out; } - kret = krb5_kt_get_full_name(gssapi_krb5_context, keytab, &str); + kret = krb5_kt_get_full_name(_gsskrb5_context, keytab, &str); if (kret) goto out; - kret = krb5_kt_resolve(gssapi_krb5_context, str, &handle->keytab); + kret = krb5_kt_resolve(_gsskrb5_context, str, &handle->keytab); free(str); if (kret) goto out; @@ -163,10 +165,10 @@ gss_krb5_import_cred(OM_uint32 *minor_status, if (id || keytab) { - ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); + ret = _gsskrb5_create_empty_oid_set(minor_status, &handle->mechanisms); if (ret == GSS_S_COMPLETE) - ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, - &handle->mechanisms); + ret = _gsskrb5_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &handle->mechanisms); if (ret != GSS_S_COMPLETE) { kret = *minor_status; goto out; @@ -174,107 +176,16 @@ gss_krb5_import_cred(OM_uint32 *minor_status, } *minor_status = 0; - *cred = handle; + *cred = (gss_cred_id_t)handle; return GSS_S_COMPLETE; out: - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); if (handle->principal) - krb5_free_principal(gssapi_krb5_context, handle->principal); + krb5_free_principal(_gsskrb5_context, handle->principal); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); *minor_status = kret; return GSS_S_FAILURE; } - -OM_uint32 -gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - int ad_type, - gss_buffer_t ad_data) -{ - krb5_error_code ret; - krb5_data data; - - ad_data->value = NULL; - ad_data->length = 0; - - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - if (context_handle->ticket == NULL) { - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - - ret = krb5_ticket_get_authorization_data_type(gssapi_krb5_context, - context_handle->ticket, - ad_type, - &data); - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - - ad_data->value = malloc(data.length); - if (ad_data->value == NULL) { - krb5_data_free(&data); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - ad_data->length = data.length; - memcpy(ad_data->value, data.data, ad_data->length); - krb5_data_free(&data); - - *minor_status = 0; - return GSS_S_COMPLETE; -} - -OM_uint32 -gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - time_t *authtime) -{ - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - if (context_handle->ticket == NULL) { - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - - *authtime = context_handle->ticket->ticket.authtime; - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - - *minor_status = 0; - return GSS_S_COMPLETE; -} - -OM_uint32 gss_krb5_copy_service_keyblock - (OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - struct EncryptionKey **out) -{ - krb5_error_code ret; - - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - if (context_handle->service_keyblock == NULL) { - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - - ret = krb5_copy_keyblock(gssapi_krb5_context, - context_handle->service_keyblock, - out); - - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - - *minor_status = 0; - return GSS_S_COMPLETE; -} diff --git a/source4/heimdal/lib/gssapi/create_emtpy_oid_set.c b/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c index 1a25e0d781..550995125a 100644 --- a/source4/heimdal/lib/gssapi/create_emtpy_oid_set.c +++ b/source4/heimdal/lib/gssapi/krb5/create_emtpy_oid_set.c @@ -31,11 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: create_emtpy_oid_set.c,v 1.5 2003/03/16 17:47:07 lha Exp $"); +RCSID("$Id: create_emtpy_oid_set.c,v 1.7 2006/10/07 22:14:24 lha Exp $"); -OM_uint32 gss_create_empty_oid_set ( +OM_uint32 _gsskrb5_create_empty_oid_set ( OM_uint32 * minor_status, gss_OID_set * oid_set ) diff --git a/source4/heimdal/lib/gssapi/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c index 08df361776..eadec1ef03 100644 --- a/source4/heimdal/lib/gssapi/decapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c @@ -31,9 +31,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: decapsulate.c,v 1.12 2005/06/16 20:40:49 lha Exp $"); +RCSID("$Id: decapsulate.c,v 1.16 2006/10/07 22:14:26 lha Exp $"); /* * return the length of the mechanism in token or -1 @@ -41,7 +41,7 @@ RCSID("$Id: decapsulate.c,v 1.12 2005/06/16 20:40:49 lha Exp $"); */ ssize_t -gssapi_krb5_get_mech (const u_char *ptr, +_gsskrb5_get_mech (const u_char *ptr, size_t total_len, const u_char **mech_ret) { @@ -76,7 +76,7 @@ _gssapi_verify_mech_header(u_char **str, const u_char *p; ssize_t mech_len; - mech_len = gssapi_krb5_get_mech (*str, total_len, &p); + mech_len = _gsskrb5_get_mech (*str, total_len, &p); if (mech_len < 0) return GSS_S_DEFECTIVE_TOKEN; @@ -92,9 +92,9 @@ _gssapi_verify_mech_header(u_char **str, } OM_uint32 -gssapi_krb5_verify_header(u_char **str, +_gsskrb5_verify_header(u_char **str, size_t total_len, - const u_char *type, + const void *type, gss_OID oid) { OM_uint32 ret; @@ -110,7 +110,7 @@ gssapi_krb5_verify_header(u_char **str, if (len < 2) return GSS_S_DEFECTIVE_TOKEN; - if ((*str)[0] != type[0] || (*str)[1] != type[1]) + if (memcmp (*str, type, 2) != 0) return GSS_S_DEFECTIVE_TOKEN; *str += 2; @@ -154,17 +154,17 @@ _gssapi_decapsulate( */ OM_uint32 -gssapi_krb5_decapsulate(OM_uint32 *minor_status, +_gsskrb5_decapsulate(OM_uint32 *minor_status, gss_buffer_t input_token_buffer, krb5_data *out_data, - const char *type, + const void *type, gss_OID oid) { u_char *p; OM_uint32 ret; p = input_token_buffer->value; - ret = gssapi_krb5_verify_header(&p, + ret = _gsskrb5_verify_header(&p, input_token_buffer->length, type, oid); diff --git a/source4/heimdal/lib/gssapi/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index f1842def7c..e890d7d2c2 100644 --- a/source4/heimdal/lib/gssapi/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -31,16 +31,17 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: delete_sec_context.c,v 1.16 2006/01/16 13:12:29 lha Exp $"); +RCSID("$Id: delete_sec_context.c,v 1.19 2006/10/07 22:14:28 lha Exp $"); -OM_uint32 gss_delete_sec_context - (OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - gss_buffer_t output_token - ) +OM_uint32 +_gsskrb5_delete_sec_context(OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + gss_buffer_t output_token) { + gsskrb5_ctx ctx; + GSSAPI_KRB5_INIT (); *minor_status = 0; @@ -53,31 +54,27 @@ OM_uint32 gss_delete_sec_context if (*context_handle == GSS_C_NO_CONTEXT) return GSS_S_COMPLETE; - HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + ctx = (gsskrb5_ctx) *context_handle; + *context_handle = GSS_C_NO_CONTEXT; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - krb5_auth_con_free (gssapi_krb5_context, - (*context_handle)->auth_context); - if((*context_handle)->source) - krb5_free_principal (gssapi_krb5_context, - (*context_handle)->source); - if((*context_handle)->target) - krb5_free_principal (gssapi_krb5_context, - (*context_handle)->target); - if ((*context_handle)->ticket) - krb5_free_ticket (gssapi_krb5_context, - (*context_handle)->ticket); - if ((*context_handle)->service_keyblock) - krb5_free_keyblock (gssapi_krb5_context, - (*context_handle)->service_keyblock); - if((*context_handle)->order) - _gssapi_msg_order_destroy(&(*context_handle)->order); - if ((*context_handle)->fwd_data.length > 0) - free((*context_handle)->fwd_data.data); + krb5_auth_con_free (_gsskrb5_context, ctx->auth_context); + if(ctx->source) + krb5_free_principal (_gsskrb5_context, ctx->source); + if(ctx->target) + krb5_free_principal (_gsskrb5_context, ctx->target); + if (ctx->ticket) + krb5_free_ticket (_gsskrb5_context, ctx->ticket); + if(ctx->order) + _gssapi_msg_order_destroy(&ctx->order); + if (ctx->service_keyblock) + krb5_free_keyblock (_gsskrb5_context, ctx->service_keyblock); + krb5_data_free(&ctx->fwd_data); - HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); - HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); - memset(*context_handle, 0, sizeof(**context_handle)); - free (*context_handle); - *context_handle = GSS_C_NO_CONTEXT; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); + memset(ctx, 0, sizeof(*ctx)); + free (ctx); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c index 27a232fd3c..8fce7d8572 100644 --- a/source4/heimdal/lib/gssapi/display_name.c +++ b/source4/heimdal/lib/gssapi/krb5/display_name.c @@ -31,28 +31,27 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_name.c,v 1.9 2003/03/16 17:46:11 lha Exp $"); +RCSID("$Id: display_name.c,v 1.12 2006/10/07 22:14:31 lha Exp $"); -OM_uint32 gss_display_name +OM_uint32 _gsskrb5_display_name (OM_uint32 * minor_status, const gss_name_t input_name, gss_buffer_t output_name_buffer, gss_OID * output_name_type ) { + krb5_const_principal name = (krb5_const_principal)input_name; krb5_error_code kret; char *buf; size_t len; GSSAPI_KRB5_INIT (); - kret = krb5_unparse_name (gssapi_krb5_context, - input_name, - &buf); + kret = krb5_unparse_name (_gsskrb5_context, name, &buf); if (kret) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); return GSS_S_FAILURE; } len = strlen (buf); diff --git a/source4/heimdal/lib/gssapi/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index 0aa88bb57c..11926ca557 100644 --- a/source4/heimdal/lib/gssapi/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -31,9 +31,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_status.c,v 1.14 2005/10/12 07:23:03 lha Exp $"); +RCSID("$Id: display_status.c,v 1.16 2006/10/07 22:14:33 lha Exp $"); static const char * calling_error(OM_uint32 v) @@ -112,9 +112,9 @@ supplementary_error(OM_uint32 v) } void -gssapi_krb5_clear_status (void) +_gsskrb5_clear_status (void) { - struct gssapi_thr_context *ctx = gssapi_get_thread_context(1); + struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1); if (ctx == NULL) return; HEIMDAL_MUTEX_lock(&ctx->mutex); @@ -125,9 +125,9 @@ gssapi_krb5_clear_status (void) } void -gssapi_krb5_set_status (const char *fmt, ...) +_gsskrb5_set_status (const char *fmt, ...) { - struct gssapi_thr_context *ctx = gssapi_get_thread_context(1); + struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1); va_list args; if (ctx == NULL) @@ -143,22 +143,22 @@ gssapi_krb5_set_status (const char *fmt, ...) } void -gssapi_krb5_set_error_string (void) +_gsskrb5_set_error_string (void) { char *e; - e = krb5_get_error_string(gssapi_krb5_context); + e = krb5_get_error_string(_gsskrb5_context); if (e) { - gssapi_krb5_set_status("%s", e); - krb5_free_error_string(gssapi_krb5_context, e); + _gsskrb5_set_status("%s", e); + krb5_free_error_string(_gsskrb5_context, e); } else - gssapi_krb5_clear_status(); + _gsskrb5_clear_status(); } char * -gssapi_krb5_get_error_string (void) +_gsskrb5_get_error_string (void) { - struct gssapi_thr_context *ctx = gssapi_get_thread_context(0); + struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(0); char *ret; if (ctx == NULL) @@ -170,7 +170,7 @@ gssapi_krb5_get_error_string (void) return ret; } -OM_uint32 gss_display_status +OM_uint32 _gsskrb5_display_status (OM_uint32 *minor_status, OM_uint32 status_value, int status_type, @@ -200,9 +200,9 @@ OM_uint32 gss_display_status calling_error(GSS_CALLING_ERROR(status_value)), routine_error(GSS_ROUTINE_ERROR(status_value))); } else if (status_type == GSS_C_MECH_CODE) { - buf = gssapi_krb5_get_error_string (); + buf = _gsskrb5_get_error_string (); if (buf == NULL) { - const char *tmp = krb5_get_err_text (gssapi_krb5_context, + const char *tmp = krb5_get_err_text (_gsskrb5_context, status_value); if (tmp == NULL) asprintf(&buf, "unknown mech error-code %u", diff --git a/source4/heimdal/lib/gssapi/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c index 2b54e90ec8..475ae61efc 100644 --- a/source4/heimdal/lib/gssapi/duplicate_name.c +++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c @@ -31,26 +31,26 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: duplicate_name.c,v 1.7 2003/03/16 17:44:26 lha Exp $"); +RCSID("$Id: duplicate_name.c,v 1.10 2006/10/07 22:14:35 lha Exp $"); -OM_uint32 gss_duplicate_name ( +OM_uint32 _gsskrb5_duplicate_name ( OM_uint32 * minor_status, const gss_name_t src_name, gss_name_t * dest_name ) { + krb5_const_principal src = (krb5_const_principal)src_name; + krb5_principal *dest = (krb5_principal *)dest_name; krb5_error_code kret; GSSAPI_KRB5_INIT (); - kret = krb5_copy_principal (gssapi_krb5_context, - src_name, - dest_name); + kret = krb5_copy_principal (_gsskrb5_context, src, dest); if (kret) { *minor_status = kret; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); return GSS_S_FAILURE; } else { *minor_status = 0; diff --git a/source4/heimdal/lib/gssapi/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c index 4d488a6c42..a015a95103 100644 --- a/source4/heimdal/lib/gssapi/encapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c @@ -31,9 +31,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: encapsulate.c,v 1.8 2003/09/04 18:08:55 lha Exp $"); +RCSID("$Id: encapsulate.c,v 1.12 2006/10/14 10:02:56 lha Exp $"); void _gssapi_encap_length (size_t data_len, @@ -45,13 +45,13 @@ _gssapi_encap_length (size_t data_len, *len = 1 + 1 + mech->length + data_len; - len_len = length_len(*len); + len_len = der_length_len(*len); *total_len = 1 + len_len + *len; } void -gssapi_krb5_encap_length (size_t data_len, +_gsskrb5_encap_length (size_t data_len, size_t *len, size_t *total_len, const gss_OID mech) @@ -59,28 +59,30 @@ gssapi_krb5_encap_length (size_t data_len, _gssapi_encap_length(data_len + 2, len, total_len, mech); } -u_char * -gssapi_krb5_make_header (u_char *p, +void * +_gsskrb5_make_header (void *ptr, size_t len, - const u_char *type, + const void *type, const gss_OID mech) { + u_char *p = ptr; p = _gssapi_make_mech_header(p, len, mech); memcpy (p, type, 2); p += 2; return p; } -u_char * -_gssapi_make_mech_header(u_char *p, +void * +_gssapi_make_mech_header(void *ptr, size_t len, const gss_OID mech) { + u_char *p = ptr; int e; size_t len_len, foo; *p++ = 0x60; - len_len = length_len(len); + len_len = der_length_len(len); e = der_put_length (p + len_len - 1, len_len, len, &foo); if(e || foo != len_len) abort (); @@ -105,7 +107,7 @@ _gssapi_encapsulate( ) { size_t len, outer_len; - u_char *p; + void *p; _gssapi_encap_length (in_data->length, &len, &outer_len, mech); @@ -127,18 +129,18 @@ _gssapi_encapsulate( */ OM_uint32 -gssapi_krb5_encapsulate( +_gsskrb5_encapsulate( OM_uint32 *minor_status, const krb5_data *in_data, gss_buffer_t output_token, - const u_char *type, + const void *type, const gss_OID mech ) { size_t len, outer_len; u_char *p; - gssapi_krb5_encap_length (in_data->length, &len, &outer_len, mech); + _gsskrb5_encap_length (in_data->length, &len, &outer_len, mech); output_token->length = outer_len; output_token->value = malloc (outer_len); @@ -147,7 +149,7 @@ gssapi_krb5_encapsulate( return GSS_S_FAILURE; } - p = gssapi_krb5_make_header (output_token->value, len, type, mech); + p = _gsskrb5_make_header (output_token->value, len, type, mech); memcpy (p, in_data->data, in_data->length); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c new file mode 100644 index 0000000000..d00c458898 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/export_name.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1997, 1999, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: export_name.c,v 1.8 2006/10/07 22:14:40 lha Exp $"); + +OM_uint32 _gsskrb5_export_name + (OM_uint32 * minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name + ) +{ + krb5_const_principal princ = (krb5_const_principal)input_name; + krb5_error_code kret; + char *buf, *name; + size_t len; + + GSSAPI_KRB5_INIT (); + kret = krb5_unparse_name (_gsskrb5_context, princ, &name); + if (kret) { + *minor_status = kret; + _gsskrb5_set_error_string (); + return GSS_S_FAILURE; + } + len = strlen (name); + + exported_name->length = 10 + len + GSS_KRB5_MECHANISM->length; + exported_name->value = malloc(exported_name->length); + if (exported_name->value == NULL) { + free (name); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */ + + buf = exported_name->value; + memcpy(buf, "\x04\x01", 2); + buf += 2; + buf[0] = ((GSS_KRB5_MECHANISM->length + 2) >> 8) & 0xff; + buf[1] = (GSS_KRB5_MECHANISM->length + 2) & 0xff; + buf+= 2; + buf[0] = 0x06; + buf[1] = (GSS_KRB5_MECHANISM->length) & 0xFF; + buf+= 2; + + memcpy(buf, GSS_KRB5_MECHANISM->elements, GSS_KRB5_MECHANISM->length); + buf += GSS_KRB5_MECHANISM->length; + + buf[0] = (len >> 24) & 0xff; + buf[1] = (len >> 16) & 0xff; + buf[2] = (len >> 8) & 0xff; + buf[3] = (len) & 0xff; + buf += 4; + + memcpy (buf, name, len); + + free (name); + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c new file mode 100644 index 0000000000..aff03a0b67 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: export_sec_context.c,v 1.11 2006/10/07 22:14:42 lha Exp $"); + +OM_uint32 +_gsskrb5_export_sec_context ( + OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + gss_buffer_t interprocess_token + ) +{ + const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle; + krb5_storage *sp; + krb5_auth_context ac; + OM_uint32 ret = GSS_S_COMPLETE; + krb5_data data; + gss_buffer_desc buffer; + int flags; + OM_uint32 minor; + krb5_error_code kret; + + GSSAPI_KRB5_INIT (); + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (!(ctx->flags & GSS_C_TRANS_FLAG)) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + + sp = krb5_storage_emem (); + if (sp == NULL) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + ac = ctx->auth_context; + + /* flagging included fields */ + + flags = 0; + if (ac->local_address) + flags |= SC_LOCAL_ADDRESS; + if (ac->remote_address) + flags |= SC_REMOTE_ADDRESS; + if (ac->keyblock) + flags |= SC_KEYBLOCK; + if (ac->local_subkey) + flags |= SC_LOCAL_SUBKEY; + if (ac->remote_subkey) + flags |= SC_REMOTE_SUBKEY; + + kret = krb5_store_int32 (sp, flags); + if (kret) { + *minor_status = kret; + goto failure; + } + + /* marshall auth context */ + + kret = krb5_store_int32 (sp, ac->flags); + if (kret) { + *minor_status = kret; + goto failure; + } + if (ac->local_address) { + kret = krb5_store_address (sp, *ac->local_address); + if (kret) { + *minor_status = kret; + goto failure; + } + } + if (ac->remote_address) { + kret = krb5_store_address (sp, *ac->remote_address); + if (kret) { + *minor_status = kret; + goto failure; + } + } + kret = krb5_store_int16 (sp, ac->local_port); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_int16 (sp, ac->remote_port); + if (kret) { + *minor_status = kret; + goto failure; + } + if (ac->keyblock) { + kret = krb5_store_keyblock (sp, *ac->keyblock); + if (kret) { + *minor_status = kret; + goto failure; + } + } + if (ac->local_subkey) { + kret = krb5_store_keyblock (sp, *ac->local_subkey); + if (kret) { + *minor_status = kret; + goto failure; + } + } + if (ac->remote_subkey) { + kret = krb5_store_keyblock (sp, *ac->remote_subkey); + if (kret) { + *minor_status = kret; + goto failure; + } + } + kret = krb5_store_int32 (sp, ac->local_seqnumber); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_int32 (sp, ac->remote_seqnumber); + if (kret) { + *minor_status = kret; + goto failure; + } + + kret = krb5_store_int32 (sp, ac->keytype); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_int32 (sp, ac->cksumtype); + if (kret) { + *minor_status = kret; + goto failure; + } + + /* names */ + + ret = _gsskrb5_export_name (minor_status, + (gss_name_t)ctx->source, &buffer); + if (ret) + goto failure; + data.data = buffer.value; + data.length = buffer.length; + kret = krb5_store_data (sp, data); + _gsskrb5_release_buffer (&minor, &buffer); + if (kret) { + *minor_status = kret; + goto failure; + } + + ret = _gsskrb5_export_name (minor_status, + (gss_name_t)ctx->target, &buffer); + if (ret) + goto failure; + data.data = buffer.value; + data.length = buffer.length; + + ret = GSS_S_FAILURE; + + kret = krb5_store_data (sp, data); + _gsskrb5_release_buffer (&minor, &buffer); + if (kret) { + *minor_status = kret; + goto failure; + } + + kret = krb5_store_int32 (sp, ctx->flags); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_int32 (sp, ctx->more_flags); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = krb5_store_int32 (sp, ctx->lifetime); + if (kret) { + *minor_status = kret; + goto failure; + } + kret = _gssapi_msg_order_export(sp, ctx->order); + if (kret ) { + *minor_status = kret; + goto failure; + } + + kret = krb5_storage_to_data (sp, &data); + krb5_storage_free (sp); + if (kret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + *minor_status = kret; + return GSS_S_FAILURE; + } + interprocess_token->length = data.length; + interprocess_token->value = data.data; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + ret = _gsskrb5_delete_sec_context (minor_status, context_handle, + GSS_C_NO_BUFFER); + if (ret != GSS_S_COMPLETE) + _gsskrb5_release_buffer (NULL, interprocess_token); + *minor_status = 0; + return ret; + failure: + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + krb5_storage_free (sp); + return ret; +} diff --git a/source4/heimdal/lib/gssapi/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index f8c1d23f98..7419bc2fe8 100644 --- a/source4/heimdal/lib/gssapi/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -31,9 +31,10 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" +#include <gssapi_mech.h> -RCSID("$Id: external.c,v 1.7 2005/08/23 11:59:47 lha Exp $"); +RCSID("$Id: external.c,v 1.18 2006/10/20 21:50:24 lha Exp $"); /* * The implementation must reserve static storage for a @@ -226,18 +227,6 @@ static gss_OID_desc gss_krb5_mechanism_oid_desc = gss_OID GSS_KRB5_MECHANISM = &gss_krb5_mechanism_oid_desc; /* - * RFC2478, SPNEGO: - * The security mechanism of the initial - * negotiation token is identified by the Object Identifier - * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2). - */ - -static gss_OID_desc gss_spnego_mechanism_oid_desc = -{6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")}; - -gss_OID GSS_SPNEGO_MECHANISM = &gss_spnego_mechanism_oid_desc; - -/* * draft-ietf-cat-iakerb-09, IAKERB: * The mechanism ID for IAKERB proxy GSS-API Kerberos, in accordance * with the mechanism proposed by SPNEGO [7] for negotiating protocol @@ -261,7 +250,159 @@ static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc = gss_OID GSS_IAKERB_MIN_MSG_MECHANISM = &gss_iakerb_min_msg_mechanism_oid_desc; /* + * + */ + +static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc = +{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"}; + +gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO = &gss_c_peer_has_updated_spnego_oid_desc; + +/* + * 1.2.752.43.13 Heimdal GSS-API Extentions + */ + +/* 1.2.752.43.13.1 */ +static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")}; + +gss_OID GSS_KRB5_COPY_CCACHE_X = &gss_krb5_copy_ccache_x_oid_desc; + +/* 1.2.752.43.13.2 */ +static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")}; + +gss_OID GSS_KRB5_GET_TKT_FLAGS_X = &gss_krb5_get_tkt_flags_x_oid_desc; + +/* 1.2.752.43.13.3 */ +static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")}; + +gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X = &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc; + +/* 1.2.752.43.13.4 */ +static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")}; + +gss_OID GSS_KRB5_COMPAT_DES3_MIC_X = &gss_krb5_compat_des3_mic_x_oid_desc; + +/* 1.2.752.43.13.5 */ +static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")}; + +gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X = &gss_krb5_register_acceptor_identity_x_desc; + +/* 1.2.752.43.13.6 */ +static gss_OID_desc gss_krb5_export_lucid_context_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")}; + +gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X = &gss_krb5_export_lucid_context_x_desc; + +/* 1.2.752.43.13.6.1 */ +static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc = +{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")}; + +gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X = &gss_krb5_export_lucid_context_v1_x_desc; + +/* 1.2.752.43.13.7 */ +static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")}; + +gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X = &gss_krb5_set_dns_canonicalize_x_desc; + +/* 1.2.752.43.13.8 */ +static gss_OID_desc gss_krb5_get_subkey_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")}; + +gss_OID GSS_KRB5_GET_SUBKEY_X = &gss_krb5_get_subkey_x_desc; + +/* 1.2.752.43.13.9 */ +static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")}; + +gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X = &gss_krb5_get_initiator_subkey_x_desc; + +/* 1.2.752.43.13.10 */ +static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")}; + +gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X = &gss_krb5_get_acceptor_subkey_x_desc; + +/* 1.2.752.43.13.11 */ +static gss_OID_desc gss_krb5_send_to_kdc_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")}; + +gss_OID GSS_KRB5_SEND_TO_KDC_X = &gss_krb5_send_to_kdc_x_desc; + +/* 1.2.752.43.13.12 */ +static gss_OID_desc gss_krb5_get_authtime_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")}; + +gss_OID GSS_KRB5_GET_AUTHTIME_X = &gss_krb5_get_authtime_x_desc; + +/* 1.2.752.43.13.14 */ +static gss_OID_desc gss_krb5_get_service_keyblock_x_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")}; + +gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X = &gss_krb5_get_service_keyblock_x_desc; + +/* 1.2.752.43.14.1 */ +static gss_OID_desc gss_sasl_digest_md5_mechanism_desc = +{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") }; + +gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc; + +/* * Context for krb5 calls. */ -krb5_context gssapi_krb5_context; +krb5_context _gsskrb5_context; + +/* + * + */ + +static gssapi_mech_interface_desc krb5_mech = { + GMI_VERSION, + "kerberos 5", + {9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }, + _gsskrb5_acquire_cred, + _gsskrb5_release_cred, + _gsskrb5_init_sec_context, + _gsskrb5_accept_sec_context, + _gsskrb5_process_context_token, + _gsskrb5_delete_sec_context, + _gsskrb5_context_time, + _gsskrb5_get_mic, + _gsskrb5_verify_mic, + _gsskrb5_wrap, + _gsskrb5_unwrap, + _gsskrb5_display_status, + _gsskrb5_indicate_mechs, + _gsskrb5_compare_name, + _gsskrb5_display_name, + _gsskrb5_import_name, + _gsskrb5_export_name, + _gsskrb5_release_name, + _gsskrb5_inquire_cred, + _gsskrb5_inquire_context, + _gsskrb5_wrap_size_limit, + _gsskrb5_add_cred, + _gsskrb5_inquire_cred_by_mech, + _gsskrb5_export_sec_context, + _gsskrb5_import_sec_context, + _gsskrb5_inquire_names_for_mech, + _gsskrb5_inquire_mechs_for_name, + _gsskrb5_canonicalize_name, + _gsskrb5_duplicate_name, + _gsskrb5_inquire_sec_context_by_oid, + _gsskrb5_inquire_cred_by_oid, + _gsskrb5_set_sec_context_option, + _gsskrb5_set_cred_option +}; + +gssapi_mech_interface +__gss_krb5_initialize(void) +{ + return &krb5_mech; +} diff --git a/source4/heimdal/lib/gssapi/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 76f69cf41c..5a078d634d 100644 --- a/source4/heimdal/lib/gssapi/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -31,14 +31,14 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: get_mic.c,v 1.31 2006/05/08 09:55:37 lha Exp $"); +RCSID("$Id: get_mic.c,v 1.34 2006/10/18 15:59:23 lha Exp $"); static OM_uint32 mic_des (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx ctx, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -54,7 +54,7 @@ mic_des int32_t seq_number; size_t len, total_len; - gssapi_krb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); message_token->length = total_len; message_token->value = malloc (total_len); @@ -64,7 +64,7 @@ mic_des return GSS_S_FAILURE; } - p = gssapi_krb5_make_header(message_token->value, + p = _gsskrb5_make_header(message_token->value, len, "\x01\x01", /* TOK_ID */ GSS_KRB5_MECHANISM); @@ -92,10 +92,10 @@ mic_des &schedule, &zero); memcpy (p - 8, hash, 8); /* SGN_CKSUM */ - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + ctx->auth_context, &seq_number); p -= 16; /* SND_SEQ */ @@ -104,17 +104,17 @@ mic_des p[2] = (seq_number >> 16) & 0xFF; p[3] = (seq_number >> 24) & 0xFF; memset (p + 4, - (context_handle->more_flags & LOCAL) ? 0 : 0xFF, + (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); DES_set_key (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + ctx->auth_context, ++seq_number); - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); @@ -126,7 +126,7 @@ mic_des static OM_uint32 mic_des3 (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx ctx, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -146,7 +146,7 @@ mic_des3 char *tmp; char ivec[8]; - gssapi_krb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM); message_token->length = total_len; message_token->value = malloc (total_len); @@ -156,7 +156,7 @@ mic_des3 return GSS_S_FAILURE; } - p = gssapi_krb5_make_header(message_token->value, + p = _gsskrb5_make_header(message_token->value, len, "\x01\x01", /* TOK-ID */ GSS_KRB5_MECHANISM); @@ -180,18 +180,18 @@ mic_des3 memcpy (tmp, p - 8, 8); memcpy (tmp + 8, message_buffer->value, message_buffer->length); - kret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + kret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; free (tmp); - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_create_checksum (gssapi_krb5_context, + kret = krb5_create_checksum (_gsskrb5_context, crypto, KRB5_KU_USAGE_SIGN, 0, @@ -199,22 +199,22 @@ mic_des3 message_buffer->length + 8, &cksum); free (tmp); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + ctx->auth_context, &seq_number); seq[0] = (seq_number >> 0) & 0xFF; @@ -222,35 +222,35 @@ mic_des3 seq[2] = (seq_number >> 16) & 0xFF; seq[3] = (seq_number >> 24) & 0xFF; memset (seq + 4, - (context_handle->more_flags & LOCAL) ? 0 : 0xFF, + (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); - kret = krb5_crypto_init(gssapi_krb5_context, key, + kret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - if (context_handle->more_flags & COMPAT_OLD_DES3) + if (ctx->more_flags & COMPAT_OLD_DES3) memset(ivec, 0, 8); else memcpy(ivec, p + 8, 8); - kret = krb5_encrypt_ivec (gssapi_krb5_context, + kret = krb5_encrypt_ivec (_gsskrb5_context, crypto, KRB5_KU_USAGE_SEQ, seq, 8, &encdata, ivec); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -260,17 +260,17 @@ mic_des3 memcpy (p, encdata.data, encdata.length); krb5_data_free (&encdata); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + ctx->auth_context, ++seq_number); - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_Checksum (&cksum); *minor_status = 0; return GSS_S_COMPLETE; } -OM_uint32 gss_get_mic +OM_uint32 _gsskrb5_get_mic (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, gss_qop_t qop_req, @@ -278,37 +278,40 @@ OM_uint32 gss_get_mic gss_buffer_t message_token ) { + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; - ret = gss_krb5_get_subkey(context_handle, &key); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = mic_des (minor_status, context_handle, qop_req, + ret = mic_des (minor_status, ctx, qop_req, message_buffer, message_token, key); break; case KEYTYPE_DES3 : - ret = mic_des3 (minor_status, context_handle, qop_req, + ret = mic_des3 (minor_status, ctx, qop_req, message_buffer, message_token, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_get_mic_arcfour (minor_status, context_handle, qop_req, + ret = _gssapi_get_mic_arcfour (minor_status, ctx, qop_req, message_buffer, message_token, key); break; default : - ret = _gssapi_mic_cfx (minor_status, context_handle, qop_req, + ret = _gssapi_mic_cfx (minor_status, ctx, qop_req, message_buffer, message_token, key); break; } - krb5_free_keyblock (gssapi_krb5_context, key); + krb5_free_keyblock (_gsskrb5_context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h new file mode 100644 index 0000000000..426c0ab200 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h @@ -0,0 +1,705 @@ +/* This is a generated file */ +#ifndef __gsskrb5_private_h__ +#define __gsskrb5_private_h__ + +#include <stdarg.h> + +gssapi_mech_interface +__gss_krb5_initialize (void); + +OM_uint32 +__gsskrb5_ccache_lifetime ( + OM_uint32 */*minor_status*/, + krb5_ccache /*id*/, + krb5_principal /*principal*/, + OM_uint32 */*lifetime*/); + +OM_uint32 +_gss_DES3_get_mic_compat ( + OM_uint32 */*minor_status*/, + gsskrb5_ctx /*ctx*/); + +OM_uint32 +_gssapi_decapsulate ( + OM_uint32 */*minor_status*/, + gss_buffer_t /*input_token_buffer*/, + krb5_data */*out_data*/, + const gss_OID mech ); + +void +_gssapi_encap_length ( + size_t /*data_len*/, + size_t */*len*/, + size_t */*total_len*/, + const gss_OID /*mech*/); + +OM_uint32 +_gssapi_encapsulate ( + OM_uint32 */*minor_status*/, + const krb5_data */*in_data*/, + gss_buffer_t /*output_token*/, + const gss_OID mech ); + +OM_uint32 +_gssapi_get_mic_arcfour ( + OM_uint32 * /*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*message_buffer*/, + gss_buffer_t /*message_token*/, + krb5_keyblock */*key*/); + +void * +_gssapi_make_mech_header ( + void */*ptr*/, + size_t /*len*/, + const gss_OID /*mech*/); + +OM_uint32 +_gssapi_mic_cfx ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*message_buffer*/, + gss_buffer_t /*message_token*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_msg_order_check ( + struct gss_msg_order */*o*/, + OM_uint32 /*seq_num*/); + +OM_uint32 +_gssapi_msg_order_create ( + OM_uint32 */*minor_status*/, + struct gss_msg_order **/*o*/, + OM_uint32 /*flags*/, + OM_uint32 /*seq_num*/, + OM_uint32 /*jitter_window*/, + int /*use_64*/); + +OM_uint32 +_gssapi_msg_order_destroy (struct gss_msg_order **/*m*/); + +krb5_error_code +_gssapi_msg_order_export ( + krb5_storage */*sp*/, + struct gss_msg_order */*o*/); + +OM_uint32 +_gssapi_msg_order_f (OM_uint32 /*flags*/); + +OM_uint32 +_gssapi_msg_order_import ( + OM_uint32 */*minor_status*/, + krb5_storage */*sp*/, + struct gss_msg_order **/*o*/); + +OM_uint32 +_gssapi_unwrap_arcfour ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + const gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int */*conf_state*/, + gss_qop_t */*qop_state*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_unwrap_cfx ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + const gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int */*conf_state*/, + gss_qop_t */*qop_state*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_verify_mech_header ( + u_char **/*str*/, + size_t /*total_len*/, + gss_OID /*mech*/); + +OM_uint32 +_gssapi_verify_mic_arcfour ( + OM_uint32 * /*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t * /*qop_state*/, + krb5_keyblock */*key*/, + char */*type*/); + +OM_uint32 +_gssapi_verify_mic_cfx ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t */*qop_state*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_verify_pad ( + gss_buffer_t /*wrapped_token*/, + size_t /*datalen*/, + size_t */*padlen*/); + +OM_uint32 +_gssapi_wrap_arcfour ( + OM_uint32 * /*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t /*output_message_buffer*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_wrap_cfx ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*input_message_buffer*/, + int */*conf_state*/, + gss_buffer_t /*output_message_buffer*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_wrap_size_arcfour ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*ctx*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + OM_uint32 /*req_output_size*/, + OM_uint32 */*max_input_size*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gssapi_wrap_size_cfx ( + OM_uint32 */*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + OM_uint32 /*req_output_size*/, + OM_uint32 */*max_input_size*/, + krb5_keyblock */*key*/); + +OM_uint32 +_gsskrb5_accept_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + const gss_cred_id_t /*acceptor_cred_handle*/, + const gss_buffer_t /*input_token_buffer*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + gss_name_t * /*src_name*/, + gss_OID * /*mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * /*time_rec*/, + gss_cred_id_t * /*delegated_cred_handle*/); + +OM_uint32 +_gsskrb5_acquire_cred ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*desired_name*/, + OM_uint32 /*time_req*/, + const gss_OID_set /*desired_mechs*/, + gss_cred_usage_t /*cred_usage*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * time_rec ); + +OM_uint32 +_gsskrb5_add_cred ( + OM_uint32 */*minor_status*/, + const gss_cred_id_t /*input_cred_handle*/, + const gss_name_t /*desired_name*/, + const gss_OID /*desired_mech*/, + gss_cred_usage_t /*cred_usage*/, + OM_uint32 /*initiator_time_req*/, + OM_uint32 /*acceptor_time_req*/, + gss_cred_id_t */*output_cred_handle*/, + gss_OID_set */*actual_mechs*/, + OM_uint32 */*initiator_time_rec*/, + OM_uint32 */*acceptor_time_rec*/); + +OM_uint32 +_gsskrb5_add_oid_set_member ( + OM_uint32 * /*minor_status*/, + const gss_OID /*member_oid*/, + gss_OID_set * oid_set ); + +OM_uint32 +_gsskrb5_canonicalize_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + const gss_OID /*mech_type*/, + gss_name_t * output_name ); + +void +_gsskrb5_clear_status (void); + +OM_uint32 +_gsskrb5_compare_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*name1*/, + const gss_name_t /*name2*/, + int * name_equal ); + +OM_uint32 +_gsskrb5_context_time ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + OM_uint32 * time_rec ); + +OM_uint32 +_gsskrb5_create_8003_checksum ( + OM_uint32 */*minor_status*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + OM_uint32 /*flags*/, + const krb5_data */*fwd_data*/, + Checksum */*result*/); + +OM_uint32 +_gsskrb5_create_ctx ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + enum gss_ctx_id_t_state /*state*/); + +OM_uint32 +_gsskrb5_create_empty_oid_set ( + OM_uint32 * /*minor_status*/, + gss_OID_set * oid_set ); + +OM_uint32 +_gsskrb5_decapsulate ( + OM_uint32 */*minor_status*/, + gss_buffer_t /*input_token_buffer*/, + krb5_data */*out_data*/, + const void */*type*/, + gss_OID /*oid*/); + +krb5_error_code +_gsskrb5_decode_be_om_uint32 ( + const void */*ptr*/, + OM_uint32 */*n*/); + +krb5_error_code +_gsskrb5_decode_om_uint32 ( + const void */*ptr*/, + OM_uint32 */*n*/); + +OM_uint32 +_gsskrb5_delete_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + gss_buffer_t /*output_token*/); + +OM_uint32 +_gsskrb5_display_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t /*output_name_buffer*/, + gss_OID * output_name_type ); + +OM_uint32 +_gsskrb5_display_status ( + OM_uint32 */*minor_status*/, + OM_uint32 /*status_value*/, + int /*status_type*/, + const gss_OID /*mech_type*/, + OM_uint32 */*message_context*/, + gss_buffer_t /*status_string*/); + +OM_uint32 +_gsskrb5_duplicate_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*src_name*/, + gss_name_t * dest_name ); + +void +_gsskrb5_encap_length ( + size_t /*data_len*/, + size_t */*len*/, + size_t */*total_len*/, + const gss_OID /*mech*/); + +OM_uint32 +_gsskrb5_encapsulate ( + OM_uint32 */*minor_status*/, + const krb5_data */*in_data*/, + gss_buffer_t /*output_token*/, + const void */*type*/, + const gss_OID mech ); + +krb5_error_code +_gsskrb5_encode_be_om_uint32 ( + OM_uint32 /*n*/, + u_char */*p*/); + +krb5_error_code +_gsskrb5_encode_om_uint32 ( + OM_uint32 /*n*/, + u_char */*p*/); + +OM_uint32 +_gsskrb5_export_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t exported_name ); + +OM_uint32 +_gsskrb5_export_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + gss_buffer_t interprocess_token ); + +char * +_gsskrb5_get_error_string (void); + +ssize_t +_gsskrb5_get_mech ( + const u_char */*ptr*/, + size_t /*total_len*/, + const u_char **/*mech_ret*/); + +OM_uint32 +_gsskrb5_get_mic ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*message_buffer*/, + gss_buffer_t message_token ); + +struct gssapi_thr_context * +_gsskrb5_get_thread_context (int /*createp*/); + +OM_uint32 +_gsskrb5_get_tkt_flags ( + OM_uint32 */*minor_status*/, + gsskrb5_ctx /*ctx*/, + OM_uint32 */*tkt_flags*/); + +OM_uint32 +_gsskrb5_import_cred ( + OM_uint32 */*minor_status*/, + krb5_ccache /*id*/, + krb5_principal /*keytab_principal*/, + krb5_keytab /*keytab*/, + gss_cred_id_t */*cred*/); + +OM_uint32 +_gsskrb5_import_name ( + OM_uint32 * /*minor_status*/, + const gss_buffer_t /*input_name_buffer*/, + const gss_OID /*input_name_type*/, + gss_name_t * output_name ); + +OM_uint32 +_gsskrb5_import_sec_context ( + OM_uint32 * /*minor_status*/, + const gss_buffer_t /*interprocess_token*/, + gss_ctx_id_t * context_handle ); + +OM_uint32 +_gsskrb5_indicate_mechs ( + OM_uint32 * /*minor_status*/, + gss_OID_set * mech_set ); + +krb5_error_code +_gsskrb5_init (void); + +OM_uint32 +_gsskrb5_init_sec_context ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*initiator_cred_handle*/, + gss_ctx_id_t * /*context_handle*/, + const gss_name_t /*target_name*/, + const gss_OID /*mech_type*/, + OM_uint32 /*req_flags*/, + OM_uint32 /*time_req*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + const gss_buffer_t /*input_token*/, + gss_OID * /*actual_mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * time_rec ); + +OM_uint32 +_gsskrb5_inquire_context ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_name_t * /*src_name*/, + gss_name_t * /*targ_name*/, + OM_uint32 * /*lifetime_rec*/, + gss_OID * /*mech_type*/, + OM_uint32 * /*ctx_flags*/, + int * /*locally_initiated*/, + int * open_context ); + +OM_uint32 +_gsskrb5_inquire_cred ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + gss_name_t * /*output_name*/, + OM_uint32 * /*lifetime*/, + gss_cred_usage_t * /*cred_usage*/, + gss_OID_set * mechanisms ); + +OM_uint32 +_gsskrb5_inquire_cred_by_mech ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + const gss_OID /*mech_type*/, + gss_name_t * /*name*/, + OM_uint32 * /*initiator_lifetime*/, + OM_uint32 * /*acceptor_lifetime*/, + gss_cred_usage_t * cred_usage ); + +OM_uint32 +_gsskrb5_inquire_cred_by_oid ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + const gss_OID /*desired_object*/, + gss_buffer_set_t */*data_set*/); + +OM_uint32 +_gsskrb5_inquire_mechs_for_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_OID_set * mech_types ); + +OM_uint32 +_gsskrb5_inquire_names_for_mech ( + OM_uint32 * /*minor_status*/, + const gss_OID /*mechanism*/, + gss_OID_set * name_types ); + +OM_uint32 +_gsskrb5_inquire_sec_context_by_oid ( + OM_uint32 */*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_OID /*desired_object*/, + gss_buffer_set_t */*data_set*/); + +OM_uint32 +_gsskrb5_krb5_ccache_name ( + OM_uint32 */*minor_status*/, + const char */*name*/, + const char **/*out_name*/); + +OM_uint32 +_gsskrb5_lifetime_left ( + OM_uint32 */*minor_status*/, + OM_uint32 /*lifetime*/, + OM_uint32 */*lifetime_rec*/); + +void * +_gsskrb5_make_header ( + void */*ptr*/, + size_t /*len*/, + const void */*type*/, + const gss_OID /*mech*/); + +OM_uint32 +_gsskrb5_process_context_token ( + OM_uint32 */*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t token_buffer ); + +OM_uint32 +_gsskrb5_register_acceptor_identity (const char */*identity*/); + +OM_uint32 +_gsskrb5_release_buffer ( + OM_uint32 * /*minor_status*/, + gss_buffer_t buffer ); + +OM_uint32 +_gsskrb5_release_cred ( + OM_uint32 * /*minor_status*/, + gss_cred_id_t * cred_handle ); + +OM_uint32 +_gsskrb5_release_name ( + OM_uint32 * /*minor_status*/, + gss_name_t * input_name ); + +OM_uint32 +_gsskrb5_release_oid_set ( + OM_uint32 * /*minor_status*/, + gss_OID_set * set ); + +OM_uint32 +_gsskrb5_seal ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + int /*qop_req*/, + gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t output_message_buffer ); + +OM_uint32 +_gsskrb5_set_cred_option ( + OM_uint32 */*minor_status*/, + gss_cred_id_t */*cred_handle*/, + const gss_OID /*desired_object*/, + const gss_buffer_t /*value*/); + +void +_gsskrb5_set_error_string (void); + +OM_uint32 +_gsskrb5_set_sec_context_option ( + OM_uint32 */*minor_status*/, + gss_ctx_id_t */*context_handle*/, + const gss_OID /*desired_object*/, + const gss_buffer_t /*value*/); + +void +_gsskrb5_set_status ( + const char */*fmt*/, + ...); + +OM_uint32 +_gsskrb5_sign ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*qop_req*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t message_token ); + +OM_uint32 +_gsskrb5_test_oid_set_member ( + OM_uint32 * /*minor_status*/, + const gss_OID /*member*/, + const gss_OID_set /*set*/, + int * present ); + +OM_uint32 +_gsskrb5_unseal ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + int * qop_state ); + +OM_uint32 +_gsskrb5_unwrap ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + gss_qop_t * qop_state ); + +OM_uint32 +_gsskrb5_verify ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t /*token_buffer*/, + int * qop_state ); + +OM_uint32 +_gsskrb5_verify_8003_checksum ( + OM_uint32 */*minor_status*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + const Checksum */*cksum*/, + OM_uint32 */*flags*/, + krb5_data */*fwd_data*/); + +OM_uint32 +_gsskrb5_verify_header ( + u_char **/*str*/, + size_t /*total_len*/, + const void */*type*/, + gss_OID /*oid*/); + +OM_uint32 +_gsskrb5_verify_mic ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t * qop_state ); + +OM_uint32 +_gsskrb5_verify_mic_internal ( + OM_uint32 * /*minor_status*/, + const gsskrb5_ctx /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t * /*qop_state*/, + char * type ); + +OM_uint32 +_gsskrb5_wrap ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t output_message_buffer ); + +OM_uint32 +_gsskrb5_wrap_size_limit ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + OM_uint32 /*req_output_size*/, + OM_uint32 * max_input_size ); + +krb5_error_code +_gsskrb5cfx_max_wrap_length_cfx ( + krb5_crypto /*crypto*/, + int /*conf_req_flag*/, + size_t /*input_length*/, + OM_uint32 */*output_length*/); + +krb5_error_code +_gsskrb5cfx_wrap_length_cfx ( + krb5_crypto /*crypto*/, + int /*conf_req_flag*/, + size_t /*input_length*/, + size_t */*output_length*/, + size_t */*cksumsize*/, + uint16_t */*padlength*/); + +krb5_error_code +_gsskrb5i_address_to_krb5addr ( + OM_uint32 /*gss_addr_type*/, + gss_buffer_desc */*gss_addr*/, + int16_t /*port*/, + krb5_address */*address*/); + +krb5_error_code +_gsskrb5i_get_acceptor_subkey ( + const gsskrb5_ctx /*ctx*/, + krb5_keyblock **/*key*/); + +krb5_error_code +_gsskrb5i_get_initiator_subkey ( + const gsskrb5_ctx /*ctx*/, + krb5_keyblock **/*key*/); + +OM_uint32 +_gsskrb5i_get_token_key ( + const gsskrb5_ctx /*ctx*/, + krb5_keyblock **/*key*/); + +void +_gsskrb5i_is_cfx ( + gsskrb5_ctx /*ctx*/, + int */*is_cfx*/); + +#endif /* __gsskrb5_private_h__ */ diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h new file mode 100644 index 0000000000..4d814032c3 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: gsskrb5_locl.h,v 1.6 2006/10/07 22:14:49 lha Exp $ */ + +#ifndef GSSKRB5_LOCL_H +#define GSSKRB5_LOCL_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <krb5_locl.h> +#include <gssapi.h> +#include <gssapi_mech.h> +#include <assert.h> + +#include "cfx.h" + +/* + * + */ + +struct gss_msg_order; + +typedef struct { + struct krb5_auth_context_data *auth_context; + krb5_principal source, target; + OM_uint32 flags; + enum { LOCAL = 1, OPEN = 2, + COMPAT_OLD_DES3 = 4, + COMPAT_OLD_DES3_SELECTED = 8, + ACCEPTOR_SUBKEY = 16 + } more_flags; + enum gss_ctx_id_t_state { + /* initiator states */ + INITIATOR_START, + INITIATOR_WAIT_FOR_MUTAL, + INITIATOR_READY, + /* acceptor states */ + ACCEPTOR_START, + ACCEPTOR_WAIT_FOR_DCESTYLE, + ACCEPTOR_READY + } state; + struct krb5_ticket *ticket; + OM_uint32 lifetime; + HEIMDAL_MUTEX ctx_id_mutex; + struct gss_msg_order *order; + krb5_keyblock *service_keyblock; + krb5_data fwd_data; +} *gsskrb5_ctx; + +typedef struct { + krb5_principal principal; + int cred_flags; +#define GSS_CF_DESTROY_CRED_ON_RELEASE 1 + struct krb5_keytab_data *keytab; + OM_uint32 lifetime; + gss_cred_usage_t usage; + gss_OID_set mechanisms; + struct krb5_ccache_data *ccache; + HEIMDAL_MUTEX cred_id_mutex; +} *gsskrb5_cred; + +typedef struct Principal *gsskrb5_name; + +/* + * + */ + +extern krb5_context _gsskrb5_context; + +extern krb5_keytab _gsskrb5_keytab; +extern HEIMDAL_MUTEX gssapi_keytab_mutex; + +struct gssapi_thr_context { + HEIMDAL_MUTEX mutex; + char *error_string; +}; + +/* + * Prototypes + */ + +#include <krb5/gsskrb5-private.h> + +#define GSSAPI_KRB5_INIT() do { \ + krb5_error_code kret_gss_init; \ + if((kret_gss_init = _gsskrb5_init ()) != 0) { \ + *minor_status = kret_gss_init; \ + return GSS_S_FAILURE; \ + } \ +} while (0) + +/* sec_context flags */ + +#define SC_LOCAL_ADDRESS 0x01 +#define SC_REMOTE_ADDRESS 0x02 +#define SC_KEYBLOCK 0x04 +#define SC_LOCAL_SUBKEY 0x08 +#define SC_REMOTE_SUBKEY 0x10 + +#endif diff --git a/source4/heimdal/lib/gssapi/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index d393aa1a51..dc24ed5cf2 100644 --- a/source4/heimdal/lib/gssapi/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -31,30 +31,31 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_name.c,v 1.14 2006/02/15 11:59:10 lha Exp $"); +RCSID("$Id: import_name.c,v 1.17 2006/10/07 22:14:51 lha Exp $"); static OM_uint32 parse_krb5_name (OM_uint32 *minor_status, const char *name, gss_name_t *output_name) { + krb5_principal princ; krb5_error_code kerr; - kerr = krb5_parse_name (gssapi_krb5_context, name, output_name); + kerr = krb5_parse_name (_gsskrb5_context, name, &princ); - if (kerr == 0) + if (kerr == 0) { + *output_name = (gss_name_t)princ; return GSS_S_COMPLETE; - else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) { - gssapi_krb5_set_error_string (); - *minor_status = kerr; - return GSS_S_BAD_NAME; - } else { - gssapi_krb5_set_error_string (); - *minor_status = kerr; - return GSS_S_FAILURE; } + _gsskrb5_set_error_string (); + *minor_status = kerr; + + if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) + return GSS_S_BAD_NAME; + + return GSS_S_FAILURE; } static OM_uint32 @@ -91,8 +92,7 @@ import_hostbased_name (OM_uint32 *minor_status, char *p; char *host; char local_hostname[MAXHOSTNAMELEN]; - - *output_name = NULL; + krb5_principal princ = NULL; tmp = malloc (input_name_buffer->length + 1); if (tmp == NULL) { @@ -117,24 +117,24 @@ import_hostbased_name (OM_uint32 *minor_status, host = local_hostname; } - kerr = krb5_sname_to_principal (gssapi_krb5_context, + kerr = krb5_sname_to_principal (_gsskrb5_context, host, tmp, KRB5_NT_SRV_HST, - output_name); + &princ); free (tmp); *minor_status = kerr; - if (kerr == 0) + if (kerr == 0) { + *output_name = (gss_name_t)princ; return GSS_S_COMPLETE; - else if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) { - gssapi_krb5_set_error_string (); + } + _gsskrb5_set_error_string (); *minor_status = kerr; + + if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) return GSS_S_BAD_NAME; - } else { - gssapi_krb5_set_error_string (); - *minor_status = kerr; - return GSS_S_FAILURE; - } + + return GSS_S_FAILURE; } static OM_uint32 @@ -184,18 +184,7 @@ import_export_name (OM_uint32 *minor_status, return ret; } -int -gss_oid_equal(const gss_OID a, const gss_OID b) -{ - if (a == b) - return 1; - else if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length) - return 0; - else - return memcmp(a->elements, b->elements, a->length) == 0; -} - -OM_uint32 gss_import_name +OM_uint32 _gsskrb5_import_name (OM_uint32 * minor_status, const gss_buffer_t input_name_buffer, const gss_OID input_name_type, diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c new file mode 100644 index 0000000000..8131e2621d --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: import_sec_context.c,v 1.17 2006/10/07 22:14:53 lha Exp $"); + +OM_uint32 +_gsskrb5_import_sec_context ( + OM_uint32 * minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t * context_handle + ) +{ + OM_uint32 ret = GSS_S_FAILURE; + krb5_error_code kret; + krb5_storage *sp; + krb5_auth_context ac; + krb5_address local, remote; + krb5_address *localp, *remotep; + krb5_data data; + gss_buffer_desc buffer; + krb5_keyblock keyblock; + int32_t tmp; + int32_t flags; + gsskrb5_ctx ctx; + gss_name_t name; + + GSSAPI_KRB5_INIT (); + + *context_handle = GSS_C_NO_CONTEXT; + + localp = remotep = NULL; + + sp = krb5_storage_from_mem (interprocess_token->value, + interprocess_token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + *minor_status = ENOMEM; + krb5_storage_free (sp); + return GSS_S_FAILURE; + } + HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); + + kret = krb5_auth_con_init (_gsskrb5_context, + &ctx->auth_context); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + /* flags */ + + *minor_status = 0; + + if (krb5_ret_int32 (sp, &flags) != 0) + goto failure; + + /* retrieve the auth context */ + + ac = ctx->auth_context; + if (krb5_ret_uint32 (sp, &ac->flags) != 0) + goto failure; + if (flags & SC_LOCAL_ADDRESS) { + if (krb5_ret_address (sp, localp = &local) != 0) + goto failure; + } + + if (flags & SC_REMOTE_ADDRESS) { + if (krb5_ret_address (sp, remotep = &remote) != 0) + goto failure; + } + + krb5_auth_con_setaddrs (_gsskrb5_context, ac, localp, remotep); + if (localp) + krb5_free_address (_gsskrb5_context, localp); + if (remotep) + krb5_free_address (_gsskrb5_context, remotep); + localp = remotep = NULL; + + if (krb5_ret_int16 (sp, &ac->local_port) != 0) + goto failure; + + if (krb5_ret_int16 (sp, &ac->remote_port) != 0) + goto failure; + if (flags & SC_KEYBLOCK) { + if (krb5_ret_keyblock (sp, &keyblock) != 0) + goto failure; + krb5_auth_con_setkey (_gsskrb5_context, ac, &keyblock); + krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + } + if (flags & SC_LOCAL_SUBKEY) { + if (krb5_ret_keyblock (sp, &keyblock) != 0) + goto failure; + krb5_auth_con_setlocalsubkey (_gsskrb5_context, ac, &keyblock); + krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + } + if (flags & SC_REMOTE_SUBKEY) { + if (krb5_ret_keyblock (sp, &keyblock) != 0) + goto failure; + krb5_auth_con_setremotesubkey (_gsskrb5_context, ac, &keyblock); + krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + } + if (krb5_ret_uint32 (sp, &ac->local_seqnumber)) + goto failure; + if (krb5_ret_uint32 (sp, &ac->remote_seqnumber)) + goto failure; + + if (krb5_ret_int32 (sp, &tmp) != 0) + goto failure; + ac->keytype = tmp; + if (krb5_ret_int32 (sp, &tmp) != 0) + goto failure; + ac->cksumtype = tmp; + + /* names */ + + if (krb5_ret_data (sp, &data)) + goto failure; + buffer.value = data.data; + buffer.length = data.length; + + ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, + &name); + if (ret) { + ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, + &name); + if (ret) { + krb5_data_free (&data); + goto failure; + } + } + ctx->source = (krb5_principal)name; + krb5_data_free (&data); + + if (krb5_ret_data (sp, &data) != 0) + goto failure; + buffer.value = data.data; + buffer.length = data.length; + + ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, + &name); + if (ret) { + ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, + &name); + if (ret) { + krb5_data_free (&data); + goto failure; + } + } + ctx->target = (krb5_principal)name; + krb5_data_free (&data); + + if (krb5_ret_int32 (sp, &tmp)) + goto failure; + ctx->flags = tmp; + if (krb5_ret_int32 (sp, &tmp)) + goto failure; + ctx->more_flags = tmp; + if (krb5_ret_int32 (sp, &tmp)) + goto failure; + ctx->lifetime = tmp; + + ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order); + if (ret) + goto failure; + + krb5_storage_free (sp); + + *context_handle = (gss_ctx_id_t)ctx; + + return GSS_S_COMPLETE; + +failure: + krb5_auth_con_free (_gsskrb5_context, + ctx->auth_context); + if (ctx->source != NULL) + krb5_free_principal(_gsskrb5_context, ctx->source); + if (ctx->target != NULL) + krb5_free_principal(_gsskrb5_context, ctx->target); + if (localp) + krb5_free_address (_gsskrb5_context, localp); + if (remotep) + krb5_free_address (_gsskrb5_context, remotep); + if(ctx->order) + _gssapi_msg_order_destroy(&ctx->order); + HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); + krb5_storage_free (sp); + free (ctx); + *context_handle = GSS_C_NO_CONTEXT; + return ret; +} diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c new file mode 100644 index 0000000000..3827533219 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: indicate_mechs.c,v 1.9 2006/10/07 22:14:56 lha Exp $"); + +OM_uint32 _gsskrb5_indicate_mechs + (OM_uint32 * minor_status, + gss_OID_set * mech_set + ) +{ + OM_uint32 ret, junk; + + ret = _gsskrb5_create_empty_oid_set(minor_status, mech_set); + if (ret) + return ret; + + ret = _gsskrb5_add_oid_set_member(minor_status, + GSS_KRB5_MECHANISM, mech_set); + if (ret) { + _gsskrb5_release_oid_set(&junk, mech_set); + return ret; + } + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/init.c b/source4/heimdal/lib/gssapi/krb5/init.c index 11d7c9bb9f..cbef8740b7 100644 --- a/source4/heimdal/lib/gssapi/init.c +++ b/source4/heimdal/lib/gssapi/krb5/init.c @@ -31,15 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: init.c,v 1.7 2003/07/22 19:50:11 lha Exp $"); +RCSID("$Id: init.c,v 1.9 2006/10/07 22:14:58 lha Exp $"); -#ifdef _SAMBA_BUILD_ -#include "auth/kerberos/krb5_init_context.h" -#endif - -static HEIMDAL_MUTEX gssapi_krb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static HEIMDAL_MUTEX _gsskrb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER; static int created_key; static HEIMDAL_thread_key gssapi_context_key; @@ -58,12 +54,12 @@ gssapi_destroy_thread_context(void *ptr) struct gssapi_thr_context * -gssapi_get_thread_context(int createp) +_gsskrb5_get_thread_context(int createp) { struct gssapi_thr_context *ctx; int ret; - HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex); if (!created_key) abort(); @@ -80,72 +76,36 @@ gssapi_get_thread_context(int createp) if (ret) goto fail; } - HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); return ctx; fail: - HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); if (ctx) free(ctx); return NULL; } -#ifdef _SAMBA_BUILD_ -/* Init krb5 with an event context. Disgusting Samba-specific hack */ - -krb5_error_code -gssapi_krb5_init_ev (void *event_context) +krb5_error_code +_gsskrb5_init (void) { - static struct smb_krb5_context *smb_krb5_context; krb5_error_code ret = 0; - HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex); - if(smb_krb5_context == NULL) { - ret = smb_krb5_init_context(event_context, &smb_krb5_context); - } + if(_gsskrb5_context == NULL) + ret = krb5_init_context (&_gsskrb5_context); if (ret == 0 && !created_key) { HEIMDAL_key_create(&gssapi_context_key, gssapi_destroy_thread_context, ret); if (ret) { - smb_krb5_free_context(smb_krb5_context); - smb_krb5_context = NULL; + krb5_free_context(_gsskrb5_context); + _gsskrb5_context = NULL; } else created_key = 1; } - if (ret == 0) { - gssapi_krb5_context = smb_krb5_context->krb5_context; - } - HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); - return ret; -} -#endif - -krb5_error_code -gssapi_krb5_init (void) -{ - krb5_error_code ret = 0; -#ifdef _SAMBA_BUILD_ - ret = gssapi_krb5_init_ev(NULL); -#else - HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); - - if(gssapi_krb5_context == NULL) { - ret = krb5_init_context (&gssapi_krb5_context); - } - if (ret == 0 && !created_key) { - HEIMDAL_key_create(&gssapi_context_key, - gssapi_destroy_thread_context, - ret); - if (ret) { - krb5_free_context(gssapi_krb5_context); - gssapi_krb5_context = NULL; - } else - created_key = 1; - } + HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); - HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); -#endif return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c new file mode 100644 index 0000000000..00f2543833 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -0,0 +1,789 @@ +/* + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: init_sec_context.c,v 1.72 2006/10/24 23:03:19 lha Exp $"); + +/* + * copy the addresses from `input_chan_bindings' (if any) to + * the auth context `ac' + */ + +static OM_uint32 +set_addresses (krb5_auth_context ac, + const gss_channel_bindings_t input_chan_bindings) +{ + /* Port numbers are expected to be in application_data.value, + * initator's port first */ + + krb5_address initiator_addr, acceptor_addr; + krb5_error_code kret; + + if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS + || input_chan_bindings->application_data.length != + 2 * sizeof(ac->local_port)) + return 0; + + memset(&initiator_addr, 0, sizeof(initiator_addr)); + memset(&acceptor_addr, 0, sizeof(acceptor_addr)); + + ac->local_port = + *(int16_t *) input_chan_bindings->application_data.value; + + ac->remote_port = + *((int16_t *) input_chan_bindings->application_data.value + 1); + + kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->acceptor_addrtype, + &input_chan_bindings->acceptor_address, + ac->remote_port, + &acceptor_addr); + if (kret) + return kret; + + kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->initiator_addrtype, + &input_chan_bindings->initiator_address, + ac->local_port, + &initiator_addr); + if (kret) { + krb5_free_address (_gsskrb5_context, &acceptor_addr); + return kret; + } + + kret = krb5_auth_con_setaddrs(_gsskrb5_context, + ac, + &initiator_addr, /* local address */ + &acceptor_addr); /* remote address */ + + krb5_free_address (_gsskrb5_context, &initiator_addr); + krb5_free_address (_gsskrb5_context, &acceptor_addr); + +#if 0 + free(input_chan_bindings->application_data.value); + input_chan_bindings->application_data.value = NULL; + input_chan_bindings->application_data.length = 0; +#endif + + return kret; +} + +OM_uint32 +_gsskrb5_create_ctx( + OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_channel_bindings_t input_chan_bindings, + enum gss_ctx_id_t_state state) +{ + krb5_error_code kret; + gsskrb5_ctx ctx; + + *context_handle = NULL; + + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + ctx->auth_context = NULL; + ctx->source = NULL; + ctx->target = NULL; + ctx->state = state; + ctx->flags = 0; + ctx->more_flags = 0; + ctx->service_keyblock = NULL; + ctx->ticket = NULL; + krb5_data_zero(&ctx->fwd_data); + ctx->lifetime = GSS_C_INDEFINITE; + ctx->order = NULL; + HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); + + kret = krb5_auth_con_init (_gsskrb5_context, &ctx->auth_context); + if (kret) { + *minor_status = kret; + _gsskrb5_set_error_string (); + + HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); + + return GSS_S_FAILURE; + } + + kret = set_addresses(ctx->auth_context, input_chan_bindings); + if (kret) { + *minor_status = kret; + + HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); + + krb5_auth_con_free(_gsskrb5_context, ctx->auth_context); + + return GSS_S_BAD_BINDINGS; + } + + /* + * We need a sequence number + */ + + krb5_auth_con_addflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_SEQUENCE | + KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED, + NULL); + + *context_handle = (gss_ctx_id_t)ctx; + + return GSS_S_COMPLETE; +} + + +static OM_uint32 +gsskrb5_get_creds( + OM_uint32 * minor_status, + krb5_ccache ccache, + gsskrb5_ctx ctx, + krb5_const_principal target_name, + OM_uint32 time_req, + OM_uint32 * time_rec, + krb5_creds ** cred) +{ + OM_uint32 ret; + krb5_error_code kret; + krb5_creds this_cred; + OM_uint32 lifetime_rec; + + *cred = NULL; + + memset(&this_cred, 0, sizeof(this_cred)); + this_cred.client = ctx->source; + this_cred.server = ctx->target; + + if (time_req && time_req != GSS_C_INDEFINITE) { + krb5_timestamp ts; + + krb5_timeofday (_gsskrb5_context, &ts); + this_cred.times.endtime = ts + time_req; + } else { + this_cred.times.endtime = 0; + } + + this_cred.session.keytype = KEYTYPE_NULL; + + kret = krb5_get_credentials(_gsskrb5_context, + 0, + ccache, + &this_cred, + cred); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + ctx->lifetime = (*cred)->times.endtime; + + ret = _gsskrb5_lifetime_left(minor_status, ctx->lifetime, &lifetime_rec); + if (ret) return ret; + + if (lifetime_rec == 0) { + *minor_status = 0; + return GSS_S_CONTEXT_EXPIRED; + } + + if (time_rec) *time_rec = lifetime_rec; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +gsskrb5_initiator_ready( + OM_uint32 * minor_status, + gsskrb5_ctx ctx) +{ + OM_uint32 ret; + int32_t seq_number; + int is_cfx = 0; + OM_uint32 flags = ctx->flags; + + krb5_auth_getremoteseqnumber (_gsskrb5_context, + ctx->auth_context, + &seq_number); + + _gsskrb5i_is_cfx(ctx, &is_cfx); + + ret = _gssapi_msg_order_create(minor_status, + &ctx->order, + _gssapi_msg_order_f(flags), + seq_number, 0, is_cfx); + if (ret) return ret; + + ctx->state = INITIATOR_READY; + ctx->more_flags |= OPEN; + + return GSS_S_COMPLETE; +} + +/* + * handle delegated creds in init-sec-context + */ + +static void +do_delegation (krb5_auth_context ac, + krb5_ccache ccache, + krb5_creds *cred, + krb5_const_principal name, + krb5_data *fwd_data, + uint32_t *flags) +{ + krb5_creds creds; + KDCOptions fwd_flags; + krb5_error_code kret; + + memset (&creds, 0, sizeof(creds)); + krb5_data_zero (fwd_data); + + kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &creds.client); + if (kret) + goto out; + + kret = krb5_build_principal(_gsskrb5_context, + &creds.server, + strlen(creds.client->realm), + creds.client->realm, + KRB5_TGS_NAME, + creds.client->realm, + NULL); + if (kret) + goto out; + + creds.times.endtime = 0; + + memset(&fwd_flags, 0, sizeof(fwd_flags)); + fwd_flags.forwarded = 1; + fwd_flags.forwardable = 1; + + if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/ + name->name.name_string.len < 2) + goto out; + + kret = krb5_get_forwarded_creds(_gsskrb5_context, + ac, + ccache, + KDCOptions2int(fwd_flags), + name->name.name_string.val[1], + &creds, + fwd_data); + + out: + if (kret) + *flags &= ~GSS_C_DELEG_FLAG; + else + *flags |= GSS_C_DELEG_FLAG; + + if (creds.client) + krb5_free_principal(_gsskrb5_context, creds.client); + if (creds.server) + krb5_free_principal(_gsskrb5_context, creds.server); +} + +/* + * first stage of init-sec-context + */ + +static OM_uint32 +init_auth +(OM_uint32 * minor_status, + gsskrb5_cred initiator_cred_handle, + gsskrb5_ctx ctx, + krb5_const_principal name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + OM_uint32 ret = GSS_S_FAILURE; + krb5_error_code kret; + krb5_flags ap_options; + krb5_creds *cred = NULL; + krb5_data outbuf; + krb5_ccache ccache = NULL; + uint32_t flags; + krb5_data authenticator; + Checksum cksum; + krb5_enctype enctype; + krb5_data fwd_data; + OM_uint32 lifetime_rec; + + krb5_data_zero(&outbuf); + krb5_data_zero(&fwd_data); + + *minor_status = 0; + + if (actual_mech_type) + *actual_mech_type = GSS_KRB5_MECHANISM; + + if (initiator_cred_handle == NULL) { + kret = krb5_cc_default (_gsskrb5_context, &ccache); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + } else + ccache = initiator_cred_handle->ccache; + + kret = krb5_cc_get_principal (_gsskrb5_context, ccache, &ctx->source); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + kret = krb5_copy_principal (_gsskrb5_context, name, &ctx->target); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + ret = _gss_DES3_get_mic_compat(minor_status, ctx); + if (ret) + goto failure; + + + ret = gsskrb5_get_creds(minor_status, + ccache, + ctx, + ctx->target, + time_req, + time_rec, + &cred); + if (ret) + goto failure; + + ctx->lifetime = cred->times.endtime; + + ret = _gsskrb5_lifetime_left(minor_status, + ctx->lifetime, + &lifetime_rec); + if (ret) { + goto failure; + } + + if (lifetime_rec == 0) { + *minor_status = 0; + ret = GSS_S_CONTEXT_EXPIRED; + goto failure; + } + + krb5_auth_con_setkey(_gsskrb5_context, + ctx->auth_context, + &cred->session); + + kret = krb5_auth_con_generatelocalsubkey(_gsskrb5_context, + ctx->auth_context, + &cred->session); + if(kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + /* + * If the credential doesn't have ok-as-delegate, check what local + * policy say about ok-as-delegate, default is FALSE that makes + * code ignore the KDC setting and follow what the application + * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the + * KDC doesn't set ok-as-delegate. + */ + if (!cred->flags.b.ok_as_delegate) { + krb5_boolean delegate; + + krb5_appdefault_boolean(_gsskrb5_context, + "gssapi", name->realm, + "ok-as-delegate", FALSE, &delegate); + if (delegate) + req_flags &= ~GSS_C_DELEG_FLAG; + } + + flags = 0; + ap_options = 0; + if (req_flags & GSS_C_DELEG_FLAG) + do_delegation (ctx->auth_context, + ccache, cred, name, &fwd_data, &flags); + + if (req_flags & GSS_C_MUTUAL_FLAG) { + flags |= GSS_C_MUTUAL_FLAG; + ap_options |= AP_OPTS_MUTUAL_REQUIRED; + } + + if (req_flags & GSS_C_REPLAY_FLAG) + flags |= GSS_C_REPLAY_FLAG; + if (req_flags & GSS_C_SEQUENCE_FLAG) + flags |= GSS_C_SEQUENCE_FLAG; + if (req_flags & GSS_C_ANON_FLAG) + ; /* XXX */ + if (req_flags & GSS_C_DCE_STYLE) { + /* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */ + flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG; + ap_options |= AP_OPTS_MUTUAL_REQUIRED; + } + if (req_flags & GSS_C_IDENTIFY_FLAG) + flags |= GSS_C_IDENTIFY_FLAG; + if (req_flags & GSS_C_EXTENDED_ERROR_FLAG) + flags |= GSS_C_EXTENDED_ERROR_FLAG; + + flags |= GSS_C_CONF_FLAG; + flags |= GSS_C_INTEG_FLAG; + flags |= GSS_C_TRANS_FLAG; + + if (ret_flags) + *ret_flags = flags; + ctx->flags = flags; + ctx->more_flags |= LOCAL; + + ret = _gsskrb5_create_8003_checksum (minor_status, + input_chan_bindings, + flags, + &fwd_data, + &cksum); + krb5_data_free (&fwd_data); + if (ret) + goto failure; + + enctype = ctx->auth_context->keyblock->keytype; + + kret = krb5_build_authenticator (_gsskrb5_context, + ctx->auth_context, + enctype, + cred, + &cksum, + NULL, + &authenticator, + KRB5_KU_AP_REQ_AUTH); + + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + kret = krb5_build_ap_req (_gsskrb5_context, + enctype, + cred, + ap_options, + authenticator, + &outbuf); + + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + ret = GSS_S_FAILURE; + goto failure; + } + + ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token, + (u_char *)"\x01\x00", GSS_KRB5_MECHANISM); + if (ret) + goto failure; + + krb5_data_free (&outbuf); + krb5_free_creds(_gsskrb5_context, cred); + free_Checksum(&cksum); + if (initiator_cred_handle == NULL) + krb5_cc_close(_gsskrb5_context, ccache); + + if (flags & GSS_C_MUTUAL_FLAG) { + ctx->state = INITIATOR_WAIT_FOR_MUTAL; + return GSS_S_CONTINUE_NEEDED; + } + + return gsskrb5_initiator_ready(minor_status, ctx); +failure: + if(cred) + krb5_free_creds(_gsskrb5_context, cred); + if (ccache && initiator_cred_handle == NULL) + krb5_cc_close(_gsskrb5_context, ccache); + + return ret; + +} + +static OM_uint32 +repl_mutual + (OM_uint32 * minor_status, + gsskrb5_ctx ctx, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + OM_uint32 ret; + krb5_error_code kret; + krb5_data indata; + krb5_ap_rep_enc_part *repl; + int is_cfx = 0; + + output_token->length = 0; + output_token->value = NULL; + + if (actual_mech_type) + *actual_mech_type = GSS_KRB5_MECHANISM; + + if (req_flags & GSS_C_DCE_STYLE) { + /* There is no OID wrapping. */ + indata.length = input_token->length; + indata.data = input_token->value; + } else { + ret = _gsskrb5_decapsulate (minor_status, + input_token, + &indata, + "\x02\x00", + GSS_KRB5_MECHANISM); + if (ret) { + /* XXX - Handle AP_ERROR */ + return ret; + } + } + + kret = krb5_rd_rep (_gsskrb5_context, + ctx->auth_context, + &indata, + &repl); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + krb5_free_ap_rep_enc_part (_gsskrb5_context, + repl); + + _gsskrb5i_is_cfx(ctx, &is_cfx); + if (is_cfx) { + krb5_keyblock *key = NULL; + + kret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + ctx->auth_context, + &key); + if (kret == 0 && key != NULL) { + ctx->more_flags |= ACCEPTOR_SUBKEY; + krb5_free_keyblock (_gsskrb5_context, key); + } + } + + + *minor_status = 0; + if (time_rec) { + ret = _gsskrb5_lifetime_left(minor_status, + ctx->lifetime, + time_rec); + } else { + ret = GSS_S_COMPLETE; + } + if (ret_flags) + *ret_flags = ctx->flags; + + if (req_flags & GSS_C_DCE_STYLE) { + int32_t con_flags; + krb5_data outbuf; + + /* Do don't do sequence number for the mk-rep */ + krb5_auth_con_removeflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_SEQUENCE, + &con_flags); + + kret = krb5_mk_rep(_gsskrb5_context, + ctx->auth_context, + &outbuf); + if (kret) { + _gsskrb5_set_error_string (); + *minor_status = kret; + return GSS_S_FAILURE; + } + + output_token->length = outbuf.length; + output_token->value = outbuf.data; + + krb5_auth_con_removeflags(_gsskrb5_context, + ctx->auth_context, + KRB5_AUTH_CONTEXT_DO_SEQUENCE, + NULL); + } + + return gsskrb5_initiator_ready(minor_status, ctx); +} + +/* + * gss_init_sec_context + */ + +OM_uint32 _gsskrb5_init_sec_context +(OM_uint32 * minor_status, + const gss_cred_id_t initiator_cred_handle, + gss_ctx_id_t * context_handle, + const gss_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle; + krb5_const_principal name = (krb5_const_principal)target_name; + gsskrb5_ctx ctx; + OM_uint32 ret; + + GSSAPI_KRB5_INIT (); + + output_token->length = 0; + output_token->value = NULL; + + if (context_handle == NULL) { + *minor_status = 0; + return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE; + } + + if (ret_flags) + *ret_flags = 0; + if (time_rec) + *time_rec = 0; + + if (target_name == GSS_C_NO_NAME) { + if (actual_mech_type) + *actual_mech_type = GSS_C_NO_OID; + *minor_status = 0; + return GSS_S_BAD_NAME; + } + + if (mech_type != GSS_C_NO_OID && + !gss_oid_equal(mech_type, GSS_KRB5_MECHANISM)) + return GSS_S_BAD_MECH; + + if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) { + OM_uint32 ret; + + if (*context_handle != GSS_C_NO_CONTEXT) { + *minor_status = 0; + return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE; + } + + ret = _gsskrb5_create_ctx(minor_status, + context_handle, + input_chan_bindings, + INITIATOR_START); + if (ret) + return ret; + } + + if (*context_handle == GSS_C_NO_CONTEXT) { + *minor_status = 0; + return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE; + } + + ctx = (gsskrb5_ctx) *context_handle; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + switch (ctx->state) { + case INITIATOR_START: + ret = init_auth(minor_status, + cred, + ctx, + name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + break; + case INITIATOR_WAIT_FOR_MUTAL: + ret = repl_mutual(minor_status, + ctx, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + break; + case INITIATOR_READY: + /* + * If we get there, the caller have called + * gss_init_sec_context() one time too many. + */ + *minor_status = 0; + ret = GSS_S_BAD_STATUS; + break; + default: + *minor_status = 0; + ret = GSS_S_BAD_STATUS; + break; + } + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + /* destroy context in case of error */ + if (GSS_ERROR(ret)) { + OM_uint32 min2; + _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER); + } + + return ret; + +} diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c new file mode 100644 index 0000000000..ef43e6852c --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_context.c,v 1.10 2006/10/07 22:15:03 lha Exp $"); + +OM_uint32 _gsskrb5_inquire_context ( + OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + gss_name_t * src_name, + gss_name_t * targ_name, + OM_uint32 * lifetime_rec, + gss_OID * mech_type, + OM_uint32 * ctx_flags, + int * locally_initiated, + int * open_context + ) +{ + OM_uint32 ret; + gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle; + gss_name_t name; + + if (src_name) + *src_name = GSS_C_NO_NAME; + if (targ_name) + *targ_name = GSS_C_NO_NAME; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (src_name) { + name = (gss_name_t)ctx->source; + ret = _gsskrb5_duplicate_name (minor_status, name, src_name); + if (ret) + goto failed; + } + + if (targ_name) { + name = (gss_name_t)ctx->target; + ret = _gsskrb5_duplicate_name (minor_status, name, targ_name); + if (ret) + goto failed; + } + + if (lifetime_rec) { + ret = _gsskrb5_lifetime_left(minor_status, + ctx->lifetime, + lifetime_rec); + if (ret) + goto failed; + } + + if (mech_type) + *mech_type = GSS_KRB5_MECHANISM; + + if (ctx_flags) + *ctx_flags = ctx->flags; + + if (locally_initiated) + *locally_initiated = ctx->more_flags & LOCAL; + + if (open_context) + *open_context = ctx->more_flags & OPEN; + + *minor_status = 0; + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_COMPLETE; + +failed: + if (src_name) + _gsskrb5_release_name(NULL, src_name); + if (targ_name) + _gsskrb5_release_name(NULL, targ_name); + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; +} diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c new file mode 100644 index 0000000000..0593729365 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_cred.c,v 1.12 2006/10/07 22:15:06 lha Exp $"); + +OM_uint32 _gsskrb5_inquire_cred +(OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + gss_name_t * output_name, + OM_uint32 * lifetime, + gss_cred_usage_t * cred_usage, + gss_OID_set * mechanisms + ) +{ + gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL; + gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL; + gsskrb5_cred acred = NULL, icred = NULL; + OM_uint32 ret; + + *minor_status = 0; + + if (output_name) + *output_name = NULL; + if (mechanisms) + *mechanisms = GSS_C_NO_OID_SET; + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + ret = _gsskrb5_acquire_cred(minor_status, + GSS_C_NO_NAME, + GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, + GSS_C_ACCEPT, + &aqcred_accept, + NULL, + NULL); + if (ret == GSS_S_COMPLETE) + acred = (gsskrb5_cred)aqcred_accept; + + ret = _gsskrb5_acquire_cred(minor_status, + GSS_C_NO_NAME, + GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, + GSS_C_INITIATE, + &aqcred_init, + NULL, + NULL); + if (ret == GSS_S_COMPLETE) + acred = (gsskrb5_cred)aqcred_init; + + if (icred == NULL && acred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + } else + acred = (gsskrb5_cred)cred_handle; + + if (acred) + HEIMDAL_MUTEX_lock(&acred->cred_id_mutex); + if (icred) + HEIMDAL_MUTEX_lock(&icred->cred_id_mutex); + + if (output_name != NULL) { + if (icred && icred->principal != NULL) { + gss_name_t name; + + if (acred) + name = (gss_name_t)acred->principal; + else + name = (gss_name_t)icred->principal; + + ret = _gsskrb5_duplicate_name(minor_status, name, output_name); + if (ret) + goto out; + } else if (acred && acred->usage == GSS_C_ACCEPT) { + krb5_principal princ; + *minor_status = krb5_sname_to_principal(_gsskrb5_context, NULL, + NULL, KRB5_NT_SRV_HST, + &princ); + if (*minor_status) { + ret = GSS_S_FAILURE; + goto out; + } + *output_name = (gss_name_t)princ; + } else { + krb5_principal princ; + *minor_status = krb5_get_default_principal(_gsskrb5_context, + &princ); + if (*minor_status) { + ret = GSS_S_FAILURE; + goto out; + } + *output_name = (gss_name_t)princ; + } + } + if (lifetime != NULL) { + OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE; + + if (acred) alife = acred->lifetime; + if (icred) ilife = icred->lifetime; + + ret = _gsskrb5_lifetime_left(minor_status, + min(alife,ilife), + lifetime); + if (ret) + goto out; + } + if (cred_usage != NULL) { + if (acred && icred) + *cred_usage = GSS_C_BOTH; + else if (acred) + *cred_usage = GSS_C_ACCEPT; + else if (icred) + *cred_usage = GSS_C_INITIATE; + else + abort(); + } + + if (mechanisms != NULL) { + ret = _gsskrb5_create_empty_oid_set(minor_status, mechanisms); + if (ret) + goto out; + if (acred) + ret = _gsskrb5_add_oid_set_member(minor_status, + &acred->mechanisms->elements[0], + mechanisms); + if (ret == GSS_S_COMPLETE && icred) + ret = _gsskrb5_add_oid_set_member(minor_status, + &icred->mechanisms->elements[0], + mechanisms); + if (ret) + goto out; + } + ret = GSS_S_COMPLETE; +out: + if (acred) + HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex); + if (icred) + HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex); + + if (aqcred_init != GSS_C_NO_CREDENTIAL) + ret = _gsskrb5_release_cred(minor_status, &aqcred_init); + if (aqcred_accept != GSS_C_NO_CREDENTIAL) + ret = _gsskrb5_release_cred(minor_status, &aqcred_accept); + + return ret; +} diff --git a/source4/heimdal/lib/gssapi/arcfour.h b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c index 0406b64b09..954a5e3119 100644 --- a/source4/heimdal/lib/gssapi/arcfour.h +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c @@ -31,53 +31,53 @@ * SUCH DAMAGE. */ -/* $Id: arcfour.h,v 1.5 2004/03/07 22:30:57 lha Exp $ */ +#include "krb5/gsskrb5_locl.h" -#ifndef GSSAPI_ARCFOUR_H_ -#define GSSAPI_ARCFOUR_H_ 1 +RCSID("$Id: inquire_cred_by_mech.c,v 1.4 2006/10/07 22:15:08 lha Exp $"); -#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32 -#define GSS_ARCFOUR_WRAP_TOKEN_OFFSET 13 +OM_uint32 _gsskrb5_inquire_cred_by_mech ( + OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + const gss_OID mech_type, + gss_name_t * name, + OM_uint32 * initiator_lifetime, + OM_uint32 * acceptor_lifetime, + gss_cred_usage_t * cred_usage + ) +{ + OM_uint32 ret; + OM_uint32 lifetime; -OM_uint32 _gssapi_wrap_arcfour(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - const gss_buffer_t input_message_buffer, - int *conf_state, - gss_buffer_t output_message_buffer, - krb5_keyblock *key); + if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 && + gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) { + *minor_status = EINVAL; + return GSS_S_BAD_MECH; + } -OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - const gss_buffer_t input_message_buffer, - gss_buffer_t output_message_buffer, - int *conf_state, - gss_qop_t *qop_state, - krb5_keyblock *key); + ret = _gsskrb5_inquire_cred (minor_status, + cred_handle, + name, + &lifetime, + cred_usage, + NULL); + + if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) { + gsskrb5_cred cred = (gsskrb5_cred)cred_handle; + gss_cred_usage_t usage; -OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - gss_qop_t qop_req, - const gss_buffer_t message_buffer, - gss_buffer_t message_token, - krb5_keyblock *key); + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + usage = cred->usage; + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); -OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - const gss_buffer_t message_buffer, - const gss_buffer_t token_buffer, - gss_qop_t *qop_state, - krb5_keyblock *key, - char *type); -OM_uint32 -_gssapi_wrap_size_arcfour(OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_input_size, - OM_uint32 * output_size, - OM_uint32 * padlen, - krb5_keyblock *key); + if (initiator_lifetime) { + if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) + *initiator_lifetime = lifetime; + } + if (acceptor_lifetime) { + if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH) + *acceptor_lifetime = lifetime; + } + } -#endif /* GSSAPI_ARCFOUR_H_ */ + return ret; +} diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c new file mode 100644 index 0000000000..26927c740c --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_cred_by_oid.c,v 1.4 2006/10/07 22:15:10 lha Exp $"); + +OM_uint32 _gsskrb5_inquire_cred_by_oid + (OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + gsskrb5_cred cred = (gsskrb5_cred)cred_handle; + krb5_error_code ret; + gss_buffer_desc buffer; + char *str; + + if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + + if (cred->ccache == NULL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = krb5_cc_get_full_name(_gsskrb5_context, cred->ccache, &str); + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + if (ret) { + *minor_status = ret; + _gsskrb5_set_error_string (); + return GSS_S_FAILURE; + } + + buffer.value = str; + buffer.length = strlen(str); + + ret = gss_add_buffer_set_member(minor_status, &buffer, data_set); + if (ret != GSS_S_COMPLETE) + _gsskrb5_clear_status (); + + free(str); + + *minor_status = 0; + return GSS_S_COMPLETE; +} + diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c new file mode 100644 index 0000000000..5c1f082f45 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_mechs_for_name.c,v 1.3 2006/10/07 22:15:13 lha Exp $"); + +OM_uint32 _gsskrb5_inquire_mechs_for_name ( + OM_uint32 * minor_status, + const gss_name_t input_name, + gss_OID_set * mech_types + ) +{ + OM_uint32 ret; + + ret = _gsskrb5_create_empty_oid_set(minor_status, mech_types); + if (ret) + return ret; + + ret = _gsskrb5_add_oid_set_member(minor_status, + GSS_KRB5_MECHANISM, + mech_types); + if (ret) + _gsskrb5_release_oid_set(NULL, mech_types); + + return ret; +} diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c new file mode 100644 index 0000000000..5d8aefab1c --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_names_for_mech.c,v 1.3 2006/10/07 22:15:15 lha Exp $"); + + +static gss_OID *name_list[] = { + &GSS_C_NT_HOSTBASED_SERVICE, + &GSS_C_NT_USER_NAME, + &GSS_KRB5_NT_PRINCIPAL_NAME, + &GSS_C_NT_EXPORT_NAME, + NULL +}; + +OM_uint32 _gsskrb5_inquire_names_for_mech ( + OM_uint32 * minor_status, + const gss_OID mechanism, + gss_OID_set * name_types + ) +{ + OM_uint32 ret; + int i; + + *minor_status = 0; + + if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 && + gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) { + *name_types = GSS_C_NO_OID_SET; + return GSS_S_BAD_MECH; + } + + ret = _gsskrb5_create_empty_oid_set(minor_status, name_types); + if (ret != GSS_S_COMPLETE) + return ret; + + for (i = 0; name_list[i] != NULL; i++) { + ret = _gsskrb5_add_oid_set_member(minor_status, + *(name_list[i]), + name_types); + if (ret != GSS_S_COMPLETE) + break; + } + + if (ret != GSS_S_COMPLETE) + _gsskrb5_release_oid_set(NULL, name_types); + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c new file mode 100644 index 0000000000..0b46cc5495 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: inquire_sec_context_by_oid.c,v 1.8 2006/10/24 15:55:28 lha Exp $"); + +static int +oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) +{ + int ret; + heim_oid oid; + heim_oid prefix; + + *suffix = 0; + + ret = der_get_oid(oid_enc->elements, oid_enc->length, + &oid, NULL); + if (ret) { + return 0; + } + + ret = der_get_oid(prefix_enc->elements, prefix_enc->length, + &prefix, NULL); + if (ret) { + der_free_oid(&oid); + return 0; + } + + ret = 0; + + if (oid.length - 1 == prefix.length) { + *suffix = oid.components[oid.length - 1]; + oid.length--; + ret = (der_heim_oid_cmp(&oid, &prefix) == 0); + oid.length++; + } + + der_free_oid(&oid); + der_free_oid(&prefix); + + return ret; +} + +static OM_uint32 inquire_sec_context_tkt_flags + (OM_uint32 *minor_status, + const gsskrb5_ctx context_handle, + gss_buffer_set_t *data_set) +{ + OM_uint32 tkt_flags; + unsigned char buf[4]; + gss_buffer_desc value; + + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + + if (context_handle->ticket == NULL) { + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + _gsskrb5_set_status("No ticket from which to obtain flags"); + *minor_status = EINVAL; + return GSS_S_BAD_MECH; + } + + tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + + _gsskrb5_encode_om_uint32(tkt_flags, buf); + value.length = sizeof(buf); + value.value = buf; + + return gss_add_buffer_set_member(minor_status, + &value, + data_set); +} + +enum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY }; + +static OM_uint32 inquire_sec_context_get_subkey + (OM_uint32 *minor_status, + const gsskrb5_ctx context_handle, + enum keytype keytype, + gss_buffer_set_t *data_set) +{ + krb5_keyblock *key = NULL; + krb5_storage *sp = NULL; + krb5_data data; + OM_uint32 maj_stat = GSS_S_COMPLETE; + krb5_error_code ret; + + krb5_data_zero(&data); + + sp = krb5_storage_emem(); + if (sp == NULL) { + _gsskrb5_clear_status(); + ret = ENOMEM; + goto out; + } + + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + switch(keytype) { + case ACCEPTOR_KEY: + ret = _gsskrb5i_get_acceptor_subkey(context_handle, &key); + if (ret) + _gsskrb5_set_error_string (); + break; + case INITIATOR_KEY: + ret = _gsskrb5i_get_initiator_subkey(context_handle, &key); + if (ret) + _gsskrb5_set_error_string (); + break; + case TOKEN_KEY: + ret = _gsskrb5i_get_token_key(context_handle, &key); + if (ret) + _gsskrb5_set_error_string (); + break; + default: + _gsskrb5_set_status("%d is not a valid subkey type", keytype); + ret = EINVAL; + break; + } + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + if (ret) + goto out; + + ret = krb5_store_keyblock(sp, *key); + krb5_free_keyblock (_gsskrb5_context, key); + if (ret) { + _gsskrb5_set_error_string (); + goto out; + } + + ret = krb5_storage_to_data(sp, &data); + if (ret) { + _gsskrb5_set_error_string (); + goto out; + } + + { + gss_buffer_desc value; + + value.length = data.length; + value.value = data.data; + + maj_stat = gss_add_buffer_set_member(minor_status, + &value, + data_set); + } + +out: + krb5_data_free(&data); + if (sp) + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + maj_stat = GSS_S_FAILURE; + } + return maj_stat; +} + +static OM_uint32 inquire_sec_context_authz_data + (OM_uint32 *minor_status, + const gsskrb5_ctx context_handle, + unsigned ad_type, + gss_buffer_set_t *data_set) +{ + krb5_data data; + gss_buffer_desc ad_data; + OM_uint32 ret; + + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + if (context_handle->ticket == NULL) { + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + *minor_status = EINVAL; + _gsskrb5_set_status("No ticket to obtain authz data from"); + return GSS_S_NO_CONTEXT; + } + + ret = krb5_ticket_get_authorization_data_type(_gsskrb5_context, + context_handle->ticket, + ad_type, + &data); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + if (ret) { + _gsskrb5_set_error_string (); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ad_data.value = data.data; + ad_data.length = data.length; + + ret = gss_add_buffer_set_member(minor_status, + &ad_data, + data_set); + + krb5_data_free(&data); + + return ret; +} + +static OM_uint32 inquire_sec_context_has_updated_spnego + (OM_uint32 *minor_status, + const gsskrb5_ctx context_handle, + gss_buffer_set_t *data_set) +{ + int is_updated = 0; + + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + + /* + * For Windows SPNEGO implementations, both the initiator and the + * acceptor are assumed to have been updated if a "newer" [CLAR] or + * different enctype is negotiated for use by the Kerberos GSS-API + * mechanism. + */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + _gsskrb5i_is_cfx(context_handle, &is_updated); + if (is_updated == 0) { + krb5_keyblock *acceptor_subkey; + + if (context_handle->more_flags & LOCAL) + acceptor_subkey = context_handle->auth_context->remote_subkey; + else + acceptor_subkey = context_handle->auth_context->local_subkey; + + if (acceptor_subkey != NULL) + is_updated = (acceptor_subkey->keytype != + context_handle->auth_context->keyblock->keytype); + } + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + + return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE; +} + +/* + * + */ + +static OM_uint32 +export_lucid_sec_context_v1(OM_uint32 *minor_status, + gsskrb5_ctx context_handle, + gss_buffer_set_t *data_set) +{ + krb5_storage *sp = NULL; + OM_uint32 major_status = GSS_S_COMPLETE; + krb5_error_code ret; + krb5_keyblock *key = NULL; + int32_t number; + int is_cfx; + krb5_data data; + + *minor_status = 0; + + GSSAPI_KRB5_INIT (); + + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + + _gsskrb5i_is_cfx(context_handle, &is_cfx); + + sp = krb5_storage_emem(); + if (sp == NULL) { + _gsskrb5_clear_status(); + ret = ENOMEM; + goto out; + } + + ret = krb5_store_int32(sp, 1); + if (ret) goto out; + ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0); + if (ret) goto out; + ret = krb5_store_int32(sp, context_handle->lifetime); + if (ret) goto out; + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + context_handle->auth_context, + &number); + ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ + ret = krb5_store_uint32(sp, (uint32_t)number); + krb5_auth_getremoteseqnumber (_gsskrb5_context, + context_handle->auth_context, + &number); + ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ + ret = krb5_store_uint32(sp, (uint32_t)number); + ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); + if (ret) goto out; + + ret = _gsskrb5i_get_token_key(context_handle, &key); + if (ret) goto out; + + if (is_cfx == 0) { + int sign_alg, seal_alg; + + switch (key->keytype) { + case ETYPE_DES_CBC_CRC: + case ETYPE_DES_CBC_MD4: + case ETYPE_DES_CBC_MD5: + sign_alg = 0; + seal_alg = 0; + break; + case ETYPE_DES3_CBC_MD5: + case ETYPE_DES3_CBC_SHA1: + sign_alg = 4; + seal_alg = 2; + break; + case ETYPE_ARCFOUR_HMAC_MD5: + case ETYPE_ARCFOUR_HMAC_MD5_56: + sign_alg = 17; + seal_alg = 16; + break; + default: + sign_alg = -1; + seal_alg = -1; + break; + } + ret = krb5_store_int32(sp, sign_alg); + if (ret) goto out; + ret = krb5_store_int32(sp, seal_alg); + if (ret) goto out; + /* ctx_key */ + ret = krb5_store_keyblock(sp, *key); + if (ret) goto out; + } else { + int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0; + + /* have_acceptor_subkey */ + ret = krb5_store_int32(sp, subkey_p); + if (ret) goto out; + /* ctx_key */ + ret = krb5_store_keyblock(sp, *key); + if (ret) goto out; + /* acceptor_subkey */ + if (subkey_p) { + ret = krb5_store_keyblock(sp, *key); + if (ret) goto out; + } + } + ret = krb5_storage_to_data(sp, &data); + if (ret) goto out; + + { + gss_buffer_desc ad_data; + + ad_data.value = data.data; + ad_data.length = data.length; + + ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); + krb5_data_free(&data); + if (ret) + goto out; + } + +out: + if (key) + krb5_free_keyblock (_gsskrb5_context, key); + if (sp) + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + } + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + return major_status; +} + +static OM_uint32 +get_authtime(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + gss_buffer_set_t *data_set) + +{ + gss_buffer_desc value; + OM_uint32 authtime; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + if (ctx->ticket == NULL) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + _gsskrb5_set_status("No ticket to obtain auth time from"); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + authtime = ctx->ticket->ticket.authtime; + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + value.length = 4; + value.value = malloc(value.length); + if (!value.value) { + _gsskrb5_clear_status(); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + _gsskrb5_encode_om_uint32(authtime, value.value); + + return gss_add_buffer_set_member(minor_status, + &value, + data_set); +} + + +static OM_uint32 +get_service_keyblock + (OM_uint32 *minor_status, + gsskrb5_ctx ctx, + gss_buffer_set_t *data_set) +{ + krb5_storage *sp = NULL; + krb5_data data; + OM_uint32 maj_stat = GSS_S_COMPLETE; + krb5_error_code ret = EINVAL; + + sp = krb5_storage_emem(); + if (sp == NULL) { + _gsskrb5_clear_status(); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + if (ctx->service_keyblock == NULL) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + _gsskrb5_set_status("No service keyblock on gssapi context"); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + krb5_data_zero(&data); + + ret = krb5_store_keyblock(sp, *ctx->service_keyblock); + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + if (ret) + goto out; + + ret = krb5_storage_to_data(sp, &data); + if (ret) + goto out; + + { + gss_buffer_desc value; + + value.length = data.length; + value.value = data.data; + + maj_stat = gss_add_buffer_set_member(minor_status, + &value, + data_set); + } + +out: + krb5_data_free(&data); + if (sp) + krb5_storage_free(sp); + if (ret) { + _gsskrb5_set_error_string (); + *minor_status = ret; + maj_stat = GSS_S_FAILURE; + } + return maj_stat; +} +/* + * + */ + +OM_uint32 _gsskrb5_inquire_sec_context_by_oid + (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + unsigned suffix; + + if (ctx == NULL) { + *minor_status = EINVAL; + return GSS_S_NO_CONTEXT; + } + + if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) { + return inquire_sec_context_tkt_flags(minor_status, + ctx, + data_set); + } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) { + return inquire_sec_context_has_updated_spnego(minor_status, + ctx, + data_set); + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) { + return inquire_sec_context_get_subkey(minor_status, + ctx, + TOKEN_KEY, + data_set); + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) { + return inquire_sec_context_get_subkey(minor_status, + ctx, + INITIATOR_KEY, + data_set); + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) { + return inquire_sec_context_get_subkey(minor_status, + ctx, + ACCEPTOR_KEY, + data_set); + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) { + return get_authtime(minor_status, ctx, data_set); + } else if (oid_prefix_equal(desired_object, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X, + &suffix)) { + return inquire_sec_context_authz_data(minor_status, + ctx, + suffix, + data_set); + } else if (oid_prefix_equal(desired_object, + GSS_KRB5_EXPORT_LUCID_CONTEXT_X, + &suffix)) { + if (suffix == 1) + return export_lucid_sec_context_v1(minor_status, + ctx, + data_set); + *minor_status = 0; + return GSS_S_FAILURE; + } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) { + return get_service_keyblock(minor_status, ctx, data_set); + } else { + *minor_status = 0; + return GSS_S_FAILURE; + } +} + diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c new file mode 100644 index 0000000000..99568c9dd0 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: process_context_token.c,v 1.4 2006/10/07 22:15:19 lha Exp $"); + +OM_uint32 _gsskrb5_process_context_token ( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t token_buffer + ) +{ + OM_uint32 ret = GSS_S_FAILURE; + gss_buffer_desc empty_buffer; + gss_qop_t qop_state; + + empty_buffer.length = 0; + empty_buffer.value = NULL; + + qop_state = GSS_C_QOP_DEFAULT; + + ret = _gsskrb5_verify_mic_internal(minor_status, + (gsskrb5_ctx)context_handle, + token_buffer, &empty_buffer, + GSS_C_QOP_DEFAULT, "\x01\x02"); + + if (ret == GSS_S_COMPLETE) + ret = _gsskrb5_delete_sec_context(minor_status, + rk_UNCONST(&context_handle), + GSS_C_NO_BUFFER); + if (ret == GSS_S_COMPLETE) + *minor_status = 0; + + return ret; +} diff --git a/source4/heimdal/lib/gssapi/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c index 258b76f627..b62ad02117 100644 --- a/source4/heimdal/lib/gssapi/release_buffer.c +++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c @@ -31,11 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_buffer.c,v 1.5 2003/03/16 17:58:20 lha Exp $"); +RCSID("$Id: release_buffer.c,v 1.7 2006/10/07 22:15:22 lha Exp $"); -OM_uint32 gss_release_buffer +OM_uint32 _gsskrb5_release_buffer (OM_uint32 * minor_status, gss_buffer_t buffer ) diff --git a/source4/heimdal/lib/gssapi/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c index fc9fc3fc01..662461ccfd 100644 --- a/source4/heimdal/lib/gssapi/release_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c @@ -31,43 +31,46 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_cred.c,v 1.11 2005/11/02 08:57:35 lha Exp $"); +RCSID("$Id: release_cred.c,v 1.13 2006/10/07 22:15:24 lha Exp $"); -OM_uint32 gss_release_cred +OM_uint32 _gsskrb5_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle ) { + gsskrb5_cred cred; + *minor_status = 0; - if (*cred_handle == GSS_C_NO_CREDENTIAL) { + if (*cred_handle == NULL) return GSS_S_COMPLETE; - } + + cred = (gsskrb5_cred)*cred_handle; + *cred_handle = GSS_C_NO_CREDENTIAL; GSSAPI_KRB5_INIT (); - HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex); + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); - if ((*cred_handle)->principal != NULL) - krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); - if ((*cred_handle)->keytab != NULL) - krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab); - if ((*cred_handle)->ccache != NULL) { + if (cred->principal != NULL) + krb5_free_principal(_gsskrb5_context, cred->principal); + if (cred->keytab != NULL) + krb5_kt_close(_gsskrb5_context, cred->keytab); + if (cred->ccache != NULL) { const krb5_cc_ops *ops; - ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache); - if ((*cred_handle)->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE) - krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache); + ops = krb5_cc_get_ops(_gsskrb5_context, cred->ccache); + if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE) + krb5_cc_destroy(_gsskrb5_context, cred->ccache); else - krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); + krb5_cc_close(_gsskrb5_context, cred->ccache); } - gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); - HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex); - HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex); - memset(*cred_handle, 0, sizeof(**cred_handle)); - free(*cred_handle); - *cred_handle = GSS_C_NO_CREDENTIAL; + _gsskrb5_release_oid_set(NULL, &cred->mechanisms); + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + HEIMDAL_MUTEX_destroy(&cred->cred_id_mutex); + memset(cred, 0, sizeof(*cred)); + free(cred); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c index 6894ffae49..a92ad939a5 100644 --- a/source4/heimdal/lib/gssapi/release_name.c +++ b/source4/heimdal/lib/gssapi/krb5/release_name.c @@ -31,20 +31,25 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_name.c,v 1.7 2003/03/16 17:52:48 lha Exp $"); +RCSID("$Id: release_name.c,v 1.10 2006/10/07 22:15:26 lha Exp $"); -OM_uint32 gss_release_name +OM_uint32 _gsskrb5_release_name (OM_uint32 * minor_status, gss_name_t * input_name ) { + krb5_principal name = (krb5_principal)*input_name; + GSSAPI_KRB5_INIT (); + if (minor_status) *minor_status = 0; - krb5_free_principal(gssapi_krb5_context, - *input_name); + *input_name = GSS_C_NO_NAME; + + krb5_free_principal(_gsskrb5_context, name); + return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/release_oid_set.c b/source4/heimdal/lib/gssapi/krb5/release_oid_set.c index 04eb01565f..a9f79a3082 100644 --- a/source4/heimdal/lib/gssapi/release_oid_set.c +++ b/source4/heimdal/lib/gssapi/krb5/release_oid_set.c @@ -31,11 +31,11 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_oid_set.c,v 1.5 2003/03/16 17:53:25 lha Exp $"); +RCSID("$Id: release_oid_set.c,v 1.7 2006/10/07 22:15:30 lha Exp $"); -OM_uint32 gss_release_oid_set +OM_uint32 _gsskrb5_release_oid_set (OM_uint32 * minor_status, gss_OID_set * set ) diff --git a/source4/heimdal/lib/gssapi/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c index 35a9b924af..3014edd04d 100755 --- a/source4/heimdal/lib/gssapi/sequence.c +++ b/source4/heimdal/lib/gssapi/krb5/sequence.c @@ -31,9 +31,9 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: sequence.c,v 1.6 2006/04/12 17:43:39 lha Exp $"); +RCSID("$Id: sequence.c,v 1.8 2006/10/07 22:15:32 lha Exp $"); #define DEFAULT_JITTER_WINDOW 20 @@ -159,8 +159,8 @@ _gssapi_msg_order_check(struct gss_msg_order *o, OM_uint32 seq_num) r = (o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG))==GSS_C_REPLAY_FLAG; - /* sequence number larger than largest sequence number - * or smaller than the first sequence number */ + /* sequence number larger then largest sequence number + * or smaller then the first sequence number */ if (seq_num > o->elem[0] || seq_num < o->first_seq || o->length == 0) diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c new file mode 100644 index 0000000000..5807ef0166 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: set_cred_option.c,v 1.4 2006/10/24 20:14:13 lha Exp $"); + +static gss_OID_desc gss_krb5_import_cred_x_oid_desc = +{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */ + +gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc; + +static OM_uint32 +import_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + OM_uint32 major_stat; + krb5_error_code ret; + krb5_principal keytab_principal = NULL; + krb5_keytab keytab = NULL; + krb5_storage *sp = NULL; + krb5_ccache id = NULL; + char *str; + + if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_mem(value->value, value->length); + if (sp == NULL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + /* credential cache name */ + ret = krb5_ret_string(sp, &str); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + if (str[0]) { + ret = krb5_cc_resolve(_gsskrb5_context, str, &id); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + } + free(str); + str = NULL; + + /* keytab principal name */ + ret = krb5_ret_string(sp, &str); + if (ret == 0 && str[0]) + ret = krb5_parse_name(_gsskrb5_context, str, &keytab_principal); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + free(str); + str = NULL; + + /* keytab principal */ + ret = krb5_ret_string(sp, &str); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + if (str[0]) { + ret = krb5_kt_resolve(_gsskrb5_context, str, &keytab); + if (ret) { + *minor_status = ret; + major_stat = GSS_S_FAILURE; + goto out; + } + } + free(str); + str = NULL; + + major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal, + keytab, cred_handle); +out: + if (id) + krb5_cc_close(_gsskrb5_context, id); + if (keytab_principal) + krb5_free_principal(_gsskrb5_context, keytab_principal); + if (keytab) + krb5_kt_close(_gsskrb5_context, keytab); + if (str) + free(str); + if (sp) + krb5_storage_free(sp); + + return major_stat; +} + + +OM_uint32 +_gsskrb5_set_cred_option + (OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + GSSAPI_KRB5_INIT (); + + if (value == GSS_C_NO_BUFFER) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) { + return import_cred(minor_status, cred_handle, value); + } + + *minor_status = EINVAL; + return GSS_S_FAILURE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c new file mode 100644 index 0000000000..67f5e8e722 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * glue routine for _gsskrb5_inquire_sec_context_by_oid + */ + +#include "krb5/gsskrb5_locl.h" + +RCSID("$Id: set_sec_context_option.c,v 1.6 2006/10/20 18:58:22 lha Exp $"); + +static OM_uint32 +get_bool(OM_uint32 *minor_status, + const gss_buffer_t value, + int *flag) +{ + if (value->value == NULL || value->length != 1) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + *flag = *((const char *)value->value) != 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +_gsskrb5_set_sec_context_option + (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + OM_uint32 maj_stat; + + GSSAPI_KRB5_INIT (); + + if (value == GSS_C_NO_BUFFER) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) { + gsskrb5_ctx ctx; + int flag; + + if (*context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_NO_CONTEXT; + } + + maj_stat = get_bool(minor_status, value, &flag); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + + ctx = (gsskrb5_ctx)*context_handle; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + if (flag) + ctx->more_flags |= COMPAT_OLD_DES3; + else + ctx->more_flags &= ~COMPAT_OLD_DES3; + ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_COMPLETE; + } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) { + int flag; + + maj_stat = get_bool(minor_status, value, &flag); + if (maj_stat != GSS_S_COMPLETE) + return maj_stat; + + krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag); + return GSS_S_COMPLETE; + + } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { + char *str; + + if (value == NULL || value->length == 0) { + str = NULL; + } else { + str = malloc(value->length + 1); + if (str) { + *minor_status = 0; + return GSS_S_UNAVAILABLE; + } + memcpy(str, value->value, value->length); + str[value->length] = '\0'; + } + + _gsskrb5_register_acceptor_identity(str); + free(str); + + *minor_status = 0; + return GSS_S_COMPLETE; + + } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) { + + if (value == NULL || value->length == 0) { + krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL); + } else { + struct gsskrb5_send_to_kdc c; + + if (value->length != sizeof(c)) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + memcpy(&c, value->value, sizeof(c)); + krb5_set_send_to_kdc_func(_gsskrb5_context, + (krb5_send_to_kdc_func)c.func, + c.ptr); + } + + *minor_status = 0; + return GSS_S_COMPLETE; + } + + + *minor_status = EINVAL; + return GSS_S_FAILURE; +} diff --git a/source4/heimdal/lib/gssapi/test_oid_set_member.c b/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c index e747c5acc1..5a0ac4418f 100644 --- a/source4/heimdal/lib/gssapi/test_oid_set_member.c +++ b/source4/heimdal/lib/gssapi/krb5/test_oid_set_member.c @@ -31,25 +31,25 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: test_oid_set_member.c,v 1.5 2003/03/16 17:54:06 lha Exp $"); +RCSID("$Id: test_oid_set_member.c,v 1.7 2006/10/07 22:15:50 lha Exp $"); -OM_uint32 gss_test_oid_set_member ( - OM_uint32 * minor_status, +OM_uint32 _gsskrb5_test_oid_set_member + (OM_uint32 * minor_status, const gss_OID member, const gss_OID_set set, int * present ) { - size_t i; + size_t i; - *minor_status = 0; - *present = 0; - for (i = 0; i < set->count; ++i) - if (gss_oid_equal(member, &set->elements[i]) != 0) { - *present = 1; - break; - } - return GSS_S_COMPLETE; + *minor_status = 0; + *present = 0; + for (i = 0; i < set->count; ++i) + if (gss_oid_equal(member, &set->elements[i]) != 0) { + *present = 1; + break; + } + return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index c358c1aa24..758390080c 100644 --- a/source4/heimdal/lib/gssapi/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -31,14 +31,14 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: unwrap.c,v 1.34 2005/04/27 17:50:40 lha Exp $"); +RCSID("$Id: unwrap.c,v 1.38 2006/10/18 15:59:28 lha Exp $"); static OM_uint32 unwrap_des (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, @@ -54,14 +54,14 @@ unwrap_des DES_cblock deskey; DES_cblock zero; int i; - int32_t seq_number; + uint32_t seq_number; size_t padlength; OM_uint32 ret; int cstate; int cmp; p = input_message_buffer->value; - ret = gssapi_krb5_verify_header (&p, + ret = _gsskrb5_verify_header (&p, input_message_buffer->length, "\x02\x01", GSS_KRB5_MECHANISM); @@ -138,7 +138,7 @@ unwrap_des memset (&schedule, 0, sizeof(schedule)); seq = p; - gssapi_decode_om_uint32(seq, &seq_number); + _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4); @@ -174,7 +174,7 @@ unwrap_des static OM_uint32 unwrap_des3 (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, @@ -187,7 +187,7 @@ unwrap_des3 u_char *seq; krb5_data seq_data; u_char cksum[20]; - int32_t seq_number; + uint32_t seq_number; size_t padlength; OM_uint32 ret; int cstate; @@ -196,7 +196,7 @@ unwrap_des3 int cmp; p = input_message_buffer->value; - ret = gssapi_krb5_verify_header (&p, + ret = _gsskrb5_verify_header (&p, input_message_buffer->length, "\x02\x01", GSS_KRB5_MECHANISM); @@ -226,18 +226,18 @@ unwrap_des3 /* decrypt data */ krb5_data tmp; - ret = krb5_crypto_init(gssapi_krb5_context, key, + ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_decrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL, + ret = krb5_decrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL, p, input_message_buffer->length - len, &tmp); - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -259,10 +259,10 @@ unwrap_des3 p -= 28; - ret = krb5_crypto_init(gssapi_krb5_context, key, + ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_FAILURE; @@ -271,15 +271,15 @@ unwrap_des3 DES_cblock ivec; memcpy(&ivec, p + 8, 8); - ret = krb5_decrypt_ivec (gssapi_krb5_context, + ret = krb5_decrypt_ivec (_gsskrb5_context, crypto, KRB5_KU_USAGE_SEQ, p, 8, &seq_data, &ivec); } - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_FAILURE; @@ -292,7 +292,7 @@ unwrap_des3 } seq = seq_data.data; - gssapi_decode_om_uint32(seq, &seq_number); + _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4); @@ -325,21 +325,21 @@ unwrap_des3 csum.checksum.length = 20; csum.checksum.data = cksum; - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_verify_checksum (gssapi_krb5_context, crypto, + ret = krb5_verify_checksum (_gsskrb5_context, crypto, KRB5_KU_USAGE_SIGN, p + 20, input_message_buffer->length - len + 8, &csum); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -357,7 +357,7 @@ unwrap_des3 return GSS_S_COMPLETE; } -OM_uint32 gss_unwrap +OM_uint32 _gsskrb5_unwrap (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, @@ -369,45 +369,48 @@ OM_uint32 gss_unwrap krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; + gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; output_message_buffer->value = NULL; output_message_buffer->length = 0; if (qop_state != NULL) *qop_state = GSS_C_QOP_DEFAULT; - ret = gss_krb5_get_subkey(context_handle, &key); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); *minor_status = 0; switch (keytype) { case KEYTYPE_DES : - ret = unwrap_des (minor_status, context_handle, + ret = unwrap_des (minor_status, ctx, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; case KEYTYPE_DES3 : - ret = unwrap_des3 (minor_status, context_handle, + ret = unwrap_des3 (minor_status, ctx, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_unwrap_arcfour (minor_status, context_handle, + ret = _gssapi_unwrap_arcfour (minor_status, ctx, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; default : - ret = _gssapi_unwrap_cfx (minor_status, context_handle, + ret = _gssapi_unwrap_cfx (minor_status, ctx, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; } - krb5_free_keyblock (gssapi_krb5_context, key); + krb5_free_keyblock (_gsskrb5_context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 7b7d437e99..920937cafc 100644 --- a/source4/heimdal/lib/gssapi/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -31,14 +31,14 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: verify_mic.c,v 1.32 2005/04/27 17:51:04 lha Exp $"); +RCSID("$Id: verify_mic.c,v 1.36 2006/10/18 15:59:30 lha Exp $"); static OM_uint32 verify_mic_des (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -52,12 +52,12 @@ verify_mic_des DES_key_schedule schedule; DES_cblock zero; DES_cblock deskey; - int32_t seq_number; + uint32_t seq_number; OM_uint32 ret; int cmp; p = token_buffer->value; - ret = gssapi_krb5_verify_header (&p, + ret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); @@ -104,7 +104,7 @@ verify_mic_des memset (&schedule, 0, sizeof(schedule)); seq = p; - gssapi_decode_om_uint32(seq, &seq_number); + _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4); @@ -130,7 +130,7 @@ verify_mic_des static OM_uint32 verify_mic_des3 (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -140,7 +140,7 @@ verify_mic_des3 { u_char *p; u_char *seq; - int32_t seq_number; + uint32_t seq_number; OM_uint32 ret; krb5_crypto crypto; krb5_data seq_data; @@ -150,7 +150,7 @@ verify_mic_des3 char ivec[8]; p = token_buffer->value; - ret = gssapi_krb5_verify_header (&p, + ret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); @@ -164,10 +164,10 @@ verify_mic_des3 return GSS_S_BAD_MIC; p += 4; - ret = krb5_crypto_init(gssapi_krb5_context, key, + ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret){ - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -180,14 +180,14 @@ retry: else memcpy(ivec, p + 8, 8); - ret = krb5_decrypt_ivec (gssapi_krb5_context, + ret = krb5_decrypt_ivec (_gsskrb5_context, crypto, KRB5_KU_USAGE_SEQ, p, 8, &seq_data, ivec); if (ret) { if (docompat++) { - gssapi_krb5_set_error_string (); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + _gsskrb5_set_error_string (); + krb5_crypto_destroy (_gsskrb5_context, crypto); *minor_status = ret; return GSS_S_FAILURE; } else @@ -197,7 +197,7 @@ retry: if (seq_data.length != 8) { krb5_data_free (&seq_data); if (docompat++) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); return GSS_S_BAD_MIC; } else goto retry; @@ -206,7 +206,7 @@ retry: HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); seq = seq_data.data; - gssapi_decode_om_uint32(seq, &seq_number); + _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4); @@ -215,7 +215,7 @@ retry: krb5_data_free (&seq_data); if (cmp != 0) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); *minor_status = 0; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; @@ -223,7 +223,7 @@ retry: ret = _gssapi_msg_order_check(context_handle->order, seq_number); if (ret) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); *minor_status = 0; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return ret; @@ -233,7 +233,7 @@ retry: tmp = malloc (message_buffer->length + 8); if (tmp == NULL) { - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -246,28 +246,28 @@ retry: csum.checksum.length = 20; csum.checksum.data = p + 8; - ret = krb5_verify_checksum (gssapi_krb5_context, crypto, + ret = krb5_verify_checksum (_gsskrb5_context, crypto, KRB5_KU_USAGE_SIGN, tmp, message_buffer->length + 8, &csum); free (tmp); if (ret) { - gssapi_krb5_set_error_string (); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + _gsskrb5_set_error_string (); + krb5_crypto_destroy (_gsskrb5_context, crypto); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); return GSS_S_COMPLETE; } OM_uint32 -gss_verify_mic_internal +_gsskrb5_verify_mic_internal (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -278,14 +278,16 @@ gss_verify_mic_internal OM_uint32 ret; krb5_keytype keytype; - ret = gss_krb5_get_subkey(context_handle, &key); + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(context_handle, &key); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } *minor_status = 0; - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : ret = verify_mic_des (minor_status, context_handle, @@ -309,13 +311,13 @@ gss_verify_mic_internal key); break; } - krb5_free_keyblock (gssapi_krb5_context, key); + krb5_free_keyblock (_gsskrb5_context, key); return ret; } OM_uint32 -gss_verify_mic +_gsskrb5_verify_mic (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer, @@ -328,9 +330,10 @@ gss_verify_mic if (qop_state != NULL) *qop_state = GSS_C_QOP_DEFAULT; - ret = gss_verify_mic_internal(minor_status, context_handle, - message_buffer, token_buffer, - qop_state, "\x01\x01"); + ret = _gsskrb5_verify_mic_internal(minor_status, + (gsskrb5_ctx)context_handle, + message_buffer, token_buffer, + qop_state, "\x01\x01"); return ret; } diff --git a/source4/heimdal/lib/gssapi/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index 7072ca2754..8514137999 100644 --- a/source4/heimdal/lib/gssapi/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,110 +31,84 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" +#include "krb5/gsskrb5_locl.h" -RCSID("$Id: wrap.c,v 1.33 2006/05/05 10:27:36 lha Exp $"); +RCSID("$Id: wrap.c,v 1.37 2006/10/18 15:59:33 lha Exp $"); -OM_uint32 -gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, - gss_ctx_id_t context_handle, - gss_buffer_t key) +/* + * Return initiator subkey, or if that doesn't exists, the subkey. + */ + +krb5_error_code +_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key) { krb5_error_code ret; - krb5_keyblock *skey = NULL; - - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - if (context_handle->more_flags & LOCAL) { - ret = krb5_auth_con_getlocalsubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); - if (ret) { - *minor_status = ret; - return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ - } - + *key = NULL; + + if (ctx->more_flags & LOCAL) { + ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context, + ctx->auth_context, + key); } else { - ret = krb5_auth_con_getremotesubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); - if (ret) { - *minor_status = ret; - return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ - } - + ret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + ctx->auth_context, + key); } - - /* If there was no subkey, perhaps try this... */ - if(skey == NULL) { - krb5_auth_con_getkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); + if (*key == NULL) + ret = krb5_auth_con_getkey(_gsskrb5_context, + ctx->auth_context, + key); + if (*key == NULL) { + _gsskrb5_set_status("No initiator subkey available"); + return GSS_KRB5_S_KG_NO_SUBKEY; } + return ret; +} - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); +krb5_error_code +_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key) +{ + krb5_error_code ret; + *key = NULL; - /* ensure never to segfault */ - if(skey == NULL) { - return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ + if (ctx->more_flags & LOCAL) { + ret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + ctx->auth_context, + key); + } else { + ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context, + ctx->auth_context, + key); } - - key->length = skey->keyvalue.length; - key->value = malloc (key->length); - if (!key->value) { - krb5_free_keyblock(gssapi_krb5_context, skey); - *minor_status = ENOMEM; - return GSS_S_FAILURE; + if (*key == NULL) { + _gsskrb5_set_status("No acceptor subkey available"); + return GSS_KRB5_S_KG_NO_SUBKEY; } - memcpy(key->value, skey->keyvalue.data, key->length); - krb5_free_keyblock(gssapi_krb5_context, skey); - return 0; + return ret; } OM_uint32 -gss_krb5_get_subkey(const gss_ctx_id_t context_handle, - krb5_keyblock **key) +_gsskrb5i_get_token_key(const gsskrb5_ctx ctx, krb5_keyblock **key) { - krb5_keyblock *skey = NULL; - - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - if (context_handle->more_flags & LOCAL) { - krb5_auth_con_getremotesubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); - } else { - krb5_auth_con_getlocalsubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); + _gsskrb5i_get_acceptor_subkey(ctx, key); + if(*key == NULL) { + /* + * Only use the initiator subkey or ticket session key if an + * acceptor subkey was not required. + */ + if ((ctx->more_flags & ACCEPTOR_SUBKEY) == 0) + _gsskrb5i_get_initiator_subkey(ctx, key); } - /* - * Only use the initiator subkey or ticket session key if - * an acceptor subkey was not required. - */ - if (skey == NULL && - (context_handle->more_flags & ACCEPTOR_SUBKEY) == 0) { - if (context_handle->more_flags & LOCAL) { - krb5_auth_con_getlocalsubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); - } else { - krb5_auth_con_getremotesubkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); - } - if(skey == NULL) - krb5_auth_con_getkey(gssapi_krb5_context, - context_handle->auth_context, - &skey); + if (*key == NULL) { + _gsskrb5_set_status("No token key available"); + return GSS_KRB5_S_KG_NO_SUBKEY; } - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - if(skey == NULL) - return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ - *key = skey; + _gsskrb5_clear_status(); return 0; } static OM_uint32 -sub_wrap_size_limit ( +sub_wrap_size ( OM_uint32 req_output_size, OM_uint32 * max_input_size, int blocksize, @@ -145,7 +119,7 @@ sub_wrap_size_limit ( len = 8 + req_output_size + blocksize + extrasize; - gssapi_krb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); total_len -= req_output_size; /* token length */ if (total_len < req_output_size) { @@ -158,7 +132,7 @@ sub_wrap_size_limit ( } OM_uint32 -gss_wrap_size_limit ( +_gsskrb5_wrap_size_limit ( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, @@ -170,118 +144,38 @@ gss_wrap_size_limit ( krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; - OM_uint32 output_size; - OM_uint32 blocksize; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; - ret = gss_krb5_get_subkey(context_handle, &key); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = sub_wrap_size_limit(req_output_size, max_input_size, 8, 22); - break; - case KEYTYPE_DES3 : - ret = sub_wrap_size_limit(req_output_size, max_input_size, 8, 34); + ret = sub_wrap_size(req_output_size, max_input_size, 8, 22); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_wrap_size_arcfour(minor_status, context_handle, + ret = _gssapi_wrap_size_arcfour(minor_status, ctx, conf_req_flag, qop_req, - req_output_size, &output_size, - &blocksize, key); - - if (output_size > req_output_size) { - *max_input_size = req_output_size - (output_size - req_output_size); - (*max_input_size) &= (~(OM_uint32)(blocksize - 1)); - } else { - *max_input_size = 0; - } - break; - default : - ret = _gssapi_wrap_size_cfx(minor_status, context_handle, - conf_req_flag, qop_req, - req_output_size, &output_size, - &blocksize, key); - if (output_size > req_output_size) { - *max_input_size = req_output_size - (output_size - req_output_size); - (*max_input_size) &= (~(OM_uint32)(blocksize - 1)); - } else { - *max_input_size = 0; - } - break; - } - krb5_free_keyblock (gssapi_krb5_context, key); - *minor_status = 0; - return ret; -} - -static OM_uint32 -sub_wrap_size ( - OM_uint32 req_input_size, - OM_uint32 * output_size, - int blocksize, - int extrasize - ) -{ - size_t len, total_len, padlength, datalen; - - padlength = blocksize - (req_input_size % blocksize); - datalen = req_input_size + padlength + 8; - len = datalen + extrasize; - gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM); - - *output_size = total_len; - - return GSS_S_COMPLETE; -} - -OM_uint32 -gsskrb5_wrap_size ( - OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_input_size, - OM_uint32 * output_size - ) -{ - krb5_keyblock *key; - OM_uint32 ret, padlen; - krb5_keytype keytype; - - ret = gss_krb5_get_subkey(context_handle, &key); - if (ret) { - gssapi_krb5_set_error_string (); - *minor_status = ret; - return GSS_S_FAILURE; - } - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); - - switch (keytype) { - case KEYTYPE_DES : - ret = sub_wrap_size(req_input_size, output_size, 8, 22); + req_output_size, max_input_size, key); break; case KEYTYPE_DES3 : - ret = sub_wrap_size(req_input_size, output_size, 8, 34); - break; - case KEYTYPE_ARCFOUR: - case KEYTYPE_ARCFOUR_56: - ret = _gssapi_wrap_size_arcfour(minor_status, context_handle, - conf_req_flag, qop_req, - req_input_size, output_size, &padlen, key); + ret = sub_wrap_size(req_output_size, max_input_size, 8, 34); break; default : - ret = _gssapi_wrap_size_cfx(minor_status, context_handle, + ret = _gssapi_wrap_size_cfx(minor_status, ctx, conf_req_flag, qop_req, - req_input_size, output_size, &padlen, key); + req_output_size, max_input_size, key); break; } - krb5_free_keyblock (gssapi_krb5_context, key); + krb5_free_keyblock (_gsskrb5_context, key); *minor_status = 0; return ret; } @@ -289,7 +183,7 @@ gsskrb5_wrap_size ( static OM_uint32 wrap_des (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx ctx, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -311,7 +205,7 @@ wrap_des padlength = 8 - (input_message_buffer->length % 8); datalen = input_message_buffer->length + padlength + 8; len = datalen + 22; - gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM); output_message_buffer->length = total_len; output_message_buffer->value = malloc (total_len); @@ -321,7 +215,7 @@ wrap_des return GSS_S_FAILURE; } - p = gssapi_krb5_make_header(output_message_buffer->value, + p = _gsskrb5_make_header(output_message_buffer->value, len, "\x02\x01", /* TOK_ID */ GSS_KRB5_MECHANISM); @@ -363,9 +257,9 @@ wrap_des memcpy (p - 8, hash, 8); /* sequence number */ - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + ctx->auth_context, &seq_number); p -= 16; @@ -374,17 +268,17 @@ wrap_des p[2] = (seq_number >> 16) & 0xFF; p[3] = (seq_number >> 24) & 0xFF; memset (p + 4, - (context_handle->more_flags & LOCAL) ? 0 : 0xFF, + (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); DES_set_key (&deskey, &schedule); DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + ctx->auth_context, ++seq_number); - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); /* encrypt the data */ p += 16; @@ -415,7 +309,7 @@ wrap_des static OM_uint32 wrap_des3 (OM_uint32 * minor_status, - const gss_ctx_id_t context_handle, + const gsskrb5_ctx ctx, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -436,7 +330,7 @@ wrap_des3 padlength = 8 - (input_message_buffer->length % 8); datalen = input_message_buffer->length + padlength + 8; len = datalen + 34; - gssapi_krb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM); + _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM); output_message_buffer->length = total_len; output_message_buffer->value = malloc (total_len); @@ -446,7 +340,7 @@ wrap_des3 return GSS_S_FAILURE; } - p = gssapi_krb5_make_header(output_message_buffer->value, + p = _gsskrb5_make_header(output_message_buffer->value, len, "\x02\x01", /* TOK_ID */ GSS_KRB5_MECHANISM); @@ -472,9 +366,9 @@ wrap_des3 input_message_buffer->length); memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength); - ret = krb5_crypto_init(gssapi_krb5_context, key, 0, &crypto); + ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -482,16 +376,16 @@ wrap_des3 return GSS_S_FAILURE; } - ret = krb5_create_checksum (gssapi_krb5_context, + ret = krb5_create_checksum (_gsskrb5_context, crypto, KRB5_KU_USAGE_SIGN, 0, p + 20, datalen + 8, &cksum); - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -505,10 +399,10 @@ wrap_des3 memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); free_Checksum (&cksum); - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + ctx->auth_context, &seq_number); seq[0] = (seq_number >> 0) & 0xFF; @@ -516,11 +410,11 @@ wrap_des3 seq[2] = (seq_number >> 16) & 0xFF; seq[3] = (seq_number >> 24) & 0xFF; memset (seq + 4, - (context_handle->more_flags & LOCAL) ? 0 : 0xFF, + (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); - ret = krb5_crypto_init(gssapi_krb5_context, key, ETYPE_DES3_CBC_NONE, + ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { free (output_message_buffer->value); @@ -534,15 +428,15 @@ wrap_des3 DES_cblock ivec; memcpy (&ivec, p + 8, 8); - ret = krb5_encrypt_ivec (gssapi_krb5_context, + ret = krb5_encrypt_ivec (_gsskrb5_context, crypto, KRB5_KU_USAGE_SEQ, seq, 8, &encdata, &ivec); } - krb5_crypto_destroy (gssapi_krb5_context, crypto); + krb5_crypto_destroy (_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -555,10 +449,10 @@ wrap_des3 memcpy (p, encdata.data, encdata.length); krb5_data_free (&encdata); - krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, - context_handle->auth_context, + krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + ctx->auth_context, ++seq_number); - HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); /* encrypt the data */ p += 28; @@ -566,21 +460,21 @@ wrap_des3 if(conf_req_flag) { krb5_data tmp; - ret = krb5_crypto_init(gssapi_krb5_context, key, + ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_encrypt(gssapi_krb5_context, crypto, KRB5_KU_USAGE_SEAL, + ret = krb5_encrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL, p, datalen, &tmp); - krb5_crypto_destroy(gssapi_krb5_context, crypto); + krb5_crypto_destroy(_gsskrb5_context, crypto); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -598,7 +492,7 @@ wrap_des3 return GSS_S_COMPLETE; } -OM_uint32 gss_wrap +OM_uint32 _gsskrb5_wrap (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, @@ -611,38 +505,41 @@ OM_uint32 gss_wrap krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; - ret = gss_krb5_get_subkey(context_handle, &key); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gsskrb5i_get_token_key(ctx, &key); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - gssapi_krb5_set_error_string (); + _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (gssapi_krb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = wrap_des (minor_status, context_handle, conf_req_flag, + ret = wrap_des (minor_status, ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; case KEYTYPE_DES3 : - ret = wrap_des3 (minor_status, context_handle, conf_req_flag, + ret = wrap_des3 (minor_status, ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_wrap_arcfour (minor_status, context_handle, conf_req_flag, + ret = _gssapi_wrap_arcfour (minor_status, ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; default : - ret = _gssapi_wrap_cfx (minor_status, context_handle, conf_req_flag, + ret = _gssapi_wrap_cfx (minor_status, ctx, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; } - krb5_free_keyblock (gssapi_krb5_context, key); + krb5_free_keyblock (_gsskrb5_context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/mech/context.h b/source4/heimdal/lib/gssapi/mech/context.h new file mode 100644 index 0000000000..7a215dd7d8 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/context.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/context.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id: context.h,v 1.2 2006/06/28 09:00:25 lha Exp $ + */ + +#include <gssapi_mech.h> + +struct _gss_context { + gssapi_mech_interface gc_mech; + gss_ctx_id_t gc_ctx; +}; diff --git a/source4/heimdal/lib/gssapi/mech/cred.h b/source4/heimdal/lib/gssapi/mech/cred.h new file mode 100644 index 0000000000..df89e79727 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/cred.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/cred.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id: cred.h,v 1.3 2006/10/05 18:26:54 lha Exp $ + */ + +struct _gss_mechanism_cred { + SLIST_ENTRY(_gss_mechanism_cred) gmc_link; + gssapi_mech_interface gmc_mech; /* mechanism ops for MC */ + gss_OID gmc_mech_oid; /* mechanism oid for MC */ + gss_cred_id_t gmc_cred; /* underlying MC */ +}; +SLIST_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred); + +struct _gss_cred { + gss_cred_usage_t gc_usage; + struct _gss_mechanism_cred_list gc_mc; +}; + diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c new file mode 100644 index 0000000000..4d634bf20f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_accept_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_accept_sec_context.c,v 1.6 2006/10/25 00:45:12 lha Exp $"); + +OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + OM_uint32 major_status, mech_ret_flags; + gssapi_mech_interface m; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + struct _gss_cred *cred = (struct _gss_cred *) acceptor_cred_handle; + struct _gss_mechanism_cred *mc; + gss_cred_id_t acceptor_mc, delegated_mc; + gss_name_t src_mn; + int allocated_ctx; + + *minor_status = 0; + if (src_name) *src_name = 0; + if (mech_type) *mech_type = 0; + if (ret_flags) *ret_flags = 0; + if (time_rec) *time_rec = 0; + if (delegated_cred_handle) *delegated_cred_handle = 0; + output_token->length = 0; + output_token->value = 0; + + /* + * If this is the first call (*context_handle is NULL), we must + * parse the input token to figure out the mechanism to use. + */ + if (*context_handle == GSS_C_NO_CONTEXT) { + unsigned char *p = input_token->value; + size_t len = input_token->length; + size_t a, b; + gss_OID_desc mech_oid; + + /* + * Token must start with [APPLICATION 0] SEQUENCE. + * But if it doesn't assume its DCE-STYLE Kerberos! + */ + if (len == 0) + return (GSS_S_DEFECTIVE_TOKEN); + if (*p != 0x60) { + mech_oid = *GSS_KRB5_MECHANISM; + } else { + p++; + len--; + + /* + * Decode the length and make sure it agrees with the + * token length. + */ + if (len == 0) + return (GSS_S_DEFECTIVE_TOKEN); + if ((*p & 0x80) == 0) { + a = *p; + p++; + len--; + } else { + b = *p & 0x7f; + p++; + len--; + if (len < b) + return (GSS_S_DEFECTIVE_TOKEN); + a = 0; + while (b) { + a = (a << 8) | *p; + p++; + len--; + b--; + } + } + if (a != len) + return (GSS_S_DEFECTIVE_TOKEN); + + /* + * Decode the OID for the mechanism. Simplify life by + * assuming that the OID length is less than 128 bytes. + */ + if (len < 2 || *p != 0x06) + return (GSS_S_DEFECTIVE_TOKEN); + if ((p[1] & 0x80) || p[1] > (len - 2)) + return (GSS_S_DEFECTIVE_TOKEN); + mech_oid.length = p[1]; + p += 2; + len -= 2; + mech_oid.elements = p; + } + /* + * Now that we have a mechanism, we can find the + * implementation. + */ + ctx = malloc(sizeof(struct _gss_context)); + if (!ctx) { + *minor_status = ENOMEM; + return (GSS_S_DEFECTIVE_TOKEN); + } + memset(ctx, 0, sizeof(struct _gss_context)); + m = ctx->gc_mech = __gss_get_mechanism(&mech_oid); + if (!m) { + free(ctx); + return (GSS_S_BAD_MECH); + } + allocated_ctx = 1; + } else { + m = ctx->gc_mech; + allocated_ctx = 0; + } + + if (cred) { + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) + if (mc->gmc_mech == m) + break; + if (!mc) + return (GSS_S_BAD_MECH); + acceptor_mc = mc->gmc_cred; + } else { + acceptor_mc = GSS_C_NO_CREDENTIAL; + } + delegated_mc = GSS_C_NO_CREDENTIAL; + + mech_ret_flags = 0; + major_status = m->gm_accept_sec_context(minor_status, + &ctx->gc_ctx, + acceptor_mc, + input_token, + input_chan_bindings, + &src_mn, + mech_type, + output_token, + &mech_ret_flags, + time_rec, + &delegated_mc); + if (major_status != GSS_S_COMPLETE && + major_status != GSS_S_CONTINUE_NEEDED) + return (major_status); + + if (!src_name) { + m->gm_release_name(minor_status, &src_mn); + } else { + /* + * Make a new name and mark it as an MN. + */ + struct _gss_name *name = _gss_make_name(m, src_mn); + + if (!name) { + m->gm_release_name(minor_status, &src_mn); + return (GSS_S_FAILURE); + } + *src_name = (gss_name_t) name; + } + + if (mech_ret_flags & GSS_C_DELEG_FLAG) { + if (!delegated_cred_handle) { + m->gm_release_cred(minor_status, &delegated_mc); + *ret_flags &= ~GSS_C_DELEG_FLAG; + } else { + struct _gss_cred *dcred; + struct _gss_mechanism_cred *dmc; + + dcred = malloc(sizeof(struct _gss_cred)); + if (!dcred) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + SLIST_INIT(&dcred->gc_mc); + dmc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!dmc) { + free(dcred); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + m->gm_inquire_cred(minor_status, delegated_mc, + 0, 0, &dcred->gc_usage, 0); + dmc->gmc_mech = m; + dmc->gmc_mech_oid = &m->gm_mech_oid; + dmc->gmc_cred = delegated_mc; + SLIST_INSERT_HEAD(&dcred->gc_mc, dmc, gmc_link); + + *delegated_cred_handle = (gss_cred_id_t) dcred; + } + } + + if (ret_flags) + *ret_flags = mech_ret_flags; + *context_handle = (gss_ctx_id_t) ctx; + return (major_status); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c new file mode 100644 index 0000000000..0b3554c0fa --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_acquire_cred.c,v 1.4 2006/10/25 00:44:55 lha Exp $"); + +OM_uint32 +gss_acquire_cred(OM_uint32 *minor_status, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + OM_uint32 major_status; + gss_OID_set mechs = desired_mechs; + gss_OID_set_desc set; + struct _gss_name *name = (struct _gss_name *) desired_name; + gssapi_mech_interface m; + struct _gss_cred *cred; + struct _gss_mechanism_cred *mc; + OM_uint32 min_time, cred_time; + int i; + + _gss_load_mech(); + + /* + * First make sure that at least one of the requested + * mechanisms is one that we support. + */ + if (mechs) { + for (i = 0; i < mechs->count; i++) { + int t; + gss_test_oid_set_member(minor_status, + &mechs->elements[i], _gss_mech_oids, &t); + if (t) + break; + } + if (i == mechs->count) { + *output_cred_handle = 0; + *minor_status = 0; + return (GSS_S_BAD_MECH); + } + } + + if (actual_mechs) { + major_status = gss_create_empty_oid_set(minor_status, + actual_mechs); + if (major_status) + return (major_status); + } + + cred = malloc(sizeof(struct _gss_cred)); + if (!cred) { + if (actual_mechs) + gss_release_oid_set(minor_status, actual_mechs); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + cred->gc_usage = cred_usage; + SLIST_INIT(&cred->gc_mc); + + if (mechs == GSS_C_NO_OID_SET) + mechs = _gss_mech_oids; + + set.count = 1; + min_time = GSS_C_INDEFINITE; + for (i = 0; i < mechs->count; i++) { + struct _gss_mechanism_name *mn = NULL; + + m = __gss_get_mechanism(&mechs->elements[i]); + if (!m) + continue; + + if (desired_name != GSS_C_NO_NAME) { + mn = _gss_find_mn(name, &mechs->elements[i]); + if (!mn) + continue; + } + + mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!mc) { + continue; + } + SLIST_INIT(&cred->gc_mc); + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + + /* + * XXX Probably need to do something with actual_mechs. + */ + set.elements = &mechs->elements[i]; + major_status = m->gm_acquire_cred(minor_status, + (desired_name != GSS_C_NO_NAME + ? mn->gmn_name : GSS_C_NO_NAME), + time_req, &set, cred_usage, + &mc->gmc_cred, NULL, &cred_time); + if (major_status) { + free(mc); + continue; + } + if (cred_time < min_time) + min_time = cred_time; + + if (actual_mechs) { + major_status = gss_add_oid_set_member(minor_status, + mc->gmc_mech_oid, actual_mechs); + if (major_status) { + m->gm_release_cred(minor_status, + &mc->gmc_cred); + free(mc); + continue; + } + } + + SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); + } + + /* + * If we didn't manage to create a single credential, return + * an error. + */ + if (!SLIST_FIRST(&cred->gc_mc)) { + free(cred); + if (actual_mechs) + gss_release_oid_set(minor_status, actual_mechs); + *output_cred_handle = 0; + *minor_status = 0; + return (GSS_S_NO_CRED); + } + + if (time_rec) + *time_rec = min_time; + *output_cred_handle = (gss_cred_id_t) cred; + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c new file mode 100644 index 0000000000..beffd54e29 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_add_cred.c,v 1.3 2006/06/29 08:23:53 lha Exp $"); + +static struct _gss_mechanism_cred * +_gss_copy_cred(struct _gss_mechanism_cred *mc) +{ + struct _gss_mechanism_cred *new_mc; + gssapi_mech_interface m = mc->gmc_mech; + OM_uint32 major_status, minor_status; + gss_name_t name; + gss_cred_id_t cred; + OM_uint32 initiator_lifetime, acceptor_lifetime; + gss_cred_usage_t cred_usage; + + major_status = m->gm_inquire_cred_by_mech(&minor_status, + mc->gmc_cred, mc->gmc_mech_oid, + &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage); + if (major_status) + return (0); + + major_status = m->gm_add_cred(&minor_status, + GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, + cred_usage, initiator_lifetime, acceptor_lifetime, + &cred, 0, 0, 0); + m->gm_release_name(&minor_status, &name); + + if (major_status) + return (0); + + new_mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!new_mc) { + m->gm_release_cred(&minor_status, &cred); + return (0); + } + new_mc->gmc_mech = m; + new_mc->gmc_mech_oid = &m->gm_mech_oid; + new_mc->gmc_cred = cred; + + return (new_mc); +} + +OM_uint32 +gss_add_cred(OM_uint32 *minor_status, + const gss_cred_id_t input_cred_handle, + const gss_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle; + struct _gss_cred *new_cred; + gss_cred_id_t release_cred; + struct _gss_mechanism_cred *mc, *target_mc, *copy_mc; + struct _gss_mechanism_name *mn; + OM_uint32 junk; + + *output_cred_handle = 0; + *minor_status = 0; + + new_cred = malloc(sizeof(struct _gss_cred)); + if (!new_cred) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + new_cred->gc_usage = cred_usage; + SLIST_INIT(&new_cred->gc_mc); + + /* + * We go through all the mc attached to the input_cred_handle + * and check the mechanism. If it matches, we call + * gss_add_cred for that mechanism, otherwise we copy the mc + * to new_cred. + */ + target_mc = 0; + if (cred) { + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) { + target_mc = mc; + } + copy_mc = _gss_copy_cred(mc); + if (!copy_mc) { + release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link); + } + } + + /* + * Figure out a suitable mn, if any. + */ + if (desired_name) { + mn = _gss_find_mn((struct _gss_name *) desired_name, + desired_mech); + if (!mn) { + free(new_cred); + return (GSS_S_BAD_NAME); + } + } else { + mn = 0; + } + + m = __gss_get_mechanism(desired_mech); + + mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!mc) { + release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + + major_status = m->gm_add_cred(minor_status, + target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL, + desired_name ? mn->gmn_name : GSS_C_NO_NAME, + desired_mech, + cred_usage, + initiator_time_req, + acceptor_time_req, + &mc->gmc_cred, + actual_mechs, + initiator_time_rec, + acceptor_time_rec); + + if (major_status) { + release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + free(mc); + return (major_status); + } + SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link); + *output_cred_handle = (gss_cred_id_t) new_cred; + + return (GSS_S_COMPLETE); +} + diff --git a/source4/heimdal/lib/gssapi/ccache_name.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c index 3bebb83c1f..5806cec009 100755..100644 --- a/source4/heimdal/lib/gssapi/ccache_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,50 +31,37 @@ * SUCH DAMAGE. */ -#include "gssapi_locl.h" - -RCSID("$Id: ccache_name.c,v 1.2 2005/06/16 20:38:49 lha Exp $"); - -char *last_out_name; +#include "mech_locl.h" +RCSID("$Id: gss_add_oid_set_member.c,v 1.3 2006/10/22 09:36:13 lha Exp $"); OM_uint32 -gss_krb5_ccache_name(OM_uint32 *minor_status, - const char *name, - const char **out_name) +gss_add_oid_set_member (OM_uint32 * minor_status, + const gss_OID member_oid, + gss_OID_set * oid_set) { - krb5_error_code kret; - - *minor_status = 0; + gss_OID tmp; + size_t n; + OM_uint32 res; + int present; - GSSAPI_KRB5_INIT(); + res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present); + if (res != GSS_S_COMPLETE) + return res; - if (out_name) { - const char *n; - - if (last_out_name) { - free(last_out_name); - last_out_name = NULL; - } - - n = krb5_cc_default_name(gssapi_krb5_context); - if (n == NULL) { - *minor_status = ENOMEM; - gssapi_krb5_set_error_string (); - return GSS_S_FAILURE; - } - last_out_name = strdup(n); - if (last_out_name == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - *out_name = last_out_name; + if (present) { + *minor_status = 0; + return GSS_S_COMPLETE; } - kret = krb5_cc_set_default_name(gssapi_krb5_context, name); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); + n = (*oid_set)->count + 1; + tmp = realloc ((*oid_set)->elements, n * sizeof(gss_OID_desc)); + if (tmp == NULL) { + *minor_status = ENOMEM; return GSS_S_FAILURE; } + (*oid_set)->elements = tmp; + (*oid_set)->count = n; + (*oid_set)->elements[n-1] = *member_oid; + *minor_status = 0; return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c new file mode 100644 index 0000000000..9e9bd5e790 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_buffer_set.c,v 1.2 2006/10/24 21:53:02 lha Exp $"); + +OM_uint32 +gss_create_empty_buffer_set + (OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + gss_buffer_set_t set; + + set = (gss_buffer_set_desc *) malloc(sizeof(*set)); + if (set == GSS_C_NO_BUFFER_SET) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + set->count = 0; + set->elements = NULL; + + *buffer_set = set; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gss_add_buffer_set_member + (OM_uint32 * minor_status, + const gss_buffer_t member_buffer, + gss_buffer_set_t *buffer_set) +{ + gss_buffer_set_t set; + gss_buffer_t p; + OM_uint32 ret; + + if (*buffer_set == GSS_C_NO_BUFFER_SET) { + ret = gss_create_empty_buffer_set(minor_status, + buffer_set); + if (ret) { + return ret; + } + } + + set = *buffer_set; + set->elements = realloc(set->elements, + (set->count + 1) * sizeof(set->elements[0])); + if (set->elements == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + p = &set->elements[set->count]; + + p->value = malloc(member_buffer->length); + if (p->value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(p->value, member_buffer->value, member_buffer->length); + p->length = member_buffer->length; + + set->count++; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gss_release_buffer_set(OM_uint32 * minor_status, + gss_buffer_set_t *buffer_set) +{ + int i; + OM_uint32 minor; + + *minor_status = 0; + + if (*buffer_set == GSS_C_NO_BUFFER_SET) + return GSS_S_COMPLETE; + + for (i = 0; i < (*buffer_set)->count; i++) + gss_release_buffer(&minor, &((*buffer_set)->elements[i])); + + free((*buffer_set)->elements); + + (*buffer_set)->elements = NULL; + (*buffer_set)->count = 0; + + free(*buffer_set); + *buffer_set = GSS_C_NO_BUFFER_SET; + + return GSS_S_COMPLETE; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c new file mode 100644 index 0000000000..38a464be46 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_canonicalize_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_canonicalize_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_canonicalize_name(OM_uint32 *minor_status, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t *output_name) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + gssapi_mech_interface m = __gss_get_mechanism(mech_type); + gss_name_t new_canonical_name; + + *minor_status = 0; + *output_name = 0; + + mn = _gss_find_mn(name, mech_type); + if (!mn) { + return (GSS_S_BAD_MECH); + } + + m = mn->gmn_mech; + major_status = m->gm_canonicalize_name(minor_status, + mn->gmn_name, mech_type, &new_canonical_name); + if (major_status) + return (major_status); + + /* + * Now we make a new name and mark it as an MN. + */ + *minor_status = 0; + name = malloc(sizeof(struct _gss_name)); + if (!name) { + m->gm_release_name(minor_status, &new_canonical_name); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(name, 0, sizeof(struct _gss_name)); + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + m->gm_release_name(minor_status, &new_canonical_name); + free(name); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + SLIST_INIT(&name->gn_mn); + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; + mn->gmn_name = new_canonical_name; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); + + *output_name = (gss_name_t) name; + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c new file mode 100644 index 0000000000..1068bfabf6 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_compare_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_compare_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_compare_name(OM_uint32 *minor_status, + const gss_name_t name1_arg, + const gss_name_t name2_arg, + int *name_equal) +{ + struct _gss_name *name1 = (struct _gss_name *) name1_arg; + struct _gss_name *name2 = (struct _gss_name *) name2_arg; + + /* + * First check the implementation-independant name if both + * names have one. Otherwise, try to find common mechanism + * names and compare them. + */ + if (name1->gn_value.value && name2->gn_value.value) { + *name_equal = 1; + if (!gss_oid_equal(&name1->gn_type, &name2->gn_type)) { + *name_equal = 0; + } else if (name1->gn_value.length != name2->gn_value.length || + memcmp(name1->gn_value.value, name1->gn_value.value, + name1->gn_value.length)) { + *name_equal = 0; + } + } else { + struct _gss_mechanism_name *mn1; + struct _gss_mechanism_name *mn2; + + SLIST_FOREACH(mn1, &name1->gn_mn, gmn_link) { + mn2 = _gss_find_mn(name2, mn1->gmn_mech_oid); + if (mn2) { + return (mn1->gmn_mech->gm_compare_name( + minor_status, + mn1->gmn_name, + mn2->gmn_name, + name_equal)); + } + } + *name_equal = 0; + } + + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c new file mode 100644 index 0000000000..4b17381776 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_context_time.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_context_time.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_context_time(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + OM_uint32 *time_rec) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_context_time(minor_status, ctx->gc_ctx, time_rec)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c new file mode 100644 index 0000000000..7298ec9e83 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_create_empty_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_create_empty_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_create_empty_oid_set(OM_uint32 *minor_status, + gss_OID_set *oid_set) +{ + gss_OID_set set; + + *minor_status = 0; + *oid_set = 0; + + set = malloc(sizeof(gss_OID_set_desc)); + if (!set) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + set->count = 0; + set->elements = 0; + *oid_set = set; + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c new file mode 100644 index 0000000000..8ebb848188 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_decapsulate_token.c,v 1.2 2006/10/14 10:04:45 lha Exp $"); + +OM_uint32 +gss_decapsulate_token(gss_buffer_t input_token, + gss_OID oid, + gss_buffer_t output_token) +{ + GSSAPIContextToken ct; + heim_oid o; + OM_uint32 status; + int ret; + size_t size; + + output_token->length = 0; + output_token->value = NULL; + + ret = der_get_oid (oid->elements, oid->length, &o, &size); + if (ret) + return GSS_S_FAILURE; + + ret = decode_GSSAPIContextToken(input_token->value, input_token->length, + &ct, NULL); + if (ret) { + der_free_oid(&o); + return GSS_S_FAILURE; + } + + if (der_heim_oid_cmp(&ct.thisMech, &o) == 0) { + status = GSS_S_COMPLETE; + output_token->value = ct.innerContextToken.data; + output_token->length = ct.innerContextToken.length; + der_free_oid(&ct.thisMech); + } else { + free_GSSAPIContextToken(&ct); + status = GSS_S_FAILURE; + } + der_free_oid(&o); + + return status; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c new file mode 100644 index 0000000000..06ef8e6d09 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_delete_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_delete_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_delete_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token) +{ + OM_uint32 major_status; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + + *minor_status = 0; + if (ctx) { + /* + * If we have an implementation ctx, delete it, + * otherwise fake an empty token. + */ + if (ctx->gc_ctx) { + major_status = ctx->gc_mech->gm_delete_sec_context( + minor_status, &ctx->gc_ctx, output_token); + } else if (output_token != GSS_C_NO_BUFFER) { + output_token->length = 0; + output_token->value = 0; + } + free(ctx); + *context_handle = 0; + } + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c new file mode 100644 index 0000000000..79f62a7a4f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_display_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_display_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_display_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + /* + * If we know it, copy the buffer used to import the name in + * the first place. Otherwise, ask all the MNs in turn if + * they can display the thing. + */ + if (name->gn_value.value) { + output_name_buffer->value = malloc(name->gn_value.length); + if (!output_name_buffer->value) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + output_name_buffer->length = name->gn_value.length; + memcpy(output_name_buffer->value, name->gn_value.value, + output_name_buffer->length); + if (output_name_type) + *output_name_type = &name->gn_type; + + *minor_status = 0; + return (GSS_S_COMPLETE); + } else { + SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { + major_status = mn->gmn_mech->gm_display_name( + minor_status, mn->gmn_name, + output_name_buffer, + output_name_type); + if (major_status == GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + } + } + + *minor_status = 0; + return (GSS_S_FAILURE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c new file mode 100644 index 0000000000..7871f5338b --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_display_status.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ +/* + * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_display_status.c,v 1.4 2006/07/19 11:02:33 lha Exp $"); + +static const char * +calling_error(OM_uint32 v) +{ + static const char *msgs[] = { + NULL, /* 0 */ + "A required input parameter could not be read.", /* */ + "A required output parameter could not be written.", /* */ + "A parameter was malformed" + }; + + v >>= GSS_C_CALLING_ERROR_OFFSET; + + if (v == 0) + return ""; + else if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown calling error"; + else + return msgs[v]; +} + +static const char * +routine_error(OM_uint32 v) +{ + static const char *msgs[] = { + NULL, /* 0 */ + "An unsupported mechanism was requested", + "An invalid name was supplied", + "A supplied name was of an unsupported type", + "Incorrect channel bindings were supplied", + "An invalid status code was supplied", + "A token had an invalid MIC", + "No credentials were supplied, " + "or the credentials were unavailable or inaccessible.", + "No context has been established", + "A token was invalid", + "A credential was invalid", + "The referenced credentials have expired", + "The context has expired", + "Miscellaneous failure (see text)", + "The quality-of-protection requested could not be provide", + "The operation is forbidden by local security policy", + "The operation or option is not available", + "The requested credential element already exists", + "The provided name was not a mechanism name.", + }; + + v >>= GSS_C_ROUTINE_ERROR_OFFSET; + + if (v == 0) + return ""; + else if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown routine error"; + else + return msgs[v]; +} + +static const char * +supplementary_error(OM_uint32 v) +{ + static const char *msgs[] = { + "normal completion", + "continuation call to routine required", + "duplicate per-message token detected", + "timed-out per-message token detected", + "reordered (early) per-message token detected", + "skipped predecessor token(s) detected" + }; + + v >>= GSS_C_SUPPLEMENTARY_OFFSET; + + if (v >= sizeof(msgs)/sizeof(*msgs)) + return "unknown routine error"; + else + return msgs[v]; +} + + +OM_uint32 +gss_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_content, + gss_buffer_t status_string) +{ + OM_uint32 major_status; + + *minor_status = 0; + switch (status_type) { + case GSS_C_GSS_CODE: { + char *buf; + + if (GSS_SUPPLEMENTARY_INFO(status_value)) + asprintf(&buf, "%s", supplementary_error( + GSS_SUPPLEMENTARY_INFO(status_value))); + else + asprintf (&buf, "%s %s", + calling_error(GSS_CALLING_ERROR(status_value)), + routine_error(GSS_ROUTINE_ERROR(status_value))); + + status_string->length = strlen(buf); + status_string->value = buf; + + return GSS_S_COMPLETE; + } + case GSS_C_MECH_CODE: { + gssapi_mech_interface m; + m = __gss_get_mechanism(mech_type); + if (m) { + major_status = m->gm_display_status(minor_status, + status_value, status_type, mech_type, + message_content, status_string); + if (major_status == GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + } + } + } + status_string->value = NULL; + status_string->length = 0; + return (GSS_S_BAD_STATUS); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c new file mode 100644 index 0000000000..5ef828f472 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_duplicate_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_duplicate_name.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 gss_duplicate_name(OM_uint32 *minor_status, + const gss_name_t src_name, + gss_name_t *dest_name) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) src_name; + struct _gss_name *new_name; + struct _gss_mechanism_name *mn; + + *minor_status = 0; + + /* + * If this name has a value (i.e. it didn't come from + * gss_canonicalize_name(), we re-import the thing. Otherwise, + * we make an empty name to hold the MN copy. + */ + if (name->gn_value.value) { + major_status = gss_import_name(minor_status, + &name->gn_value, &name->gn_type, dest_name); + if (major_status != GSS_S_COMPLETE) + return (major_status); + new_name = (struct _gss_name *) *dest_name; + } else { + new_name = malloc(sizeof(struct _gss_name)); + if (!new_name) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(new_name, 0, sizeof(struct _gss_name)); + SLIST_INIT(&name->gn_mn); + *dest_name = (gss_name_t) new_name; + } + + /* + * Import the new name into any mechanisms listed in the + * original name. We could probably get away with only doing + * this if the original was canonical. + */ + SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { + _gss_find_mn(new_name, mn->gmn_mech_oid); + } + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c new file mode 100644 index 0000000000..bfb0e75315 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_duplicate_oid.c,v 1.1 2006/06/28 09:07:07 lha Exp $"); + +OM_uint32 gss_duplicate_oid ( + OM_uint32 *minor_status, + gss_OID src_oid, + gss_OID *dest_oid + ) +{ + *minor_status = 0; + + if (src_oid == GSS_C_NO_OID) { + *dest_oid = GSS_C_NO_OID; + return GSS_S_COMPLETE; + } + + *dest_oid = malloc(sizeof(**dest_oid)); + if (*dest_oid == GSS_C_NO_OID) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + (*dest_oid)->elements = malloc(src_oid->length); + if ((*dest_oid)->elements == NULL) { + free(*dest_oid); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy((*dest_oid)->elements, src_oid->elements, src_oid->length); + (*dest_oid)->length = src_oid->length; + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c new file mode 100644 index 0000000000..d1285815ee --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_encapsulate_token.c,v 1.2 2006/10/14 10:05:12 lha Exp $"); + +OM_uint32 +gss_encapsulate_token(gss_buffer_t input_token, + gss_OID oid, + gss_buffer_t output_token) +{ + GSSAPIContextToken ct; + int ret; + size_t size; + + ret = der_get_oid (oid->elements, oid->length, &ct.thisMech, &size); + if (ret) { + output_token->value = NULL; + output_token->length = 0; + return GSS_S_FAILURE; + } + + ct.innerContextToken.data = input_token->value; + ct.innerContextToken.length = input_token->length; + + ASN1_MALLOC_ENCODE(GSSAPIContextToken, + output_token->value, output_token->length, + &ct, &size, ret); + der_free_oid(&ct.thisMech); + if (ret) { + output_token->length = 0; + output_token->value = NULL; + return GSS_S_FAILURE; + } + if (output_token->length != size) + abort(); + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c new file mode 100644 index 0000000000..bc1c39c8ee --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_export_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_export_name.c,v 1.3 2006/07/05 22:41:57 lha Exp $"); + +OM_uint32 +gss_export_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name) +{ + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mechanism_name *mn; + + exported_name->value = NULL; + exported_name->length = 0; + + /* + * If this name already has any attached MNs, export the first + * one, otherwise export based on the first mechanism in our + * list. + */ + mn = SLIST_FIRST(&name->gn_mn); + if (!mn) { + *minor_status = 0; + return (GSS_S_NAME_NOT_MN); + } + + return mn->gmn_mech->gm_export_name(minor_status, + mn->gmn_name, exported_name); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c new file mode 100644 index 0000000000..1acc72b33d --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_export_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_export_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_export_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t interprocess_token) +{ + OM_uint32 major_status; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + gssapi_mech_interface m = ctx->gc_mech; + gss_buffer_desc buf; + + major_status = m->gm_export_sec_context(minor_status, + &ctx->gc_ctx, &buf); + + if (major_status == GSS_S_COMPLETE) { + unsigned char *p; + + free(ctx); + *context_handle = GSS_C_NO_CONTEXT; + interprocess_token->length = buf.length + + 2 + m->gm_mech_oid.length; + interprocess_token->value = malloc(interprocess_token->length); + if (!interprocess_token->value) { + /* + * We are in trouble here - the context is + * already gone. This is allowed as long as we + * set the caller's context_handle to + * GSS_C_NO_CONTEXT, which we did above. + * Return GSS_S_FAILURE. + */ + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + p = interprocess_token->value; + p[0] = m->gm_mech_oid.length >> 8; + p[1] = m->gm_mech_oid.length; + memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length); + memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length); + gss_release_buffer(minor_status, &buf); + } + + return (major_status); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c new file mode 100644 index 0000000000..e9a8f294a4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_get_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_get_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_get_mic(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + gss_qop_t qop_req, + const gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req, + message_buffer, message_token)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c new file mode 100644 index 0000000000..9684301ba4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c @@ -0,0 +1,214 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_import_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_import_name.c,v 1.3 2006/06/29 21:23:13 lha Exp $"); + +static OM_uint32 +_gss_import_export_name(OM_uint32 *minor_status, + const gss_buffer_t input_name_buffer, + gss_name_t *output_name) +{ + OM_uint32 major_status; + unsigned char *p = input_name_buffer->value; + size_t len = input_name_buffer->length; + size_t t; + gss_OID_desc mech_oid; + gssapi_mech_interface m; + struct _gss_name *name; + gss_name_t new_canonical_name; + + *minor_status = 0; + *output_name = 0; + + /* + * Make sure that TOK_ID is {4, 1}. + */ + if (len < 2) + return (GSS_S_BAD_NAME); + if (p[0] != 4 || p[1] != 1) + return (GSS_S_BAD_NAME); + p += 2; + len -= 2; + + /* + * Get the mech length and the name length and sanity + * check the size of of the buffer. + */ + if (len < 2) + return (GSS_S_BAD_NAME); + t = (p[0] << 8) + p[1]; + p += 2; + len -= 2; + + /* + * Check the DER encoded OID to make sure it agrees with the + * length we just decoded. + */ + if (p[0] != 6) /* 6=OID */ + return (GSS_S_BAD_NAME); + p++; + len--; + t--; + if (p[0] & 0x80) { + int digits = p[0]; + p++; + len--; + t--; + mech_oid.length = 0; + while (digits--) { + mech_oid.length = (mech_oid.length << 8) | p[0]; + p++; + len--; + t--; + } + } else { + mech_oid.length = p[0]; + p++; + len--; + t--; + } + if (mech_oid.length != t) + return (GSS_S_BAD_NAME); + + mech_oid.elements = p; + + if (len < t + 4) + return (GSS_S_BAD_NAME); + p += t; + len -= t; + + t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + p += 4; + len -= 4; + + if (len != t) + return (GSS_S_BAD_NAME); + + m = __gss_get_mechanism(&mech_oid); + if (!m) + return (GSS_S_BAD_MECH); + + /* + * Ask the mechanism to import the name. + */ + major_status = m->gm_import_name(minor_status, + input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name); + + /* + * Now we make a new name and mark it as an MN. + */ + name = _gss_make_name(m, new_canonical_name); + if (!name) { + m->gm_release_name(minor_status, &new_canonical_name); + return (GSS_S_FAILURE); + } + + *output_name = (gss_name_t) name; + + *minor_status = 0; + return (GSS_S_COMPLETE); +} + +OM_uint32 +gss_import_name(OM_uint32 *minor_status, + const gss_buffer_t input_name_buffer, + const gss_OID input_name_type, + gss_name_t *output_name) +{ + gss_OID name_type = input_name_type; + OM_uint32 major_status; + struct _gss_name *name; + + if (input_name_buffer->length == 0) { + *minor_status = 0; + *output_name = 0; + return (GSS_S_BAD_NAME); + } + + /* + * Use GSS_NT_USER_NAME as default name type. + */ + if (name_type == GSS_C_NO_OID) + name_type = GSS_C_NT_USER_NAME; + + /* + * If this is an exported name, we need to parse it to find + * the mechanism and then import it as an MN. See RFC 2743 + * section 3.2 for a description of the format. + */ + if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) { + return _gss_import_export_name(minor_status, + input_name_buffer, output_name); + } + + /* + * Only allow certain name types. This is pretty bogus - we + * should figure out the list of supported name types using + * gss_inquire_names_for_mech. + */ + if (!gss_oid_equal(name_type, GSS_C_NT_USER_NAME) + && !gss_oid_equal(name_type, GSS_C_NT_MACHINE_UID_NAME) + && !gss_oid_equal(name_type, GSS_C_NT_STRING_UID_NAME) + && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE_X) + && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE) + && !gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS) + && !gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) { + *minor_status = 0; + *output_name = 0; + return (GSS_S_BAD_NAMETYPE); + } + + *minor_status = 0; + name = malloc(sizeof(struct _gss_name)); + if (!name) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(name, 0, sizeof(struct _gss_name)); + + major_status = _gss_copy_oid(minor_status, + name_type, &name->gn_type); + if (major_status) { + free(name); + return (GSS_S_FAILURE); + } + + major_status = _gss_copy_buffer(minor_status, + input_name_buffer, &name->gn_value); + if (major_status) { + gss_name_t rname = (gss_name_t)name; + gss_release_name(minor_status, &rname); + return (GSS_S_FAILURE); + } + + SLIST_INIT(&name->gn_mn); + + *output_name = (gss_name_t) name; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c new file mode 100644 index 0000000000..5466f97cf4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_import_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_import_sec_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_import_sec_context(OM_uint32 *minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_context *ctx; + gss_OID_desc mech_oid; + gss_buffer_desc buf; + unsigned char *p; + size_t len; + + *minor_status = 0; + *context_handle = 0; + + /* + * We added an oid to the front of the token in + * gss_export_sec_context. + */ + p = interprocess_token->value; + len = interprocess_token->length; + if (len < 2) + return (GSS_S_DEFECTIVE_TOKEN); + mech_oid.length = (p[0] << 8) | p[1]; + if (len < mech_oid.length + 2) + return (GSS_S_DEFECTIVE_TOKEN); + mech_oid.elements = p + 2; + buf.length = len - 2 - mech_oid.length; + buf.value = p + 2 + mech_oid.length; + + m = __gss_get_mechanism(&mech_oid); + if (!m) + return (GSS_S_DEFECTIVE_TOKEN); + + ctx = malloc(sizeof(struct _gss_context)); + if (!ctx) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + ctx->gc_mech = m; + major_status = m->gm_import_sec_context(minor_status, + &buf, &ctx->gc_ctx); + if (major_status != GSS_S_COMPLETE) { + free(ctx); + } else { + *context_handle = (gss_ctx_id_t) ctx; + } + + return (major_status); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c new file mode 100644 index 0000000000..0da6c48834 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_indicate_mechs.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_indicate_mechs.c,v 1.3 2006/07/05 22:36:49 lha Exp $"); + +OM_uint32 +gss_indicate_mechs(OM_uint32 *minor_status, + gss_OID_set *mech_set) +{ + struct _gss_mech_switch *m; + OM_uint32 major_status; + gss_OID_set set; + int i; + + _gss_load_mech(); + + major_status = gss_create_empty_oid_set(minor_status, mech_set); + if (major_status) + return (major_status); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_indicate_mechs) { + major_status = m->gm_mech.gm_indicate_mechs( + minor_status, &set); + if (major_status) + continue; + for (i = 0; i < set->count; i++) + major_status = gss_add_oid_set_member( + minor_status, &set->elements[i], mech_set); + gss_release_oid_set(minor_status, &set); + } else { + major_status = gss_add_oid_set_member( + minor_status, &m->gm_mech_oid, mech_set); + } + } + + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c new file mode 100644 index 0000000000..ccaf91ba9d --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_init_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_init_sec_context.c,v 1.3 2006/07/06 22:30:09 lha Exp $"); + +OM_uint32 +gss_init_sec_context(OM_uint32 * minor_status, + const gss_cred_id_t initiator_cred_handle, + gss_ctx_id_t * context_handle, + const gss_name_t target_name, + const gss_OID input_mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_name *name = (struct _gss_name *) target_name; + struct _gss_mechanism_name *mn; + struct _gss_context *ctx = (struct _gss_context *) *context_handle; + struct _gss_cred *cred = (struct _gss_cred *) initiator_cred_handle; + struct _gss_mechanism_cred *mc; + gss_cred_id_t cred_handle; + int allocated_ctx; + gss_OID mech_type = input_mech_type; + + *minor_status = 0; + + /* + * If we haven't allocated a context yet, do so now and lookup + * the mechanism switch table. If we have one already, make + * sure we use the same mechanism switch as before. + */ + if (!ctx) { + if (mech_type == NULL) + mech_type = GSS_KRB5_MECHANISM; + + ctx = malloc(sizeof(struct _gss_context)); + if (!ctx) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(ctx, 0, sizeof(struct _gss_context)); + m = ctx->gc_mech = __gss_get_mechanism(mech_type); + if (!m) { + free(ctx); + return (GSS_S_BAD_MECH); + } + allocated_ctx = 1; + } else { + m = ctx->gc_mech; + mech_type = &ctx->gc_mech->gm_mech_oid; + allocated_ctx = 0; + } + + /* + * Find the MN for this mechanism. + */ + mn = _gss_find_mn(name, mech_type); + if (mn == NULL) { + if (allocated_ctx) + free(ctx); + return GSS_S_BAD_NAME; + } + + /* + * If we have a cred, find the cred for this mechanism. + */ + cred_handle = GSS_C_NO_CREDENTIAL; + if (cred) { + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (gss_oid_equal(mech_type, mc->gmc_mech_oid)) { + cred_handle = mc->gmc_cred; + break; + } + } + } + + major_status = m->gm_init_sec_context(minor_status, + cred_handle, + &ctx->gc_ctx, + mn->gmn_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + + if (major_status != GSS_S_COMPLETE + && major_status != GSS_S_CONTINUE_NEEDED) { + if (allocated_ctx) + free(ctx); + } else { + *context_handle = (gss_ctx_id_t) ctx; + } + + return (major_status); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c new file mode 100644 index 0000000000..88bbb3941f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_context.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_inquire_context(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + gss_name_t *src_name, + gss_name_t *targ_name, + OM_uint32 *lifetime_rec, + gss_OID *mech_type, + OM_uint32 *ctx_flags, + int *locally_initiated, + int *open) +{ + OM_uint32 major_status; + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + struct _gss_name *name; + gss_name_t src_mn, targ_mn; + + major_status = m->gm_inquire_context(minor_status, + ctx->gc_ctx, + src_name ? &src_mn : 0, + targ_name ? &targ_mn : 0, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open); + + if (src_name) *src_name = 0; + if (targ_name) *targ_name = 0; + + if (major_status != GSS_S_COMPLETE) { + return (major_status); + } + + if (src_name) { + name = _gss_make_name(m, src_mn); + if (!name) { + minor_status = 0; + return (GSS_S_FAILURE); + } + *src_name = (gss_name_t) name; + } + + if (targ_name) { + name = _gss_make_name(m, targ_mn); + if (!name) { + minor_status = 0; + return (GSS_S_FAILURE); + } + *targ_name = (gss_name_t) name; + } + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c new file mode 100644 index 0000000000..223140205d --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_cred.c,v 1.5 2006/07/20 02:03:18 lha Exp $"); + +OM_uint32 +gss_inquire_cred(OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + gss_name_t *name_ret, + OM_uint32 *lifetime, + gss_cred_usage_t *cred_usage, + gss_OID_set *mechanisms) +{ + OM_uint32 major_status; + struct _gss_mech_switch *m; + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + struct _gss_name *name; + struct _gss_mechanism_name *mn; + OM_uint32 min_lifetime; + int found = 0; + + _gss_load_mech(); + + *minor_status = 0; + if (name_ret) + *name_ret = 0; + if (lifetime) + *lifetime = 0; + if (cred_usage) + *cred_usage = 0; + + if (name_ret) { + name = malloc(sizeof(struct _gss_name)); + if (!name) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + memset(name, 0, sizeof(struct _gss_name)); + SLIST_INIT(&name->gn_mn); + } else { + name = 0; + } + + if (mechanisms) { + major_status = gss_create_empty_oid_set(minor_status, + mechanisms); + if (major_status) { + if (name) free(name); + return (major_status); + } + } + + min_lifetime = GSS_C_INDEFINITE; + if (cred) { + struct _gss_mechanism_cred *mc; + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + gss_name_t mc_name; + OM_uint32 mc_lifetime; + + major_status = mc->gmc_mech->gm_inquire_cred(minor_status, + mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL); + if (major_status) + continue; + + if (name) { + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + mc->gmc_mech->gm_release_name(minor_status, + &mc_name); + continue; + } + mn->gmn_mech = mc->gmc_mech; + mn->gmn_mech_oid = mc->gmc_mech_oid; + mn->gmn_name = mc_name; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); + } else { + mc->gmc_mech->gm_release_name(minor_status, + &mc_name); + } + + if (mc_lifetime < min_lifetime) + min_lifetime = mc_lifetime; + + if (mechanisms) + gss_add_oid_set_member(minor_status, + mc->gmc_mech_oid, mechanisms); + found++; + } + } else { + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + gss_name_t mc_name; + OM_uint32 mc_lifetime; + + major_status = m->gm_mech.gm_inquire_cred(minor_status, + GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime, + cred_usage, NULL); + if (major_status) + continue; + + if (name && mc_name) { + mn = malloc( + sizeof(struct _gss_mechanism_name)); + if (!mn) { + m->gm_mech.gm_release_name( + minor_status, &mc_name); + continue; + } + mn->gmn_mech = &m->gm_mech; + mn->gmn_mech_oid = &m->gm_mech_oid; + mn->gmn_name = mc_name; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); + } else if (mc_name) { + m->gm_mech.gm_release_name(minor_status, + &mc_name); + } + + if (mc_lifetime < min_lifetime) + min_lifetime = mc_lifetime; + + if (mechanisms) + gss_add_oid_set_member(minor_status, + &m->gm_mech_oid, mechanisms); + found++; + } + } + + if (found == 0) { + gss_release_oid_set(minor_status, mechanisms); + *minor_status = 0; + return (GSS_S_NO_CRED); + } + + *minor_status = 0; + if (name_ret) + *name_ret = (gss_name_t) name; + if (lifetime) + *lifetime = min_lifetime; + if (cred && cred_usage) + *cred_usage = cred->gc_usage; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c new file mode 100644 index 0000000000..771a6956a5 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_cred_by_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_cred_by_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_inquire_cred_by_mech(OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + const gss_OID mech_type, + gss_name_t *cred_name, + OM_uint32 *initiator_lifetime, + OM_uint32 *acceptor_lifetime, + gss_cred_usage_t *cred_usage) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + struct _gss_mechanism_cred *mcp; + gss_cred_id_t mc; + gss_name_t mn; + struct _gss_name *name; + + *minor_status = 0; + + m = __gss_get_mechanism(mech_type); + if (!m) + return (GSS_S_NO_CRED); + + if (cred_handle != GSS_C_NO_CREDENTIAL) { + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + SLIST_FOREACH(mcp, &cred->gc_mc, gmc_link) + if (mcp->gmc_mech == m) + break; + if (!mcp) + return (GSS_S_NO_CRED); + mc = mcp->gmc_cred; + } else { + mc = GSS_C_NO_CREDENTIAL; + } + + major_status = m->gm_inquire_cred_by_mech(minor_status, mc, mech_type, + &mn, initiator_lifetime, acceptor_lifetime, cred_usage); + if (major_status != GSS_S_COMPLETE) + return (major_status); + + name = _gss_make_name(m, mn); + if (!name) { + m->gm_release_name(minor_status, &mn); + return (GSS_S_NO_CRED); + } + + *cred_name = (gss_name_t) name; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c new file mode 100644 index 0000000000..3cfe89af21 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_cred_by_oid.c,v 1.2 2006/06/28 16:20:41 lha Exp $"); + +OM_uint32 +gss_inquire_cred_by_oid (OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + struct _gss_cred *cred = (struct _gss_cred *) cred_handle; + OM_uint32 status = GSS_S_COMPLETE; + struct _gss_mechanism_cred *mc; + gssapi_mech_interface m; + gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; + + *minor_status = 0; + + if (cred == NULL) + return GSS_S_NO_CRED; + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + gss_buffer_set_t rset = GSS_C_NO_BUFFER_SET; + int i; + + m = mc->gmc_mech; + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_inquire_cred_by_oid == NULL) + continue; + + status = m->gm_inquire_cred_by_oid(minor_status, + mc->gmc_cred, desired_object, &rset); + if (status != GSS_S_COMPLETE) + continue; + + for (i = 0; i < rset->count; i++) { + status = gss_add_buffer_set_member(minor_status, + &rset->elements[i], &set); + if (status != GSS_S_COMPLETE) + break; + } + gss_release_buffer_set(minor_status, &rset); + } + if (set == GSS_C_NO_BUFFER_SET) + status = GSS_S_FAILURE; + *data_set = set; + return status; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c new file mode 100644 index 0000000000..7052bf8b72 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_mechs_for_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_mechs_for_name.c,v 1.3 2006/07/20 02:04:00 lha Exp $"); + +OM_uint32 +gss_inquire_mechs_for_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_OID_set *mech_types) +{ + OM_uint32 major_status; + struct _gss_name *name = (struct _gss_name *) input_name; + struct _gss_mech_switch *m; + gss_OID_set name_types; + int present; + + *minor_status = 0; + + _gss_load_mech(); + + major_status = gss_create_empty_oid_set(minor_status, mech_types); + if (major_status) + return (major_status); + + /* + * We go through all the loaded mechanisms and see if this + * name's type is supported by the mechanism. If it is, add + * the mechanism to the set. + */ + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + major_status = gss_inquire_names_for_mech(minor_status, + &m->gm_mech_oid, &name_types); + if (major_status) { + gss_release_oid_set(minor_status, mech_types); + return (major_status); + } + gss_test_oid_set_member(minor_status, + &name->gn_type, name_types, &present); + gss_release_oid_set(minor_status, &name_types); + if (present) { + major_status = gss_add_oid_set_member(minor_status, + &m->gm_mech_oid, mech_types); + if (major_status) { + gss_release_oid_set(minor_status, mech_types); + return (major_status); + } + } + } + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c new file mode 100644 index 0000000000..2293163b03 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_inquire_names_for_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_names_for_mech.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_inquire_names_for_mech(OM_uint32 *minor_status, + const gss_OID mechanism, + gss_OID_set *name_types) +{ + OM_uint32 major_status; + gssapi_mech_interface m = __gss_get_mechanism(mechanism); + + *minor_status = 0; + if (!m) + return (GSS_S_BAD_MECH); + + /* + * If the implementation can do it, ask it for a list of + * names, otherwise fake it. + */ + if (m->gm_inquire_names_for_mech) { + return (m->gm_inquire_names_for_mech(minor_status, + mechanism, name_types)); + } else { + major_status = gss_create_empty_oid_set(minor_status, + name_types); + if (major_status) + return (major_status); + major_status = gss_add_oid_set_member(minor_status, + GSS_C_NT_HOSTBASED_SERVICE, name_types); + if (major_status) { + OM_uint32 ms; + gss_release_oid_set(&ms, name_types); + return (major_status); + } + major_status = gss_add_oid_set_member(minor_status, + GSS_C_NT_USER_NAME, name_types); + if (major_status) { + OM_uint32 ms; + gss_release_oid_set(&ms, name_types); + return (major_status); + } + } + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c new file mode 100644 index 0000000000..7f5632ac55 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_inquire_sec_context_by_oid.c,v 1.1 2006/06/28 09:07:08 lha Exp $"); + +OM_uint32 +gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + OM_uint32 major_status; + gssapi_mech_interface m; + + *minor_status = 0; + + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + m = ctx->gc_mech; + + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_inquire_sec_context_by_oid != NULL) + major_status = m->gm_inquire_sec_context_by_oid(minor_status, + ctx->gc_ctx, desired_object, data_set); + else + major_status = GSS_S_BAD_MECH; + + return major_status; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c new file mode 100644 index 0000000000..c6ea3cecb7 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -0,0 +1,710 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_krb5.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +#include "krb5/gsskrb5_locl.h" +RCSID("$Id: gss_krb5.c,v 1.13 2006/10/20 22:05:02 lha Exp $"); + +#include <krb5.h> +#include <roken.h> + + +OM_uint32 +gss_krb5_copy_ccache(OM_uint32 *minor_status, + gss_cred_id_t cred, + krb5_ccache out) +{ + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + krb5_context context; + krb5_error_code kret; + krb5_ccache id; + OM_uint32 ret; + char *str; + + ret = gss_inquire_cred_by_oid(minor_status, + cred, + GSS_KRB5_COPY_CCACHE_X, + &data_set); + if (ret) + return ret; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + kret = krb5_init_context(&context); + if (kret) { + *minor_status = kret; + gss_release_buffer_set(minor_status, &data_set); + return GSS_S_FAILURE; + } + + kret = asprintf(&str, "%.*s", (int)data_set->elements[0].length, + (char *)data_set->elements[0].value); + gss_release_buffer_set(minor_status, &data_set); + if (kret == -1) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + kret = krb5_cc_resolve(context, str, &id); + free(str); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } + + kret = krb5_cc_copy_cache(context, id, out); + krb5_cc_close(context, id); + krb5_free_context(context); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } + + return ret; +} + +OM_uint32 +gss_krb5_import_cred(OM_uint32 *minor_status, + krb5_ccache id, + krb5_principal keytab_principal, + krb5_keytab keytab, + gss_cred_id_t *cred) +{ + gss_buffer_desc buffer; + OM_uint32 major_status; + krb5_context context; + krb5_error_code ret; + krb5_storage *sp; + krb5_data data; + char *str; + + *cred = GSS_C_NO_CREDENTIAL; + + ret = krb5_init_context(&context); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto out; + } + + if (id) { + ret = krb5_cc_get_full_name(context, id, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + ret = krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + if (keytab_principal) { + ret = krb5_unparse_name(context, keytab_principal, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + + if (keytab) { + ret = krb5_kt_get_full_name(context, keytab, &str); + if (ret == 0) { + ret = krb5_store_string(sp, str); + free(str); + } + } else + krb5_store_string(sp, ""); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto out; + } + + krb5_storage_to_data(sp, &data); + + buffer.value = data.data; + buffer.length = data.length; + + major_status = gss_set_cred_option(minor_status, + cred, + GSS_KRB5_IMPORT_CRED_X, + &buffer); + krb5_data_free(&data); +out: + if (sp) + krb5_storage_free(sp); + krb5_free_context(context); + return major_status; +} + +OM_uint32 +gsskrb5_register_acceptor_identity(const char *identity) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + buffer.value = rk_UNCONST(identity); + buffer.length = strlen(identity); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +OM_uint32 +gsskrb5_set_dns_canonicalize(int flag) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + char b = (flag != 0); + + _gss_load_mech(); + + buffer.value = &b; + buffer.length = sizeof(b); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SET_DNS_CANONICALIZE_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + + + +static krb5_error_code +set_key(krb5_keyblock *keyblock, gss_krb5_lucid_key_t *key) +{ + key->type = keyblock->keytype; + key->length = keyblock->keyvalue.length; + key->data = malloc(key->length); + if (key->data == NULL && key->length != 0) + return ENOMEM; + memcpy(key->data, keyblock->keyvalue.data, key->length); + return 0; +} + +static void +free_key(gss_krb5_lucid_key_t *key) +{ + memset(key->data, 0, key->length); + free(key->data); + memset(key, 0, sizeof(*key)); +} + + +OM_uint32 +gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + OM_uint32 version, + void **rctx) +{ + krb5_context context = NULL; + krb5_error_code ret; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 major_status; + gss_krb5_lucid_context_v1_t *ctx = NULL; + krb5_storage *sp = NULL; + uint32_t num; + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT || version != 1) { + ret = EINVAL; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + *context_handle, + GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = krb5_init_context(&context); + if (ret) + goto out; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + ret = ENOMEM; + goto out; + } + + sp = krb5_storage_from_mem(data_set->elements[0].value, + data_set->elements[0].length); + if (sp == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + if (num != 1) { + ret = EINVAL; + goto out; + } + ctx->version = 1; + /* initiator */ + ret = krb5_ret_uint32(sp, &ctx->initiate); + if (ret) goto out; + /* endtime */ + ret = krb5_ret_uint32(sp, &ctx->endtime); + if (ret) goto out; + /* send_seq */ + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->send_seq = ((uint64_t)num) << 32; + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->send_seq |= num; + /* recv_seq */ + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->recv_seq = ((uint64_t)num) << 32; + ret = krb5_ret_uint32(sp, &num); + if (ret) goto out; + ctx->recv_seq |= num; + /* protocol */ + ret = krb5_ret_uint32(sp, &ctx->protocol); + if (ret) goto out; + if (ctx->protocol == 0) { + krb5_keyblock key; + + /* sign_alg */ + ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.sign_alg); + if (ret) goto out; + /* seal_alg */ + ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.seal_alg); + if (ret) goto out; + /* ctx_key */ + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->rfc1964_kd.ctx_key); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + } else if (ctx->protocol == 1) { + krb5_keyblock key; + + /* acceptor_subkey */ + ret = krb5_ret_uint32(sp, &ctx->cfx_kd.have_acceptor_subkey); + if (ret) goto out; + /* ctx_key */ + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->cfx_kd.ctx_key); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + /* acceptor_subkey */ + if (ctx->cfx_kd.have_acceptor_subkey) { + ret = krb5_ret_keyblock(sp, &key); + if (ret) goto out; + ret = set_key(&key, &ctx->cfx_kd.acceptor_subkey); + krb5_free_keyblock_contents(context, &key); + if (ret) goto out; + } + } else { + ret = EINVAL; + goto out; + } + + *rctx = ctx; + +out: + gss_release_buffer_set(minor_status, &data_set); + if (sp) + krb5_storage_free(sp); + if (context) + krb5_free_context(context); + + if (ret) { + if (ctx) + gss_krb5_free_lucid_sec_context(NULL, ctx); + + *minor_status = ret; + return GSS_S_FAILURE; + } + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) +{ + gss_krb5_lucid_context_v1_t *ctx = c; + + if (ctx->version != 1) { + if (minor_status) + *minor_status = 0; + return GSS_S_FAILURE; + } + + if (ctx->protocol == 0) { + free_key(&ctx->rfc1964_kd.ctx_key); + } else if (ctx->protocol == 1) { + free_key(&ctx->cfx_kd.ctx_key); + if (ctx->cfx_kd.have_acceptor_subkey) + free_key(&ctx->cfx_kd.acceptor_subkey); + } + free(ctx); + if (minor_status) + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c) +{ + struct _gss_mech_switch *m; + gss_buffer_desc buffer; + OM_uint32 junk; + + _gss_load_mech(); + + if (c) { + buffer.value = c; + buffer.length = sizeof(*c); + } else { + buffer.value = NULL; + buffer.length = 0; + } + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_sec_context_option == NULL) + continue; + m->gm_mech.gm_set_sec_context_option(&junk, NULL, + GSS_KRB5_SEND_TO_KDC_X, &buffer); + } + + return (GSS_S_COMPLETE); +} + +OM_uint32 +gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + time_t *authtime) +{ + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 maj_stat; + krb5_error_code ret; + OM_uint32 time32; + + if (context_handle == GSS_C_NO_CONTEXT) { + _gsskrb5_set_status("no context handle"); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + maj_stat = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + GSS_KRB5_GET_AUTHTIME_X, + &data_set); + if (maj_stat) + return maj_stat; + + if (data_set == GSS_C_NO_BUFFER_SET) { + _gsskrb5_set_status("no buffers returned"); + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (data_set->count != 1) { + _gsskrb5_set_status("%d != 1 buffers returned", data_set->count); + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (data_set->elements[0].length != 4) { + gss_release_buffer_set(minor_status, &data_set); + _gsskrb5_set_status("Error extracting authtime from security context: only got %d < 4 bytes", + data_set->elements[0].length); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = _gsskrb5_decode_om_uint32(data_set->elements[0].value, &time32); + if (ret) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = ret; + return GSS_S_FAILURE; + } + *authtime = time32; + + gss_release_buffer_set(minor_status, &data_set); + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int ad_type, + gss_buffer_t ad_data) +{ + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 maj_stat; + gss_OID_desc authz_oid_flat; + heim_oid authz_oid; + heim_oid new_authz_oid; + size_t size; + + if (context_handle == GSS_C_NO_CONTEXT) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + /* All this to append an integer to an oid... */ + + if (der_get_oid(GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->elements, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->length, + &authz_oid, NULL) != 0) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + new_authz_oid.length = authz_oid.length + 1; + new_authz_oid.components = malloc(new_authz_oid.length * sizeof(*new_authz_oid.components)); + if (!new_authz_oid.components) { + free(authz_oid.components); + + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(new_authz_oid.components, authz_oid.components, + authz_oid.length * sizeof(*authz_oid.components)); + + free(authz_oid.components); + + new_authz_oid.components[new_authz_oid.length - 1] = ad_type; + + authz_oid_flat.length = der_length_oid(&new_authz_oid); + authz_oid_flat.elements = malloc(authz_oid_flat.length); + + if (!authz_oid_flat.elements) { + free(new_authz_oid.components); + + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + if (der_put_oid((unsigned char *)authz_oid_flat.elements + authz_oid_flat.length - 1, + authz_oid_flat.length, + &new_authz_oid, &size) != 0) { + free(new_authz_oid.components); + + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + free(new_authz_oid.components); + + /* FINALLY, we have the OID */ + + maj_stat = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + &authz_oid_flat, + &data_set); + + free(authz_oid_flat.elements); + + if (maj_stat) + return maj_stat; + + if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ad_data->value = malloc(data_set->elements[0].length); + if (ad_data->value == NULL) { + gss_release_buffer_set(minor_status, &data_set); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ad_data->length = data_set->elements[0].length; + memcpy(ad_data->value, data_set->elements[0].value, ad_data->length); + gss_release_buffer_set(minor_status, &data_set); + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +static OM_uint32 +gsskrb5_extract_key(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + const gss_OID oid, + krb5_keyblock **keyblock) +{ + krb5_error_code ret; + gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; + OM_uint32 major_status; + krb5_storage *sp = NULL; + + ret = _gsskrb5_init(); + if(ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + if (context_handle == GSS_C_NO_CONTEXT) { + _gsskrb5_set_status("no context handle"); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + major_status = + gss_inquire_sec_context_by_oid (minor_status, + context_handle, + oid, + &data_set); + if (major_status) + return major_status; + + if (data_set == GSS_C_NO_BUFFER_SET) { + _gsskrb5_set_status("no buffers returned"); + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (data_set->count != 1) { + _gsskrb5_set_status("%d != 1 buffers returned", data_set->count); + gss_release_buffer_set(minor_status, &data_set); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_mem(data_set->elements[0].value, + data_set->elements[0].length); + if (sp == NULL) { + ret = ENOMEM; + goto out; + } + + *keyblock = calloc(1, sizeof(**keyblock)); + if (keyblock == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_ret_keyblock(sp, *keyblock); + +out: + gss_release_buffer_set(minor_status, &data_set); + if (sp) + krb5_storage_free(sp); + if (ret) { + _gsskrb5_set_error_string(); + if (keyblock) { + krb5_free_keyblock(_gsskrb5_context, *keyblock); + } + + *minor_status = ret; + return GSS_S_FAILURE; + } + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gsskrb5_extract_service_keyblock(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_SERVICE_KEYBLOCK_X, + keyblock); +} + +OM_uint32 +gsskrb5_get_initiator_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_INITIATOR_SUBKEY_X, + keyblock); +} + +OM_uint32 +gsskrb5_get_subkey(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + krb5_keyblock **keyblock) +{ + return gsskrb5_extract_key(minor_status, + context_handle, + GSS_KRB5_GET_ACCEPTOR_SUBKEY_X, + keyblock); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c new file mode 100644 index 0000000000..3d01ba69d4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -0,0 +1,324 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_mech_switch.c,v 1.2 2006/02/04 09:40:21 dfr Exp $ + */ + +#include "mech_locl.h" +#include <heim_threads.h> +RCSID("$Id: gss_mech_switch.c,v 1.7 2006/10/09 11:13:30 lha Exp $"); + +#ifndef _PATH_GSS_MECH +#define _PATH_GSS_MECH "/etc/gss/mech" +#endif + +struct _gss_mech_switch_list _gss_mechs = { NULL } ; +gss_OID_set _gss_mech_oids; +static HEIMDAL_MUTEX _gss_mech_mutex = HEIMDAL_MUTEX_INITIALIZER; + +/* + * Convert a string containing an OID in 'dot' form + * (e.g. 1.2.840.113554.1.2.2) to a gss_OID. + */ +static int +_gss_string_to_oid(const char* s, gss_OID oid) +{ + int number_count, i, j; + int byte_count; + const char *p, *q; + char *res; + + /* + * First figure out how many numbers in the oid, then + * calculate the compiled oid size. + */ + number_count = 0; + for (p = s; p; p = q) { + q = strchr(p, '.'); + if (q) q = q + 1; + number_count++; + } + + /* + * The first two numbers are in the first byte and each + * subsequent number is encoded in a variable byte sequence. + */ + if (number_count < 2) + return (EINVAL); + + /* + * We do this in two passes. The first pass, we just figure + * out the size. Second time around, we actually encode the + * number. + */ + res = 0; + for (i = 0; i < 2; i++) { + byte_count = 0; + for (p = s, j = 0; p; p = q, j++) { + unsigned int number = 0; + + /* + * Find the end of this number. + */ + q = strchr(p, '.'); + if (q) q = q + 1; + + /* + * Read the number of of the string. Don't + * bother with anything except base ten. + */ + while (*p && *p != '.') { + number = 10 * number + (*p - '0'); + p++; + } + + /* + * Encode the number. The first two numbers + * are packed into the first byte. Subsequent + * numbers are encoded in bytes seven bits at + * a time with the last byte having the high + * bit set. + */ + if (j == 0) { + if (res) + *res = number * 40; + } else if (j == 1) { + if (res) { + *res += number; + res++; + } + byte_count++; + } else if (j >= 2) { + /* + * The number is encoded in seven bit chunks. + */ + unsigned int t; + int bytes; + + bytes = 0; + for (t = number; t; t >>= 7) + bytes++; + if (bytes == 0) bytes = 1; + while (bytes) { + if (res) { + int bit = 7*(bytes-1); + + *res = (number >> bit) & 0x7f; + if (bytes != 1) + *res |= 0x80; + res++; + } + byte_count++; + bytes--; + } + } + } + if (!res) { + res = malloc(byte_count); + if (!res) + return (ENOMEM); + oid->length = byte_count; + oid->elements = res; + } + } + + return (0); +} + +#define SYM(name) \ +do { \ + m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \ + if (!m->gm_mech.gm_ ## name) { \ + fprintf(stderr, "can't find symbol gss_" #name "\n"); \ + goto bad; \ + } \ +} while (0) + +#define OPTSYM(name) \ +do { \ + m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \ +} while (0) + +/* + * + */ +static int +add_builtin(gssapi_mech_interface mech) +{ + struct _gss_mech_switch *m; + OM_uint32 minor_status; + + m = malloc(sizeof(*m)); + if (m == NULL) + return 1; + m->gm_so = NULL; + m->gm_mech = *mech; + m->gm_mech_oid = mech->gm_mech_oid; /* XXX */ + gss_add_oid_set_member(&minor_status, + &m->gm_mech.gm_mech_oid, &_gss_mech_oids); + + SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); + return 0; +} + +/* + * Load the mechanisms file (/etc/gss/mech). + */ +void +_gss_load_mech(void) +{ + OM_uint32 major_status, minor_status; + FILE *fp; + char buf[256]; + char *p; + char *name, *oid, *lib, *kobj; + struct _gss_mech_switch *m; + void *so; + + + HEIMDAL_MUTEX_lock(&_gss_mech_mutex); + + if (SLIST_FIRST(&_gss_mechs)) { + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); + return; + } + + major_status = gss_create_empty_oid_set(&minor_status, + &_gss_mech_oids); + if (major_status) { + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); + return; + } + + add_builtin(__gss_krb5_initialize()); + add_builtin(__gss_spnego_initialize()); + + fp = fopen(_PATH_GSS_MECH, "r"); + if (!fp) { +/* perror(_PATH_GSS_MECH); */ + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); + return; + } + + while (fgets(buf, sizeof(buf), fp)) { + if (*buf == '#') + continue; + p = buf; + name = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + oid = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + lib = strsep(&p, "\t\n "); + if (p) while (isspace((unsigned char)*p)) p++; + kobj = strsep(&p, "\t\n "); + if (!name || !oid || !lib || !kobj) + continue; + +#ifndef RTLD_LOCAL +#define RTLD_LOCAL 0 +#endif + + so = dlopen(lib, RTLD_LOCAL); + if (!so) { +/* fprintf(stderr, "dlopen: %s\n", dlerror()); */ + continue; + } + + m = malloc(sizeof(*m)); + if (!m) + break; + m->gm_so = so; + if (_gss_string_to_oid(oid, &m->gm_mech.gm_mech_oid)) { + free(m); + continue; + } + + major_status = gss_add_oid_set_member(&minor_status, + &m->gm_mech.gm_mech_oid, &_gss_mech_oids); + if (major_status) { + free(m->gm_mech.gm_mech_oid.elements); + free(m); + continue; + } + + SYM(acquire_cred); + SYM(release_cred); + SYM(init_sec_context); + SYM(accept_sec_context); + SYM(process_context_token); + SYM(delete_sec_context); + SYM(context_time); + SYM(get_mic); + SYM(verify_mic); + SYM(wrap); + SYM(unwrap); + SYM(display_status); + SYM(indicate_mechs); + SYM(compare_name); + SYM(display_name); + SYM(import_name); + SYM(export_name); + SYM(release_name); + SYM(inquire_cred); + SYM(inquire_context); + SYM(wrap_size_limit); + SYM(add_cred); + SYM(inquire_cred_by_mech); + SYM(export_sec_context); + SYM(import_sec_context); + SYM(inquire_names_for_mech); + SYM(inquire_mechs_for_name); + SYM(canonicalize_name); + SYM(duplicate_name); + OPTSYM(inquire_cred_by_oid); + OPTSYM(inquire_sec_context_by_oid); + OPTSYM(set_sec_context_option); + OPTSYM(set_cred_option); + + SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); + continue; + + bad: + free(m->gm_mech.gm_mech_oid.elements); + free(m); + dlclose(so); + continue; + } + fclose(fp); + HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); +} + +gssapi_mech_interface +__gss_get_mechanism(gss_OID mech) +{ + struct _gss_mech_switch *m; + + _gss_load_mech(); + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech)) + return &m->gm_mech; + } + return NULL; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_names.c b/source4/heimdal/lib/gssapi/mech/gss_names.c new file mode 100644 index 0000000000..833c582006 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_names.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_names.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_names.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +struct _gss_mechanism_name * +_gss_find_mn(struct _gss_name *name, gss_OID mech) +{ + OM_uint32 major_status, minor_status; + gssapi_mech_interface m; + struct _gss_mechanism_name *mn; + + SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { + if (gss_oid_equal(mech, mn->gmn_mech_oid)) + break; + } + + if (!mn) { + /* + * If this name is canonical (i.e. there is only an + * MN but it is from a different mech), give up now. + */ + if (!name->gn_value.value) + return (0); + + m = __gss_get_mechanism(mech); + if (!m) + return (0); + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) + return (0); + + major_status = m->gm_import_name(&minor_status, + &name->gn_value, + (name->gn_type.elements + ? &name->gn_type : GSS_C_NO_OID), + &mn->gmn_name); + if (major_status) { + free(mn); + return (0); + } + + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); + } + return (mn); +} + +/* + * Make a name from an MN. + */ +struct _gss_name * +_gss_make_name(gssapi_mech_interface m, gss_name_t new_mn) +{ + struct _gss_name *name; + struct _gss_mechanism_name *mn; + + name = malloc(sizeof(struct _gss_name)); + if (!name) + return (0); + memset(name, 0, sizeof(struct _gss_name)); + + mn = malloc(sizeof(struct _gss_mechanism_name)); + if (!mn) { + free(name); + return (0); + } + + SLIST_INIT(&name->gn_mn); + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; + mn->gmn_name = new_mn; + SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); + + return (name); +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c new file mode 100644 index 0000000000..1a8b811f37 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_oid_equal.c,v 1.1 2006/06/28 09:07:08 lha Exp $"); + +int +gss_oid_equal(const gss_OID a, const gss_OID b) +{ + if (a == b) + return 1; + if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length) + return 0; + return memcmp(a->elements, b->elements, a->length) == 0; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c new file mode 100644 index 0000000000..1e6f39979f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_process_context_token.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_process_context_token.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_process_context_token(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t token_buffer) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_process_context_token(minor_status, ctx->gc_ctx, + token_buffer)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c new file mode 100644 index 0000000000..66705bb40e --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_buffer.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_release_buffer.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + + *minor_status = 0; + if (buffer->value) + free(buffer->value); + buffer->length = 0; + buffer->value = 0; + + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c new file mode 100644 index 0000000000..760621c861 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_release_cred.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) +{ + struct _gss_cred *cred = (struct _gss_cred *) *cred_handle; + struct _gss_mechanism_cred *mc; + + if (*cred_handle == GSS_C_NO_CREDENTIAL) + return (GSS_S_COMPLETE); + + while (SLIST_FIRST(&cred->gc_mc)) { + mc = SLIST_FIRST(&cred->gc_mc); + SLIST_REMOVE_HEAD(&cred->gc_mc, gmc_link); + mc->gmc_mech->gm_release_cred(minor_status, &mc->gmc_cred); + free(mc); + } + free(cred); + + *minor_status = 0; + *cred_handle = 0; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c new file mode 100644 index 0000000000..1286cd3b79 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_release_name.c,v 1.3 2006/10/22 07:59:06 lha Exp $"); + +OM_uint32 +gss_release_name(OM_uint32 *minor_status, + gss_name_t *input_name) +{ + struct _gss_name *name = (struct _gss_name *) *input_name; + + *minor_status = 0; + if (name) { + if (name->gn_type.elements) + free(name->gn_type.elements); + while (SLIST_FIRST(&name->gn_mn)) { + struct _gss_mechanism_name *mn; + mn = SLIST_FIRST(&name->gn_mn); + SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link); + mn->gmn_mech->gm_release_name(minor_status, + &mn->gmn_name); + free(mn); + } + gss_release_buffer(minor_status, &name->gn_value); + free(name); + *input_name = GSS_C_NO_NAME; + } + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c new file mode 100644 index 0000000000..fc84fabd29 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +RCSID("$Id: gss_release_oid.c,v 1.1 2006/06/30 09:34:54 lha Exp $"); + +OM_uint32 +gss_release_oid(OM_uint32 *minor_status, gss_OID *oid) +{ + gss_OID o = *oid; + + *oid = GSS_C_NO_OID; + + if (minor_status != NULL) + *minor_status = 0; + + if (o == GSS_C_NO_OID) + return GSS_S_COMPLETE; + + if (o->elements != NULL) { + free(o->elements); + o->elements = NULL; + } + o->length = 0; + free(o); + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c new file mode 100644 index 0000000000..101657e4fb --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_release_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_release_oid_set.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_release_oid_set(OM_uint32 *minor_status, + gss_OID_set *set) +{ + + *minor_status = 0; + if (*set) { + if ((*set)->elements) + free((*set)->elements); + free(*set); + *set = 0; + } + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c new file mode 100644 index 0000000000..2f66f90d4f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_seal.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_seal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_seal.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_seal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + + return (gss_wrap(minor_status, + context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, + output_message_buffer)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c new file mode 100644 index 0000000000..f8e013da18 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_set_cred_option.c,v 1.7 2006/07/01 08:50:49 lha Exp $"); + +OM_uint32 +gss_set_cred_option (OM_uint32 *minor_status, + gss_cred_id_t *cred_handle, + const gss_OID object, + const gss_buffer_t value) +{ + struct _gss_cred *cred = (struct _gss_cred *) *cred_handle; + OM_uint32 major_status = GSS_S_COMPLETE; + struct _gss_mechanism_cred *mc; + int one_ok = 0; + + *minor_status = 0; + + _gss_load_mech(); + + if (cred == NULL) { + struct _gss_mech_switch *m; + + cred = malloc(sizeof(*cred)); + if (cred == NULL) + return GSS_S_FAILURE; + + cred->gc_usage = GSS_C_BOTH; /* XXX */ + SLIST_INIT(&cred->gc_mc); + + SLIST_FOREACH(m, &_gss_mechs, gm_link) { + + if (m->gm_mech.gm_set_cred_option == NULL) + continue; + + mc = malloc(sizeof(*mc)); + if (mc == NULL) { + /* XXX free the other mc's */ + return GSS_S_FAILURE; + } + + mc->gmc_mech = &m->gm_mech; + mc->gmc_mech_oid = &m->gm_mech_oid; + mc->gmc_cred = GSS_C_NO_CREDENTIAL; + + major_status = m->gm_mech.gm_set_cred_option( + minor_status, &mc->gmc_cred, object, value); + + if (major_status) { + free(mc); + continue; + } + one_ok = 1; + SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); + } + *cred_handle = (gss_cred_id_t)cred; + if (!one_ok) { + OM_uint32 junk; + gss_release_cred(&junk, cred_handle); + } + } else { + gssapi_mech_interface m; + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + m = mc->gmc_mech; + + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_set_cred_option == NULL) + continue; + + major_status = m->gm_set_cred_option(minor_status, + &mc->gmc_cred, object, value); + if (major_status == GSS_S_BAD_MECH) + one_ok = 1; + } + } + if (one_ok) { + *minor_status = 0; + return GSS_S_COMPLETE; + } + return major_status; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c new file mode 100644 index 0000000000..aa562a23b6 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" +RCSID("$Id: gss_set_sec_context_option.c,v 1.2 2006/06/28 14:39:00 lha Exp $"); + +OM_uint32 +gss_set_sec_context_option (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + const gss_OID object, + const gss_buffer_t value) +{ + struct _gss_context *ctx; + OM_uint32 major_status; + gssapi_mech_interface m; + + *minor_status = 0; + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + ctx = (struct _gss_context *) *context_handle; + + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + + m = ctx->gc_mech; + + if (m == NULL) + return GSS_S_BAD_MECH; + + if (m->gm_set_sec_context_option != NULL) + major_status = m->gm_set_sec_context_option(minor_status, + &ctx->gc_ctx, object, value); + else + major_status = GSS_S_BAD_MECH; + + return major_status; +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c new file mode 100644 index 0000000000..8c854e5e43 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_sign.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_sign.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_sign.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_sign(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + int qop_req, + gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + + return gss_get_mic(minor_status, + context_handle, qop_req, message_buffer, message_token); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c new file mode 100644 index 0000000000..a71a8b7c92 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_test_oid_set_member.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_test_oid_set_member.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_test_oid_set_member(OM_uint32 *minor_status, + const gss_OID member, + const gss_OID_set set, + int *present) +{ + int i; + + *present = 0; + for (i = 0; i < set->count; i++) + if (gss_oid_equal(member, &set->elements[i])) + *present = 1; + + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c new file mode 100644 index 0000000000..128dc7883c --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_unseal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_unseal.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_unseal(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + int *qop_state) +{ + + return (gss_unwrap(minor_status, + context_handle, input_message_buffer, + output_message_buffer, conf_state, (gss_qop_t *)qop_state)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c new file mode 100644 index 0000000000..1c9484b18d --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_unwrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_unwrap.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_unwrap(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + gss_qop_t *qop_state) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_unwrap(minor_status, ctx->gc_ctx, + input_message_buffer, output_message_buffer, + conf_state, qop_state)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_utils.c b/source4/heimdal/lib/gssapi/mech/gss_utils.c new file mode 100644 index 0000000000..33ee033209 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_utils.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_utils.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_utils.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +_gss_copy_oid(OM_uint32 *minor_status, + const gss_OID from_oid, gss_OID to_oid) +{ + size_t len = from_oid->length; + + *minor_status = 0; + to_oid->elements = malloc(len); + if (!to_oid->elements) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + to_oid->length = len; + memcpy(to_oid->elements, from_oid->elements, len); + return (GSS_S_COMPLETE); +} + + +OM_uint32 +_gss_copy_buffer(OM_uint32 *minor_status, + const gss_buffer_t from_buf, gss_buffer_t to_buf) +{ + size_t len = from_buf->length; + + *minor_status = 0; + to_buf->value = malloc(len); + if (!to_buf->value) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + to_buf->length = len; + memcpy(to_buf->value, from_buf->value, len); + return (GSS_S_COMPLETE); +} + diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c new file mode 100644 index 0000000000..a99d17e2d7 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_verify.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_verify.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_verify.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_verify(OM_uint32 *minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t message_buffer, + gss_buffer_t token_buffer, + int *qop_state) +{ + + return (gss_verify_mic(minor_status, + context_handle, message_buffer, token_buffer, + (gss_qop_t *)qop_state)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c new file mode 100644 index 0000000000..b51ed7a8c4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_verify_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_verify_mic.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); + +OM_uint32 +gss_verify_mic(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t message_buffer, + const gss_buffer_t token_buffer, + gss_qop_t *qop_state) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_verify_mic(minor_status, ctx->gc_ctx, + message_buffer, token_buffer, qop_state)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c new file mode 100644 index 0000000000..a97ec1308f --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_wrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_wrap.c,v 1.2 2006/06/28 09:00:26 lha Exp $"); + +OM_uint32 +gss_wrap(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + const gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_wrap(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, input_message_buffer, + conf_state, output_message_buffer)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c new file mode 100644 index 0000000000..27493aa90d --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/gss_wrap_size_limit.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" +RCSID("$Id: gss_wrap_size_limit.c,v 1.2 2006/06/28 09:00:26 lha Exp $"); + +OM_uint32 +gss_wrap_size_limit(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) +{ + struct _gss_context *ctx = (struct _gss_context *) context_handle; + gssapi_mech_interface m = ctx->gc_mech; + + return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx, + conf_req_flag, qop_req, req_output_size, max_input_size)); +} diff --git a/source4/heimdal/lib/gssapi/mech/gssapi.asn1 b/source4/heimdal/lib/gssapi/mech/gssapi.asn1 new file mode 100644 index 0000000000..544618b7d4 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gssapi.asn1 @@ -0,0 +1,12 @@ +-- $Id: gssapi.asn1,v 1.3 2006/10/18 21:08:19 lha Exp $ + +GSS-API DEFINITIONS ::= BEGIN + +IMPORTS heim_any_set FROM heim; + +GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE { + thisMech OBJECT IDENTIFIER, + innerContextToken heim_any_set +} + +END
\ No newline at end of file diff --git a/source4/heimdal/lib/gssapi/mech/mech_locl.h b/source4/heimdal/lib/gssapi/mech/mech_locl.h new file mode 100644 index 0000000000..f5db15c5fa --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/mech_locl.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: mech_locl.h,v 1.4 2006/10/07 18:25:27 lha Exp $ */ + +#include <config.h> + +#include <krb5-types.h> + +#include <sys/types.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <dlfcn.h> +#include <errno.h> + +#include <gssapi_asn1.h> +#include <der.h> + +#include <roken.h> + +#include <gssapi.h> +#include <gssapi_mech.h> + +#include "mechqueue.h" + +#include "context.h" +#include "cred.h" +#include "mech_switch.h" +#include "name.h" +#include "utils.h" diff --git a/source4/heimdal/lib/gssapi/mech/mech_switch.h b/source4/heimdal/lib/gssapi/mech/mech_switch.h new file mode 100644 index 0000000000..0984d36ef3 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/mech_switch.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id: mech_switch.h,v 1.3 2006/10/05 18:31:53 lha Exp $ + */ + +#include <gssapi_mech.h> + +struct _gss_mech_switch { + SLIST_ENTRY(_gss_mech_switch) gm_link; + gss_OID_desc gm_mech_oid; + void *gm_so; + gssapi_mech_interface_desc gm_mech; +}; +SLIST_HEAD(_gss_mech_switch_list, _gss_mech_switch); +extern struct _gss_mech_switch_list _gss_mechs; +extern gss_OID_set _gss_mech_oids; + +void _gss_load_mech(void); diff --git a/source4/heimdal/lib/gssapi/mech/mechqueue.h b/source4/heimdal/lib/gssapi/mech/mechqueue.h new file mode 100644 index 0000000000..8434b76c00 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/mechqueue.h @@ -0,0 +1,101 @@ +/* $NetBSD: queue.h,v 1.39 2004/04/18 14:25:34 lukem Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _MECHQUEUE_H_ +#define _MECHQUEUE_H_ + +#ifndef SLIST_HEAD + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) do { \ + (head)->slh_first = NULL; \ +} while (/*CONSTCOND*/0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (/*CONSTCOND*/0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while(curelm->field.sle_next != (elm)) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +/* + * Singly-linked List access methods. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#endif /* SLIST_HEAD */ + +#endif /* !_MECHQUEUE_H_ */ diff --git a/source4/heimdal/lib/gssapi/mech/name.h b/source4/heimdal/lib/gssapi/mech/name.h new file mode 100644 index 0000000000..3e7443ba20 --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/name.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/name.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id: name.h,v 1.4 2006/10/05 18:36:07 lha Exp $ + */ + +struct _gss_mechanism_name { + SLIST_ENTRY(_gss_mechanism_name) gmn_link; + gssapi_mech_interface gmn_mech; /* mechanism ops for MN */ + gss_OID gmn_mech_oid; /* mechanism oid for MN */ + gss_name_t gmn_name; /* underlying MN */ +}; +SLIST_HEAD(_gss_mechanism_name_list, _gss_mechanism_name); + +struct _gss_name { + gss_OID_desc gn_type; /* type of name */ + gss_buffer_desc gn_value; /* value (as imported) */ + struct _gss_mechanism_name_list gn_mn; /* list of MNs */ +}; + +struct _gss_mechanism_name * + _gss_find_mn(struct _gss_name *name, gss_OID mech); +struct _gss_name * + _gss_make_name(gssapi_mech_interface m, gss_name_t new_mn); diff --git a/source4/heimdal/lib/gssapi/mech/utils.h b/source4/heimdal/lib/gssapi/mech/utils.h new file mode 100644 index 0000000000..75a507298c --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/utils.h @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libgssapi/utils.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ + * $Id: utils.h,v 1.3 2006/07/20 01:48:25 lha Exp $ + */ + +OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID); +OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status, + const gss_buffer_t from_buf, gss_buffer_t to_buf); diff --git a/source4/heimdal/lib/gssapi/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego.asn1 deleted file mode 100755 index 5dc767cf76..0000000000 --- a/source4/heimdal/lib/gssapi/spnego.asn1 +++ /dev/null @@ -1,42 +0,0 @@ --- $Id: spnego.asn1,v 1.4 2004/03/07 13:38:08 lha Exp $ - -SPNEGO DEFINITIONS ::= -BEGIN - -MechType::= OBJECT IDENTIFIER - -MechTypeList ::= SEQUENCE OF MechType - -ContextFlags ::= BIT STRING { - delegFlag (0), - mutualFlag (1), - replayFlag (2), - sequenceFlag (3), - anonFlag (4), - confFlag (5), - integFlag (6) -} - -NegTokenInit ::= SEQUENCE { - mechTypes [0] MechTypeList OPTIONAL, - reqFlags [1] ContextFlags OPTIONAL, - mechToken [2] OCTET STRING OPTIONAL, - mechListMIC [3] OCTET STRING OPTIONAL - } - -NegTokenTarg ::= SEQUENCE { - negResult [0] ENUMERATED { - accept_completed (0), - accept_incomplete (1), - reject (2) } OPTIONAL, - supportedMech [1] MechType OPTIONAL, - responseToken [2] OCTET STRING OPTIONAL, - mechListMIC [3] OCTET STRING OPTIONAL -} - -NegotiationToken ::= CHOICE { - negTokenInit[0] NegTokenInit, - negTokenTarg[1] NegTokenTarg -} - -END diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c new file mode 100644 index 0000000000..8a885a3e2f --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -0,0 +1,873 @@ +/* + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * Portions Copyright (c) 2004 PADL Software Pty Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" + +RCSID("$Id: accept_sec_context.c,v 1.6 2006/10/07 22:26:57 lha Exp $"); + +OM_uint32 +_gss_spnego_encode_response(OM_uint32 *minor_status, + const NegTokenResp *resp, + gss_buffer_t data, + u_char **ret_buf) +{ + OM_uint32 ret; + u_char *buf; + size_t buf_size, buf_len; + + buf_size = 1024; + buf = malloc(buf_size); + if (buf == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + do { + ret = encode_NegTokenResp(buf + buf_size - 1, + buf_size, + resp, &buf_len); + if (ret == 0) { + size_t tmp; + + ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, + buf_size - buf_len, + buf_len, + ASN1_C_CONTEXT, + CONS, + 1, + &tmp); + if (ret == 0) + buf_len += tmp; + } + if (ret) { + if (ret == ASN1_OVERFLOW) { + u_char *tmp; + + buf_size *= 2; + tmp = realloc (buf, buf_size); + if (tmp == NULL) { + *minor_status = ENOMEM; + free(buf); + return GSS_S_FAILURE; + } + buf = tmp; + } else { + *minor_status = ret; + free(buf); + return GSS_S_FAILURE; + } + } + } while (ret == ASN1_OVERFLOW); + + data->value = buf + buf_size - buf_len; + data->length = buf_len; + *ret_buf = buf; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +send_reject (OM_uint32 *minor_status, + gss_buffer_t output_token) +{ + NegTokenResp resp; + gss_buffer_desc data; + u_char *buf; + OM_uint32 ret; + + ALLOC(resp.negResult, 1); + if (resp.negResult == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + *(resp.negResult) = reject; + resp.supportedMech = NULL; + resp.responseToken = NULL; + resp.mechListMIC = NULL; + + ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf); + free_NegTokenResp(&resp); + if (ret != GSS_S_COMPLETE) + return ret; + + output_token->value = malloc(data.length); + if (output_token->value == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + } else { + output_token->length = data.length; + memcpy(output_token->value, data.value, output_token->length); + } + free(buf); + if (ret != GSS_S_COMPLETE) + return ret; + return GSS_S_BAD_MECH; +} + +OM_uint32 +_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status, + int includeMSCompatOID, + const gssspnego_cred cred_handle, + MechTypeList *mechtypelist, + gss_OID *preferred_mech) +{ + OM_uint32 ret; + gss_OID_set supported_mechs = GSS_C_NO_OID_SET; + int i, count; + + if (cred_handle != NULL) { + ret = gss_inquire_cred(minor_status, + cred_handle->negotiated_cred_id, + NULL, + NULL, + NULL, + &supported_mechs); + } else { + ret = gss_indicate_mechs(minor_status, &supported_mechs); + } + + if (ret != GSS_S_COMPLETE) { + return ret; + } + + if (supported_mechs->count == 0) { + *minor_status = ENOENT; + gss_release_oid_set(minor_status, &supported_mechs); + return GSS_S_FAILURE; + } + + count = supported_mechs->count; + if (includeMSCompatOID) + count++; + + mechtypelist->len = 0; + mechtypelist->val = calloc(count, sizeof(MechType)); + if (mechtypelist->val == NULL) { + *minor_status = ENOMEM; + gss_release_oid_set(minor_status, &supported_mechs); + return GSS_S_FAILURE; + } + + for (i = 0; i < supported_mechs->count; i++) { + ret = _gss_spnego_add_mech_type(&supported_mechs->elements[i], + includeMSCompatOID, + mechtypelist); + if (ret != 0) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + break; + } + } + + if (ret == GSS_S_COMPLETE && preferred_mech != NULL) { + ret = gss_duplicate_oid(minor_status, + &supported_mechs->elements[0], + preferred_mech); + } + + if (ret != GSS_S_COMPLETE) { + free_MechTypeList(mechtypelist); + mechtypelist->len = 0; + mechtypelist->val = NULL; + } + gss_release_oid_set(minor_status, &supported_mechs); + + return ret; +} + +static OM_uint32 +send_supported_mechs (OM_uint32 *minor_status, + gss_buffer_t output_token) +{ + NegTokenInit ni; + char hostname[MAXHOSTNAMELEN], *p; + gss_buffer_desc name_buf; + gss_OID name_type; + gss_name_t target_princ; + gss_name_t canon_princ; + OM_uint32 ret, minor; + u_char *buf; + size_t buf_size, buf_len; + gss_buffer_desc data; + + memset(&ni, 0, sizeof(ni)); + + ni.reqFlags = NULL; + ni.mechToken = NULL; + ni.negHints = NULL; + ni.mechListMIC = NULL; + + ret = _gss_spnego_indicate_mechtypelist(minor_status, 1, + NULL, + &ni.mechTypes, NULL); + if (ret != GSS_S_COMPLETE) { + return ret; + } + + memset(&target_princ, 0, sizeof(target_princ)); + if (gethostname(hostname, sizeof(hostname) - 1) != 0) { + *minor_status = errno; + free_NegTokenInit(&ni); + return GSS_S_FAILURE; + } + + /* Send the constructed SAM name for this host */ + for (p = hostname; *p != '\0' && *p != '.'; p++) { + *p = toupper((unsigned char)*p); + } + *p++ = '$'; + *p = '\0'; + + name_buf.length = strlen(hostname); + name_buf.value = hostname; + + ret = gss_import_name(minor_status, &name_buf, + GSS_C_NO_OID, + &target_princ); + if (ret != GSS_S_COMPLETE) { + return ret; + } + + name_buf.length = 0; + name_buf.value = NULL; + + /* Canonicalize the name using the preferred mechanism */ + ret = gss_canonicalize_name(minor_status, + target_princ, + GSS_C_NO_OID, + &canon_princ); + if (ret != GSS_S_COMPLETE) { + gss_release_name(&minor, &target_princ); + return ret; + } + + ret = gss_display_name(minor_status, canon_princ, + &name_buf, &name_type); + if (ret != GSS_S_COMPLETE) { + gss_release_name(&minor, &canon_princ); + gss_release_name(&minor, &target_princ); + return ret; + } + + gss_release_name(&minor, &canon_princ); + gss_release_name(&minor, &target_princ); + + ALLOC(ni.negHints, 1); + if (ni.negHints == NULL) { + *minor_status = ENOMEM; + gss_release_buffer(&minor, &name_buf); + free_NegTokenInit(&ni); + return GSS_S_FAILURE; + } + + ALLOC(ni.negHints->hintName, 1); + if (ni.negHints->hintName == NULL) { + *minor_status = ENOMEM; + gss_release_buffer(&minor, &name_buf); + free_NegTokenInit(&ni); + return GSS_S_FAILURE; + } + + *(ni.negHints->hintName) = name_buf.value; + name_buf.value = NULL; + ni.negHints->hintAddress = NULL; + + buf_size = 1024; + buf = malloc(buf_size); + if (buf == NULL) { + free_NegTokenInit(&ni); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + do { + ret = encode_NegTokenInit(buf + buf_size - 1, + buf_size, + &ni, &buf_len); + if (ret == 0) { + size_t tmp; + + ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, + buf_size - buf_len, + buf_len, + ASN1_C_CONTEXT, + CONS, + 0, + &tmp); + if (ret == 0) + buf_len += tmp; + } + if (ret) { + if (ret == ASN1_OVERFLOW) { + u_char *tmp; + + buf_size *= 2; + tmp = realloc (buf, buf_size); + if (tmp == NULL) { + *minor_status = ENOMEM; + free(buf); + free_NegTokenInit(&ni); + return GSS_S_FAILURE; + } + buf = tmp; + } else { + *minor_status = ret; + free(buf); + free_NegTokenInit(&ni); + return GSS_S_FAILURE; + } + } + } while (ret == ASN1_OVERFLOW); + + data.value = buf + buf_size - buf_len; + data.length = buf_len; + + ret = gss_encapsulate_token(&data, + GSS_SPNEGO_MECHANISM, + output_token); + free (buf); + free_NegTokenInit (&ni); + + if (ret != GSS_S_COMPLETE) + return ret; + + *minor_status = 0; + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 +send_accept (OM_uint32 *minor_status, + gssspnego_ctx context_handle, + gss_buffer_t mech_token, + int initial_response, + gss_buffer_t mech_buf, + gss_buffer_t output_token) +{ + NegTokenResp resp; + gss_buffer_desc data; + u_char *buf; + OM_uint32 ret; + gss_buffer_desc mech_mic_buf; + + memset(&resp, 0, sizeof(resp)); + + ALLOC(resp.negResult, 1); + if (resp.negResult == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + if (context_handle->open) { + if (mech_token != GSS_C_NO_BUFFER + && mech_token->length != 0 + && mech_buf != GSS_C_NO_BUFFER) + *(resp.negResult) = accept_incomplete; + else + *(resp.negResult) = accept_completed; + } else { + if (initial_response && context_handle->require_mic) + *(resp.negResult) = request_mic; + else + *(resp.negResult) = accept_incomplete; + } + + if (initial_response) { + ALLOC(resp.supportedMech, 1); + if (resp.supportedMech == NULL) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = der_get_oid(context_handle->preferred_mech_type->elements, + context_handle->preferred_mech_type->length, + resp.supportedMech, + NULL); + if (ret) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + } else { + resp.supportedMech = NULL; + } + + if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) { + ALLOC(resp.responseToken, 1); + if (resp.responseToken == NULL) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + resp.responseToken->length = mech_token->length; + resp.responseToken->data = mech_token->value; + mech_token->length = 0; + mech_token->value = NULL; + } else { + resp.responseToken = NULL; + } + + if (mech_buf != GSS_C_NO_BUFFER) { + ALLOC(resp.mechListMIC, 1); + if (resp.mechListMIC == NULL) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = gss_get_mic(minor_status, + context_handle->negotiated_ctx_id, + 0, + mech_buf, + &mech_mic_buf); + if (ret != GSS_S_COMPLETE) { + free_NegTokenResp(&resp); + return ret; + } + + resp.mechListMIC->length = mech_mic_buf.length; + resp.mechListMIC->data = mech_mic_buf.value; + } else + resp.mechListMIC = NULL; + + ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf); + if (ret != GSS_S_COMPLETE) { + free_NegTokenResp(&resp); + return ret; + } + + /* + * The response should not be encapsulated, because + * it is a SubsequentContextToken (note though RFC 1964 + * specifies encapsulation for all _Kerberos_ tokens). + */ + output_token->value = malloc(data.length); + if (output_token->value == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + } else { + output_token->length = data.length; + memcpy(output_token->value, data.value, output_token->length); + } + free(buf); + if (ret != GSS_S_COMPLETE) { + free_NegTokenResp(&resp); + return ret; + } + + ret = (*(resp.negResult) == accept_completed) ? GSS_S_COMPLETE : + GSS_S_CONTINUE_NEEDED; + free_NegTokenResp(&resp); + return ret; +} + + +static OM_uint32 +verify_mechlist_mic + (OM_uint32 *minor_status, + gssspnego_ctx context_handle, + gss_buffer_t mech_buf, + heim_octet_string *mechListMIC + ) +{ + OM_uint32 ret; + gss_buffer_desc mic_buf; + + if (context_handle->verified_mic) { + /* This doesn't make sense, we've already verified it? */ + *minor_status = 0; + return GSS_S_DUPLICATE_TOKEN; + } + + if (mechListMIC == NULL) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + + mic_buf.length = mechListMIC->length; + mic_buf.value = mechListMIC->data; + + ret = gss_verify_mic(minor_status, + context_handle->negotiated_ctx_id, + mech_buf, + &mic_buf, + NULL); + + if (ret != GSS_S_COMPLETE) + ret = GSS_S_DEFECTIVE_TOKEN; + + return ret; +} + +OM_uint32 +_gss_spnego_accept_sec_context + (OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t *delegated_cred_handle + ) +{ + OM_uint32 ret, ret2, minor; + NegTokenInit ni; + NegTokenResp na; + size_t ni_len, na_len; + int i; + gss_buffer_desc data; + size_t len, taglen; + int initialToken; + unsigned int negResult = accept_incomplete; + gss_buffer_t mech_input_token = GSS_C_NO_BUFFER; + gss_buffer_t mech_output_token = GSS_C_NO_BUFFER; + gss_buffer_desc mech_buf; + gss_OID preferred_mech_type = GSS_C_NO_OID; + gssspnego_ctx ctx; + gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle; + + *minor_status = 0; + + output_token->length = 0; + output_token->value = NULL; + + if (src_name != NULL) + *src_name = GSS_C_NO_NAME; + + if (mech_type != NULL) + *mech_type = GSS_C_NO_OID; + + if (ret_flags != NULL) + *ret_flags = 0; + + if (time_rec != NULL) + *time_rec = 0; + + if (delegated_cred_handle != NULL) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + + mech_buf.value = NULL; + + if (*context_handle == GSS_C_NO_CONTEXT) { + ret = _gss_spnego_alloc_sec_context(minor_status, + context_handle); + if (ret != GSS_S_COMPLETE) + return ret; + + if (input_token_buffer->length == 0) { + return send_supported_mechs (minor_status, + output_token); + } + } + + ctx = (gssspnego_ctx)*context_handle; + + /* + * The GSS-API encapsulation is only present on the initial + * context token (negTokenInit). + */ + ret = gss_decapsulate_token (input_token_buffer, + GSS_SPNEGO_MECHANISM, + &data); + initialToken = (ret == GSS_S_COMPLETE); + + if (!initialToken) { + data.value = input_token_buffer->value; + data.length = input_token_buffer->length; + } + + ret = der_match_tag_and_length(data.value, data.length, + ASN1_C_CONTEXT, CONS, + initialToken ? 0 : 1, + &len, &taglen); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + if (len > data.length - taglen) { + *minor_status = ASN1_OVERRUN; + return GSS_S_FAILURE; + } + + if (initialToken) { + ret = decode_NegTokenInit((const unsigned char *)data.value + taglen, + len, &ni, &ni_len); + } else { + ret = decode_NegTokenResp((const unsigned char *)data.value + taglen, + len, &na, &na_len); + } + if (ret) { + *minor_status = ret; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (!initialToken && na.negResult != NULL) { + negResult = *(na.negResult); + } + + if (negResult == reject || negResult == request_mic) { + /* request_mic should only be sent by acceptor */ + free_NegTokenResp(&na); + return GSS_S_DEFECTIVE_TOKEN; + } + + if (initialToken) { + for (i = 0; i < ni.mechTypes.len; ++i) { + /* Call glue layer to find first mech we support */ + ret = _gss_spnego_select_mech(minor_status, &ni.mechTypes.val[i], + &preferred_mech_type); + if (ret == 0) + break; + } + if (preferred_mech_type == GSS_C_NO_OID) { + free_NegTokenInit(&ni); + return GSS_S_BAD_MECH; + } + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (initialToken) { + ctx->preferred_mech_type = preferred_mech_type; + ctx->initiator_mech_types.len = ni.mechTypes.len; + ctx->initiator_mech_types.val = ni.mechTypes.val; + ni.mechTypes.len = 0; + ni.mechTypes.val = NULL; + } + + { + gss_buffer_desc ibuf, obuf; + int require_mic, verify_mic, get_mic; + int require_response; + heim_octet_string *mic; + + if (initialToken) { + if (ni.mechToken != NULL) { + ibuf.length = ni.mechToken->length; + ibuf.value = ni.mechToken->data; + mech_input_token = &ibuf; + } + } else { + if (na.responseToken != NULL) { + ibuf.length = na.responseToken->length; + ibuf.value = na.responseToken->data; + mech_input_token = &ibuf; + } + } + + if (mech_input_token != GSS_C_NO_BUFFER) { + gss_cred_id_t mech_cred; + gss_cred_id_t mech_delegated_cred; + gss_cred_id_t *mech_delegated_cred_p; + + if (acceptor_cred != NULL) + mech_cred = acceptor_cred->negotiated_cred_id; + else + mech_cred = GSS_C_NO_CREDENTIAL; + + if (delegated_cred_handle != NULL) { + mech_delegated_cred = GSS_C_NO_CREDENTIAL; + mech_delegated_cred_p = &mech_delegated_cred; + } else { + mech_delegated_cred_p = NULL; + } + + if (ctx->mech_src_name != GSS_C_NO_NAME) + gss_release_name(&minor, &ctx->mech_src_name); + + if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL) + _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); + + ret = gss_accept_sec_context(&minor, + &ctx->negotiated_ctx_id, + mech_cred, + mech_input_token, + input_chan_bindings, + &ctx->mech_src_name, + &ctx->negotiated_mech_type, + &obuf, + &ctx->mech_flags, + &ctx->mech_time_rec, + mech_delegated_cred_p); + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { + if (mech_delegated_cred_p != NULL && + mech_delegated_cred != GSS_C_NO_CREDENTIAL) { + ret2 = _gss_spnego_alloc_cred(minor_status, + mech_delegated_cred, + &ctx->delegated_cred_id); + if (ret2 != GSS_S_COMPLETE) + ret = ret2; + } + mech_output_token = &obuf; + } + if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { + if (initialToken) + free_NegTokenInit(&ni); + else + free_NegTokenResp(&na); + send_reject (minor_status, output_token); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; + } + if (ret == GSS_S_COMPLETE) + ctx->open = 1; + } else + ret = GSS_S_COMPLETE; + + ret2 = _gss_spnego_require_mechlist_mic(minor_status, + ctx, + &require_mic); + if (ret2) + goto out; + + ctx->require_mic = require_mic; + + mic = initialToken ? ni.mechListMIC : na.mechListMIC; + if (mic != NULL) + require_mic = 1; + + if (ctx->open && require_mic) { + if (mech_input_token == GSS_C_NO_BUFFER) { /* Even/One */ + verify_mic = 1; + get_mic = 0; + } else if (mech_output_token != GSS_C_NO_BUFFER && + mech_output_token->length == 0) { /* Odd */ + get_mic = verify_mic = 1; + } else { /* Even/One */ + verify_mic = 0; + get_mic = 1; + } + + if (verify_mic || get_mic) { + int eret; + size_t buf_len; + + ASN1_MALLOC_ENCODE(MechTypeList, + mech_buf.value, mech_buf.length, + &ctx->initiator_mech_types, &buf_len, eret); + if (eret) { + ret2 = GSS_S_FAILURE; + *minor_status = eret; + goto out; + } + if (mech_buf.length != buf_len) + abort(); + } + + if (verify_mic) { + ret2 = verify_mechlist_mic(minor_status, ctx, &mech_buf, mic); + if (ret2) { + if (get_mic) + send_reject (minor_status, output_token); + goto out; + } + + ctx->verified_mic = 1; + } + } else + verify_mic = get_mic = 0; + + if (ctx->mech_flags & GSS_C_DCE_STYLE) + require_response = (negResult != accept_completed); + else + require_response = 0; + + /* + * Check whether we need to send a result: there should be only + * one accept_completed response sent in the entire negotiation + */ + if ((mech_output_token != GSS_C_NO_BUFFER && + mech_output_token->length != 0) + || require_response + || get_mic) { + ret2 = send_accept (minor_status, + ctx, + mech_output_token, + initialToken, + get_mic ? &mech_buf : NULL, + output_token); + if (ret2) + goto out; + } + + out: + if (ret2 != GSS_S_COMPLETE) + ret = ret2; + if (mech_output_token != NULL) + gss_release_buffer(&minor, mech_output_token); + if (mech_buf.value != NULL) + free(mech_buf.value); + if (initialToken) + free_NegTokenInit(&ni); + else + free_NegTokenResp(&na); + } + + if (ret == GSS_S_COMPLETE) { + if (src_name != NULL) { + ret2 = gss_duplicate_name(minor_status, + ctx->mech_src_name, + src_name); + if (ret2 != GSS_S_COMPLETE) + ret = ret2; + } + if (delegated_cred_handle != NULL) { + *delegated_cred_handle = ctx->delegated_cred_id; + ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; + } + } + + if (mech_type != NULL) + *mech_type = ctx->negotiated_mech_type; + if (ret_flags != NULL) + *ret_flags = ctx->mech_flags; + if (time_rec != NULL) + *time_rec = ctx->mech_time_rec; + + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; + } + + _gss_spnego_internal_delete_sec_context(&minor, context_handle, + GSS_C_NO_BUFFER); + + return ret; +} + diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c new file mode 100644 index 0000000000..aeae088258 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/compat.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" + +RCSID("$Id: compat.c,v 1.6 2006/10/07 22:26:59 lha Exp $"); + +/* + * Apparently Microsoft got the OID wrong, and used + * 1.2.840.48018.1.2.2 instead. We need both this and + * the correct Kerberos OID here in order to deal with + * this. Because this is manifest in SPNEGO only I'd + * prefer to deal with this here rather than inside the + * Kerberos mechanism. + */ +static gss_OID_desc gss_mskrb_mechanism_oid_desc = + {9, (void *)"\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"}; + +static gss_OID_desc gss_krb5_mechanism_oid_desc = + {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; + +/* + * Allocate a SPNEGO context handle + */ +OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status, + gss_ctx_id_t *context_handle) +{ + gssspnego_ctx ctx; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ctx->initiator_mech_types.len = 0; + ctx->initiator_mech_types.val = NULL; + ctx->preferred_mech_type = GSS_C_NO_OID; + ctx->negotiated_mech_type = GSS_C_NO_OID; + ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT; + + /* + * Cache these so we can return them before returning + * GSS_S_COMPLETE, even if the mechanism has itself + * completed earlier + */ + ctx->mech_flags = 0; + ctx->mech_time_rec = 0; + ctx->mech_src_name = GSS_C_NO_NAME; + ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; + + ctx->open = 0; + ctx->local = 0; + ctx->require_mic = 0; + ctx->verified_mic = 0; + + HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); + + *context_handle = (gss_ctx_id_t)ctx; + + return GSS_S_COMPLETE; +} + +/* + * Free a SPNEGO context handle. The caller must have acquired + * the lock before this is called. + */ +OM_uint32 _gss_spnego_internal_delete_sec_context + (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token + ) +{ + gssspnego_ctx ctx; + OM_uint32 ret, minor; + + *minor_status = 0; + + if (context_handle == NULL) { + return GSS_S_NO_CONTEXT; + } + + if (output_token != GSS_C_NO_BUFFER) { + output_token->length = 0; + output_token->value = NULL; + } + + ctx = (gssspnego_ctx)*context_handle; + *context_handle = GSS_C_NO_CONTEXT; + + if (ctx == NULL) { + return GSS_S_NO_CONTEXT; + } + + if (ctx->initiator_mech_types.val != NULL) + free_MechTypeList(&ctx->initiator_mech_types); + + _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); + + gss_release_oid(&minor, &ctx->preferred_mech_type); + ctx->negotiated_mech_type = GSS_C_NO_OID; + + gss_release_name(&minor, &ctx->mech_src_name); + + if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) { + ret = gss_delete_sec_context(minor_status, + &ctx->negotiated_ctx_id, + output_token); + ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT; + } else { + ret = GSS_S_COMPLETE; + } + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); + + free(ctx); + *context_handle = NULL; + + return ret; +} + +/* + * For compatability with the Windows SPNEGO implementation, the + * default is to ignore the mechListMIC unless CFX is used and + * a non-preferred mechanism was negotiated + */ + +OM_uint32 +_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status, + gssspnego_ctx ctx, + int *require_mic) +{ + gss_buffer_set_t buffer_set = GSS_C_NO_BUFFER_SET; + OM_uint32 minor; + + *minor_status = 0; + *require_mic = 0; + + if (ctx == NULL) { + return GSS_S_COMPLETE; + } + + if (ctx->require_mic) { + /* Acceptor requested it: mandatory to honour */ + *require_mic = 1; + return GSS_S_COMPLETE; + } + + /* + * Check whether peer indicated implicit support for updated SPNEGO + * (eg. in the Kerberos case by using CFX) + */ + if (gss_inquire_sec_context_by_oid(&minor, ctx->negotiated_ctx_id, + GSS_C_PEER_HAS_UPDATED_SPNEGO, + &buffer_set) == GSS_S_COMPLETE) { + *require_mic = 1; + gss_release_buffer_set(&minor, &buffer_set); + } + + /* Safe-to-omit MIC rules follow */ + if (*require_mic) { + if (gss_oid_equal(ctx->negotiated_mech_type, ctx->preferred_mech_type)) { + *require_mic = 0; + } else if (gss_oid_equal(ctx->negotiated_mech_type, &gss_krb5_mechanism_oid_desc) && + gss_oid_equal(ctx->preferred_mech_type, &gss_mskrb_mechanism_oid_desc)) { + *require_mic = 0; + } + } + + return GSS_S_COMPLETE; +} + +int _gss_spnego_add_mech_type(gss_OID mech_type, + int includeMSCompatOID, + MechTypeList *mechtypelist) +{ + int ret; + + if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM)) + return 0; + + if (includeMSCompatOID && + gss_oid_equal(mech_type, &gss_krb5_mechanism_oid_desc)) { + ret = der_get_oid(gss_mskrb_mechanism_oid_desc.elements, + gss_mskrb_mechanism_oid_desc.length, + &mechtypelist->val[mechtypelist->len], + NULL); + if (ret) + return ret; + mechtypelist->len++; + } + ret = der_get_oid(mech_type->elements, + mech_type->length, + &mechtypelist->val[mechtypelist->len], + NULL); + if (ret) + return ret; + mechtypelist->len++; + + return 0; +} + +OM_uint32 +_gss_spnego_select_mech(OM_uint32 *minor_status, + MechType *mechType, + gss_OID *mech_p) +{ + char mechbuf[64]; + size_t mech_len; + gss_OID_desc oid; + OM_uint32 ret; + + ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1, + sizeof(mechbuf), + mechType, + &mech_len); + if (ret) { + return GSS_S_DEFECTIVE_TOKEN; + } + + oid.length = mech_len; + oid.elements = mechbuf + sizeof(mechbuf) - mech_len; + + if (gss_oid_equal(&oid, GSS_SPNEGO_MECHANISM)) { + return GSS_S_BAD_MECH; + } + + *minor_status = 0; + + /* Translate broken MS Kebreros OID */ + if (gss_oid_equal(&oid, &gss_mskrb_mechanism_oid_desc)) { + gssapi_mech_interface mech; + + mech = __gss_get_mechanism(&gss_krb5_mechanism_oid_desc); + if (mech == NULL) + return GSS_S_BAD_MECH; + + ret = gss_duplicate_oid(minor_status, + &gss_mskrb_mechanism_oid_desc, + mech_p); + } else { + gssapi_mech_interface mech; + + mech = __gss_get_mechanism(&oid); + if (mech == NULL) + return GSS_S_BAD_MECH; + + ret = gss_duplicate_oid(minor_status, + &mech->gm_mech_oid, + mech_p); + } + + return ret; +} + diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c new file mode 100644 index 0000000000..902ddbbdf9 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" + +RCSID("$Id: context_stubs.c,v 1.8 2006/10/07 22:27:01 lha Exp $"); + +static OM_uint32 +spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) +{ + OM_uint32 ret, junk; + gss_OID_set m; + int i; + + ret = gss_indicate_mechs(minor_status, &m); + if (ret != GSS_S_COMPLETE) + return ret; + + ret = gss_create_empty_oid_set(minor_status, mechs); + if (ret != GSS_S_COMPLETE) { + gss_release_oid_set(&junk, &m); + return ret; + } + + for (i = 0; i < m->count; i++) { + if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM)) + continue; + + ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs); + if (ret) { + gss_release_oid_set(&junk, &m); + gss_release_oid_set(&junk, mechs); + return ret; + } + } + return ret; +} + + + +OM_uint32 _gss_spnego_process_context_token + (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t token_buffer + ) +{ + gss_ctx_id_t context ; + gssspnego_ctx ctx; + OM_uint32 ret; + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + context = context_handle; + ctx = (gssspnego_ctx)context_handle; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + ret = gss_process_context_token(minor_status, + ctx->negotiated_ctx_id, + token_buffer); + if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; + } + + ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT; + + return _gss_spnego_internal_delete_sec_context(minor_status, + &context, + GSS_C_NO_BUFFER); +} + +OM_uint32 _gss_spnego_delete_sec_context + (OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token + ) +{ + gssspnego_ctx ctx; + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + ctx = (gssspnego_ctx)*context_handle; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + return _gss_spnego_internal_delete_sec_context(minor_status, + context_handle, + output_token); +} + +OM_uint32 _gss_spnego_context_time + (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + OM_uint32 *time_rec + ) +{ + gssspnego_ctx ctx; + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_context_time(minor_status, + ctx->negotiated_ctx_id, + time_rec); +} + +OM_uint32 _gss_spnego_get_mic + (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + gss_qop_t qop_req, + const gss_buffer_t message_buffer, + gss_buffer_t message_token + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_get_mic(minor_status, ctx->negotiated_ctx_id, + qop_req, message_buffer, message_token); +} + +OM_uint32 _gss_spnego_verify_mic + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t message_buffer, + const gss_buffer_t token_buffer, + gss_qop_t * qop_state + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_verify_mic(minor_status, + ctx->negotiated_ctx_id, + message_buffer, + token_buffer, + qop_state); +} + +OM_uint32 _gss_spnego_wrap + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + const gss_buffer_t input_message_buffer, + int * conf_state, + gss_buffer_t output_message_buffer + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_wrap(minor_status, + ctx->negotiated_ctx_id, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer); +} + +OM_uint32 _gss_spnego_unwrap + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int * conf_state, + gss_qop_t * qop_state + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_unwrap(minor_status, + ctx->negotiated_ctx_id, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state); +} + +OM_uint32 _gss_spnego_display_status + (OM_uint32 * minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 * message_context, + gss_buffer_t status_string + ) +{ + return GSS_S_FAILURE; +} + +OM_uint32 _gss_spnego_compare_name + (OM_uint32 *minor_status, + const gss_name_t name1, + const gss_name_t name2, + int * name_equal + ) +{ + return gss_compare_name(minor_status, name1, name2, name_equal); +} + +OM_uint32 _gss_spnego_display_name + (OM_uint32 * minor_status, + const gss_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID * output_name_type + ) +{ + return gss_display_name(minor_status, input_name, + output_name_buffer, output_name_type); +} + +OM_uint32 _gss_spnego_import_name + (OM_uint32 * minor_status, + const gss_buffer_t input_name_buffer, + const gss_OID input_name_type, + gss_name_t * output_name + ) +{ + return gss_import_name(minor_status, input_name_buffer, + input_name_type, output_name); +} + +OM_uint32 _gss_spnego_export_name + (OM_uint32 * minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name + ) +{ + return gss_export_name(minor_status, input_name, + exported_name); +} + +OM_uint32 _gss_spnego_release_name + (OM_uint32 * minor_status, + gss_name_t * input_name + ) +{ + return gss_release_name(minor_status, input_name); +} + +OM_uint32 _gss_spnego_inquire_context ( + OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + gss_name_t * src_name, + gss_name_t * targ_name, + OM_uint32 * lifetime_rec, + gss_OID * mech_type, + OM_uint32 * ctx_flags, + int * locally_initiated, + int * open_context + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_inquire_context(minor_status, + ctx->negotiated_ctx_id, + src_name, + targ_name, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open_context); +} + +OM_uint32 _gss_spnego_wrap_size_limit ( + OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 * max_input_size + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_wrap_size_limit(minor_status, + ctx->negotiated_ctx_id, + conf_req_flag, + qop_req, + req_output_size, + max_input_size); +} + +OM_uint32 _gss_spnego_export_sec_context ( + OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + gss_buffer_t interprocess_token + ) +{ + gssspnego_ctx ctx; + OM_uint32 ret; + + *minor_status = 0; + + if (context_handle == NULL) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)*context_handle; + + if (ctx == NULL) + return GSS_S_NO_CONTEXT; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_NO_CONTEXT; + } + + ret = gss_export_sec_context(minor_status, + &ctx->negotiated_ctx_id, + interprocess_token); + if (ret == GSS_S_COMPLETE) { + ret = _gss_spnego_internal_delete_sec_context(minor_status, + context_handle, + GSS_C_NO_BUFFER); + if (ret == GSS_S_COMPLETE) + return GSS_S_COMPLETE; + } + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + return ret; +} + +OM_uint32 _gss_spnego_import_sec_context ( + OM_uint32 * minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle + ) +{ + OM_uint32 ret, minor; + gss_ctx_id_t context; + gssspnego_ctx ctx; + + ret = _gss_spnego_alloc_sec_context(minor_status, &context); + if (ret != GSS_S_COMPLETE) { + return ret; + } + ctx = (gssspnego_ctx)context; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + ret = gss_import_sec_context(minor_status, + interprocess_token, + &ctx->negotiated_ctx_id); + if (ret != GSS_S_COMPLETE) { + _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER); + return ret; + } + + ctx->open = 1; + /* don't bother filling in the rest of the fields */ + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + *context_handle = (gss_ctx_id_t)ctx; + + return GSS_S_COMPLETE; +} + +OM_uint32 _gss_spnego_inquire_names_for_mech ( + OM_uint32 * minor_status, + const gss_OID mechanism, + gss_OID_set * name_types + ) +{ + gss_OID_set mechs, names, n; + OM_uint32 ret, junk; + int i, j; + + *name_types = NULL; + + ret = spnego_supported_mechs(minor_status, &mechs); + if (ret != GSS_S_COMPLETE) + return ret; + + ret = gss_create_empty_oid_set(minor_status, &names); + if (ret != GSS_S_COMPLETE) + goto out; + + for (i = 0; i < mechs->count; i++) { + ret = gss_inquire_names_for_mech(minor_status, + &mechs->elements[i], + &n); + if (ret) + continue; + + for (j = 0; j < n->count; j++) + gss_add_oid_set_member(minor_status, + &n->elements[j], + &names); + gss_release_oid_set(&junk, &n); + } + + ret = GSS_S_COMPLETE; + *name_types = names; +out: + + gss_release_oid_set(&junk, &mechs); + + return GSS_S_COMPLETE; +} + +OM_uint32 _gss_spnego_inquire_mechs_for_name ( + OM_uint32 * minor_status, + const gss_name_t input_name, + gss_OID_set * mech_types + ) +{ + OM_uint32 ret, junk; + + ret = gss_create_empty_oid_set(minor_status, mech_types); + if (ret) + return ret; + + ret = gss_add_oid_set_member(minor_status, + GSS_SPNEGO_MECHANISM, + mech_types); + if (ret) + gss_release_oid_set(&junk, mech_types); + + return ret; +} + +OM_uint32 _gss_spnego_canonicalize_name ( + OM_uint32 * minor_status, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t * output_name + ) +{ + /* XXX */ + return gss_duplicate_name(minor_status, input_name, output_name); +} + +OM_uint32 _gss_spnego_duplicate_name ( + OM_uint32 * minor_status, + const gss_name_t src_name, + gss_name_t * dest_name + ) +{ + return gss_duplicate_name(minor_status, src_name, dest_name); +} + +OM_uint32 _gss_spnego_sign + (OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int qop_req, + gss_buffer_t message_buffer, + gss_buffer_t message_token + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_sign(minor_status, + ctx->negotiated_ctx_id, + qop_req, + message_buffer, + message_token); +} + +OM_uint32 _gss_spnego_verify + (OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t message_buffer, + gss_buffer_t token_buffer, + int * qop_state + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_verify(minor_status, + ctx->negotiated_ctx_id, + message_buffer, + token_buffer, + qop_state); +} + +OM_uint32 _gss_spnego_seal + (OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + int conf_req_flag, + int qop_req, + gss_buffer_t input_message_buffer, + int * conf_state, + gss_buffer_t output_message_buffer + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_seal(minor_status, + ctx->negotiated_ctx_id, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer); +} + +OM_uint32 _gss_spnego_unseal + (OM_uint32 * minor_status, + gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int * conf_state, + int * qop_state + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_unseal(minor_status, + ctx->negotiated_ctx_id, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state); +} + +#if 0 +OM_uint32 _gss_spnego_unwrap_ex + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_buffer_t token_header_buffer, + const gss_buffer_t associated_data_buffer, + const gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int * conf_state, + gss_qop_t * qop_state) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_unwrap_ex(minor_status, + ctx->negotiated_ctx_id, + token_header_buffer, + associated_data_buffer, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state); +} + +OM_uint32 _gss_spnego_wrap_ex + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + const gss_buffer_t associated_data_buffer, + const gss_buffer_t input_message_buffer, + int * conf_state, + gss_buffer_t output_token_buffer, + gss_buffer_t output_message_buffer + ) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 && + associated_data_buffer->length != input_message_buffer->length) { + *minor_status = EINVAL; + return GSS_S_BAD_QOP; + } + + return gss_wrap_ex(minor_status, + ctx->negotiated_ctx_id, + conf_req_flag, + qop_req, + associated_data_buffer, + input_message_buffer, + conf_state, + output_token_buffer, + output_message_buffer); +} + +OM_uint32 _gss_spnego_complete_auth_token + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + gss_buffer_t input_message_buffer) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_complete_auth_token(minor_status, + ctx->negotiated_ctx_id, + input_message_buffer); +} +#endif + +OM_uint32 _gss_spnego_inquire_sec_context_by_oid + (OM_uint32 * minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_inquire_sec_context_by_oid(minor_status, + ctx->negotiated_ctx_id, + desired_object, + data_set); +} + +OM_uint32 _gss_spnego_set_sec_context_option + (OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_OID desired_object, + const gss_buffer_t value) +{ + gssspnego_ctx ctx; + + *minor_status = 0; + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + ctx = (gssspnego_ctx)context_handle; + + if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { + return GSS_S_NO_CONTEXT; + } + + return gss_set_sec_context_option(minor_status, + &ctx->negotiated_ctx_id, + desired_object, + value); +} + diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c new file mode 100644 index 0000000000..8f8edab15e --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" + +RCSID("$Id: cred_stubs.c,v 1.5 2006/10/07 22:27:04 lha Exp $"); + +OM_uint32 +_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) +{ + gssspnego_cred cred; + OM_uint32 ret; + + *minor_status = 0; + + if (*cred_handle == GSS_C_NO_CREDENTIAL) { + return GSS_S_COMPLETE; + } + cred = (gssspnego_cred)*cred_handle; + + ret = gss_release_cred(minor_status, &cred->negotiated_cred_id); + + free(cred); + *cred_handle = GSS_C_NO_CREDENTIAL; + + return ret; +} + +OM_uint32 +_gss_spnego_alloc_cred(OM_uint32 *minor_status, + gss_cred_id_t mech_cred_handle, + gss_cred_id_t *cred_handle) +{ + gssspnego_cred cred; + + if (*cred_handle != GSS_C_NO_CREDENTIAL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + cred = calloc(1, sizeof(*cred)); + if (cred == NULL) { + *cred_handle = GSS_C_NO_CREDENTIAL; + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + cred->negotiated_cred_id = mech_cred_handle; + + *cred_handle = (gss_cred_id_t)cred; + + return GSS_S_COMPLETE; +} + +/* + * For now, just a simple wrapper that avoids recursion. When + * we support gss_{get,set}_neg_mechs() we will need to expose + * more functionality. + */ +OM_uint32 _gss_spnego_acquire_cred +(OM_uint32 *minor_status, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t * output_cred_handle, + gss_OID_set * actual_mechs, + OM_uint32 * time_rec + ) +{ + OM_uint32 ret, tmp; + gss_OID_set_desc actual_desired_mechs; + gss_OID_set mechs; + int i, j; + gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; + gssspnego_cred cred; + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + + ret = gss_indicate_mechs(minor_status, &mechs); + if (ret != GSS_S_COMPLETE) + return ret; + + /* Remove ourselves from this list */ + actual_desired_mechs.count = mechs->count; + actual_desired_mechs.elements = malloc(actual_desired_mechs.count * + sizeof(gss_OID_desc)); + if (actual_desired_mechs.elements == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + goto out; + } + + for (i = 0, j = 0; i < mechs->count; i++) { + if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM)) + continue; + + actual_desired_mechs.elements[j] = mechs->elements[i]; + j++; + } + actual_desired_mechs.count = j; + + ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL, + &cred_handle); + if (ret != GSS_S_COMPLETE) + goto out; + + cred = (gssspnego_cred)cred_handle; + ret = gss_acquire_cred(minor_status, desired_name, + time_req, &actual_desired_mechs, + cred_usage, + &cred->negotiated_cred_id, + actual_mechs, time_rec); + if (ret != GSS_S_COMPLETE) + goto out; + + *output_cred_handle = cred_handle; + +out: + gss_release_oid_set(&tmp, &mechs); + if (actual_desired_mechs.elements != NULL) { + free(actual_desired_mechs.elements); + } + if (ret != GSS_S_COMPLETE) { + _gss_spnego_release_cred(&tmp, &cred_handle); + } + + return ret; +} + +OM_uint32 _gss_spnego_inquire_cred + (OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + gss_name_t * name, + OM_uint32 * lifetime, + gss_cred_usage_t * cred_usage, + gss_OID_set * mechanisms + ) +{ + gssspnego_cred cred; + OM_uint32 ret; + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + cred = (gssspnego_cred)cred_handle; + + ret = gss_inquire_cred(minor_status, + cred->negotiated_cred_id, + name, + lifetime, + cred_usage, + mechanisms); + + return ret; +} + +OM_uint32 _gss_spnego_add_cred ( + OM_uint32 * minor_status, + const gss_cred_id_t input_cred_handle, + const gss_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t * output_cred_handle, + gss_OID_set * actual_mechs, + OM_uint32 * initiator_time_rec, + OM_uint32 * acceptor_time_rec + ) +{ + gss_cred_id_t spnego_output_cred_handle = GSS_C_NO_CREDENTIAL; + OM_uint32 ret, tmp; + gssspnego_cred input_cred, output_cred; + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + + ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL, + &spnego_output_cred_handle); + if (ret) + return ret; + + input_cred = (gssspnego_cred)input_cred_handle; + output_cred = (gssspnego_cred)spnego_output_cred_handle; + + ret = gss_add_cred(minor_status, + input_cred->negotiated_cred_id, + desired_name, + desired_mech, + cred_usage, + initiator_time_req, + acceptor_time_req, + &output_cred->negotiated_cred_id, + actual_mechs, + initiator_time_rec, + acceptor_time_rec); + if (ret) { + _gss_spnego_release_cred(&tmp, &spnego_output_cred_handle); + return ret; + } + + *output_cred_handle = spnego_output_cred_handle; + + return GSS_S_COMPLETE; +} + +OM_uint32 _gss_spnego_inquire_cred_by_mech ( + OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + const gss_OID mech_type, + gss_name_t * name, + OM_uint32 * initiator_lifetime, + OM_uint32 * acceptor_lifetime, + gss_cred_usage_t * cred_usage + ) +{ + gssspnego_cred cred; + OM_uint32 ret; + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + cred = (gssspnego_cred)cred_handle; + + ret = gss_inquire_cred_by_mech(minor_status, + cred->negotiated_cred_id, + mech_type, + name, + initiator_lifetime, + acceptor_lifetime, + cred_usage); + + return ret; +} + +OM_uint32 _gss_spnego_inquire_cred_by_oid + (OM_uint32 * minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + gssspnego_cred cred; + OM_uint32 ret; + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + cred = (gssspnego_cred)cred_handle; + + ret = gss_inquire_cred_by_oid(minor_status, + cred->negotiated_cred_id, + desired_object, + data_set); + + return ret; +} + diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c new file mode 100644 index 0000000000..b7e02a55e1 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/external.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" +#include <gssapi_mech.h> + +RCSID("$Id: external.c,v 1.7 2006/10/07 22:27:06 lha Exp $"); + +/* + * RFC2478, SPNEGO: + * The security mechanism of the initial + * negotiation token is identified by the Object Identifier + * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2). + */ + +static gssapi_mech_interface_desc spnego_mech = { + GMI_VERSION, + "spnego", + {6, (void *)"\x2b\x06\x01\x05\x05\x02"}, + _gss_spnego_acquire_cred, + _gss_spnego_release_cred, + _gss_spnego_init_sec_context, + _gss_spnego_accept_sec_context, + _gss_spnego_process_context_token, + _gss_spnego_internal_delete_sec_context, + _gss_spnego_context_time, + _gss_spnego_get_mic, + _gss_spnego_verify_mic, + _gss_spnego_wrap, + _gss_spnego_unwrap, + _gss_spnego_display_status, + NULL, + _gss_spnego_compare_name, + _gss_spnego_display_name, + _gss_spnego_import_name, + _gss_spnego_export_name, + _gss_spnego_release_name, + _gss_spnego_inquire_cred, + _gss_spnego_inquire_context, + _gss_spnego_wrap_size_limit, + _gss_spnego_add_cred, + _gss_spnego_inquire_cred_by_mech, + _gss_spnego_export_sec_context, + _gss_spnego_import_sec_context, + _gss_spnego_inquire_names_for_mech, + _gss_spnego_inquire_mechs_for_name, + _gss_spnego_canonicalize_name, + _gss_spnego_duplicate_name +}; + +gssapi_mech_interface +__gss_spnego_initialize(void) +{ + return &spnego_mech; +} + +static gss_OID_desc _gss_spnego_mechanism_desc = + {6, (void *)"\x2b\x06\x01\x05\x05\x02"}; + +gss_OID GSS_SPNEGO_MECHANISM = &_gss_spnego_mechanism_desc; diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c new file mode 100644 index 0000000000..5a652fdb2e --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c @@ -0,0 +1,578 @@ +/* + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * Portions Copyright (c) 2004 PADL Software Pty Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "spnego/spnego_locl.h" + +RCSID("$Id: init_sec_context.c,v 1.6 2006/10/14 10:09:15 lha Exp $"); + +/* + * Send a reply. Note that we only need to send a reply if we + * need to send a MIC or a mechanism token. Otherwise, we can + * return an empty buffer. + * + * The return value of this will be returned to the API, so it + * must return GSS_S_CONTINUE_NEEDED if a token was generated. + */ +static OM_uint32 +spnego_reply_internal(OM_uint32 *minor_status, + gssspnego_ctx context_handle, + const gss_buffer_t mech_buf, + gss_buffer_t mech_token, + gss_buffer_t output_token) +{ + NegTokenResp resp; + gss_buffer_desc mic_buf; + OM_uint32 ret; + gss_buffer_desc data; + u_char *buf; + + if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) { + output_token->length = 0; + output_token->value = NULL; + + return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE; + } + + memset(&resp, 0, sizeof(resp)); + + ALLOC(resp.negResult, 1); + if (resp.negResult == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + resp.supportedMech = NULL; + + output_token->length = 0; + output_token->value = NULL; + + if (mech_token->length == 0) { + resp.responseToken = NULL; + *(resp.negResult) = accept_completed; + } else { + ALLOC(resp.responseToken, 1); + if (resp.responseToken == NULL) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + resp.responseToken->length = mech_token->length; + resp.responseToken->data = mech_token->value; + mech_token->length = 0; + mech_token->value = NULL; + + *(resp.negResult) = accept_incomplete; + } + + if (mech_buf != GSS_C_NO_BUFFER) { + ALLOC(resp.mechListMIC, 1); + if (resp.mechListMIC == NULL) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = gss_get_mic(minor_status, + context_handle->negotiated_ctx_id, + 0, + mech_buf, + &mic_buf); + if (ret) { + free_NegTokenResp(&resp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + resp.mechListMIC->length = mic_buf.length; + resp.mechListMIC->data = mic_buf.value; + } else { + resp.mechListMIC = NULL; + } + + ret = _gss_spnego_encode_response (minor_status, &resp, + &data, &buf); + if (ret) { + free_NegTokenResp(&resp); + return ret; + } + + output_token->value = malloc(data.length); + if (output_token->value == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_FAILURE; + } else { + output_token->length = data.length; + memcpy(output_token->value, data.value, output_token->length); + } + free(buf); + + if (*(resp.negResult) == accept_completed) + ret = GSS_S_COMPLETE; + else + ret = GSS_S_CONTINUE_NEEDED; + + free_NegTokenResp(&resp); + return ret; +} + +static OM_uint32 +spnego_initial + (OM_uint32 * minor_status, + gssspnego_cred cred, + gss_ctx_id_t * context_handle, + const gss_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + NegTokenInit ni; + int ret; + OM_uint32 sub, minor; + gss_buffer_desc mech_token; + u_char *buf; + size_t buf_size, buf_len; + gss_buffer_desc data; + size_t ni_len; + gss_ctx_id_t context; + gssspnego_ctx ctx; + + memset (&ni, 0, sizeof(ni)); + + *context_handle = GSS_C_NO_CONTEXT; + + *minor_status = 0; + + sub = _gss_spnego_alloc_sec_context(&minor, &context); + if (GSS_ERROR(sub)) { + *minor_status = minor; + return sub; + } + ctx = (gssspnego_ctx)context; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + ctx->local = 1; + + sub = _gss_spnego_indicate_mechtypelist(&minor, 0, + cred, + &ni.mechTypes, + &ctx->preferred_mech_type); + if (GSS_ERROR(sub)) { + *minor_status = minor; + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return sub; + } + + ni.reqFlags = NULL; + + /* + * If we have a credential handle, use it to select the mechanism + * that we will use + */ + + /* generate optimistic token */ + sub = gss_init_sec_context(&minor, + (cred != NULL) ? cred->negotiated_cred_id : + GSS_C_NO_CREDENTIAL, + &ctx->negotiated_ctx_id, + target_name, + GSS_C_NO_OID, + req_flags, + time_req, + input_chan_bindings, + input_token, + &ctx->negotiated_mech_type, + &mech_token, + &ctx->mech_flags, + &ctx->mech_time_rec); + if (GSS_ERROR(sub)) { + free_NegTokenInit(&ni); + *minor_status = minor; + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return sub; + } + + if (mech_token.length != 0) { + ALLOC(ni.mechToken, 1); + if (ni.mechToken == NULL) { + free_NegTokenInit(&ni); + gss_release_buffer(&minor, &mech_token); + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + ni.mechToken->length = mech_token.length; + ni.mechToken->data = malloc(mech_token.length); + if (ni.mechToken->data == NULL && mech_token.length != 0) { + free_NegTokenInit(&ni); + gss_release_buffer(&minor, &mech_token); + *minor_status = ENOMEM; + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + memcpy(ni.mechToken->data, mech_token.value, mech_token.length); + gss_release_buffer(&minor, &mech_token); + } else + ni.mechToken = NULL; + + ni.mechListMIC = NULL; + + ni_len = length_NegTokenInit(&ni); + buf_size = 1 + der_length_len(ni_len) + ni_len; + + buf = malloc(buf_size); + if (buf == NULL) { + free_NegTokenInit(&ni); + *minor_status = ENOMEM; + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + ret = encode_NegTokenInit(buf + buf_size - 1, + ni_len, + &ni, &buf_len); + if (ret == 0 && ni_len != buf_len) + abort(); + + if (ret == 0) { + size_t tmp; + + ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, + buf_size - buf_len, + buf_len, + ASN1_C_CONTEXT, + CONS, + 0, + &tmp); + if (ret == 0 && tmp + buf_len != buf_size) + abort(); + } + if (ret) { + *minor_status = ret; + free(buf); + free_NegTokenInit(&ni); + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + data.value = buf; + data.length = buf_size; + + ctx->initiator_mech_types.len = ni.mechTypes.len; + ctx->initiator_mech_types.val = ni.mechTypes.val; + ni.mechTypes.len = 0; + ni.mechTypes.val = NULL; + + free_NegTokenInit(&ni); + + sub = gss_encapsulate_token(&data, + GSS_SPNEGO_MECHANISM, + output_token); + free (buf); + + if (sub) { + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return sub; + } + + if (actual_mech_type) + *actual_mech_type = ctx->negotiated_mech_type; + if (ret_flags) + *ret_flags = ctx->mech_flags; + if (time_rec) + *time_rec = ctx->mech_time_rec; + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + *context_handle = context; + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 +spnego_reply + (OM_uint32 * minor_status, + const gssspnego_cred cred, + gss_ctx_id_t * context_handle, + const gss_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + OM_uint32 ret, minor; + NegTokenResp resp; + u_char oidbuf[17]; + size_t oidlen; + size_t len, taglen; + gss_OID_desc mech; + int require_mic; + size_t buf_len; + gss_buffer_desc mic_buf, mech_buf; + gss_buffer_desc mech_output_token; + gssspnego_ctx ctx; + + *minor_status = 0; + + ctx = (gssspnego_ctx)*context_handle; + + output_token->length = 0; + output_token->value = NULL; + + mech_output_token.length = 0; + mech_output_token.value = NULL; + + mech_buf.value = NULL; + mech_buf.length = 0; + + ret = der_match_tag_and_length(input_token->value, input_token->length, + ASN1_C_CONTEXT, CONS, 1, &len, &taglen); + if (ret) + return ret; + + if (len > input_token->length - taglen) + return ASN1_OVERRUN; + + ret = decode_NegTokenResp((const unsigned char *)input_token->value+taglen, + len, &resp, NULL); + if (ret) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + if (resp.negResult == NULL + || *(resp.negResult) == reject + || resp.supportedMech == NULL) { + free_NegTokenResp(&resp); + return GSS_S_BAD_MECH; + } + + ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1, + sizeof(oidbuf), + resp.supportedMech, + &oidlen); + if (ret || (oidlen == GSS_SPNEGO_MECHANISM->length && + memcmp(oidbuf + sizeof(oidbuf) - oidlen, + GSS_SPNEGO_MECHANISM->elements, + oidlen) == 0)) { + /* Avoid recursively embedded SPNEGO */ + free_NegTokenResp(&resp); + return GSS_S_BAD_MECH; + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (resp.responseToken != NULL) { + gss_buffer_desc mech_input_token; + + mech_input_token.length = resp.responseToken->length; + mech_input_token.value = resp.responseToken->data; + + mech.length = oidlen; + mech.elements = oidbuf + sizeof(oidbuf) - oidlen; + + /* Fall through as if the negotiated mechanism + was requested explicitly */ + ret = gss_init_sec_context(&minor, + (cred != NULL) ? cred->negotiated_cred_id : + GSS_C_NO_CREDENTIAL, + &ctx->negotiated_ctx_id, + target_name, + &mech, + req_flags, + time_req, + input_chan_bindings, + &mech_input_token, + &ctx->negotiated_mech_type, + &mech_output_token, + &ctx->mech_flags, + &ctx->mech_time_rec); + if (GSS_ERROR(ret)) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free_NegTokenResp(&resp); + *minor_status = minor; + return ret; + } + if (ret == GSS_S_COMPLETE) { + ctx->open = 1; + } + } + + if (*(resp.negResult) == request_mic) { + ctx->require_mic = 1; + } + + if (ctx->open) { + /* + * Verify the mechListMIC if one was provided or CFX was + * used and a non-preferred mechanism was selected + */ + if (resp.mechListMIC != NULL) { + require_mic = 1; + } else { + ret = _gss_spnego_require_mechlist_mic(minor_status, ctx, + &require_mic); + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free_NegTokenResp(&resp); + gss_release_buffer(&minor, &mech_output_token); + return ret; + } + } + } else { + require_mic = 0; + } + + if (require_mic) { + ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length, + &ctx->initiator_mech_types, &buf_len, ret); + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free_NegTokenResp(&resp); + gss_release_buffer(&minor, &mech_output_token); + *minor_status = ret; + return GSS_S_FAILURE; + } + if (mech_buf.length != buf_len) + abort(); + + if (resp.mechListMIC == NULL) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free(mech_buf.value); + free_NegTokenResp(&resp); + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } + mic_buf.length = resp.mechListMIC->length; + mic_buf.value = resp.mechListMIC->data; + + if (mech_output_token.length == 0) { + ret = gss_verify_mic(minor_status, + ctx->negotiated_ctx_id, + &mech_buf, + &mic_buf, + NULL); + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free(mech_buf.value); + gss_release_buffer(&minor, &mech_output_token); + free_NegTokenResp(&resp); + return GSS_S_DEFECTIVE_TOKEN; + } + ctx->verified_mic = 1; + } + } + + ret = spnego_reply_internal(minor_status, ctx, + require_mic ? &mech_buf : NULL, + &mech_output_token, + output_token); + + if (mech_buf.value != NULL) + free(mech_buf.value); + + free_NegTokenResp(&resp); + gss_release_buffer(&minor, &mech_output_token); + + if (actual_mech_type) + *actual_mech_type = ctx->negotiated_mech_type; + if (ret_flags) + *ret_flags = ctx->mech_flags; + if (time_rec) + *time_rec = ctx->mech_time_rec; + + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; +} + +OM_uint32 _gss_spnego_init_sec_context + (OM_uint32 * minor_status, + const gss_cred_id_t initiator_cred_handle, + gss_ctx_id_t * context_handle, + const gss_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec + ) +{ + gssspnego_cred cred = (gssspnego_cred)initiator_cred_handle; + + if (*context_handle == GSS_C_NO_CONTEXT) + return spnego_initial (minor_status, + cred, + context_handle, + target_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + else + return spnego_reply (minor_status, + cred, + context_handle, + target_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); +} + diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h new file mode 100644 index 0000000000..df50f65580 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h @@ -0,0 +1,347 @@ +/* This is a generated file */ +#ifndef __spnego_private_h__ +#define __spnego_private_h__ + +#include <stdarg.h> + +gssapi_mech_interface +__gss_spnego_initialize (void); + +OM_uint32 +_gss_spnego_accept_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + const gss_cred_id_t /*acceptor_cred_handle*/, + const gss_buffer_t /*input_token_buffer*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + gss_name_t * /*src_name*/, + gss_OID * /*mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * /*time_rec*/, + gss_cred_id_t *delegated_cred_handle ); + +OM_uint32 +_gss_spnego_acquire_cred ( + OM_uint32 */*minor_status*/, + const gss_name_t /*desired_name*/, + OM_uint32 /*time_req*/, + const gss_OID_set /*desired_mechs*/, + gss_cred_usage_t /*cred_usage*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * time_rec ); + +OM_uint32 +_gss_spnego_add_cred ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*input_cred_handle*/, + const gss_name_t /*desired_name*/, + const gss_OID /*desired_mech*/, + gss_cred_usage_t /*cred_usage*/, + OM_uint32 /*initiator_time_req*/, + OM_uint32 /*acceptor_time_req*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * /*initiator_time_rec*/, + OM_uint32 * acceptor_time_rec ); + +int +_gss_spnego_add_mech_type ( + gss_OID /*mech_type*/, + int /*includeMSCompatOID*/, + MechTypeList */*mechtypelist*/); + +OM_uint32 +_gss_spnego_alloc_cred ( + OM_uint32 */*minor_status*/, + gss_cred_id_t /*mech_cred_handle*/, + gss_cred_id_t */*cred_handle*/); + +OM_uint32 +_gss_spnego_alloc_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t */*context_handle*/); + +OM_uint32 +_gss_spnego_canonicalize_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + const gss_OID /*mech_type*/, + gss_name_t * output_name ); + +OM_uint32 +_gss_spnego_compare_name ( + OM_uint32 */*minor_status*/, + const gss_name_t /*name1*/, + const gss_name_t /*name2*/, + int * name_equal ); + +OM_uint32 +_gss_spnego_context_time ( + OM_uint32 */*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + OM_uint32 *time_rec ); + +OM_uint32 +_gss_spnego_delete_sec_context ( + OM_uint32 */*minor_status*/, + gss_ctx_id_t */*context_handle*/, + gss_buffer_t output_token ); + +OM_uint32 +_gss_spnego_display_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t /*output_name_buffer*/, + gss_OID * output_name_type ); + +OM_uint32 +_gss_spnego_display_status ( + OM_uint32 * /*minor_status*/, + OM_uint32 /*status_value*/, + int /*status_type*/, + const gss_OID /*mech_type*/, + OM_uint32 * /*message_context*/, + gss_buffer_t status_string ); + +OM_uint32 +_gss_spnego_duplicate_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*src_name*/, + gss_name_t * dest_name ); + +OM_uint32 +_gss_spnego_encode_response ( + OM_uint32 */*minor_status*/, + const NegTokenResp */*resp*/, + gss_buffer_t /*data*/, + u_char **/*ret_buf*/); + +OM_uint32 +_gss_spnego_export_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_buffer_t exported_name ); + +OM_uint32 +_gss_spnego_export_sec_context ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + gss_buffer_t interprocess_token ); + +OM_uint32 +_gss_spnego_get_mic ( + OM_uint32 */*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*message_buffer*/, + gss_buffer_t message_token ); + +OM_uint32 +_gss_spnego_import_name ( + OM_uint32 * /*minor_status*/, + const gss_buffer_t /*input_name_buffer*/, + const gss_OID /*input_name_type*/, + gss_name_t * output_name ); + +OM_uint32 +_gss_spnego_import_sec_context ( + OM_uint32 * /*minor_status*/, + const gss_buffer_t /*interprocess_token*/, + gss_ctx_id_t *context_handle ); + +OM_uint32 +_gss_spnego_indicate_mechtypelist ( + OM_uint32 */*minor_status*/, + int /*includeMSCompatOID*/, + const gssspnego_cred /*cred_handle*/, + MechTypeList */*mechtypelist*/, + gss_OID */*preferred_mech*/); + +OM_uint32 +_gss_spnego_init_sec_context ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*initiator_cred_handle*/, + gss_ctx_id_t * /*context_handle*/, + const gss_name_t /*target_name*/, + const gss_OID /*mech_type*/, + OM_uint32 /*req_flags*/, + OM_uint32 /*time_req*/, + const gss_channel_bindings_t /*input_chan_bindings*/, + const gss_buffer_t /*input_token*/, + gss_OID * /*actual_mech_type*/, + gss_buffer_t /*output_token*/, + OM_uint32 * /*ret_flags*/, + OM_uint32 * time_rec ); + +OM_uint32 +_gss_spnego_inquire_context ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + gss_name_t * /*src_name*/, + gss_name_t * /*targ_name*/, + OM_uint32 * /*lifetime_rec*/, + gss_OID * /*mech_type*/, + OM_uint32 * /*ctx_flags*/, + int * /*locally_initiated*/, + int * open_context ); + +OM_uint32 +_gss_spnego_inquire_cred ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + gss_name_t * /*name*/, + OM_uint32 * /*lifetime*/, + gss_cred_usage_t * /*cred_usage*/, + gss_OID_set * mechanisms ); + +OM_uint32 +_gss_spnego_inquire_cred_by_mech ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + const gss_OID /*mech_type*/, + gss_name_t * /*name*/, + OM_uint32 * /*initiator_lifetime*/, + OM_uint32 * /*acceptor_lifetime*/, + gss_cred_usage_t * cred_usage ); + +OM_uint32 +_gss_spnego_inquire_cred_by_oid ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*cred_handle*/, + const gss_OID /*desired_object*/, + gss_buffer_set_t */*data_set*/); + +OM_uint32 +_gss_spnego_inquire_mechs_for_name ( + OM_uint32 * /*minor_status*/, + const gss_name_t /*input_name*/, + gss_OID_set * mech_types ); + +OM_uint32 +_gss_spnego_inquire_names_for_mech ( + OM_uint32 * /*minor_status*/, + const gss_OID /*mechanism*/, + gss_OID_set * name_types ); + +OM_uint32 +_gss_spnego_inquire_sec_context_by_oid ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_OID /*desired_object*/, + gss_buffer_set_t */*data_set*/); + +OM_uint32 +_gss_spnego_internal_delete_sec_context ( + OM_uint32 */*minor_status*/, + gss_ctx_id_t */*context_handle*/, + gss_buffer_t output_token ); + +OM_uint32 +_gss_spnego_process_context_token ( + OM_uint32 */*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t token_buffer ); + +OM_uint32 +_gss_spnego_release_cred ( + OM_uint32 */*minor_status*/, + gss_cred_id_t */*cred_handle*/); + +OM_uint32 +_gss_spnego_release_name ( + OM_uint32 * /*minor_status*/, + gss_name_t * input_name ); + +OM_uint32 +_gss_spnego_require_mechlist_mic ( + OM_uint32 */*minor_status*/, + gssspnego_ctx /*ctx*/, + int */*require_mic*/); + +OM_uint32 +_gss_spnego_seal ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + int /*qop_req*/, + gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t output_message_buffer ); + +OM_uint32 +_gss_spnego_select_mech ( + OM_uint32 */*minor_status*/, + MechType */*mechType*/, + gss_OID */*mech_p*/); + +OM_uint32 +_gss_spnego_set_sec_context_option ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t * /*context_handle*/, + const gss_OID /*desired_object*/, + const gss_buffer_t /*value*/); + +OM_uint32 +_gss_spnego_sign ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + int /*qop_req*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t message_token ); + +OM_uint32 +_gss_spnego_unseal ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + int * qop_state ); + +OM_uint32 +_gss_spnego_unwrap ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*input_message_buffer*/, + gss_buffer_t /*output_message_buffer*/, + int * /*conf_state*/, + gss_qop_t * qop_state ); + +OM_uint32 +_gss_spnego_verify ( + OM_uint32 * /*minor_status*/, + gss_ctx_id_t /*context_handle*/, + gss_buffer_t /*message_buffer*/, + gss_buffer_t /*token_buffer*/, + int * qop_state ); + +OM_uint32 +_gss_spnego_verify_mic ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + const gss_buffer_t /*message_buffer*/, + const gss_buffer_t /*token_buffer*/, + gss_qop_t * qop_state ); + +OM_uint32 +_gss_spnego_wrap ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + const gss_buffer_t /*input_message_buffer*/, + int * /*conf_state*/, + gss_buffer_t output_message_buffer ); + +OM_uint32 +_gss_spnego_wrap_size_limit ( + OM_uint32 * /*minor_status*/, + const gss_ctx_id_t /*context_handle*/, + int /*conf_req_flag*/, + gss_qop_t /*qop_req*/, + OM_uint32 /*req_output_size*/, + OM_uint32 * max_input_size ); + +#endif /* __spnego_private_h__ */ diff --git a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 new file mode 100644 index 0000000000..187ce0a0a6 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 @@ -0,0 +1,51 @@ +-- $Id: spnego.asn1,v 1.1.1.1 2006/06/28 08:34:45 lha Exp $ + +SPNEGO DEFINITIONS ::= +BEGIN + +MechType::= OBJECT IDENTIFIER + +MechTypeList ::= SEQUENCE OF MechType + +ContextFlags ::= BIT STRING { + delegFlag (0), + mutualFlag (1), + replayFlag (2), + sequenceFlag (3), + anonFlag (4), + confFlag (5), + integFlag (6) +} + +NegHints ::= SEQUENCE { + hintName [0] GeneralString OPTIONAL, + hintAddress [1] OCTET STRING OPTIONAL +} + +NegTokenInit ::= SEQUENCE { + mechTypes [0] MechTypeList, + reqFlags [1] ContextFlags OPTIONAL, + mechToken [2] OCTET STRING OPTIONAL, + negHints [3] NegHints OPTIONAL, + mechListMIC [4] OCTET STRING OPTIONAL + } + +-- NB: negResult is not OPTIONAL in the new SPNEGO spec but +-- Windows clients do not always send it +NegTokenResp ::= SEQUENCE { + negResult [0] ENUMERATED { + accept_completed (0), + accept_incomplete (1), + reject (2), + request-mic (3) } OPTIONAL, + supportedMech [1] MechType OPTIONAL, + responseToken [2] OCTET STRING OPTIONAL, + mechListMIC [3] OCTET STRING OPTIONAL +} + +NegotiationToken ::= CHOICE { + negTokenInit[0] NegTokenInit, + negTokenResp[1] NegTokenResp +} + +END diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h new file mode 100644 index 0000000000..571bce5569 --- /dev/null +++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: spnego_locl.h,v 1.11 2006/10/12 06:28:06 lha Exp $ */ + +#ifndef SPNEGO_LOCL_H +#define SPNEGO_LOCL_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#endif + +#include <gssapi/gssapi_spnego.h> +#include <gssapi.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +#include <heim_threads.h> +#include <asn1_err.h> + +#include <gssapi_mech.h> + +#include "spnego_asn1.h" +#include <der.h> + +#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) + +typedef struct { + gss_cred_id_t negotiated_cred_id; +} *gssspnego_cred; + +typedef struct { + MechTypeList initiator_mech_types; + gss_OID preferred_mech_type; + gss_OID negotiated_mech_type; + gss_ctx_id_t negotiated_ctx_id; + OM_uint32 mech_flags; + OM_uint32 mech_time_rec; + gss_name_t mech_src_name; + gss_cred_id_t delegated_cred_id; + int open : 1; + int local : 1; + int require_mic : 1; + int verified_mic : 1; + HEIMDAL_MUTEX ctx_id_mutex; +} *gssspnego_ctx; + +#include <spnego/spnego-private.h> + +#endif /* SPNEGO_LOCL_H */ |