From c37191e06e9b4aeb570ae96a9b210f529c734d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Fri, 18 Aug 2006 10:44:40 +0000 Subject: [PATCH] Frontend for remote digest service in KDC git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17885 ec53bebd-3082-4978-b11e-865c3cabbd6b --- kuser/Makefile.am | 21 +++++ kuser/kdigest-commands.in | 152 +++++++++++++++++++++++++++++++ kuser/kdigest.c | 187 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 kuser/kdigest-commands.in create mode 100644 kuser/kdigest.c diff --git a/kuser/Makefile.am b/kuser/Makefile.am index 2d9e40728..d0fd2f52d 100644 --- a/kuser/Makefile.am +++ b/kuser/Makefile.am @@ -6,7 +6,10 @@ AM_CPPFLAGS += $(INCLUDE_krb4) $(INCLUDE_des) -I$(srcdir)/../lib/krb5 man_MANS = kinit.1 klist.1 kdestroy.1 kgetcred.1 +SLC = $(top_builddir)/lib/sl/slc + bin_PROGRAMS = kinit klist kdestroy kgetcred +libexec_PROGRAMS = kdigest noinst_PROGRAMS = kverify kdecode_ticket generate-requests copy_cred_cache noinst_MANS = copy_cred_cache.1 @@ -23,6 +26,24 @@ kdestroy_LDADD = $(kinit_LDADD) klist_LDADD = $(kinit_LDADD) +kdigest_SOURCES = \ + kdigest.c \ + kdigest-commands.c + +kdigest_LDADD = \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_des) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(top_builddir)/lib/sl/libsl.la \ + $(LIB_roken) + +$(kdigest_OBJECTS): kdigest-commands.h + +CLEANFILES = kdigest-commands.h kdigest-commands.c + +kdigest-commands.c kdigest-commands.h: kdigest-commands.in + $(SLC) $(srcdir)/kdigest-commands.in + LDADD = \ $(top_builddir)/lib/krb5/libkrb5.la \ $(LIB_des) \ diff --git a/kuser/kdigest-commands.in b/kuser/kdigest-commands.in new file mode 100644 index 000000000..cff54fcbc --- /dev/null +++ b/kuser/kdigest-commands.in @@ -0,0 +1,152 @@ +/* + * 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 the Institute 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 THE INSTITUTE 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 INSTITUTE 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. + */ +/* $Id$ */ + +command = { + name = "server-init" + option = { + long = "type" + type = "string" + help = "digest type" + default = "sasl" + } + option = { + long = "digest" + type = "string" + argument = "digest-type" + help = "digest type to use in the algorithm" + } + option = { + long = "cb-type" + type = "string" + argument = "type" + help = "type of channel bindings" + } + option = { + long = "cb-value" + type = "string" + argument = "value" + help = "value of channel bindings" + } + option = { + long = "hostname" + type = "string" + argument = "hostname" + help = "hostname of the server" + } + help = "Sets up a digest context and return initial parameters" +} +command = { + name = "server-request" + option = { + long = "username" + type = "string" + argument = "name" + help = "digest type" + } + option = { + long = "server-nonce" + type = "string" + argument = "nonce" + help = "" + } + option = { + long = "server-identifier" + type = "string" + argument = "nonce" + help = "" + } + option = { + long = "client-nonce" + type = "string" + argument = "nonce" + help = "" + } + option = { + long = "opaque" + type = "string" + argument = "string" + help = "" + } + option = { + long = "authentication-name" + type = "string" + argument = "name" + help = "" + } + option = { + long = "realm" + type = "string" + argument = "realm" + help = "" + } + option = { + long = "method" + type = "string" + argument = "method" + help = "" + } + option = { + long = "uri" + type = "string" + argument = "uri" + help = "" + } + option = { + long = "nounce-count" + type = "string" + argument = "count" + help = "" + } + option = { + long = "qop" + type = "string" + argument = "qop" + help = "" + } + option = { + long = "ccache" + type = "string" + argument = "ccache" + help = "Where the the credential cache is created when the KDC returns tickets" + } + help = "Completes digest negotiation and return final parameters" +} +command = { + name = "help" + name = "?" + argument = "[command]" + min_args = "0" + max_args = "1" + help = "Help! I need somebody." +} diff --git a/kuser/kdigest.c b/kuser/kdigest.c new file mode 100644 index 000000000..8e059295f --- /dev/null +++ b/kuser/kdigest.c @@ -0,0 +1,187 @@ +/* + * 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 the Institute 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 THE INSTITUTE 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 INSTITUTE 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 "kuser_locl.h" +RCSID("$Id$"); +#include +#include +#include "crypto-headers.h" + +static int version_flag = 0; +static int help_flag = 0; + +static 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), + NULL, ""); + exit (ret); +} + +const static char *secret = "secret"; +static char server_nonce[16]; +static char server_identifier; + +int +server_init(struct server_init_options *opt, int argc, char ** argv) +{ + char *s; + + if (strcasecmp(opt->type_string, "CHAP") != 0) + errx(1, "type not CHAP"); + + RAND_pseudo_bytes(&server_identifier, sizeof(server_identifier)); + RAND_pseudo_bytes(&server_nonce, sizeof(server_nonce)); + + printf("type=%s\n", opt->type_string); + hex_encode(server_nonce, sizeof(server_nonce), &s); + printf("server-nonce=%s\n", s); + free(s); + printf("identifier=%02X\n", (server_identifier & 0xff)); + printf("opaque=bar\n"); + + return 0; +} + +int +server_request(struct server_request_options *opt, int argc, char **argv) +{ + MD5_CTX ctx; + char md[16], *h; + + if (opt->server_nonce_string == NULL) + errx(1, "server nonce missing"); + if (opt->server_identifier_string == NULL) + errx(1, "server identifier missing"); + + if (opt->opaque_string == NULL) + errx(1, "opaque missing"); + if (strcmp(opt->opaque_string, "bar") != 0) + errx(1, "opaque wrong string"); + + if (hex_decode(opt->server_nonce_string, server_nonce, 16) != 16) + errx(1, "server nonce wrong length"); + if (hex_decode(opt->server_identifier_string, &server_identifier, 1) != 1) + errx(1, "server identifier wrong length"); + + MD5_Init(&ctx); + MD5_Update(&ctx, &server_identifier, 1); + MD5_Update(&ctx, secret, strlen(secret)); + MD5_Update(&ctx, server_nonce, 16); + MD5_Final(md, &ctx); + + hex_encode(md, 16, &h); + + printf("responseData=%s\n", h); + printf("tickets=no\n"); + + /* + printf("rsp=bar\n"); + printf("cb-type=type\n"); + printf("cb-binding=binding\n"); + printf("hash-a1=bar\n"); + printf("message=message here\n"); + */ + return 0; +} + +/* + * + */ + +int +help(void *opt, int argc, char **argv) +{ + if(argc == 0) { + sl_help(commands, 1, argv - 1 /* XXX */); + } else { + SL_cmd *c = sl_match (commands, argv[0], 0); + if(c == NULL) { + fprintf (stderr, "No such command: %s. " + "Try \"help\" for a list of commands\n", + argv[0]); + } else { + if(c->func) { + char *fake[] = { NULL, "--help", NULL }; + fake[0] = argv[0]; + (*c->func)(2, fake); + fprintf(stderr, "\n"); + } + if(c->help && *c->help) + fprintf (stderr, "%s\n", c->help); + if((++c)->name && c->func == NULL) { + int f = 0; + fprintf (stderr, "Synonyms:"); + while (c->name && c->func == NULL) { + fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name); + f = 1; + } + fprintf (stderr, "\n"); + } + } + } + return 0; +} + +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); + exit(0); + } + + argc -= optidx; + argv += optidx; + + if (argc == 0) { + help(NULL, argc, argv); + return 1; + } + + return sl_command (commands, argc, argv); +}