diff options
Diffstat (limited to 'src/plugins/preauth/test')
-rw-r--r-- | src/plugins/preauth/test/Makefile.in | 4 | ||||
-rw-r--r-- | src/plugins/preauth/test/cltest.c | 86 | ||||
-rw-r--r-- | src/plugins/preauth/test/common.c | 61 | ||||
-rw-r--r-- | src/plugins/preauth/test/common.h | 41 | ||||
-rw-r--r-- | src/plugins/preauth/test/deps | 14 | ||||
-rw-r--r-- | src/plugins/preauth/test/kdctest.c | 96 |
6 files changed, 236 insertions, 66 deletions
diff --git a/src/plugins/preauth/test/Makefile.in b/src/plugins/preauth/test/Makefile.in index ac3cb8155bb2..77321b60f5e2 100644 --- a/src/plugins/preauth/test/Makefile.in +++ b/src/plugins/preauth/test/Makefile.in @@ -9,9 +9,9 @@ RELDIR=../plugins/preauth/test SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) -STLIBOBJS=cltest.o kdctest.o +STLIBOBJS=cltest.o kdctest.o common.o -SRCS= $(srcdir)/cltest.c $(srcdir)/kdctest.c +SRCS= $(srcdir)/cltest.c $(srcdir)/kdctest.c $(srcdir)/common.c all-unix: all-liblinks install-unix: install-libs diff --git a/src/plugins/preauth/test/cltest.c b/src/plugins/preauth/test/cltest.c index 4c31e1c0f8b2..f5f7c5aba167 100644 --- a/src/plugins/preauth/test/cltest.c +++ b/src/plugins/preauth/test/cltest.c @@ -1,7 +1,7 @@ /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* plugins/preauth/test/cltest.c - Test clpreauth module */ /* - * Copyright (C) 2015 by the Massachusetts Institute of Technology. + * Copyright (C) 2015, 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +32,7 @@ /* * This module is used to test preauth interface features. At this time, the - * clpreauth module does two things: + * clpreauth module does the following: * * - It decrypts a message from the initial KDC pa-data using the reply key and * prints it to stdout. (The unencrypted message "no key" can also be @@ -45,17 +45,27 @@ * it to the server, instructing the kdcpreauth module to assert one or more * space-separated authentication indicators. (This string is sent on both * round trips if a second round trip is requested.) + * + * - If a KDC_ERR_ENCTYPE_NOSUPP error with e-data is received, it prints the + * accompanying error padata and sends a follow-up request containing + * "tryagain". + * + * - If the "fail_optimistic", "fail_2rt", or "fail_tryagain" gic options are + * set, it fails with a recognizable error string at the requested point in + * processing. */ #include "k5-int.h" #include <krb5/clpreauth_plugin.h> - -#define TEST_PA_TYPE -123 +#include "common.h" static krb5_preauthtype pa_types[] = { TEST_PA_TYPE, 0 }; struct client_state { char *indicators; + krb5_boolean fail_optimistic; + krb5_boolean fail_2rt; + krb5_boolean fail_tryagain; }; struct client_request_state { @@ -70,6 +80,7 @@ test_init(krb5_context context, krb5_clpreauth_moddata *moddata_out) st = malloc(sizeof(*st)); assert(st != NULL); st->indicators = NULL; + st->fail_optimistic = st->fail_2rt = st->fail_tryagain = FALSE; *moddata_out = (krb5_clpreauth_moddata)st; return 0; } @@ -114,7 +125,6 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, struct client_state *st = (struct client_state *)moddata; struct client_request_state *reqst = (struct client_request_state *)modreq; krb5_error_code ret; - krb5_pa_data **list, *pa; krb5_keyblock *k; krb5_enc_data enc; krb5_data plain; @@ -123,20 +133,18 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, if (pa_data->length == 0) { /* This is an optimistic preauth test. Send a recognizable padata * value so the KDC knows not to expect a cookie. */ - list = k5calloc(2, sizeof(*list), &ret); - assert(!ret); - pa = k5alloc(sizeof(*pa), &ret); - assert(!ret); - pa->pa_type = TEST_PA_TYPE; - pa->contents = (uint8_t *)strdup("optimistic"); - assert(pa->contents != NULL); - pa->length = 10; - list[0] = pa; - list[1] = NULL; - *out_pa_data = list; + if (st->fail_optimistic) { + k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced optimistic fail"); + return KRB5_PREAUTH_FAILED; + } + *out_pa_data = make_pa_list("optimistic", 10); return 0; } else if (reqst->second_round_trip) { printf("2rt: %.*s\n", pa_data->length, pa_data->contents); + if (st->fail_2rt) { + k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced 2rt fail"); + return KRB5_PREAUTH_FAILED; + } } else if (pa_data->length == 6 && memcmp(pa_data->contents, "no key", 6) == 0) { printf("no key\n"); @@ -157,17 +165,34 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata, reqst->second_round_trip = TRUE; indstr = (st->indicators != NULL) ? st->indicators : ""; - list = k5calloc(2, sizeof(*list), &ret); - assert(!ret); - pa = k5alloc(sizeof(*pa), &ret); - assert(!ret); - pa->pa_type = TEST_PA_TYPE; - pa->contents = (uint8_t *)strdup(indstr); - assert(pa->contents != NULL); - pa->length = strlen(indstr); - list[0] = pa; - list[1] = NULL; - *out_pa_data = list; + *out_pa_data = make_pa_list(indstr, strlen(indstr)); + return 0; +} + +static krb5_error_code +test_tryagain(krb5_context context, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, + krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, + krb5_kdc_req *request, krb5_data *enc_req, krb5_data *enc_prev, + krb5_preauthtype pa_type, krb5_error *error, + krb5_pa_data **padata, krb5_prompter_fct prompter, + void *prompter_data, krb5_pa_data ***padata_out) +{ + struct client_state *st = (struct client_state *)moddata; + int i; + + *padata_out = NULL; + if (st->fail_tryagain) { + k5_setmsg(context, KRB5_PREAUTH_FAILED, "induced tryagain fail"); + return KRB5_PREAUTH_FAILED; + } + if (error->error != KDC_ERR_ENCTYPE_NOSUPP) + return KRB5_PREAUTH_FAILED; + for (i = 0; padata[i] != NULL; i++) { + if (padata[i]->pa_type == TEST_PA_TYPE) + printf("tryagain: %.*s\n", padata[i]->length, padata[i]->contents); + } + *padata_out = make_pa_list("tryagain", 8); return 0; } @@ -181,6 +206,12 @@ test_gic_opt(krb5_context kcontext, krb5_clpreauth_moddata moddata, free(st->indicators); st->indicators = strdup(value); assert(st->indicators != NULL); + } else if (strcmp(attr, "fail_optimistic") == 0) { + st->fail_optimistic = TRUE; + } else if (strcmp(attr, "fail_2rt") == 0) { + st->fail_2rt = TRUE; + } else if (strcmp(attr, "fail_tryagain") == 0) { + st->fail_tryagain = TRUE; } return 0; } @@ -205,6 +236,7 @@ clpreauth_test_initvt(krb5_context context, int maj_ver, vt->request_init = test_request_init; vt->request_fini = test_request_fini; vt->process = test_process; + vt->tryagain = test_tryagain; vt->gic_opts = test_gic_opt; return 0; } diff --git a/src/plugins/preauth/test/common.c b/src/plugins/preauth/test/common.c new file mode 100644 index 000000000000..4d1f49dfafc5 --- /dev/null +++ b/src/plugins/preauth/test/common.c @@ -0,0 +1,61 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* plugins/preauth/test/common.c - common functions for test preauth module */ +/* + * Copyright (C) 2017 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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 "k5-int.h" +#include "common.h" + +krb5_pa_data * +make_pa(const char *contents, size_t len) +{ + krb5_error_code ret; + krb5_pa_data *pa; + + pa = calloc(1, sizeof(*pa)); + assert(pa != NULL); + pa->pa_type = TEST_PA_TYPE; + pa->contents = k5memdup(contents, len, &ret); + assert(!ret); + pa->length = len; + return pa; +} + +/* Make a one-element padata list of type TEST_PA_TYPE. */ +krb5_pa_data ** +make_pa_list(const char *contents, size_t len) +{ + krb5_pa_data **list; + + list = calloc(2, sizeof(*list)); + assert(list != NULL); + list[0] = make_pa(contents, len); + return list; +} diff --git a/src/plugins/preauth/test/common.h b/src/plugins/preauth/test/common.h new file mode 100644 index 000000000000..b748e0874bc6 --- /dev/null +++ b/src/plugins/preauth/test/common.h @@ -0,0 +1,41 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* plugins/preauth/test/common.h - Declarations for test preauth module */ +/* + * Copyright (C) 2017 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef COMMON_H +#define COMMON_H + +#define TEST_PA_TYPE -123 + +krb5_pa_data *make_pa(const char *contents, size_t len); +krb5_pa_data **make_pa_list(const char *contents, size_t len); + +#endif /* COMMON_H */ diff --git a/src/plugins/preauth/test/deps b/src/plugins/preauth/test/deps index b48f0003261c..b1429e9e15f5 100644 --- a/src/plugins/preauth/test/deps +++ b/src/plugins/preauth/test/deps @@ -11,7 +11,7 @@ cltest.so cltest.po $(OUTPRE)cltest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/clpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cltest.c + cltest.c common.h kdctest.so kdctest.po $(OUTPRE)kdctest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ @@ -22,4 +22,14 @@ kdctest.so kdctest.po $(OUTPRE)kdctest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - kdctest.c + common.h kdctest.c +common.so common.po $(OUTPRE)common.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h common.c common.h diff --git a/src/plugins/preauth/test/kdctest.c b/src/plugins/preauth/test/kdctest.c index 026dc680dc07..66b77969a3d0 100644 --- a/src/plugins/preauth/test/kdctest.c +++ b/src/plugins/preauth/test/kdctest.c @@ -1,7 +1,7 @@ /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* plugins/preauth/test/kdctest.c - Test kdcpreauth module */ /* - * Copyright (C) 2015 by the Massachusetts Institute of Technology. + * Copyright (C) 2015, 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,10 +40,20 @@ * key; the encrypted message "no attr" is sent if there is no string * attribute.) It also sets a cookie containing "method-data". * - * - It retrieves the "2rt" attribute from the client principal. If set, the - * verify method sends the client a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error - * with the contents of the 2rt attribute as pa-data, and sets a cookie - * containing "more". + * - If the "err" attribute is set on the client principal, the verify method + * returns an KDC_ERR_ETYPE_NOSUPP error on the first try, with the contents + * of the err attribute as pa-data. If the client tries again with the + * padata value "tryagain", the verify method preuthenticates successfully + * with no additional processing. + * + * - If the "failopt" attribute is set on the client principal, the verify + * method returns KDC_ERR_PREAUTH_FAILED on optimistic preauth attempts. + * + * - If the "2rt" attribute is set on client principal, the verify method sends + * the client a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error with the contents of + * the 2rt attribute as pa-data, and sets a cookie containing "more". If the + * "fail2rt" attribute is set on the client principal, the client's second + * try results in a KDC_ERR_PREAUTH_FAILED error. * * - It receives a space-separated list from the clpreauth module and asserts * each string as an authentication indicator. It always succeeds in @@ -52,6 +62,7 @@ #include "k5-int.h" #include <krb5/kdcpreauth_plugin.h> +#include "common.h" #define TEST_PA_TYPE -123 @@ -73,11 +84,6 @@ test_edata(krb5_context context, krb5_kdc_req *req, ret = cb->get_string(context, rock, "teststring", &attr); assert(!ret); - pa = k5alloc(sizeof(*pa), &ret); - assert(!ret); - if (pa == NULL) - abort(); - pa->pa_type = TEST_PA_TYPE; if (k != NULL) { d = string2data((attr != NULL) ? attr : "no attr"); ret = krb5_c_encrypt_length(context, k->enctype, d.length, &enclen); @@ -86,12 +92,10 @@ test_edata(krb5_context context, krb5_kdc_req *req, assert(!ret); ret = krb5_c_encrypt(context, k, 1024, NULL, &d, &enc); assert(!ret); - pa->contents = (uint8_t *)enc.ciphertext.data; - pa->length = enc.ciphertext.length; + pa = make_pa(enc.ciphertext.data, enc.ciphertext.length); + free(enc.ciphertext.data); } else { - pa->contents = (uint8_t *)strdup("no key"); - assert(pa->contents != NULL); - pa->length = 6; + pa = make_pa("no key", 6); } /* Exercise setting a cookie information from the edata method. */ @@ -111,12 +115,19 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdcpreauth_verify_respond_fn respond, void *arg) { krb5_error_code ret; - krb5_boolean second_round_trip = FALSE; - krb5_pa_data **list; + krb5_boolean second_round_trip = FALSE, optimistic = FALSE; + krb5_pa_data **list = NULL; krb5_data cookie_data, d; - char *str, *ind, *attr, *toksave = NULL; + char *str, *ind, *toksave = NULL; + char *attr_err, *attr_2rt, *attr_fail2rt, *attr_failopt; - ret = cb->get_string(context, rock, "2rt", &attr); + ret = cb->get_string(context, rock, "err", &attr_err); + assert(!ret); + ret = cb->get_string(context, rock, "2rt", &attr_2rt); + assert(!ret); + ret = cb->get_string(context, rock, "fail2rt", &attr_fail2rt); + assert(!ret); + ret = cb->get_string(context, rock, "failopt", &attr_failopt); assert(!ret); /* Check the incoming cookie value. */ @@ -124,13 +135,36 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, /* Make sure we are seeing optimistic preauth and not a lost cookie. */ d = make_data(data->contents, data->length); assert(data_eq_string(d, "optimistic")); + optimistic = TRUE; } else if (data_eq_string(cookie_data, "more")) { second_round_trip = TRUE; } else { - assert(data_eq_string(cookie_data, "method-data")); + assert(data_eq_string(cookie_data, "method-data") || + data_eq_string(cookie_data, "err")); } - if (attr == NULL || second_round_trip) { + if (attr_err != NULL) { + d = make_data(data->contents, data->length); + if (data_eq_string(d, "tryagain")) { + /* Authenticate successfully. */ + enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; + } else { + d = string2data("err"); + ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); + assert(!ret); + ret = KRB5KDC_ERR_ETYPE_NOSUPP; + list = make_pa_list(attr_err, strlen(attr_err)); + } + } else if (attr_2rt != NULL && !second_round_trip) { + d = string2data("more"); + ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); + assert(!ret); + ret = KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED; + list = make_pa_list(attr_2rt, strlen(attr_2rt)); + } else if ((attr_fail2rt != NULL && second_round_trip) || + (attr_failopt != NULL && optimistic)) { + ret = KRB5KDC_ERR_PREAUTH_FAILED; + } else { /* Parse and assert the indicators. */ str = k5memdup0(data->contents, data->length, &ret); if (ret) @@ -142,21 +176,13 @@ test_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, } free(str); enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; - cb->free_string(context, rock, attr); - (*respond)(arg, 0, NULL, NULL, NULL); - } else { - d = string2data("more"); - ret = cb->set_cookie(context, rock, TEST_PA_TYPE, &d); - list = k5calloc(2, sizeof(*list), &ret); - assert(!ret); - list[0] = k5alloc(sizeof(*list[0]), &ret); - assert(!ret); - list[0]->pa_type = TEST_PA_TYPE; - list[0]->contents = (uint8_t *)attr; - list[0]->length = strlen(attr); - (*respond)(arg, KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, NULL, list, - NULL); } + + cb->free_string(context, rock, attr_err); + cb->free_string(context, rock, attr_2rt); + cb->free_string(context, rock, attr_fail2rt); + cb->free_string(context, rock, attr_failopt); + (*respond)(arg, ret, NULL, list, NULL); } static krb5_error_code |