diff options
Diffstat (limited to 'source4/heimdal/lib/gssapi')
49 files changed, 871 insertions, 411 deletions
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 9fe2bb8b46..07c4b36325 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -768,42 +768,6 @@ gss_pseudo_random gss_buffer_t prf_out ); -/* - * AEAD support - */ - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_wrap_iov(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int /* conf_req_flag */, - gss_qop_t /* qop_req */, - int * /* conf_state */, - gss_iov_buffer_desc * /*iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_unwrap_iov(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int * /* conf_state */, - gss_qop_t * /* qop_state */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_wrap_iov_length(OM_uint32 * /* minor_status */, - gss_ctx_id_t /* context_handle */, - int /* conf_req_flag */, - gss_qop_t /* qop_req */, - int * /* conf_state */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - -OM_uint32 GSSAPI_LIB_FUNCTION -gss_release_iov_buffer(OM_uint32 * /* minor_status */, - gss_iov_buffer_desc * /* iov */, - int /* iov_count */); - - OM_uint32 gss_store_cred(OM_uint32 * /* minor_status */, gss_cred_id_t /* input_cred_handle */, @@ -899,6 +863,31 @@ gss_decapsulate_token(gss_buffer_t /* input_token */, +/* + * AEAD support + */ + +/* + * GSS_IOV + */ + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *, + gss_iov_buffer_desc *, int); + + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *, + gss_iov_buffer_desc *, int); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *, + gss_iov_buffer_desc *, int); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int); + + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c index f5181cc311..a6f0165e72 100644 --- a/source4/heimdal/lib/gssapi/krb5/8003.c +++ b/source4/heimdal/lib/gssapi/krb5/8003.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - krb5_error_code _gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p) { diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 8ead2bdf75..8d998ed098 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab _gsskrb5_keytab; @@ -519,13 +517,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, } /* - * Samba style get some flags (but not DCE-STYLE) + * Samba style get some flags (but not DCE-STYLE), use + * ap_options to guess the mutual flag. */ - ctx->flags = - GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; - if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { - ctx->flags |= GSS_C_MUTUAL_FLAG; - } + ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; + if (ap_options & AP_OPTS_MUTUAL_REQUIRED) + ctx->flags |= GSS_C_MUTUAL_FLAG; } } diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index bfab5667be..4f6f38e674 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c index aa96a45e45..adc8a09fa4 100644 --- a/source4/heimdal/lib/gssapi/krb5/add_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_add_cred ( OM_uint32 *minor_status, const gss_cred_id_t input_cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c index 7dab7877d7..38a5ac2dbe 100644 --- a/source4/heimdal/lib/gssapi/krb5/aeap.c +++ b/source4/heimdal/lib/gssapi/krb5/aeap.c @@ -35,66 +35,6 @@ #include <roken.h> -static OM_uint32 -iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count) -{ - unsigned int i; - - for (i = 0; i < iov_count; i++) { - if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){ - void *ptr = malloc(iov[i].buffer.length); - if (ptr == NULL) - abort(); - if (iov[i].buffer.value) - memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length); - iov[i].buffer.value = ptr; - iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; - } - } - return GSS_S_COMPLETE; -} - -static OM_uint32 -iov_map(OM_uint32 *minor_status, - const gss_iov_buffer_desc *iov, - int iov_count, - krb5_crypto_iov *data) -{ - unsigned int i; - - for (i = 0; i < iov_count; i++) { - switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { - case GSS_IOV_BUFFER_TYPE_EMPTY: - data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; - break; - case GSS_IOV_BUFFER_TYPE_DATA: - data[i].flags = KRB5_CRYPTO_TYPE_DATA; - break; - case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: - data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; - break; - case GSS_IOV_BUFFER_TYPE_HEADER: - data[i].flags = KRB5_CRYPTO_TYPE_HEADER; - break; - case GSS_IOV_BUFFER_TYPE_TRAILER: - data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; - break; - case GSS_IOV_BUFFER_TYPE_PADDING: - data[i].flags = KRB5_CRYPTO_TYPE_PADDING; - break; - case GSS_IOV_BUFFER_TYPE_STREAM: - abort(); - break; - default: - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - data[i].data.data = iov[i].buffer.value; - data[i].data.length = iov[i].buffer.length; - } - return GSS_S_COMPLETE; -} - OM_uint32 GSSAPI_LIB_FUNCTION _gk_wrap_iov(OM_uint32 * minor_status, gss_ctx_id_t context_handle, @@ -104,50 +44,17 @@ _gk_wrap_iov(OM_uint32 * minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; - krb5_context context; - OM_uint32 major_status, junk; - krb5_crypto_iov *data; - krb5_error_code ret; - unsigned usage; - - GSSAPI_KRB5_INIT (&context); - - major_status = iov_allocate(minor_status, iov, iov_count); - if (major_status != GSS_S_COMPLETE) - return major_status; - - data = calloc(iov_count, sizeof(data[0])); - if (data == NULL) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - major_status = iov_map(minor_status, iov, iov_count, data); - if (major_status != GSS_S_COMPLETE) { - gss_release_iov_buffer(&junk, iov, iov_count); - free(data); - return major_status; - } + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + krb5_context context; - if (ctx->more_flags & LOCAL) { - usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; - } else { - usage = KRB5_KU_USAGE_INITIATOR_SIGN; - } + GSSAPI_KRB5_INIT (&context); - ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, - data, iov_count, NULL); - free(data); - if (ret) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ret; - return GSS_S_FAILURE; - } + if (ctx->more_flags & IS_CFX) + return _gssapi_wrap_cfx_iov(minor_status, ctx, context, + conf_req_flag, conf_state, + iov, iov_count); - *minor_status = 0; - return GSS_S_COMPLETE; + return GSS_S_FAILURE; } OM_uint32 GSSAPI_LIB_FUNCTION @@ -158,50 +65,16 @@ _gk_unwrap_iov(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; - krb5_error_code ret; - OM_uint32 major_status, junk; - krb5_crypto_iov *data; - unsigned usage; GSSAPI_KRB5_INIT (&context); - - major_status = iov_allocate(minor_status, iov, iov_count); - if (major_status != GSS_S_COMPLETE) - return major_status; - - data = calloc(iov_count, sizeof(data[0])); - if (data == NULL) { - gss_release_iov_buffer(&junk, iov, iov_count); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - major_status = iov_map(minor_status, iov, iov_count, data); - if (major_status != GSS_S_COMPLETE) { - gss_release_iov_buffer(&junk, iov, iov_count); - free(data); - return major_status; - } - - if (ctx->more_flags & LOCAL) { - usage = KRB5_KU_USAGE_INITIATOR_SIGN; - } else { - usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; - } - - ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, - data, iov_count, NULL); - free(data); - if (ret) { - *minor_status = ret; - gss_release_iov_buffer(&junk, iov, iov_count); - return GSS_S_FAILURE; - } - - *minor_status = 0; - return GSS_S_COMPLETE; + + if (ctx->more_flags & IS_CFX) + return _gssapi_unwrap_cfx_iov(minor_status, ctx, context, + conf_state, qop_state, iov, iov_count); + + return GSS_S_FAILURE; } OM_uint32 GSSAPI_LIB_FUNCTION @@ -213,59 +86,15 @@ _gk_wrap_iov_length(OM_uint32 * minor_status, gss_iov_buffer_desc *iov, int iov_count) { - gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; + const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_context context; - unsigned int i; - size_t size; - size_t *padding = NULL; - + GSSAPI_KRB5_INIT (&context); - *minor_status = 0; - - for (size = 0, i = 0; i < iov_count; i++) { - switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { - case GSS_IOV_BUFFER_TYPE_EMPTY: - break; - case GSS_IOV_BUFFER_TYPE_DATA: - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_HEADER: - iov[i].buffer.length = - krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER); - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_TRAILER: - iov[i].buffer.length = - krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER); - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_PADDING: - if (padding != NULL) { - *minor_status = 0; - return GSS_S_FAILURE; - } - padding = &iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_STREAM: - size += iov[i].buffer.length; - break; - case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: - break; - default: - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - } - if (padding) { - size_t pad = krb5_crypto_length(context, ctx->crypto, - KRB5_CRYPTO_TYPE_PADDING); - if (pad > 1) { - *padding = pad - (size % pad); - if (*padding == pad) - *padding = 0; - } else - *padding = 0; - } - - return GSS_S_COMPLETE; + + if (ctx->more_flags & IS_CFX) + return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context, + conf_req_flag, qop_req, conf_state, + iov, iov_count); + + return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index b48cfebcf1..e7331b0119 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt * diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c index 3a206b1be1..7e0c3fe727 100644 --- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_canonicalize_name ( OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c index 7ae26e2e7a..35e5a9e45a 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.c +++ b/source4/heimdal/lib/gssapi/krb5/cfx.c @@ -32,10 +32,8 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* - * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt + * Implementation of RFC 4121 */ #define CFXSentByAcceptor (1 << 0) @@ -101,13 +99,14 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle, return 0; } -OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, - const gsskrb5_ctx ctx, - krb5_context context, - int conf_req_flag, - gss_qop_t qop_req, - OM_uint32 req_output_size, - OM_uint32 *max_input_size) +OM_uint32 +_gssapi_wrap_size_cfx(OM_uint32 *minor_status, + const gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) { krb5_error_code ret; @@ -203,11 +202,763 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate) return 0; } +gss_iov_buffer_desc * +_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type) +{ + int i; + + for (i = 0; i < iov_count; i++) + if (type == GSS_IOV_BUFFER_TYPE(iov[i].type)) + return &iov[i]; + return NULL; +} + +static OM_uint32 +allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size) +{ + if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) { + if (buffer->buffer.length == size) + return GSS_S_COMPLETE; + free(buffer->buffer.value); + } + + buffer->buffer.value = malloc(size); + buffer->buffer.length = size; + if (buffer->buffer.value == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + buffer->type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; + + return GSS_S_COMPLETE; +} + + + +OM_uint32 +_gssapi_wrap_cfx_iov(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 major_status, junk; + gss_iov_buffer_desc *header, *trailer, *padding; + size_t gsshsize, k5hsize; + size_t gsstsize, k5tsize; + size_t i, padlength, rrc = 0, ec = 0; + gss_cfx_wrap_token token; + krb5_error_code ret; + int32_t seq_number; + unsigned usage; + krb5_crypto_iov *data = NULL; + int paddingoffset = 0; + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength); + + padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); + if (padlength != 0 && padding == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + if (conf_req_flag) { + ec = padlength; + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize); + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize); + + gsshsize = k5hsize + sizeof(*token); + gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */ + + } else { + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize); + + gsshsize = sizeof(*token); + gsstsize = k5tsize; + } + + /* + * + */ + + if (trailer == NULL) { + /* conf_req_flag=0 doesn't support DCE_STYLE */ + if (conf_req_flag == 0) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + rrc = gsstsize; + if (IS_DCE_STYLE(ctx)) + rrc -= ec; + gsshsize += gsstsize; + gsstsize = 0; + } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = allocate_buffer(minor_status, trailer, gsstsize); + if (major_status) + goto failure; + } else if (trailer->buffer.length < gsstsize) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else + trailer->buffer.length = gsstsize; + + /* + * + */ + + if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) { + major_status = allocate_buffer(minor_status, header, gsshsize); + if (major_status != GSS_S_COMPLETE) + goto failure; + } else if (header->buffer.length < gsshsize) { + *minor_status = KRB5_BAD_MSIZE; + major_status = GSS_S_FAILURE; + goto failure; + } else + header->buffer.length = gsshsize; + + token = (gss_cfx_wrap_token)header->buffer.value; + + token->TOK_ID[0] = 0x05; + token->TOK_ID[1] = 0x04; + token->Flags = 0; + token->Filler = 0xFF; + + if (ctx->more_flags & ACCEPTOR_SUBKEY) + token->Flags |= CFXAcceptorSubkey; + + if (ctx->more_flags & LOCAL) + usage = KRB5_KU_USAGE_INITIATOR_SEAL; + else + usage = KRB5_KU_USAGE_ACCEPTOR_SEAL; + + if (conf_req_flag) { + /* + * In Wrap tokens with confidentiality, the EC field is + * used to encode the size (in bytes) of the random filler. + */ + token->Flags |= CFXSealed; + token->EC[0] = (padlength >> 8) & 0xFF; + token->EC[1] = (padlength >> 0) & 0xFF; + + } else { + /* + * In Wrap tokens without confidentiality, the EC field is + * used to encode the size (in bytes) of the trailing + * checksum. + * + * This is not used in the checksum calcuation itself, + * because the checksum length could potentially vary + * depending on the data length. + */ + token->EC[0] = 0; + token->EC[1] = 0; + } + + /* + * In Wrap tokens that provide for confidentiality, the RRC + * field in the header contains the hex value 00 00 before + * encryption. + * + * In Wrap tokens that do not provide for confidentiality, + * both the EC and RRC fields in the appended checksum + * contain the hex value 00 00 for the purpose of calculating + * the checksum. + */ + token->RRC[0] = 0; + token->RRC[1] = 0; + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + krb5_auth_con_getlocalseqnumber(context, + ctx->auth_context, + &seq_number); + _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(context, + ctx->auth_context, + ++seq_number); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + data = calloc(iov_count + 3, sizeof(data[0])); + if (data == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (conf_req_flag) { + /* + plain packet: + + {"header" | encrypt(plaintext-data | padding | E"header")} + + Expanded, this is with with RRC = 0: + + {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer } + + In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer) + + {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data } + */ + + i = 0; + data[i].flags = KRB5_CRYPTO_TYPE_HEADER; + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize; + data[i].data.length = k5hsize; + + for (i = 1; i < iov_count + 1; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_PADDING; + paddingoffset = i; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i - 1].buffer.length; + data[i].data.data = iov[i - 1].buffer.value; + } + + /* + * Any necessary padding is added here to ensure that the + * encrypted token header is always at the end of the + * ciphertext. + */ + + /* XXX KRB5_CRYPTO_TYPE_PADDING */ + + /* encrypted CFX header in trailer (or after the header if in + DCE mode). Copy in header into E"header" + */ + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + if (trailer) + data[i].data.data = trailer->buffer.value; + else + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token); + + data[i].data.length = sizeof(*token); + memcpy(data[i].data.data, token, sizeof(*token)); + i++; + + /* Kerberos trailer comes after the gss trailer */ + data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token); + data[i].data.length = k5tsize; + i++; + + ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL); + if (ret != 0) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (rrc) { + token->RRC[0] = (rrc >> 8) & 0xFF; + token->RRC[1] = (rrc >> 0) & 0xFF; + } + + if (paddingoffset) + padding->buffer.length = data[paddingoffset].data.length; + + } else { + /* + plain packet: + + {data | "header" | gss-trailer (krb5 checksum) + + don't do RRC != 0 + + */ + + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i].buffer.length; + data[i].data.data = iov[i].buffer.value; + } + + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + data[i].data.data = header->buffer.value; + data[i].data.length = header->buffer.length; + i++; + + data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + data[i].data.data = trailer->buffer.value; + data[i].data.length = trailer->buffer.length; + i++; + + ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + token->EC[0] = (trailer->buffer.length >> 8) & 0xFF; + token->EC[1] = (trailer->buffer.length >> 0) & 0xFF; + } + + if (conf_state != NULL) + *conf_state = conf_req_flag; + + free(data); + + *minor_status = 0; + return GSS_S_COMPLETE; + + failure: + if (data) + free(data); + + gss_release_iov_buffer(&junk, iov, iov_count); + + return major_status; +} + +/* This is slowpath */ +static OM_uint32 +unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count) +{ + uint8_t *p, *q; + size_t len = 0, skip; + int i; + + for (i = 0; i < iov_count; i++) + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + len += iov[i].buffer.length; + + p = malloc(len); + if (p == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + q = p; + + /* copy up */ + + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + memcpy(q, iov[i].buffer.value, iov[i].buffer.length); + q += iov[i].buffer.length; + } + } + assert((q - p) == len); + + /* unrotate first part */ + q = p + rrc; + skip = rrc; + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + if (iov[i].buffer.length <= skip) { + skip -= iov[i].buffer.length; + } else { + memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip); + q += iov[i].buffer.length - skip; + skip = 0; + } + } + } + /* copy trailer */ + q = p; + skip = rrc; + for (i = 0; i < iov_count; i++) { + if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING || + GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER) + { + memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip)); + if (iov[i].buffer.length > skip) + break; + skip -= iov[i].buffer.length; + q += iov[i].buffer.length; + } + } + return GSS_S_COMPLETE; +} + + +OM_uint32 +_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + OM_uint32 seq_number_lo, seq_number_hi, major_status, junk; + gss_iov_buffer_desc *header, *trailer; + gss_cfx_wrap_token token, ttoken; + u_char token_flags; + krb5_error_code ret; + unsigned usage; + uint16_t ec, rrc; + krb5_crypto_iov *data = NULL; + int i, j; + + *minor_status = 0; + + header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); + if (header == NULL) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + if (header->buffer.length < sizeof(*token)) /* we check exact below */ + return GSS_S_DEFECTIVE_TOKEN; + + trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); + + token = (gss_cfx_wrap_token)header->buffer.value; + + if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04) + return GSS_S_DEFECTIVE_TOKEN; + + /* Ignore unknown flags */ + token_flags = token->Flags & + (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey); + + if (token_flags & CFXSentByAcceptor) { + if ((ctx->more_flags & LOCAL) == 0) + return GSS_S_DEFECTIVE_TOKEN; + } + + if (ctx->more_flags & ACCEPTOR_SUBKEY) { + if ((token_flags & CFXAcceptorSubkey) == 0) + return GSS_S_DEFECTIVE_TOKEN; + } else { + if (token_flags & CFXAcceptorSubkey) + return GSS_S_DEFECTIVE_TOKEN; + } + + if (token->Filler != 0xFF) + return GSS_S_DEFECTIVE_TOKEN; + + if (conf_state != NULL) + *conf_state = (token_flags & CFXSealed) ? 1 : 0; + + ec = (token->EC[0] << 8) | token->EC[1]; + rrc = (token->RRC[0] << 8) | token->RRC[1]; + + /* + * Check sequence number + */ + _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; + return GSS_S_UNSEQ_TOKEN; + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + ret = _gssapi_msg_order_check(ctx->order, seq_number_lo); + if (ret != 0) { + *minor_status = 0; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; + } + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + + /* + * Decrypt and/or verify checksum + */ + + if (ctx->more_flags & LOCAL) { + usage = KRB5_KU_USAGE_ACCEPTOR_SEAL; + } else { + usage = KRB5_KU_USAGE_INITIATOR_SEAL; + } + + data = calloc(iov_count + 3, sizeof(data[0])); + if (data == NULL) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (token_flags & CFXSealed) { + size_t k5tsize, k5hsize; + + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize); + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize); + + /* Rotate by RRC; bogus to do this in-place XXX */ + /* Check RRC */ + + if (trailer == NULL) { + size_t gsstsize = k5tsize + sizeof(*token); + size_t gsshsize = k5hsize + sizeof(*token); + + if (IS_DCE_STYLE(ctx)) + gsstsize += ec; + gsshsize += gsstsize; + + if (rrc != gsstsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + if (header->buffer.length != gsshsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } + } else if (trailer->buffer.length != sizeof(*token) + k5tsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } else if (header->buffer.length != sizeof(*token) + k5hsize) { + major_status = GSS_S_DEFECTIVE_TOKEN; + goto failure; + } else if (rrc != 0) { + /* go though slowpath */ + major_status = unrotate_iov(minor_status, rrc, iov, iov_count); + if (major_status) + goto failure; + } + + i = 0; + data[i].flags = KRB5_CRYPTO_TYPE_HEADER; + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize; + data[i].data.length = k5hsize; + i++; + + for (j = 0; j < iov_count; i++, j++) { + switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[j].buffer.length; + data[i].data.data = iov[j].buffer.value; + } + + /* encrypted CFX header in trailer (or after the header if in + DCE mode). Copy in header into E"header" + */ + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + if (trailer) + data[i].data.data = trailer->buffer.value; + else + data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token); + data[i].data.length = sizeof(*token); + ttoken = (gss_cfx_wrap_token)data[i].data.data; + i++; + + /* Kerberos trailer comes after the gss trailer */ + data[i].flags = KRB5_CRYPTO_TYPE_TRAILER; + data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token); + data[i].data.length = k5tsize; + i++; + + ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL); + if (ret != 0) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + + ttoken->RRC[0] = token->RRC[0]; + ttoken->RRC[1] = token->RRC[1]; + + /* Check the integrity of the header */ + if (memcmp(ttoken, token, sizeof(*token)) != 0) { + major_status = GSS_S_BAD_MIC; + goto failure; + } + } else { + /* Check RRC */ + if (rrc != 0) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (trailer == NULL) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + if (trailer->buffer.length != ec) { + *minor_status = EINVAL; + major_status = GSS_S_FAILURE; + goto failure; + } + + for (i = 0; i < iov_count; i++) { + switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_DATA: + case GSS_IOV_BUFFER_TYPE_PADDING: + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; + break; + default: + data[i].flags = KRB5_CRYPTO_TYPE_EMPTY; + break; + } + data[i].data.length = iov[i].buffer.length; + data[i].data.data = iov[i].buffer.value; + } + + data[i].flags = KRB5_CRYPTO_TYPE_DATA; + data[i].data.data = header->buffer.value; + data[i].data.length = header->buffer.length; + i++; + + data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM; + data[i].data.data = trailer->buffer.value; + data[i].data.length = trailer->buffer.length; + i++; + + token = (gss_cfx_wrap_token)header->buffer.value; + token->EC[0] = 0; + token->EC[1] = 0; + token->RRC[0] = 0; + token->RRC[1] = 0; + + ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL); + if (ret) { + *minor_status = ret; + major_status = GSS_S_FAILURE; + goto failure; + } + } + + if (qop_state != NULL) { + *qop_state = GSS_C_QOP_DEFAULT; + } + + free(data); + + *minor_status = 0; + return GSS_S_COMPLETE; + + failure: + if (data) + free(data); + + gss_release_iov_buffer(&junk, iov, iov_count); + + return major_status; +} + +OM_uint32 +_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + size_t size; + int i; + size_t *padding = NULL; + + GSSAPI_KRB5_INIT (&context); + *minor_status = 0; + + for (size = 0, i = 0; i < iov_count; i++) { + switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { + case GSS_IOV_BUFFER_TYPE_EMPTY: + break; + case GSS_IOV_BUFFER_TYPE_DATA: + size += iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_HEADER: + *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length); + if (*minor_status) + return GSS_S_FAILURE; + break; + case GSS_IOV_BUFFER_TYPE_TRAILER: + *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length); + if (*minor_status) + return GSS_S_FAILURE; + break; + case GSS_IOV_BUFFER_TYPE_PADDING: + if (padding != NULL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + padding = &iov[i].buffer.length; + break; + case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: + break; + default: + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + } + if (padding) { + size_t pad; + krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad); + if (pad > 1) { + *padding = pad - (size % pad); + if (*padding == pad) + *padding = 0; + } else + *padding = 0; + } + + return GSS_S_COMPLETE; +} + + + + OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, const gsskrb5_ctx ctx, krb5_context context, 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) diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c index fbb0f0218e..f45e4df3e2 100644 --- a/source4/heimdal/lib/gssapi/krb5/compare_name.c +++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_compare_name (OM_uint32 * minor_status, const gss_name_t name1, diff --git a/source4/heimdal/lib/gssapi/krb5/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c index 012602c074..221d219c69 100644 --- a/source4/heimdal/lib/gssapi/krb5/compat.c +++ b/source4/heimdal/lib/gssapi/krb5/compat.c @@ -33,9 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - - static krb5_error_code check_compat(OM_uint32 *minor_status, krb5_context context, krb5_const_principal name, diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c index 3230389938..987ceea4aa 100644 --- a/source4/heimdal/lib/gssapi/krb5/context_time.c +++ b/source4/heimdal/lib/gssapi/krb5/context_time.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_lifetime_left(OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index 40a8fab1b7..a4b28f91ed 100644 --- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - #if 0 OM_uint32 gss_krb5_copy_ccache(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c index a2a5de9fe7..7ccf0b0f79 100644 --- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * return the length of the mechanism in token or -1 * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index ea0831815a..b3d436ea01 100644 --- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c index 0b37731510..6487d84880 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_name.c +++ b/source4/heimdal/lib/gssapi/krb5/display_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_display_name (OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index 4136c25e53..f9d84fc762 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static const char * calling_error(OM_uint32 v) { diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c index 2b5e5c0ef4..b0188acd51 100644 --- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c +++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_duplicate_name ( OM_uint32 * minor_status, const gss_name_t src_name, diff --git a/source4/heimdal/lib/gssapi/krb5/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c index 838a34d7db..79cd9232e1 100644 --- a/source4/heimdal/lib/gssapi/krb5/encapsulate.c +++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - void _gssapi_encap_length (size_t data_len, size_t *len, diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c index bad73611dc..705bb70d91 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_name.c +++ b/source4/heimdal/lib/gssapi/krb5/export_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_export_name (OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c index 305d5c334e..3d3870a6b4 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_export_sec_context ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index 1c28f7c141..df23776a63 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,8 +34,6 @@ #include "gsskrb5_locl.h" #include <gssapi_mech.h> -RCSID("$Id$"); - /* * The implementation must reserve static storage for a * gss_OID_desc object containing the value diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 66aaba44d6..ad3009c73e 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 mic_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index 8f5387fe2b..d488ce754b 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 parse_krb5_name (OM_uint32 *minor_status, krb5_context context, diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c index ba1a977d2d..2af942338f 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_import_sec_context ( OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c index 3702106e79..b1d18bd244 100644 --- a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c +++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_indicate_mechs (OM_uint32 * minor_status, gss_OID_set * mech_set diff --git a/source4/heimdal/lib/gssapi/krb5/init.c b/source4/heimdal/lib/gssapi/krb5/init.c index b28e6a4c12..3a22c33ed6 100644 --- a/source4/heimdal/lib/gssapi/krb5/init.c +++ b/source4/heimdal/lib/gssapi/krb5/init.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; static int created_key; static HEIMDAL_thread_key context_key; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 4b632bd95a..35ab9dd88d 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * copy the addresses from `input_chan_bindings' (if any) to * the auth context `ac' @@ -697,7 +695,7 @@ repl_mutual if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; - if (ctx->flags & GSS_C_DCE_STYLE) { + if (IS_DCE_STYLE(ctx)) { /* There is no OID wrapping. */ indata.length = input_token->length; indata.data = input_token->value; diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c index 188a6135a4..381ffc9e6f 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_context ( OM_uint32 * minor_status, const gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c index 27e3014923..518736d78e 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c index 1fd9733940..9da1ac43f1 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred_by_mech ( OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c index 5a35202a6a..f32342f1d8 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, const gss_cred_id_t cred_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c index 5d54bd6508..5fa3c302a2 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_inquire_mechs_for_name ( OM_uint32 * minor_status, const gss_name_t input_name, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c index 9eba7b7f4d..591343307e 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c @@ -33,9 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - - static gss_OID *name_list[] = { &GSS_C_NT_HOSTBASED_SERVICE, &GSS_C_NT_USER_NAME, 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 index f8ef2a3aa4..ce01e666fa 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static int oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) { diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c index 9fd13f51bd..76ae3b78ed 100644 --- a/source4/heimdal/lib/gssapi/krb5/prf.c +++ b/source4/heimdal/lib/gssapi/krb5/prf.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c index 3229b36292..1c9d44588f 100644 --- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c +++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_process_context_token ( OM_uint32 *minor_status, const gss_ctx_id_t context_handle, diff --git a/source4/heimdal/lib/gssapi/krb5/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c index 18e0279939..b704e001eb 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_buffer.c +++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_buffer (OM_uint32 * minor_status, gss_buffer_t buffer diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c index 62674a1d53..5eec3c48cb 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c index 5491052c59..0fafc275d0 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_name.c +++ b/source4/heimdal/lib/gssapi/krb5/release_name.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - OM_uint32 _gsskrb5_release_name (OM_uint32 * minor_status, gss_name_t * input_name diff --git a/source4/heimdal/lib/gssapi/krb5/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c index 6391d44429..fbbc5b6c70 100644 --- a/source4/heimdal/lib/gssapi/krb5/sequence.c +++ b/source4/heimdal/lib/gssapi/krb5/sequence.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - #define DEFAULT_JITTER_WINDOW 20 struct gss_msg_order { diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 2a2390f8d1..15d7632e4c 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,8 +32,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* 1.2.752.43.13.17 */ static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc = {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")}; diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c index 460cfe942a..096e835045 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -36,8 +36,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 get_bool(OM_uint32 *minor_status, const gss_buffer_t value, diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index 0e87cb88b7..20cf952b4e 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 unwrap_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 6eb7ae4b08..c7e16e81f7 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - static OM_uint32 verify_mic_des (OM_uint32 * minor_status, diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index b9f4c237c7..3de13f908f 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -33,8 +33,6 @@ #include "gsskrb5_locl.h" -RCSID("$Id$"); - /* * Return initiator subkey, or if that doesn't exists, the subkey. */ @@ -540,7 +538,7 @@ OM_uint32 _gsskrb5_wrap if (ctx->more_flags & IS_CFX) return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag, - qop_req, input_message_buffer, conf_state, + input_message_buffer, conf_state, output_message_buffer); HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c index a8ebe644ab..b1bc7dd981 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c +++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c @@ -50,7 +50,7 @@ gss_acquire_cred(OM_uint32 *minor_status, int i; *minor_status = 0; - if (output_cred_handle) + if (output_cred_handle == NULL) return GSS_S_CALL_INACCESSIBLE_READ; if (actual_mechs) *actual_mechs = GSS_C_NO_OID_SET; diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c index cbe0cd1460..9c784f42de 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c @@ -3,27 +3,39 @@ */ #include "mech_locl.h" -RCSID("$Id$"); /** * Encrypts or sign the data. * + * This is a more complicated version of gss_wrap(), it allows the + * caller to use AEAD data (signed header/trailer) and allow greater + * controll over where the encrypted data is placed. + * * The maximum packet size is gss_context_stream_sizes.max_msg_size. * - * The caller needs provide the folloing buffers: + * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode: * * - HEADER (of size gss_context_stream_sizes.header) - * SIGN_ONLY (optional, zero or more) - * DATA - * SIGN_ONLY (optional, zero or more) - * PADDING (of size gss_context_stream_sizes.blocksize) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) * TRAILER (of size gss_context_stream_sizes.trailer) * * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the - * DATA elements is padded to a block bountry. + * DATA elements is padded to a block bountry and header is of at + * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer. + * + * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large. * * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER * + * When used in conf_req_flag=0, + * + * - HEADER (of size gss_context_stream_sizes.header) + * { DATA or SIGN_ONLY } (optional, zero or more) + * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) + * TRAILER (of size gss_context_stream_sizes.trailer) + * + * * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or * gss_context_query_attributes(). * @@ -65,6 +77,13 @@ gss_wrap_iov(OM_uint32 * minor_status, iov, iov_count); } +/** + * Decrypt or verifies the signature on the data. + * + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, @@ -99,7 +118,18 @@ gss_unwrap_iov(OM_uint32 *minor_status, iov, iov_count); } -OM_uint32 GSSAPI_LIB_FUNCTION +/** + * Update the length fields in iov buffer for the types: + * - GSS_IOV_BUFFER_TYPE_HEADER + * - GSS_IOV_BUFFER_TYPE_PADDING + * - GSS_IOV_BUFFER_TYPE_TRAILER + * + * Consider using gss_context_query_attributes() to fetch the data instead. + * + * @ingroup gssapi + */ + +OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_iov_length(OM_uint32 * minor_status, gss_ctx_id_t context_handle, int conf_req_flag, @@ -132,6 +162,13 @@ gss_wrap_iov_length(OM_uint32 * minor_status, iov, iov_count); } +/** + * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by + * looking at the GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED flag. + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_release_iov_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, @@ -146,9 +183,10 @@ gss_release_iov_buffer(OM_uint32 *minor_status, return GSS_S_CALL_INACCESSIBLE_READ; for (i = 0; i < iov_count; i++) { - if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) + if ((iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) == 0) continue; gss_release_buffer(&junk, &iov[i].buffer); + iov[i].type &= ~GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED; } return GSS_S_COMPLETE; } @@ -159,6 +197,8 @@ gss_release_iov_buffer(OM_uint32 *minor_status, * SSPI equivalent if this function is QueryContextAttributes. * * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. + * + * @ingroup gssapi */ static gss_OID_desc gss_c_attr_stream_sizes_desc = diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index 158126d99f..2bdfc28ebf 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -92,12 +92,6 @@ send_supported_mechs (OM_uint32 *minor_status, gss_buffer_t output_token) { NegotiationTokenWin nt; - char hostname[MAXHOSTNAMELEN + 1], *p; - gss_buffer_desc name_buf; - gss_OID name_type; - gss_name_t target_princ; - gss_name_t canon_princ; - OM_uint32 minor; size_t buf_len; gss_buffer_desc data; OM_uint32 ret; @@ -116,62 +110,9 @@ send_supported_mechs (OM_uint32 *minor_status, return ret; } - memset(&target_princ, 0, sizeof(target_princ)); - if (gethostname(hostname, sizeof(hostname) - 2) != 0) { - *minor_status = errno; - free_NegotiationTokenWin(&nt); - return GSS_S_FAILURE; - } - hostname[sizeof(hostname) - 1] = '\0'; - - /* 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) { - free_NegotiationTokenWin(&nt); - 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) { - free_NegotiationTokenWin(&nt); - 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) { - free_NegotiationTokenWin(&nt); - 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(nt.u.negTokenInit.negHints, 1); if (nt.u.negTokenInit.negHints == NULL) { *minor_status = ENOMEM; - gss_release_buffer(&minor, &name_buf); free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } @@ -179,20 +120,19 @@ send_supported_mechs (OM_uint32 *minor_status, ALLOC(nt.u.negTokenInit.negHints->hintName, 1); if (nt.u.negTokenInit.negHints->hintName == NULL) { *minor_status = ENOMEM; - gss_release_buffer(&minor, &name_buf); free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } - *(nt.u.negTokenInit.negHints->hintName) = name_buf.value; - name_buf.value = NULL; + *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore"); nt.u.negTokenInit.negHints->hintAddress = NULL; ASN1_MALLOC_ENCODE(NegotiationTokenWin, data.value, data.length, &nt, &buf_len, ret); free_NegotiationTokenWin(&nt); if (ret) { - return ret; + *minor_status = ret; + return GSS_S_FAILURE; } if (data.length != buf_len) abort(); |