diff options
Diffstat (limited to 'src/tests/cmocka/test_kcm_marshalling.c')
-rw-r--r-- | src/tests/cmocka/test_kcm_marshalling.c | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/src/tests/cmocka/test_kcm_marshalling.c b/src/tests/cmocka/test_kcm_marshalling.c new file mode 100644 index 0000000..8e8b386 --- /dev/null +++ b/src/tests/cmocka/test_kcm_marshalling.c @@ -0,0 +1,363 @@ +/* + Copyright (C) 2017 Red Hat + + SSSD tests: Test KCM JSON marshalling + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "config.h" + +#include <stdio.h> +#include <popt.h> + +#include "util/util_creds.h" +#include "responder/kcm/kcmsrv_ccache.h" +#include "responder/kcm/kcmsrv_ccache_be.h" +#include "tests/cmocka/common_mock.h" + +#define TEST_REALM "TESTREALM" +#define TEST_PRINC_COMPONENT "PRINC_NAME" + +#define TEST_CREDS "TESTCREDS" + +#define TEST_UUID_STR "5f8f296b-02be-4e86-9235-500e82354186" +#define TEST_SEC_KEY_ONEDIGIT TEST_UUID_STR"-0" +#define TEST_SEC_KEY_MULTIDIGITS TEST_UUID_STR"-123456" + +#define TEST_SEC_KEY_NOSEP TEST_UUID_STR"+0" + +const struct kcm_ccdb_ops ccdb_mem_ops; +const struct kcm_ccdb_ops ccdb_secdb_ops; + +struct kcm_marshalling_test_ctx { + krb5_context kctx; + krb5_principal princ; +}; + +static int setup_kcm_marshalling(void **state) +{ + struct kcm_marshalling_test_ctx *test_ctx; + krb5_error_code kerr; + + test_ctx = talloc_zero(NULL, struct kcm_marshalling_test_ctx); + assert_non_null(test_ctx); + + kerr = krb5_init_context(&test_ctx->kctx); + assert_int_equal(kerr, 0); + + kerr = krb5_build_principal(test_ctx->kctx, + &test_ctx->princ, + sizeof(TEST_REALM)-1, TEST_REALM, + TEST_PRINC_COMPONENT, NULL); + assert_int_equal(kerr, 0); + + *state = test_ctx; + return 0; +} + +static int teardown_kcm_marshalling(void **state) +{ + struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state, + struct kcm_marshalling_test_ctx); + assert_non_null(test_ctx); + + krb5_free_principal(test_ctx->kctx, test_ctx->princ); + krb5_free_context(test_ctx->kctx); + talloc_free(test_ctx); + return 0; +} + +static void assert_cc_name_equal(struct kcm_ccache *cc1, + struct kcm_ccache *cc2) +{ + const char *name1, *name2; + + name1 = kcm_cc_get_name(cc1); + name2 = kcm_cc_get_name(cc2); + assert_string_equal(name1, name2); +} + +static void assert_cc_uuid_equal(struct kcm_ccache *cc1, + struct kcm_ccache *cc2) +{ + uuid_t u1, u2; + errno_t ret; + + ret = kcm_cc_get_uuid(cc1, u1); + assert_int_equal(ret, EOK); + ret = kcm_cc_get_uuid(cc2, u2); + assert_int_equal(ret, EOK); + ret = uuid_compare(u1, u2); + assert_int_equal(ret, 0); +} + +static void assert_cc_princ_equal(struct kcm_ccache *cc1, + struct kcm_ccache *cc2) +{ + krb5_principal p1; + krb5_principal p2; + char *name1; + char *name2; + krb5_error_code kerr; + + p1 = kcm_cc_get_client_principal(cc1); + p2 = kcm_cc_get_client_principal(cc2); + + if (p1 != NULL && p2 != NULL) { + kerr = krb5_unparse_name(NULL, p1, &name1); + assert_int_equal(kerr, 0); + kerr = krb5_unparse_name(NULL, p2, &name2); + assert_int_equal(kerr, 0); + + assert_string_equal(name1, name2); + krb5_free_unparsed_name(NULL, name1); + krb5_free_unparsed_name(NULL, name2); + } else { + /* Either both principals must be NULL or both + * non-NULL and represent the same principals + */ + assert_null(p1); + assert_null(p2); + } +} + +static void assert_cc_offset_equal(struct kcm_ccache *cc1, + struct kcm_ccache *cc2) +{ + int32_t off1; + int32_t off2; + + off1 = kcm_cc_get_offset(cc1); + off2 = kcm_cc_get_offset(cc2); + assert_int_equal(off1, off2); +} + +static void assert_cc_equal(struct kcm_ccache *cc1, + struct kcm_ccache *cc2) +{ + assert_cc_name_equal(cc1, cc2); + assert_cc_uuid_equal(cc1, cc2); + assert_cc_princ_equal(cc1, cc2); + assert_cc_offset_equal(cc1, cc2); +} + +static void test_kcm_ccache_marshall_unmarshall_binary(void **state) +{ + struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state, + struct kcm_marshalling_test_ctx); + errno_t ret; + struct cli_creds owner; + struct kcm_ccache *cc; + struct kcm_ccache *cc2; + struct sss_iobuf *payload; + const char *name; + const char *key; + uint8_t *data; + uuid_t uuid; + + owner.ucred.uid = getuid(); + owner.ucred.gid = getuid(); + + name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid()); + assert_non_null(name); + + ret = kcm_cc_new(test_ctx, + test_ctx->kctx, + &owner, + name, + test_ctx->princ, + &cc); + assert_int_equal(ret, EOK); + + ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload); + assert_int_equal(ret, EOK); + + data = sss_iobuf_get_data(payload); + assert_non_null(data); + + ret = kcm_cc_get_uuid(cc, uuid); + assert_int_equal(ret, EOK); + key = sec_key_create(test_ctx, name, uuid); + assert_non_null(key); + + sss_iobuf_cursor_reset(payload); + ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2); + assert_int_equal(ret, EOK); + + assert_cc_equal(cc, cc2); + + /* This key is exactly one byte shorter than it should be */ + sss_iobuf_cursor_reset(payload); + ret = sec_kv_to_ccache_binary(test_ctx, TEST_UUID_STR "-", payload, &owner, + &cc2); + assert_int_equal(ret, EINVAL); +} + +static void test_kcm_ccache_no_princ_binary(void **state) +{ + struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state, + struct kcm_marshalling_test_ctx); + errno_t ret; + struct cli_creds owner; + const char *name; + struct kcm_ccache *cc; + krb5_principal princ; + struct kcm_ccache *cc2; + struct sss_iobuf *payload; + const char *key; + uint8_t *data; + uuid_t uuid; + + owner.ucred.uid = getuid(); + owner.ucred.gid = getuid(); + + name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid()); + assert_non_null(name); + + ret = kcm_cc_new(test_ctx, + test_ctx->kctx, + &owner, + name, + NULL, + &cc); + assert_int_equal(ret, EOK); + + princ = kcm_cc_get_client_principal(cc); + assert_null(princ); + + ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload); + assert_int_equal(ret, EOK); + + data = sss_iobuf_get_data(payload); + assert_non_null(data); + + ret = kcm_cc_get_uuid(cc, uuid); + assert_int_equal(ret, EOK); + key = sec_key_create(test_ctx, name, uuid); + assert_non_null(key); + + sss_iobuf_cursor_reset(payload); + ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2); + assert_int_equal(ret, EOK); + + assert_cc_equal(cc, cc2); +} + +void test_sec_key_get_uuid(void **state) +{ + errno_t ret; + uuid_t uuid; + char str_uuid[UUID_STR_SIZE]; + + uuid_clear(uuid); + ret = sec_key_get_uuid(TEST_SEC_KEY_ONEDIGIT, uuid); + assert_int_equal(ret, EOK); + uuid_unparse(uuid, str_uuid); + assert_string_equal(TEST_UUID_STR, str_uuid); + + ret = sec_key_get_uuid(TEST_SEC_KEY_NOSEP, uuid); + assert_int_equal(ret, EINVAL); + + ret = sec_key_get_uuid(TEST_UUID_STR, uuid); + assert_int_equal(ret, EINVAL); + + ret = sec_key_get_uuid(NULL, uuid); + assert_int_equal(ret, EINVAL); +} + +void test_sec_key_get_name(void **state) +{ + const char *name; + + name = sec_key_get_name(TEST_SEC_KEY_ONEDIGIT); + assert_non_null(name); + assert_string_equal(name, "0"); + + name = sec_key_get_name(TEST_SEC_KEY_MULTIDIGITS); + assert_non_null(name); + assert_string_equal(name, "123456"); + + name = sec_key_get_name(TEST_UUID_STR); + assert_null(name); + + name = sec_key_get_name(TEST_SEC_KEY_NOSEP); + assert_null(name); + + name = sec_key_get_name(NULL); + assert_null(name); +} + +void test_sec_key_match_name(void **state) +{ + assert_true(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, "0")); + assert_true(sec_key_match_name(TEST_SEC_KEY_MULTIDIGITS, "123456")); + + assert_false(sec_key_match_name(TEST_SEC_KEY_MULTIDIGITS, "0")); + assert_false(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, "123456")); + + assert_false(sec_key_match_name(TEST_UUID_STR, "0")); + assert_false(sec_key_match_name(TEST_SEC_KEY_NOSEP, "0")); + assert_false(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, NULL)); + assert_false(sec_key_match_name(NULL, "0")); +} + +int main(int argc, const char *argv[]) +{ + poptContext pc; + int opt; + int rv; + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_DEBUG_OPTS + POPT_TABLEEND + }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_binary, + setup_kcm_marshalling, + teardown_kcm_marshalling), + cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ_binary, + setup_kcm_marshalling, + teardown_kcm_marshalling), + cmocka_unit_test(test_sec_key_get_uuid), + cmocka_unit_test(test_sec_key_get_name), + cmocka_unit_test(test_sec_key_match_name), + }; + + /* Set debug level to invalid value so we can decide if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + DEBUG_CLI_INIT(debug_level); + + /* Even though normally the tests should clean up after themselves + * they might not after a failed run. Remove the old DB to be sure */ + tests_set_cwd(); + + rv = cmocka_run_group_tests(tests, NULL, NULL); + + return rv; +} |