gss: port NegoEx implementation from MIT
An implementation of draft-zhu-negoex-04 for MIT Kerberos was developed in 2011. This has been recently integrated, with many fixes from Greg Hudson. This commit ports it to Heimdal. The implementation has been interoperability tested with MIT Kerberos and Windows, using the GSS EAP mechanism developed as part of the Moonshot project. The SPNEGO code was also updated to import the state machine from Apple which improves mechListMIC processing and avoids discarding initial context tokens generated during mechanism probing, that can be used for optimistic tokens. Finally, to aid in testing, the GSS-API mechanism glue configuration file can be changed using the environment variable GSS_MECH_CONFIG. This environment variable name, along with the format of the configuration file, is compatible with MIT (although it would be difficult for a single mechanism binary to support both implementations).
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "heim_threads.h"
|
||||
#include <krb5.h>
|
||||
#include "krb5_locl.h"
|
||||
#include "negoex_err.h"
|
||||
|
||||
struct mg_thread_ctx {
|
||||
gss_OID mech;
|
||||
@@ -99,6 +100,8 @@ _gss_mechglue_thread(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
krb5_add_et_list(ctx->context, initialize_ngex_error_table_r);
|
||||
|
||||
HEIMDAL_setspecific(context_key, ctx, ret);
|
||||
if (ret) {
|
||||
krb5_free_context(ctx->context);
|
||||
@@ -109,6 +112,16 @@ _gss_mechglue_thread(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
krb5_context
|
||||
_gss_mg_krb5_context(void)
|
||||
{
|
||||
struct mg_thread_ctx *mg;
|
||||
|
||||
mg = _gss_mechglue_thread();
|
||||
|
||||
return mg ? mg->context : NULL;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gss_mg_get_error(const gss_OID mech,
|
||||
OM_uint32 value,
|
||||
|
@@ -30,8 +30,10 @@
|
||||
|
||||
#include "mech_locl.h"
|
||||
|
||||
static gss_cred_id_t
|
||||
_gss_mech_cred_find(gss_const_cred_id_t cred_handle, gss_OID mech_type)
|
||||
gss_cred_id_t
|
||||
_gss_mg_find_mech_cred(
|
||||
gss_const_cred_id_t cred_handle,
|
||||
gss_const_OID mech_type)
|
||||
{
|
||||
struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
|
||||
struct _gss_mechanism_cred *mc;
|
||||
@@ -227,7 +229,7 @@ gss_init_sec_context(OM_uint32 * minor_status,
|
||||
if (m->gm_flags & GM_USE_MG_CRED)
|
||||
cred_handle = initiator_cred_handle;
|
||||
else
|
||||
cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
|
||||
cred_handle = _gss_mg_find_mech_cred(initiator_cred_handle, mech_type);
|
||||
|
||||
if (initiator_cred_handle != GSS_C_NO_CREDENTIAL &&
|
||||
cred_handle == NULL) {
|
||||
|
@@ -96,8 +96,8 @@ gss_inquire_cred(OM_uint32 *minor_status,
|
||||
struct _gss_mechanism_cred *mc;
|
||||
|
||||
HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) {
|
||||
gss_name_t mc_name;
|
||||
OM_uint32 mc_lifetime;
|
||||
gss_name_t mc_name = GSS_C_NO_NAME;
|
||||
OM_uint32 mc_lifetime = GSS_C_INDEFINITE;
|
||||
|
||||
if (mc->gmc_mech->gm_inquire_cred == NULL)
|
||||
continue;
|
||||
|
@@ -179,11 +179,20 @@ do { \
|
||||
m->gm_mech.gm_ ## name = NULL; \
|
||||
} while (0)
|
||||
|
||||
/* mech exports gssspi_XXX, internally referred to as gss_XXX */
|
||||
#define OPTSPISYM(name) \
|
||||
do { \
|
||||
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \
|
||||
} while (0)
|
||||
|
||||
/* mech exports gssspi_XXX, internally referred to as gssspi_XXX */
|
||||
#define OPTSPISPISYM(name) \
|
||||
do { \
|
||||
m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \
|
||||
if (m->gm_mech.gm_ ## name == gssspi_ ## name) \
|
||||
m->gm_mech.gm_ ## name = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define COMPATSYM(name) \
|
||||
do { \
|
||||
m->gm_mech.gm_compat->gmc_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
|
||||
@@ -262,6 +271,7 @@ _gss_load_mech(void)
|
||||
void *so;
|
||||
gss_OID mech_oid;
|
||||
int found;
|
||||
const char *conf = secure_getenv("GSS_MECH_CONFIG");
|
||||
#endif
|
||||
|
||||
heim_base_once_f(&once, &_gss_mechs, init_mech_switch_list);
|
||||
@@ -285,7 +295,7 @@ _gss_load_mech(void)
|
||||
add_builtin(__gss_ntlm_initialize());
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
fp = fopen(_PATH_GSS_MECH, "r");
|
||||
fp = fopen(conf ? conf : _PATH_GSS_MECH, "r");
|
||||
if (!fp) {
|
||||
HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
|
||||
return;
|
||||
@@ -410,6 +420,9 @@ _gss_load_mech(void)
|
||||
OPTSYM(set_neg_mechs);
|
||||
OPTSYM(get_neg_mechs);
|
||||
OPTSPISYM(authorize_localname);
|
||||
OPTSPISPISYM(query_mechanism_info);
|
||||
OPTSPISPISYM(query_meta_data);
|
||||
OPTSPISPISYM(exchange_meta_data);
|
||||
|
||||
mi = (_gss_mo_init *)dlsym(so, "gss_mo_init");
|
||||
if (mi != NULL) {
|
||||
|
@@ -124,6 +124,12 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_win2k_pac_x_oid_desc = { 8, rk_UNCO
|
||||
/* GSS_C_INQ_SSPI_SESSION_KEY - 1.2.840.113554.1.2.2.5.5 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_sspi_session_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05") };
|
||||
|
||||
/* GSS_C_INQ_NEGOEX_KEY - 1.2.840.113554.1.2.2.5.16 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_negoex_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x10") };
|
||||
|
||||
/* GSS_C_INQ_NEGOEX_VERIFY_KEY - 1.2.840.113554.1.2.2.5.17 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_negoex_verify_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x11") };
|
||||
|
||||
/* GSS_KRB5_MECHANISM - 1.2.840.113554.1.2.2 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc = { 9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
|
||||
|
||||
@@ -139,6 +145,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_peer_has_updated_spnego_oid_desc = { 9,
|
||||
/* GSS_C_NTLM_RESET_CRYPTO - 1.3.6.1.4.1.7165.655.1.3 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_reset_crypto_oid_desc = { 11, rk_UNCONST("\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x03") };
|
||||
|
||||
/* GSS_NEGOEX_MECHANISM - 1.3.6.1.4.1.311.2.2.30 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_negoex_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e") };
|
||||
|
||||
/* GSS_C_MA_MECH_CONCRETE - 1.3.6.1.5.5.13.1 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_concrete_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x01") };
|
||||
|
||||
@@ -220,6 +229,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_compress_oid_desc = { 7, rk_UNCONST(
|
||||
/* GSS_C_MA_CTX_TRANS - 1.3.6.1.5.5.13.27 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_ctx_trans_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x1b") };
|
||||
|
||||
/* GSS_C_MA_NEGOEX_AND_SPNEGO - 1.2.840.113554.1.2.2.5.18 */
|
||||
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_negoex_and_spnego_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x12") };
|
||||
|
||||
struct _gss_oid_name_table _gss_ont_ma[] = {
|
||||
{ GSS_C_MA_AUTH_INIT, "GSS_C_MA_AUTH_INIT", "auth-init-princ", "" },
|
||||
{ GSS_C_MA_AUTH_INIT_ANON, "GSS_C_MA_AUTH_INIT_ANON", "auth-init-princ-anon", "" },
|
||||
@@ -243,6 +255,7 @@ struct _gss_oid_name_table _gss_ont_ma[] = {
|
||||
{ GSS_C_MA_MECH_NEGO, "GSS_C_MA_MECH_NEGO", "mech-negotiation-mech", "" },
|
||||
{ GSS_C_MA_MECH_PSEUDO, "GSS_C_MA_MECH_PSEUDO", "pseudo-mech", "" },
|
||||
{ GSS_C_MA_MIC, "GSS_C_MA_MIC", "mic", "" },
|
||||
{ GSS_C_MA_NEGOEX_AND_SPNEGO, "GSS_C_MA_NEGOEX_AND_SPNEGO", "negoex-and-spnego", "Indicates that a mechanism supports both NegoEx and SPNEGO" },
|
||||
{ GSS_C_MA_NOT_DFLT_MECH, "GSS_C_MA_NOT_DFLT_MECH", "mech-not-default", "" },
|
||||
{ GSS_C_MA_NOT_MECH, "GSS_C_MA_NOT_MECH", "not-mech", "" },
|
||||
{ GSS_C_MA_OOS_DET, "GSS_C_MA_OOS_DET", "oos-detection", "" },
|
||||
@@ -303,11 +316,14 @@ gss_OID _gss_ot_internal[] = {
|
||||
&__gss_netlogon_nt_netbios_dns_name_oid_desc,
|
||||
&__gss_c_inq_win2k_pac_x_oid_desc,
|
||||
&__gss_c_inq_sspi_session_key_oid_desc,
|
||||
&__gss_c_inq_negoex_key_oid_desc,
|
||||
&__gss_c_inq_negoex_verify_key_oid_desc,
|
||||
&__gss_krb5_mechanism_oid_desc,
|
||||
&__gss_ntlm_mechanism_oid_desc,
|
||||
&__gss_spnego_mechanism_oid_desc,
|
||||
&__gss_c_peer_has_updated_spnego_oid_desc,
|
||||
&__gss_c_ntlm_reset_crypto_oid_desc,
|
||||
&__gss_negoex_mechanism_oid_desc,
|
||||
&__gss_c_ma_mech_concrete_oid_desc,
|
||||
&__gss_c_ma_mech_pseudo_oid_desc,
|
||||
&__gss_c_ma_mech_composite_oid_desc,
|
||||
@@ -335,6 +351,7 @@ gss_OID _gss_ot_internal[] = {
|
||||
&__gss_c_ma_pfs_oid_desc,
|
||||
&__gss_c_ma_compress_oid_desc,
|
||||
&__gss_c_ma_ctx_trans_oid_desc,
|
||||
&__gss_c_ma_negoex_and_spnego_oid_desc,
|
||||
};
|
||||
|
||||
size_t _gss_ot_internal_count = sizeof(_gss_ot_internal) / sizeof(_gss_ot_internal[0]);
|
||||
|
@@ -147,3 +147,62 @@ _gss_copy_buffer(OM_uint32 *minor_status,
|
||||
return (GSS_S_COMPLETE);
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_encode_le_uint32(uint32_t n, uint8_t *p)
|
||||
{
|
||||
p[0] = (n >> 0 ) & 0xFF;
|
||||
p[1] = (n >> 8 ) & 0xFF;
|
||||
p[2] = (n >> 16) & 0xFF;
|
||||
p[3] = (n >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_decode_le_uint32(const void *ptr, uint32_t *n)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
*n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_encode_be_uint32(uint32_t n, uint8_t *p)
|
||||
{
|
||||
p[0] = (n >> 24) & 0xFF;
|
||||
p[1] = (n >> 16) & 0xFF;
|
||||
p[2] = (n >> 8 ) & 0xFF;
|
||||
p[3] = (n >> 0 ) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_decode_be_uint32(const void *ptr, uint32_t *n)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
*n = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_encode_le_uint16(uint16_t n, uint8_t *p)
|
||||
{
|
||||
p[0] = (n >> 0 ) & 0xFF;
|
||||
p[1] = (n >> 8 ) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_decode_le_uint16(const void *ptr, uint16_t *n)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
*n = (p[0] << 0) | (p[1] << 8);
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_encode_be_uint16(uint16_t n, uint8_t *p)
|
||||
{
|
||||
p[0] = (n >> 24) & 0xFF;
|
||||
p[1] = (n >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
void
|
||||
_gss_mg_decode_be_uint16(const void *ptr, uint16_t *n)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
*n = (p[0] << 24) | (p[1] << 16);
|
||||
}
|
||||
|
115
lib/gssapi/mech/gssspi_exchange_meta_data.c
Normal file
115
lib/gssapi/mech/gssspi_exchange_meta_data.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
* Portions Copyright (c) 2019 AuriStor, Inc. 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.
|
||||
*/
|
||||
|
||||
#include "mech_locl.h"
|
||||
|
||||
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
|
||||
gssspi_exchange_meta_data(
|
||||
OM_uint32 *minor_status,
|
||||
gss_const_OID input_mech_type,
|
||||
gss_cred_id_t input_cred_handle,
|
||||
gss_ctx_id_t *context_handle,
|
||||
gss_const_name_t target_name,
|
||||
OM_uint32 req_flags,
|
||||
gss_const_buffer_t meta_data)
|
||||
{
|
||||
OM_uint32 major_status, junk;
|
||||
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;
|
||||
gss_cred_id_t cred_handle;
|
||||
int allocated_ctx;
|
||||
gss_const_OID mech_type = input_mech_type;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (mech_type == GSS_C_NO_OID)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = calloc(1, sizeof(struct _gss_context));
|
||||
if (ctx == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
m = ctx->gc_mech = __gss_get_mechanism(mech_type);
|
||||
if (m == NULL) {
|
||||
free(ctx);
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
allocated_ctx = 1;
|
||||
} else {
|
||||
m = ctx->gc_mech;
|
||||
mech_type = &m->gm_mech_oid;
|
||||
allocated_ctx = 0;
|
||||
}
|
||||
|
||||
if (m->gm_exchange_meta_data == NULL) {
|
||||
major_status = GSS_S_BAD_MECH;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
goto cleanup;
|
||||
|
||||
if (m->gm_flags & GM_USE_MG_CRED)
|
||||
cred_handle = input_cred_handle;
|
||||
else
|
||||
cred_handle = _gss_mg_find_mech_cred(input_cred_handle, mech_type);
|
||||
|
||||
if (input_cred_handle != GSS_C_NO_CREDENTIAL &&
|
||||
cred_handle == NULL) {
|
||||
major_status = GSS_S_NO_CRED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* note: mechanism is not obligated to allocate a context on success */
|
||||
major_status = m->gm_exchange_meta_data(minor_status,
|
||||
mech_type,
|
||||
cred_handle,
|
||||
&ctx->gc_ctx,
|
||||
mn ? mn->gmn_name : GSS_C_NO_NAME,
|
||||
req_flags,
|
||||
meta_data);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
_gss_mg_error(m, *minor_status);
|
||||
|
||||
cleanup:
|
||||
if (major_status != GSS_S_COMPLETE || ctx->gc_ctx == GSS_C_NO_CONTEXT)
|
||||
gss_delete_sec_context(&junk, (gss_ctx_id_t *)&ctx, GSS_C_NO_BUFFER);
|
||||
|
||||
*context_handle = (gss_ctx_id_t) ctx;
|
||||
|
||||
_gss_mg_log(10, "gss-emd: return %d/%d", (int)major_status, (int)*minor_status);
|
||||
|
||||
return major_status;
|
||||
}
|
55
lib/gssapi/mech/gssspi_query_mechanism_info.c
Normal file
55
lib/gssapi/mech/gssspi_query_mechanism_info.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*-
|
||||
* Copyright (c) 2019 AuriStor, Inc.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mech_locl.h"
|
||||
|
||||
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
|
||||
gssspi_query_mechanism_info(
|
||||
OM_uint32 *minor_status,
|
||||
gss_const_OID mech_type,
|
||||
unsigned char auth_scheme[16])
|
||||
{
|
||||
OM_uint32 major_status;
|
||||
gssapi_mech_interface m;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (mech_type == GSS_C_NO_OID)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
m = __gss_get_mechanism(mech_type);
|
||||
if (m == NULL || m->gm_query_mechanism_info == NULL)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
major_status = m->gm_query_mechanism_info(minor_status,
|
||||
mech_type,
|
||||
auth_scheme);
|
||||
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
_gss_mg_error(m, *minor_status);
|
||||
|
||||
return major_status;
|
||||
}
|
117
lib/gssapi/mech/gssspi_query_meta_data.c
Normal file
117
lib/gssapi/mech/gssspi_query_meta_data.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
* Portions Copyright (c) 2019 AuriStor, Inc. 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.
|
||||
*/
|
||||
|
||||
#include "mech_locl.h"
|
||||
|
||||
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
|
||||
gssspi_query_meta_data(
|
||||
OM_uint32 *minor_status,
|
||||
gss_const_OID input_mech_type,
|
||||
gss_cred_id_t input_cred_handle,
|
||||
gss_ctx_id_t *context_handle,
|
||||
gss_const_name_t target_name,
|
||||
OM_uint32 req_flags,
|
||||
gss_buffer_t meta_data)
|
||||
{
|
||||
OM_uint32 major_status, junk;
|
||||
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;
|
||||
gss_cred_id_t cred_handle;
|
||||
int allocated_ctx;
|
||||
gss_const_OID mech_type = input_mech_type;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
_mg_buffer_zero(meta_data);
|
||||
|
||||
if (mech_type == GSS_C_NO_OID)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = calloc(1, sizeof(struct _gss_context));
|
||||
if (ctx == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
m = ctx->gc_mech = __gss_get_mechanism(mech_type);
|
||||
if (m == NULL) {
|
||||
free(ctx);
|
||||
return GSS_S_BAD_MECH;
|
||||
}
|
||||
allocated_ctx = 1;
|
||||
} else {
|
||||
m = ctx->gc_mech;
|
||||
mech_type = &m->gm_mech_oid;
|
||||
allocated_ctx = 0;
|
||||
}
|
||||
|
||||
if (m->gm_query_meta_data == NULL) {
|
||||
major_status = GSS_S_BAD_MECH;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
goto cleanup;
|
||||
|
||||
if (m->gm_flags & GM_USE_MG_CRED)
|
||||
cred_handle = input_cred_handle;
|
||||
else
|
||||
cred_handle = _gss_mg_find_mech_cred(input_cred_handle, mech_type);
|
||||
|
||||
if (input_cred_handle != GSS_C_NO_CREDENTIAL &&
|
||||
cred_handle == NULL) {
|
||||
major_status = GSS_S_NO_CRED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* note: mechanism is not obligated to allocate a context on success */
|
||||
major_status = m->gm_query_meta_data(minor_status,
|
||||
mech_type,
|
||||
cred_handle,
|
||||
&ctx->gc_ctx,
|
||||
mn ? mn->gmn_name : GSS_C_NO_NAME,
|
||||
req_flags,
|
||||
meta_data);
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
_gss_mg_error(m, *minor_status);
|
||||
|
||||
cleanup:
|
||||
if (major_status != GSS_S_COMPLETE || ctx->gc_ctx == GSS_C_NO_CONTEXT)
|
||||
gss_delete_sec_context(&junk, (gss_ctx_id_t *)&ctx, GSS_C_NO_BUFFER);
|
||||
|
||||
*context_handle = (gss_ctx_id_t) ctx;
|
||||
|
||||
_gss_mg_log(10, "gss-qmd: return %d/%d", (int)major_status, (int)*minor_status);
|
||||
|
||||
return major_status;
|
||||
}
|
@@ -56,6 +56,7 @@
|
||||
#include <gssapi.h>
|
||||
#include <gssapi_mech.h>
|
||||
#include <gssapi_krb5.h>
|
||||
#include <gssapi_spnego.h>
|
||||
|
||||
#include <heimqueue.h>
|
||||
|
||||
|
@@ -31,3 +31,13 @@ OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID);
|
||||
OM_uint32 _gss_intern_oid(OM_uint32 *, gss_const_OID, gss_OID *);
|
||||
OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status,
|
||||
const gss_buffer_t from_buf, gss_buffer_t to_buf);
|
||||
|
||||
void _gss_mg_encode_le_uint32(uint32_t n, uint8_t *p);
|
||||
void _gss_mg_decode_le_uint32(const void *ptr, uint32_t *n);
|
||||
void _gss_mg_encode_be_uint32(uint32_t n, uint8_t *p);
|
||||
void _gss_mg_decode_be_uint32(const void *ptr, uint32_t *n);
|
||||
|
||||
void _gss_mg_encode_le_uint16(uint16_t n, uint8_t *p);
|
||||
void _gss_mg_decode_le_uint16(const void *ptr, uint16_t *n);
|
||||
void _gss_mg_encode_be_uint16(uint16_t n, uint8_t *p);
|
||||
void _gss_mg_decode_be_uint16(const void *ptr, uint16_t *n);
|
||||
|
Reference in New Issue
Block a user