aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/lib/gssapi/krb5/inq_context.c90
-rw-r--r--src/lib/gssapi/mechglue/g_inq_context.c5
-rw-r--r--src/tests/gssapi/Makefile.in17
-rwxr-xr-xsrc/tests/gssapi/t_gssapi.py4
-rw-r--r--src/tests/gssapi/t_inq_ctx.c131
6 files changed, 202 insertions, 46 deletions
diff --git a/.gitignore b/.gitignore
index c70cc29..d9ceb21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -307,6 +307,7 @@ testlog
/src/tests/gssapi/t_s4u2proxy_krb5
/src/tests/gssapi/t_saslname
/src/tests/gssapi/t_spnego
+/src/tests/gssapi/t_inq_ctx
/src/tests/hammer/kdc5_hammer
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
index 096df2a..cc06a93 100644
--- a/src/lib/gssapi/krb5/inq_context.c
+++ b/src/lib/gssapi/krb5/inq_context.c
@@ -104,55 +104,66 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
*acceptor_name = (gss_name_t) NULL;
ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (ctx->terminated || !ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- initiator = NULL;
- acceptor = NULL;
context = ctx->k5_context;
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- save_error_info(*minor_status, context);
- return(GSS_S_FAILURE);
- }
-
- if ((lifetime = ctx->krb_times.endtime - now) < 0)
- lifetime = 0;
+ /* RFC 2743 states that a partially completed context must return
+ * flags, locally_initiated, and open, and *may* return mech_type. */
+ if (ctx->established) {
+ initiator = NULL;
+ acceptor = NULL;
- if (initiator_name) {
- if ((code = kg_duplicate_name(context,
- ctx->initiate ? ctx->here : ctx->there,
- &initiator))) {
+ if ((code = krb5_timeofday(context, &now))) {
*minor_status = code;
save_error_info(*minor_status, context);
return(GSS_S_FAILURE);
}
- }
- if (acceptor_name) {
- if ((code = kg_duplicate_name(context,
- ctx->initiate ? ctx->there : ctx->here,
- &acceptor))) {
- if (initiator)
- kg_release_name(context, &initiator);
- *minor_status = code;
- save_error_info(*minor_status, context);
- return(GSS_S_FAILURE);
+ if ((lifetime = ctx->krb_times.endtime - now) < 0)
+ lifetime = 0;
+
+ if (initiator_name) {
+ code = kg_duplicate_name(context,
+ ctx->initiate ? ctx->here : ctx->there,
+ &initiator);
+ if (code) {
+ *minor_status = code;
+ save_error_info(*minor_status, context);
+ return(GSS_S_FAILURE);
+ }
}
- }
- if (initiator_name)
- *initiator_name = (gss_name_t) initiator;
+ if (acceptor_name) {
+ code = kg_duplicate_name(context,
+ ctx->initiate ? ctx->there : ctx->here,
+ &acceptor);
+ if (code) {
+ if (initiator)
+ kg_release_name(context, &initiator);
+ *minor_status = code;
+ save_error_info(*minor_status, context);
+ return(GSS_S_FAILURE);
+ }
+ }
- if (acceptor_name)
- *acceptor_name = (gss_name_t) acceptor;
+ if (initiator_name)
+ *initiator_name = (gss_name_t) initiator;
- if (lifetime_rec)
- *lifetime_rec = lifetime;
+ if (acceptor_name)
+ *acceptor_name = (gss_name_t) acceptor;
+
+ if (lifetime_rec)
+ *lifetime_rec = lifetime;
+ } else {
+ lifetime = 0;
+ if (initiator_name)
+ *initiator_name = GSS_C_NO_NAME;
+
+ if (acceptor_name)
+ *acceptor_name = GSS_C_NO_NAME;
+
+ if (lifetime_rec)
+ *lifetime_rec = 0;
+ }
if (mech_type)
*mech_type = (gss_OID) ctx->mech_used;
@@ -167,7 +178,10 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
*opened = ctx->established;
*minor_status = 0;
- return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ if (ctx->established)
+ return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ else
+ return GSS_S_COMPLETE;
}
OM_uint32
diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c
index d3fb343..6f1c71e 100644
--- a/src/lib/gssapi/mechglue/g_inq_context.c
+++ b/src/lib/gssapi/mechglue/g_inq_context.c
@@ -130,6 +130,7 @@ gss_inquire_context(
/* need to convert names */
if (src_name) {
+ if (localSourceName) {
status = gssint_convert_name_to_union_name(minor_status, mech,
localSourceName, src_name);
@@ -138,7 +139,9 @@ gss_inquire_context(
mech->gss_release_name(&temp_minor, &localTargName);
return (status);
}
-
+ } else {
+ *src_name = GSS_C_NO_NAME;
+ }
}
if (targ_name) {
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index a04cbb1..9fe5ed5 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -13,7 +13,7 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
$(srcdir)/t_credstore.c $(srcdir)/t_enctypes.c $(srcdir)/t_err.c \
$(srcdir)/t_export_cred.c $(srcdir)/t_export_name.c \
$(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \
- $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c \
+ $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \
$(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
$(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_pcontok.c \
$(srcdir)/t_prf.c $(srcdir)/t_s4u.c $(srcdir)/t_s4u2proxy_krb5.c \
@@ -22,16 +22,16 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_ciflags.o \
t_credstore.o t_enctypes.o t_err.o t_export_cred.o t_export_name.o \
t_gssexts.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \
- t_inq_mechs_name.o t_iov.o t_namingexts.o t_oid.o t_pcontok.o t_prf.o \
- t_s4u.o t_s4u2proxy_krb5.o t_saslname.o t_spnego.o
+ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_namingexts.o t_oid.o \
+ t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o t_spnego.o
COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
all:: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore t_enctypes \
t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \
- t_invalid t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid \
- t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego
+ t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_namingexts \
+ t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego
check-unix:: t_oid
$(RUN_SETUP) $(VALGRIND) ./t_invalid
@@ -40,7 +40,8 @@ check-unix:: t_oid
check-pytests:: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore \
t_enctypes t_err t_export_cred t_export_name t_imp_cred t_inq_cred \
- t_inq_mechs_name t_iov t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego
+ t_inq_ctx t_inq_mechs_name t_iov t_pcontok t_s4u t_s4u2proxy_krb5 \
+ t_spnego
$(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS)
@@ -78,6 +79,8 @@ t_invalid: t_invalid.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_invalid.o $(COMMON_LIBS)
t_inq_cred: t_inq_cred.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_inq_cred.o $(COMMON_LIBS)
+t_inq_ctx: t_inq_ctx.o $(COMMON_DEPS)
+ $(CC_LINK) -o $@ t_inq_ctx.o $(COMMON_LIBS)
t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS)
t_iov: t_iov.o $(COMMON_DEPS)
@@ -102,6 +105,6 @@ t_spnego: t_spnego.o $(COMMON_DEPS)
clean::
$(RM) ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore
$(RM) t_enctypes t_err t_export_cred t_export_name t_gssexts t_imp_cred
- $(RM) t_imp_name t_invalid t_inq_cred t_inq_mechs_name t_iov
+ $(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov
$(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5
$(RM) t_saslname t_spnego
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
index c8c9034..8093c3d 100755
--- a/src/tests/gssapi/t_gssapi.py
+++ b/src/tests/gssapi/t_gssapi.py
@@ -216,4 +216,8 @@ realm.run(['./t_err', 'p:' + realm.host_princ])
# Test the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option.
realm.run(['./t_ciflags', 'p:' + realm.host_princ])
+# Test that inquire_context works properly, even on incomplete
+# contexts.
+realm.run(['./t_inq_ctx', 'p:%s' % realm.host_princ])
+
success('GSSAPI tests')
diff --git a/src/tests/gssapi/t_inq_ctx.c b/src/tests/gssapi/t_inq_ctx.c
new file mode 100644
index 0000000..6575b7c
--- /dev/null
+++ b/src/tests/gssapi/t_inq_ctx.c
@@ -0,0 +1,131 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2015 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "common.h"
+
+
+/*
+ * Test program for inquiring about a security context, intented to be run from
+ * a Python test script. Partially establishes a context to test inquiring
+ * about an incomplete context, and then establishes full contexts and inquires
+ * them. Exits with status 0 if all operations are successful, or 1 if not.
+ *
+ * Usage: ./t_inq_ctx target_name
+ */
+
+static void
+check_inq_context(const char *header, gss_ctx_id_t context,
+ int incomplete, OM_uint32 expected_flags,
+ int expected_locally_init)
+{
+ OM_uint32 major, minor;
+ gss_name_t out_init_name, out_accept_name;
+ OM_uint32 out_lifetime;
+ gss_OID out_mech_type;
+ OM_uint32 out_flags;
+ int out_locally_init;
+ int out_open;
+ int mech_is_member;
+
+ major = gss_inquire_context(&minor, context, &out_init_name,
+ &out_accept_name, &out_lifetime,
+ &out_mech_type, &out_flags, &out_locally_init,
+ &out_open);
+ check_gsserr("gss_inquire_context", major, minor);
+
+ major = gss_test_oid_set_member(&minor, out_mech_type, &mechset_krb5,
+ &mech_is_member);
+ check_gsserr("gss_test_oid_set_member", major, minor);
+
+ assert(out_flags & expected_flags);
+ assert(mech_is_member);
+ assert(out_locally_init == expected_locally_init);
+ if (incomplete) {
+ assert(!out_open);
+ assert(out_lifetime == 0);
+ assert(out_init_name == GSS_C_NO_NAME);
+ assert(out_accept_name == GSS_C_NO_NAME);
+ } else {
+ assert(out_open);
+ assert(out_lifetime > 0);
+ assert(out_init_name != GSS_C_NO_NAME);
+ assert(out_accept_name != GSS_C_NO_NAME);
+ }
+
+ (void)gss_release_name(&minor, &out_accept_name);
+ (void)gss_release_name(&minor, &out_init_name);
+}
+
+/* Call gss_init_sec_context() once to create an initiator context (which will
+ * be partial if flags includes GSS_C_MUTUAL_FLAG and the mech is krb5). */
+static void
+start_init_context(gss_OID mech, gss_cred_id_t cred, gss_name_t tname,
+ OM_uint32 flags, gss_ctx_id_t *ctx)
+{
+ OM_uint32 major, minor;
+ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER;
+
+ *ctx = GSS_C_NO_CONTEXT;
+ major = gss_init_sec_context(&minor, cred, ctx, tname, mech, flags,
+ GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS,
+ NULL, NULL, &itok, NULL, NULL);
+ check_gsserr("gss_init_sec_context", major, minor);
+ (void)gss_release_buffer(&minor, &itok);
+}
+
+int
+main(int argc, char *argv[])
+{
+ OM_uint32 minor, flags;
+ gss_name_t tname;
+ gss_ctx_id_t ictx, actx;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s targetname\n", argv[0]);
+ return 1;
+ }
+ tname = import_name(argv[1]);
+
+ flags = GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG;
+ start_init_context(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, flags, &ictx);
+ check_inq_context("Partial initiator", ictx, 1, flags, 1);
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
+
+ establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
+ tname, flags, &ictx, &actx, NULL, NULL, NULL);
+
+ check_inq_context("Complete initiator", ictx, 0, flags, 1);
+ check_inq_context("Complete acceptor", actx, 0, flags, 0);
+
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
+
+ (void)gss_release_name(&minor, &tname);
+ return 0;
+}