From 88c076e73821ccaa628da03a0c6ace5d4046d791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Sat, 1 Jul 2006 08:44:30 +0000 Subject: [PATCH] break out common function; add gssmaestro (that only tests one context for now) git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17780 ec53bebd-3082-4978-b11e-865c3cabbd6b --- appl/gssmask/Makefile.am | 6 +- appl/gssmask/common.c | 51 ++++++++ appl/gssmask/common.h | 89 ++++++++++++++ appl/gssmask/gssmaestro.c | 236 ++++++++++++++++++++++++++++++++++++++ appl/gssmask/gssmask.c | 79 +------------ 5 files changed, 385 insertions(+), 76 deletions(-) create mode 100644 appl/gssmask/common.c create mode 100644 appl/gssmask/common.h create mode 100644 appl/gssmask/gssmaestro.c diff --git a/appl/gssmask/Makefile.am b/appl/gssmask/Makefile.am index c47f6ea2c..d5d094c80 100644 --- a/appl/gssmask/Makefile.am +++ b/appl/gssmask/Makefile.am @@ -2,8 +2,10 @@ include $(top_srcdir)/Makefile.am.common -noinst_PROGRAMS = gssmask +noinst_PROGRAMS = gssmask gssmaestro -gssmask_SOURCES = gssmask.c protocol.h +gssmask_SOURCES = gssmask.c common.c common.h protocol.h + +gssmaestro_SOURCES = gssmaestro.c common.c common.h protocol.h LDADD = $(top_builddir)/lib/gssapi/libgssapi.la diff --git a/appl/gssmask/common.c b/appl/gssmask/common.c new file mode 100644 index 000000000..f1a7201cc --- /dev/null +++ b/appl/gssmask/common.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS 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 KTH OR ITS 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 +RCSID("$Id$"); + +krb5_error_code +store_string(krb5_storage *sp, const char *str) +{ + size_t len = strlen(str) + 1; + krb5_error_code ret; + + ret = krb5_store_int32(sp, len); + if (ret) + return ret; + ret = krb5_storage_write(sp, str, len); + if (ret != len) + return EINVAL; + return 0; +} + diff --git a/appl/gssmask/common.h b/appl/gssmask/common.h new file mode 100644 index 000000000..f498ed2a2 --- /dev/null +++ b/appl/gssmask/common.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS 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 KTH OR ITS 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. + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include + +#include +#include + +#include "protocol.h" + +krb5_error_code store_string(krb5_storage *, const char *); + + +#define ret32(_client, num) \ + do { \ + if (krb5_ret_int32((_client)->sock, &(num)) != 0) \ + errx(1, "krb5_ret_int32 " #num); \ + } while(0) + +#define retdata(_client, data) \ + do { \ + if (krb5_ret_data((_client)->sock, &(data)) != 0) \ + errx(1, "krb5_ret_data " #data); \ + } while(0) + +#define retstring(_client, data) \ + do { \ + if (krb5_ret_string((_client)->sock, &(data)) != 0) \ + errx(1, "krb5_ret_data " #data); \ + } while(0) + + +#define put32(_client, num) \ + do { \ + if (krb5_store_int32((_client)->sock, num) != 0) \ + errx(1, "krb5_store_int32 " #num); \ + } while(0) + +#define putdata(_client, data) \ + do { \ + if (krb5_store_data((_client)->sock, data) != 0) \ + errx(1, "krb5_store_data " #data); \ + } while(0) + +#define putstring(_client, str) \ + do { \ + if (store_string((_client)->sock, str) != 0) \ + errx(1, "krb5_store_str " #str); \ + } while(0) diff --git a/appl/gssmask/gssmaestro.c b/appl/gssmask/gssmaestro.c new file mode 100644 index 000000000..6278460e5 --- /dev/null +++ b/appl/gssmask/gssmaestro.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS 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 KTH OR ITS 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 +RCSID("$Id$"); + +/* + * + */ + +struct client { + char *name; + krb5_storage *sock; +}; + +#if 0 +static struct client *clients; +static int num_clients; +#endif + +static struct client * +connect_client(const char *name) +{ + struct client *c = ecalloc(1, sizeof(*c)); + struct addrinfo hints, *res0, *res; + int ret, fd; + + c->name = estrdup(name); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo(name, "4711", &hints, &res0); + if (ret) + errx(1, "error resolving %s", name); + + for (res = res0, fd = -1; res; res = res->ai_next) { + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd < 0) + continue; + if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) { + close(fd); + fd = -1; + continue; + } + break; /* okay we got one */ + } + if (fd < 0) + err(1, "connect to host: %s", name); + freeaddrinfo(res); + + c->sock = krb5_storage_from_fd(fd); + close(fd); + if (c->sock == NULL) + errx(1, "krb5_storage_from_fd"); + return c; +} + +static int +init_sec_context(struct client *client, + int32_t *hContext, int32_t *hCred, + int32_t flags, + const char *targetname, + const krb5_data *itoken, krb5_data *otoken) +{ + int32_t val; + krb5_data_zero(otoken); + put32(client, eInitContext); + put32(client, *hContext); + put32(client, *hCred); + put32(client, flags); + putstring(client, targetname); + putdata(client, *itoken); + ret32(client, *hContext); + ret32(client, val); + retdata(client, *otoken); + return val; +} + +static int +accept_sec_context(struct client *client, + int32_t *hContext, + const krb5_data *itoken, + krb5_data *otoken, + int32_t *hDelegCred) +{ + int32_t val; + krb5_data_zero(otoken); + put32(client, eAcceptContext); + put32(client, *hContext); + put32(client, 0); + putdata(client, *itoken); + ret32(client, *hContext); + ret32(client, val); + retdata(client, *otoken); + ret32(client, *hDelegCred); + return val; +} + +static int +acquire_cred(struct client *client, + const char *username, + const char *password, + int32_t flags, + int32_t *hCred) +{ + int32_t val; + put32(client, eAcquireCreds); + putstring(client, username); + putstring(client, password); + put32(client, flags); + ret32(client, val); + ret32(client, *hCred); + return val; +} + +static int +toast_resource(struct client *client, + int32_t hCred) +{ + int32_t val; + put32(client, eToastResource); + put32(client, hCred); + ret32(client, val); + return val; +} + +static int +goodbye(struct client *client) +{ + put32(client, eGoodBye); + return GSMERR_OK; +} + +static int version_flag; +static int help_flag; + +struct getargs args[] = { + { "version", 0, arg_flag, &version_flag, "Print version", + NULL }, + { "help", 0, arg_flag, &help_flag, NULL, + NULL } +}; + +static void +usage(int ret) +{ + arg_printusage (args, + sizeof(args) / sizeof(args[0]), + NULL, + ""); + exit (ret); +} + +int +main(int argc, char **argv) +{ + int optidx= 0; + + setprogname (argv[0]); + + if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) + usage (1); + + if (help_flag) + usage (0); + + if (version_flag) { + print_version (NULL); + return 0; + } + + if (optidx != argc) + usage (1); + + { + struct client *c; + int32_t hCred, delegCred; + int32_t clientC, serverC; + const char *user = "lha/test@SU.SE"; + const char *target = "host/nutcracker.it.su.se@SU.SE"; + krb5_data itoken, otoken; + + krb5_data_zero(&itoken); + c = connect_client("localhost"); + acquire_cred(c, user, "nothere", 1, &hCred); + init_sec_context(c, &clientC, &hCred, + GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG, + target, &itoken, &otoken); + accept_sec_context(c, &serverC, &otoken, &itoken, &delegCred); + init_sec_context(c, &clientC, &hCred, GSS_C_DELEG_FLAG, + target, &itoken, &otoken); + + toast_resource(c, clientC); + toast_resource(c, serverC); + toast_resource(c, hCred); + if (delegCred) + toast_resource(c, delegCred); + goodbye(c); + + } + printf("done\n"); + + return 0; +} diff --git a/appl/gssmask/gssmask.c b/appl/gssmask/gssmask.c index c9dd7e329..08a6b7fe1 100644 --- a/appl/gssmask/gssmask.c +++ b/appl/gssmask/gssmask.c @@ -31,22 +31,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "common.h" RCSID("$Id$"); -#include - -#include -#include -#include - -#include -#include - -#include "protocol.h" - /* * */ @@ -61,7 +48,7 @@ struct handle { }; struct client { - krb5_storage *master; + krb5_storage *sock; krb5_storage *logging; char *moniker; int32_t nHandle; @@ -74,25 +61,6 @@ FILE *logfile; static char *targetname; krb5_context context; -/* - * - */ - -static krb5_error_code -store_string(krb5_storage *sp, char *str) -{ - size_t len = strlen(str) + 1; - krb5_error_code ret; - - ret = krb5_store_int32(sp, len); - if (ret) - return ret; - ret = krb5_storage_write(sp, str, len); - if (ret != len) - return EINVAL; - return 0; -} - /* * */ @@ -299,43 +267,6 @@ acquire_cred(struct client *c, #define HandleOP(h) \ handle##h(enum gssMaggotOp op, struct client *c) -#define ret32(_client, num) \ - do { \ - if (krb5_ret_int32((_client)->master, &(num)) != 0) \ - errx(1, "krb5_ret_int32 " #num); \ - } while(0) - -#define retdata(_client, data) \ - do { \ - if (krb5_ret_data((_client)->master, &(data)) != 0) \ - errx(1, "krb5_ret_data " #data); \ - } while(0) - -#define retstring(_client, data) \ - do { \ - if (krb5_ret_string((_client)->master, &(data)) != 0) \ - errx(1, "krb5_ret_data " #data); \ - } while(0) - - -#define put32(_client, num) \ - do { \ - if (krb5_store_int32((_client)->master, num) != 0) \ - errx(1, "krb5_store_int32 " #num); \ - } while(0) - -#define putdata(_client, data) \ - do { \ - if (krb5_store_data((_client)->master, data) != 0) \ - errx(1, "krb5_store_data " #data); \ - } while(0) - -#define putstring(_client, str) \ - do { \ - if (store_string((_client)->master, str) != 0) \ - errx(1, "krb5_store_str " #str); \ - } while(0) - /* * */ @@ -824,8 +755,8 @@ handleServer(int fd) servername, sizeof(servername), NULL, 0, NI_NUMERICHOST); } - c.master = krb5_storage_from_fd(fd); - if (c.master == NULL) + c.sock = krb5_storage_from_fd(fd); + if (c.sock == NULL) errx(1, "krb5_storage_from_fd"); close(fd); @@ -847,7 +778,7 @@ handleServer(int fd) if ((handler->func)(handler->op, &c)) break; } - krb5_storage_free(c.master); + krb5_storage_free(c.sock); if (c.logging) krb5_storage_free(c.logging); }