Modified version of the patch to 1.14 that are missing test suite pieces. Also backports a random comment fixup we needed from master. diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 05dc321..ac53662 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1396,6 +1396,11 @@ OM_uint32 KRB5_CALLCONV iakerb_gss_export_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token); + +OM_uint32 KRB5_CALLCONV +iakerb_gss_import_sec_context(OM_uint32 *minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle); #endif /* LEAN_CLIENT */ OM_uint32 KRB5_CALLCONV diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 9a23656..d7ba279 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanism = { NULL, #else iakerb_gss_export_sec_context, - NULL, + iakerb_gss_import_sec_context, #endif krb5_gss_inquire_cred_by_mech, krb5_gss_inquire_names_for_mech, diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c index 4662bd9..32a341e 100644 --- a/src/lib/gssapi/krb5/iakerb.c +++ b/src/lib/gssapi/krb5/iakerb.c @@ -727,10 +727,6 @@ cleanup: return code; } -/* - * Delete an IAKERB context. This can also accept Kerberos context - * handles. The heuristic is similar to SPNEGO's delete_sec_context. - */ OM_uint32 KRB5_CALLCONV iakerb_gss_delete_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, @@ -1061,7 +1057,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, gss_buffer_t interprocess_token) { OM_uint32 maj; - iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; + iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; /* We don't currently support exporting partially established contexts. */ if (!ctx->established) @@ -1076,13 +1072,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, return maj; } -/* - * Until we implement partial context exports, there are no SPNEGO exported - * context tokens, only tokens for the underlying krb5 context. So we do not - * need to implement an iakerb_gss_import_sec_context() yet; it would be - * unreachable except via a manually constructed token. - */ +OM_uint32 KRB5_CALLCONV +iakerb_gss_import_sec_context(OM_uint32 *minor_status, + gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle) +{ + OM_uint32 maj, tmpmin; + krb5_error_code code; + gss_ctx_id_t gssc; + krb5_gss_ctx_id_t kctx; + iakerb_ctx_id_t ctx; + maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc); + if (maj != GSS_S_COMPLETE) + return maj; + kctx = (krb5_gss_ctx_id_t)gssc; + + if (!kctx->established) { + /* We don't currently support importing partially established + * contexts. */ + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + code = iakerb_alloc_context(&ctx, kctx->initiate); + if (code != 0) { + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); + *minor_status = code; + return GSS_S_FAILURE; + } + + ctx->gssc = gssc; + ctx->established = 1; + *context_handle = (gss_ctx_id_t)ctx; + return GSS_S_COMPLETE; +} #endif /* LEAN_CLIENT */ OM_uint32 KRB5_CALLCONV diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index 3423f22..ec38eea 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -2253,12 +2253,33 @@ spnego_gss_import_sec_context( const gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle) { - /* - * Until we implement partial context exports, there are no SPNEGO - * exported context tokens, only tokens for underlying mechs. So just - * return an error for now. - */ - return GSS_S_UNAVAILABLE; + OM_uint32 ret, tmpmin; + gss_ctx_id_t mctx; + spnego_gss_ctx_id_t sc; + int initiate, opened; + + ret = gss_import_sec_context(minor_status, interprocess_token, &mctx); + if (ret != GSS_S_COMPLETE) + return ret; + + ret = gss_inquire_context(&tmpmin, mctx, NULL, NULL, NULL, NULL, NULL, + &initiate, &opened); + if (ret != GSS_S_COMPLETE || !opened) { + /* We don't currently support importing partially established + * contexts. */ + (void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + sc = create_spnego_ctx(initiate); + if (sc == NULL) { + (void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + sc->ctx_handle = mctx; + sc->opened = 1; + *context_handle = (gss_ctx_id_t)sc; + return GSS_S_COMPLETE; } #endif /* LEAN_CLIENT */