|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright 2015 Red Hat, Inc.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
fd8b60 |
* obtaining a copy of this software and associated documentation files
|
|
Packit |
fd8b60 |
* (the "Software"), to deal in the Software without restriction,
|
|
Packit |
fd8b60 |
* including without limitation the rights to use, copy, modify, merge,
|
|
Packit |
fd8b60 |
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
Packit |
fd8b60 |
* and to permit persons to whom the Software is furnished to do so,
|
|
Packit |
fd8b60 |
* subject to the following conditions:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
fd8b60 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
fd8b60 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
fd8b60 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
fd8b60 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
fd8b60 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
fd8b60 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
fd8b60 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
fd8b60 |
* SOFTWARE.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include <stdio.h>
|
|
Packit |
fd8b60 |
#include <stdlib.h>
|
|
Packit |
fd8b60 |
#include <string.h>
|
|
Packit |
fd8b60 |
#include <assert.h>
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include "common.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Test program for inquiring about a security context, intented to be run from
|
|
Packit |
fd8b60 |
* a Python test script. Partially establishes a context to test inquiring
|
|
Packit |
fd8b60 |
* about an incomplete context, and then establishes full contexts and inquires
|
|
Packit |
fd8b60 |
* them. Exits with status 0 if all operations are successful, or 1 if not.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Usage: ./t_inq_ctx target_name
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
check_inq_context(gss_ctx_id_t context, int incomplete, gss_OID expected_mech,
|
|
Packit |
fd8b60 |
OM_uint32 expected_flags, int expected_locally_init)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_name_t out_init_name, out_accept_name;
|
|
Packit |
fd8b60 |
OM_uint32 out_lifetime;
|
|
Packit |
fd8b60 |
gss_OID out_mech_type;
|
|
Packit |
fd8b60 |
OM_uint32 out_flags;
|
|
Packit |
fd8b60 |
int out_locally_init;
|
|
Packit |
fd8b60 |
int out_open;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_inquire_context(&minor, context, &out_init_name,
|
|
Packit |
fd8b60 |
&out_accept_name, &out_lifetime,
|
|
Packit |
fd8b60 |
&out_mech_type, &out_flags, &out_locally_init,
|
|
Packit |
fd8b60 |
&out_open);
|
|
Packit |
fd8b60 |
check_gsserr("gss_inquire_context", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
assert(gss_oid_equal(out_mech_type, expected_mech));
|
|
Packit |
fd8b60 |
assert(out_flags == expected_flags);
|
|
Packit |
fd8b60 |
assert(out_locally_init == expected_locally_init);
|
|
Packit |
fd8b60 |
if (incomplete) {
|
|
Packit |
fd8b60 |
assert(!out_open);
|
|
Packit |
fd8b60 |
assert(out_lifetime == 0);
|
|
Packit |
fd8b60 |
assert(out_init_name == GSS_C_NO_NAME);
|
|
Packit |
fd8b60 |
assert(out_accept_name == GSS_C_NO_NAME);
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
assert(out_open);
|
|
Packit |
fd8b60 |
assert(out_lifetime > 0);
|
|
Packit |
fd8b60 |
assert(out_init_name != GSS_C_NO_NAME);
|
|
Packit |
fd8b60 |
assert(out_accept_name != GSS_C_NO_NAME);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_name(&minor, &out_accept_name);
|
|
Packit |
fd8b60 |
(void)gss_release_name(&minor, &out_init_name);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Call gss_init_sec_context() once to create an initiator context (which will
|
|
Packit |
fd8b60 |
* be partial if flags includes GSS_C_MUTUAL_FLAG and the mech is krb5). */
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
start_init_context(gss_OID mech, gss_cred_id_t cred, gss_name_t tname,
|
|
Packit |
fd8b60 |
OM_uint32 flags, gss_ctx_id_t *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc itok = GSS_C_EMPTY_BUFFER;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*ctx = GSS_C_NO_CONTEXT;
|
|
Packit |
fd8b60 |
major = gss_init_sec_context(&minor, cred, ctx, tname, mech, flags,
|
|
Packit |
fd8b60 |
GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS,
|
|
Packit |
fd8b60 |
NULL, NULL, &itok, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_init_sec_context", major, minor);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &itok);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Call gss_init_sec_context() and gss_accept_sec_context() once to create an
|
|
Packit |
fd8b60 |
* acceptor context. */
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
start_accept_context(gss_OID mech, gss_cred_id_t icred, gss_cred_id_t acred,
|
|
Packit |
fd8b60 |
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_ctx_id_t ictx = GSS_C_NO_CONTEXT;
|
|
Packit |
fd8b60 |
gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_init_sec_context(&minor, icred, &ictx, tname, mech, flags,
|
|
Packit |
fd8b60 |
GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS,
|
|
Packit |
fd8b60 |
NULL, NULL, &itok, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_init_sec_context", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*ctx = GSS_C_NO_CONTEXT;
|
|
Packit |
fd8b60 |
major = gss_accept_sec_context(&minor, ctx, acred, &itok,
|
|
Packit |
fd8b60 |
GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
|
|
Packit |
fd8b60 |
&atok, NULL, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_accept_sec_context", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &itok);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &atok);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &ictx, NULL);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
partial_iakerb_acceptor(const char *username, const char *password,
|
|
Packit |
fd8b60 |
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_name_t name;
|
|
Packit |
fd8b60 |
gss_buffer_desc ubuf, pwbuf;
|
|
Packit |
fd8b60 |
gss_OID_set_desc mechlist;
|
|
Packit |
fd8b60 |
gss_cred_id_t icred, acred;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
mechlist.count = 1;
|
|
Packit |
fd8b60 |
mechlist.elements = &mech_iakerb;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Import the username. */
|
|
Packit |
fd8b60 |
ubuf.value = (void *)username;
|
|
Packit |
fd8b60 |
ubuf.length = strlen(username);
|
|
Packit |
fd8b60 |
major = gss_import_name(&minor, &ubuf, GSS_C_NT_USER_NAME, &name);
|
|
Packit |
fd8b60 |
check_gsserr("gss_import_name", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Create an IAKERB initiator cred with the username and password. */
|
|
Packit |
fd8b60 |
pwbuf.value = (void *)password;
|
|
Packit |
fd8b60 |
pwbuf.length = strlen(password);
|
|
Packit |
fd8b60 |
major = gss_acquire_cred_with_password(&minor, name, &pwbuf, 0,
|
|
Packit |
fd8b60 |
&mechlist, GSS_C_INITIATE, &icred,
|
|
Packit |
fd8b60 |
NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_acquire_cred_with_password", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Create an acceptor cred with support for IAKERB. */
|
|
Packit |
fd8b60 |
major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE,
|
|
Packit |
fd8b60 |
&mechlist, GSS_C_ACCEPT, &acred, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_acquire_cred", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Begin context establishment to get a partial acceptor context. */
|
|
Packit |
fd8b60 |
start_accept_context(&mech_iakerb, icred, acred, tname, flags, ctx);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_name(&minor, &name);
|
|
Packit |
fd8b60 |
(void)gss_release_cred(&minor, &icred);
|
|
Packit |
fd8b60 |
(void)gss_release_cred(&minor, &acred);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Create a partially established SPNEGO acceptor. */
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
partial_spnego_acceptor(gss_name_t tname, gss_ctx_id_t *ctx)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* We could construct a fixed SPNEGO initiator token which forces a
|
|
Packit |
fd8b60 |
* renegotiation, but a simpler approach is to pass an empty token to
|
|
Packit |
fd8b60 |
* gss_accept_sec_context(), taking advantage of our compatibility support
|
|
Packit |
fd8b60 |
* for SPNEGO NegHints.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
*ctx = GSS_C_NO_CONTEXT;
|
|
Packit |
fd8b60 |
major = gss_accept_sec_context(&minor, ctx, GSS_C_NO_CREDENTIAL, &itok,
|
|
Packit |
fd8b60 |
GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
|
|
Packit |
fd8b60 |
&atok, NULL, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_accept_sec_context(neghints)", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &atok);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
int
|
|
Packit |
fd8b60 |
main(int argc, char *argv[])
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 minor, flags, dce_flags;
|
|
Packit |
fd8b60 |
gss_name_t tname;
|
|
Packit |
fd8b60 |
gss_ctx_id_t ictx, actx;
|
|
Packit |
fd8b60 |
const char *username, *password;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (argc != 4) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "Usage: %s username password targetname\n", argv[0]);
|
|
Packit |
fd8b60 |
return 1;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
username = argv[1];
|
|
Packit |
fd8b60 |
password = argv[2];
|
|
Packit |
fd8b60 |
tname = import_name(argv[3]);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
flags = GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG |
|
|
Packit |
fd8b60 |
GSS_C_INTEG_FLAG;
|
|
Packit |
fd8b60 |
start_init_context(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, flags, &ictx);
|
|
Packit |
fd8b60 |
check_inq_context(ictx, 1, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &ictx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
start_init_context(&mech_iakerb, GSS_C_NO_CREDENTIAL, tname, flags, &ictx);
|
|
Packit |
fd8b60 |
check_inq_context(ictx, 1, &mech_iakerb, flags, 1);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &ictx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
start_init_context(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, flags, &ictx);
|
|
Packit |
fd8b60 |
check_inq_context(ictx, 1, &mech_spnego, flags, 1);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &ictx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
dce_flags = flags | GSS_C_DCE_STYLE;
|
|
Packit |
fd8b60 |
start_accept_context(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
|
|
Packit |
fd8b60 |
tname, dce_flags, &actx);
|
|
Packit |
fd8b60 |
check_inq_context(actx, 1, &mech_krb5, dce_flags | GSS_C_TRANS_FLAG, 0);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &actx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
partial_iakerb_acceptor(username, password, tname, flags, &actx);
|
|
Packit |
fd8b60 |
check_inq_context(actx, 1, &mech_iakerb, 0, 0);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &actx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
partial_spnego_acceptor(tname, &actx);
|
|
Packit |
fd8b60 |
check_inq_context(actx, 1, &mech_spnego, 0, 0);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &actx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
|
|
Packit |
fd8b60 |
tname, flags, &ictx, &actx, NULL, NULL, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
check_inq_context(ictx, 0, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1);
|
|
Packit |
fd8b60 |
check_inq_context(actx, 0, &mech_krb5,
|
|
Packit |
fd8b60 |
flags | GSS_C_TRANS_FLAG | GSS_C_PROT_READY_FLAG, 0);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &ictx, NULL);
|
|
Packit |
fd8b60 |
(void)gss_delete_sec_context(&minor, &actx, NULL);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_name(&minor, &tname);
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|