static OM_uint32 gssint_unwrap_aead_iov_shim(gss_mechanism mech, OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer, gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int *conf_state, gss_qop_t *qop_state) { OM_uint32 status; gss_iov_buffer_desc iov[3]; int i = 0; iov[i].type = GSS_IOV_BUFFER_TYPE_STREAM; iov[i].buffer = *input_message_buffer; i++; if (input_assoc_buffer != NULL) { iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[i].buffer = *input_assoc_buffer; i++; } iov[i].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[i].buffer.value = NULL; iov[i].buffer.length = 0; i++; assert(mech->gss_unwrap_iov); status = mech->gss_unwrap_iov(minor_status, context_handle, conf_state, qop_state, iov, i); if (status == GSS_S_COMPLETE) { *output_payload_buffer = iov[i - 1].buffer; } else { OM_uint32 minor; map_error(minor_status, mech); if (iov[i - 1].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) { gss_release_buffer(&minor, &iov[i - 1].buffer); iov[i - 1].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED); } } return status; }
static OM_uint32 attr_localname(OM_uint32 *minor, const gss_mechanism mech, const gss_name_t mech_name, gss_buffer_t localname) { OM_uint32 major = GSS_S_UNAVAILABLE; OM_uint32 tmpMinor; int more = -1; gss_buffer_desc value; gss_buffer_desc display_value; int authenticated = 0, complete = 0; value.value = NULL; display_value.value = NULL; if (mech->gss_get_name_attribute == NULL) return GSS_S_UNAVAILABLE; major = mech->gss_get_name_attribute(minor, mech_name, GSS_C_ATTR_LOCAL_LOGIN_USER, &authenticated, &complete, &value, &display_value, &more); if (GSS_ERROR(major)) { map_error(minor, mech); goto cleanup; } if (!authenticated) major = GSS_S_UNAVAILABLE; else { localname->value = value.value; localname->length = value.length; value.value = NULL; } cleanup: if (display_value.value) gss_release_buffer(&tmpMinor, &display_value); if (value.value) gss_release_buffer(&tmpMinor, &value); return major; }
OM_uint32 gssint_wrap_aead (gss_mechanism mech, OM_uint32 *minor_status, gss_union_ctx_id_t ctx, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer, gss_buffer_t input_payload_buffer, int *conf_state, gss_buffer_t output_message_buffer) { /* EXPORT DELETE START */ OM_uint32 status; assert(ctx != NULL); assert(mech != NULL); if (mech->gss_wrap_aead) { status = mech->gss_wrap_aead(minor_status, ctx->internal_ctx_id, conf_req_flag, qop_req, input_assoc_buffer, input_payload_buffer, conf_state, output_message_buffer); if (status != GSS_S_COMPLETE) map_error(minor_status, mech); } else if (mech->gss_wrap_iov && mech->gss_wrap_iov_length) { status = gssint_wrap_aead_iov_shim(mech, minor_status, ctx->internal_ctx_id, conf_req_flag, qop_req, input_assoc_buffer, input_payload_buffer, conf_state, output_message_buffer); } else status = GSS_S_UNAVAILABLE; /* EXPORT DELETE END */ return status; }
static OM_uint32 gssint_wrap_aead_iov_shim(gss_mechanism mech, OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer, gss_buffer_t input_payload_buffer, int *conf_state, gss_buffer_t output_message_buffer) { gss_iov_buffer_desc iov[5]; OM_uint32 status; size_t offset; int i = 0, iov_count; /* HEADER | SIGN_ONLY_DATA | DATA | PADDING | TRAILER */ iov[i].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[i].buffer.value = NULL; iov[i].buffer.length = 0; i++; if (input_assoc_buffer != GSS_C_NO_BUFFER) { iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[i].buffer = *input_assoc_buffer; i++; } iov[i].type = GSS_IOV_BUFFER_TYPE_DATA; iov[i].buffer = *input_payload_buffer; i++; iov[i].type = GSS_IOV_BUFFER_TYPE_PADDING; iov[i].buffer.value = NULL; iov[i].buffer.length = 0; i++; iov[i].type = GSS_IOV_BUFFER_TYPE_TRAILER; iov[i].buffer.value = NULL; iov[i].buffer.length = 0; i++; iov_count = i; assert(mech->gss_wrap_iov_length); status = mech->gss_wrap_iov_length(minor_status, context_handle, conf_req_flag, qop_req, NULL, iov, iov_count); if (status != GSS_S_COMPLETE) { map_error(minor_status, mech); return status; } /* Format output token (does not include associated data) */ for (i = 0, output_message_buffer->length = 0; i < iov_count; i++) { if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) continue; output_message_buffer->length += iov[i].buffer.length; } output_message_buffer->value = malloc(output_message_buffer->length); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } i = 0, offset = 0; /* HEADER */ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; offset += iov[i].buffer.length; i++; /* SIGN_ONLY_DATA */ if (input_assoc_buffer != GSS_C_NO_BUFFER) i++; /* DATA */ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; offset += iov[i].buffer.length; memcpy(iov[i].buffer.value, input_payload_buffer->value, iov[i].buffer.length); i++; /* PADDING */ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; offset += iov[i].buffer.length; i++; /* TRAILER */ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset; offset += iov[i].buffer.length; i++; assert(offset == output_message_buffer->length); assert(mech->gss_wrap_iov); status = mech->gss_wrap_iov(minor_status, context_handle, conf_req_flag, qop_req, conf_state, iov, iov_count); if (status != GSS_S_COMPLETE) { OM_uint32 minor; map_error(minor_status, mech); gss_release_buffer(&minor, output_message_buffer); } return status; }
static OM_uint32 attr_pname_to_uid(OM_uint32 *minor, const gss_mechanism mech, const gss_name_t mech_name, uid_t *uidp) { OM_uint32 major = GSS_S_UNAVAILABLE; #ifndef NO_PASSWORD OM_uint32 tmpMinor; int more = -1; if (mech->gss_get_name_attribute == NULL) return GSS_S_UNAVAILABLE; while (more != 0) { gss_buffer_desc value; gss_buffer_desc display_value; int authenticated = 0, complete = 0, code; char pwbuf[BUFSIZ]; struct passwd pw, *pwd; char *localLoginUser; major = mech->gss_get_name_attribute(minor, mech_name, GSS_C_ATTR_LOCAL_LOGIN_USER, &authenticated, &complete, &value, &display_value, &more); if (GSS_ERROR(major)) { map_error(minor, mech); break; } localLoginUser = malloc(value.length + 1); if (localLoginUser == NULL) { major = GSS_S_FAILURE; *minor = ENOMEM; break; } memcpy(localLoginUser, value.value, value.length); localLoginUser[value.length] = '\0'; code = k5_getpwnam_r(localLoginUser, &pw, pwbuf, sizeof(pwbuf), &pwd); free(localLoginUser); gss_release_buffer(&tmpMinor, &value); gss_release_buffer(&tmpMinor, &display_value); if (code == 0 && pwd != NULL) { *uidp = pwd->pw_uid; major = GSS_S_COMPLETE; *minor = 0; break; } else major = GSS_S_UNAVAILABLE; } #endif /* !NO_PASSWORD */ return major; }