From: Alexandra Ellwood Date: Mon, 10 Mar 2008 21:55:44 +0000 (+0000) Subject: Add CCAPI v2 tests X-Git-Tag: krb5-1.7-alpha1~717 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b03001c9aad53a6ecdc8ebef0493882bad0a826c;p=krb5.git Add CCAPI v2 tests First pass at CCAPI v2 tests. More commits to this bug will follow. ticket: new git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20269 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/ccapi/test/main.c b/src/ccapi/test/main.c index eb8731c53..995cb1c8b 100644 --- a/src/ccapi/test/main.c +++ b/src/ccapi/test/main.c @@ -8,6 +8,7 @@ #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" #include "test_ccapi_iterators.h" +#include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { @@ -20,11 +21,29 @@ int main (int argc, const char * argv[]) { T_CCAPI_INIT; + // *** ccapi v2 compat *** + err = check_cc_shutdown(); + err = check_cc_get_change_time(); + err = check_cc_open(); + err = check_cc_create(); + err = check_cc_close(); + err = check_cc_destroy(); + err = check_cc_get_cred_version(); + err = check_cc_get_name(); + err = check_cc_get_principal(); + err = check_cc_set_principal(); + err = check_cc_store(); + err = check_cc_remove_cred(); + //err = check_cc_seq_fetch_NCs_begin(); + //err = check_cc_seq_fetch_NCs_next(); + //err = check_cc_seq_fetch_creds_begin(); + //err = check_cc_seq_fetch_creds_next(); + //err = check_cc_get_NC_info(); + err = check_constants(); // *** cc_context *** err = check_cc_initialize(); - err = check_cc_context_get_version(); err = check_cc_context_release(); err = check_cc_context_get_change_time(); err = check_cc_context_get_default_ccache_name(); diff --git a/src/ccapi/test/test_ccapi_globals.c b/src/ccapi/test/test_ccapi_globals.c index c508c188c..f9aadbdda 100644 --- a/src/ccapi/test/test_ccapi_globals.c +++ b/src/ccapi/test/test_ccapi_globals.c @@ -46,12 +46,37 @@ const char * ccapi_error_strings[30] = { }; +const char * ccapiv2_error_strings[24] = { + + "CC_NOERROR", + "CC_BADNAME", + "CC_NOTFOUND", + "CC_END", + "CC_IO", + "CC_WRITE", + "CC_NOMEM", + "CC_FORMAT", + "CC_LOCKED", + "CC_BAD_API_VERSION", + "CC_NO_EXIST", + "CC_NOT_SUPP", + "CC_BAD_PARM", + "CC_ERR_CACHE_ATTACH", + "CC_ERR_CACHE_RELEASE", + "CC_ERR_CACHE_FULL", + "CC_ERR_CRED_VERSION" + +}; + const char *translate_ccapi_error(cc_int32 err) { if (err == 0) { return ccapi_error_strings[0]; - } - else if (err >= 201 && err <= 228){ + } else + if (err >= 0 && err <= 16){ + return ccapiv2_error_strings[err]; + } else + if (err >= 201 && err <= 228){ return ccapi_error_strings[err - 200]; } else { @@ -59,4 +84,4 @@ const char *translate_ccapi_error(cc_int32 err) { } return ""; -} \ No newline at end of file +} diff --git a/src/ccapi/test/test_ccapi_v2.c b/src/ccapi/test/test_ccapi_v2.c new file mode 100644 index 000000000..a5ce3d9d6 --- /dev/null +++ b/src/ccapi/test/test_ccapi_v2.c @@ -0,0 +1,1335 @@ +#include +#include "test_ccapi_v2.h" +#include +#include +#include "test_ccapi_check.h" +#include "test_ccapi_util.h" + +// --------------------------------------------------------------------------- + +static cc_result destroy_all_ccaches_v2(apiCB *context) { + cc_result err = ccNoError; + infoNC **info = NULL; + int i = 0; + + err = cc_get_NC_info(context, &info); + + for (i = 0; !err && info[i]; i++) { + ccache_p *ccache = NULL; + + err = cc_open(context, info[i]->name, info[i]->vers, 0, &ccache); + + if (!err) { cc_destroy(context, &ccache); } + } + + if (info) { cc_free_NC_info(context, &info); } + + if (err) { + log_error("cc_get_NC_info or cc_open failed with %s (%d)", translate_ccapi_error(err), err); + } + + return err; +} + +// --------------------------------------------------------------------------- +// return zero when both unions are considered equal, non-zero when not + +static int compare_v5_creds_unions_compat(const cred_union *a, const cred_union *b) { + int retval = -1; + + if (a && b && a->cred_type == b->cred_type) { + if (a->cred_type == CC_CRED_V5) { + if (!strcmp(a->cred.pV5Cred->client, b->cred.pV5Cred->client) && + !strcmp(a->cred.pV5Cred->server, b->cred.pV5Cred->server) && + a->cred.pV5Cred->starttime == b->cred.pV5Cred->starttime) { + retval = 0; + } + } else if (a->cred_type == CC_CRED_V4) { + if (!strcmp (a->cred.pV4Cred->principal, + b->cred.pV4Cred->principal) && + !strcmp (a->cred.pV4Cred->principal_instance, + b->cred.pV4Cred->principal_instance) && + !strcmp (a->cred.pV4Cred->service, + b->cred.pV4Cred->service) && + !strcmp (a->cred.pV4Cred->service_instance, + b->cred.pV4Cred->service_instance) && + !strcmp (a->cred.pV4Cred->realm, + b->cred.pV4Cred->realm) && + a->cred.pV4Cred->issue_date == b->cred.pV4Cred->issue_date) { + retval = 0; + } + } + } + + return retval; +} + +// --------------------------------------------------------------------------- + +static cc_result new_v5_creds_union_compat (cred_union *out_union, const char *realm) +{ + cc_result err = CC_NOERROR; + cred_union *creds_union = NULL; + cc_credentials_v5_compat *v5creds = NULL; + static int num_runs = 1; + char *client = NULL; + char *server = NULL; + + if (!out_union) { err = CC_BAD_PARM; } + + if (!err) { + v5creds = malloc (sizeof (*v5creds)); + if (!v5creds) { + err = ccErrNoMem; + } + } + + if (!err) { + asprintf(&client, "client@%s", realm); + asprintf(&server, "host/%d%s@%s", num_runs++, realm, realm); + if (!client || !server) { + err = ccErrNoMem; + } + } + + if (!err) { + v5creds->client = client; + v5creds->server = server; + v5creds->keyblock.type = 1; + v5creds->keyblock.length = 0; + v5creds->keyblock.data = NULL; + v5creds->authtime = time (NULL); + v5creds->starttime = time (NULL); + v5creds->endtime = time(NULL) + 1000; + v5creds->renew_till = time(NULL) + 10000; + v5creds->is_skey = 0; + v5creds->ticket_flags = TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE | TKT_FLG_RENEWABLE | TKT_FLG_INITIAL; + v5creds->addresses = NULL; + v5creds->ticket.type = 0; + v5creds->ticket.length = 0; + v5creds->ticket.data = NULL; + v5creds->second_ticket.type = 0; + v5creds->second_ticket.length = 0; + v5creds->second_ticket.data = NULL; + v5creds->authdata = NULL; + } + + + if (!err) { + creds_union = malloc (sizeof (*creds_union)); + if (creds_union) { + creds_union->cred_type = CC_CRED_V5; + creds_union->cred.pV5Cred = v5creds; + } else { + err = ccErrNoMem; + } + } + if (!err) { + *out_union = *creds_union; + creds_union = NULL; + } + + return err; +} + +// --------------------------------------------------------------------------- + +static void release_v5_creds_union_compat(cred_union *creds_union) { + cc_credentials_v5_compat *v5creds = NULL; + + if (creds_union) { + if (creds_union->cred.pV5Cred) { + v5creds = creds_union->cred.pV5Cred; + if (v5creds->client) { free(v5creds->client); } + if (v5creds->server) { free(v5creds->server); } + if (v5creds->keyblock.data) { free(v5creds->keyblock.data); } + if (v5creds->ticket.data) { free(v5creds->ticket.data); } + if (v5creds->second_ticket.data) { free(v5creds->second_ticket.data); } + free(v5creds); + } + } +} + +// --------------------------------------------------------------------------- + +int check_cc_shutdown(void) { + cc_result err = 0; + apiCB *context = NULL; + + BEGIN_TEST("cc_shutdown"); + + // try with valid context + err = check_once_cc_shutdown(&context, CC_NOERROR, NULL); + + // try with NULL + err = check_once_cc_shutdown(NULL, CC_BAD_PARM, NULL); + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +cc_result check_once_cc_shutdown(apiCB **out_context, cc_result expected_err, const char *description) { + cc_result err = 0; + apiCB *context = NULL; + + cc_result possible_return_values[2] = { + CC_NOERROR, + CC_BAD_PARM, + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (out_context) { + err = cc_initialize(out_context, ccapi_version_2, NULL, NULL); + if (!err) { + context = *out_context; + } else { + log_error("failure in cc_initialize, unable to perform check"); + return err; + } + } + + if (!err) { + err = cc_shutdown(&context); + // check returned error + check_err(err, expected_err, possible_return_values); + + } + + if (out_context) { + *out_context = NULL; + } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_get_change_time(void) { + cc_result err = 0; + apiCB *context = NULL; + cc_time_t last_change_time = 0; + ccache_p *ccache = NULL; + cred_union creds_union; + + BEGIN_TEST("cc_get_change_time"); + + /* + * Make a context + * make sure the change time changes after: + * a ccache is created + * a ccache is destroyed + * a credential is stored + * a credential is removed + * a ccache principal is changed + * clean up memory + */ + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + if (!err) { + + // try bad parameters first + err = check_once_cc_get_change_time(context, NULL, CC_BAD_PARM, "NULL param, should fail"); + + // get_change_time should always give something > 0 + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "first-run, should be > 0"); + + // create a ccache + err = cc_create(context, "TEST_CCACHE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + if (err) { + log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + } + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after creating a new ccache"); + + if (!err) { + // change principal (fails with ccErrBadInternalMessage) + err = cc_set_principal(context, ccache, CC_CRED_V5, "foo@BAR.ORG"); + if (err) { + log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + err = CC_NOERROR; + } + } + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after changing a principle"); + + new_v5_creds_union_compat(&creds_union, "BAR.ORG"); + + // store a credential + if (!err) { + err = cc_store(context, ccache, creds_union); + if (err) { + log_error("failed to store a credential - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + err = CC_NOERROR; + } + } + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after storing a credential"); + + // remove a credential + if (!err) { + err = cc_remove_cred(context, ccache, creds_union); + if (err) { + log_error("failed to remove a credential - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + err = CC_NOERROR; + } + } + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after removing a credential"); + + release_v5_creds_union_compat(&creds_union); + + if (ccache) { + // destroy a ccache + err = cc_destroy(context, &ccache); + check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after destroying a ccache"); + } + } + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_int32 check_once_cc_get_change_time(apiCB *context, cc_time_t *last_time, cc_result expected_err, const char *description) { + cc_result err = 0; + cc_time_t last_change_time; + cc_time_t current_change_time = 0; + + cc_result possible_return_values[3] = { + CC_NOERROR, + CC_BAD_PARM, + CC_NO_EXIST, + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (last_time != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_get_change_time(context, ¤t_change_time); + } else { + err = cc_get_change_time(context, NULL); + } + + check_err(err, expected_err, possible_return_values); + + if (!err) { + last_change_time = *last_time; + check_if(current_change_time <= last_change_time, "context change time did not increase when it was supposed to (%d <= %d)", current_change_time, last_change_time); + *last_time = current_change_time; + } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_open(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name = "TEST_OPEN_CCACHE"; + + BEGIN_TEST("cc_open"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + if (!err) { + // create a ccache + err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + if (err) { + log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err); + failure_count++; + } + if (!err) { + err = cc_close(context, &ccache); + ccache = NULL; + } + + // try default ccache + if (!err) { + err = check_once_cc_open(context, name, CC_CRED_V5, &ccache, CC_NOERROR, NULL); + } + + // check version + if (!err) { + err = check_once_cc_open(context, name, CC_CRED_V4, &ccache, CC_ERR_CRED_VERSION, NULL); + } + // try bad parameters + err = check_once_cc_open(context, NULL, CC_CRED_V5, &ccache, CC_BAD_PARM, NULL); + err = check_once_cc_open(context, name, CC_CRED_V5, NULL, CC_BAD_PARM, NULL); + err = check_once_cc_open(context, name, CC_CRED_UNKNOWN, &ccache, CC_ERR_CRED_VERSION, NULL); + } + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_open(apiCB *context, const char *name, cc_int32 version, ccache_p **ccache, cc_result expected_err, const char *description) { + cc_result err = 0; + char *stored_name = NULL; + + cc_result possible_return_values[5] = { + CC_NOERROR, + CC_BAD_PARM, + CC_NO_EXIST, + CC_NOMEM, + CC_ERR_CRED_VERSION + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param + err = cc_open(context, name, version, 0, ccache); + } else { + err = cc_open(context, name, version, 0, NULL); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(*ccache == NULL, NULL); + + if (!err) { + err = cc_get_name(context, *ccache, &stored_name); + } + if (!err) { + check_if(strcmp(stored_name, name), NULL); + } + if (stored_name) { cc_free_name(context, &stored_name); } + + + if (ccache && *ccache) { + cc_ccache_release(*ccache); + *ccache = NULL; + } + } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_create(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name = "TEST_CC_CREATE"; + + BEGIN_TEST("cc_create"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + if (!err) { + if (!err) { + err = cc_open(context, name, CC_CRED_V5, 0, &ccache); + if (!err) { + err = cc_destroy (context, &ccache); + } else { + err = CC_NOERROR; /* ccache does not exist */ + } + } + // try making a ccache with a unique name (the now destroyed cache's name) + if (!err) { + err = check_once_cc_create(context, name, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_NOERROR, NULL); + } + + // try making a ccache with a non-unique name (the existing cache's name) + if (!err) { + err = check_once_cc_create(context, name, CC_CRED_V5, "foo/baz@BAR.ORG", &ccache, CC_NOERROR, NULL); + } + + // try bad parameters + err = check_once_cc_create(context, NULL, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_BAD_PARM, "NULL name"); // NULL name + err = check_once_cc_create(context, "name", CC_CRED_MAX, "foo@BAR.ORG", &ccache, CC_ERR_CRED_VERSION, "invalid creds_vers"); // invalid creds_vers + err = check_once_cc_create(context, "name", CC_CRED_V5, NULL, &ccache, CC_BAD_PARM, "NULL principal"); // NULL principal + err = check_once_cc_create(context, "name", CC_CRED_V5, "foo@BAR.ORG", NULL, CC_BAD_PARM, "NULL ccache"); // NULL ccache + } + + if (ccache) { cc_destroy(context, &ccache); } + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_create(apiCB *context, const char *name, cc_int32 cred_vers, const char *principal, ccache_p **ccache, cc_int32 expected_err, const char *description) { + cc_result err = 0; + char *stored_name = NULL; + char *stored_principal = NULL; + cc_int32 stored_creds_vers = 0; + + cc_result possible_return_values[6] = { + CC_NOERROR, + CC_BADNAME, + CC_BAD_PARM, + CC_NO_EXIST, + CC_NOMEM, + CC_ERR_CRED_VERSION, + }; + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_create(context, name, principal, cred_vers, 0, ccache); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(*ccache == NULL, NULL); + + // make sure all of the ccache's info matches what we gave it + // name + err = cc_get_name(context, *ccache, &stored_name); + if (!err) { check_if(strcmp(stored_name, name), NULL); } + if (stored_name) { cc_free_name(context, &stored_name); } + // cred_vers + err = cc_get_cred_version(context, *ccache, &stored_creds_vers); + if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } + // principal + err = cc_get_principal(context, *ccache, &stored_principal); + if (!err) { check_if(strcmp(stored_principal, principal), NULL); } + if (stored_principal) { cc_free_principal(context, &stored_principal); } + + if (ccache && *ccache) { + cc_destroy(context, ccache); + *ccache = NULL; + } + } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_close(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name = "TEST_CC_CLOSE"; + + BEGIN_TEST("cc_close"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + + if (!err) { + check_once_cc_close(context, ccache, CC_NOERROR, NULL); + ccache = NULL; + } + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_close(apiCB *context, ccache_p *ccache, cc_result expected_err, const char *description) { + cc_result err = CC_NOERROR; + + cc_result possible_return_values[2] = { + CC_NOERROR, + CC_BAD_PARM + }; + + char *name = NULL; + + err = cc_get_name(context, ccache, &name); + err = cc_close(context, &ccache); + ccache = NULL; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && name) { // try opening released ccache to make sure it still exists + err = cc_open(context, name, CC_CRED_V5, 0, &ccache); + } + check_if(err == CC_NO_EXIST, "released ccache was actually destroyed instead"); + check_if(err != CC_NOERROR, "released ccache cannot be opened"); + + if (ccache) { cc_destroy(context, &ccache); } + if (name) { cc_free_name(context, &name); } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_destroy(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name = "TEST_CC_DESTROY"; + + BEGIN_TEST("cc_destroy"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + + if (!err) { + check_once_cc_destroy(context, ccache, CC_NOERROR, NULL); + ccache = NULL; + } + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_destroy(apiCB *context, ccache_p *ccache, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + + cc_result possible_return_values[2] = { + CC_NOERROR, + CC_BAD_PARM, + }; + + char *name = NULL; + + BEGIN_CHECK_ONCE(description); + +#ifdef cc_ccache_destroy + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_get_name(context, ccache, &name); + err = cc_destroy(context, &ccache); + ccache = NULL; + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err && name) { // try opening released ccache to make sure it still exists + err = cc_open(context, name, CC_CRED_V5, 0, &ccache); + } + check_if(err != CC_NO_EXIST, "destroyed ccache was actually released instead"); + + if (ccache) { cc_destroy(context, &ccache); } + if (name) { cc_free_name(context, &name); } + +#endif /* cc_ccache_destroy */ + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_get_cred_version(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name = "TEST_CC_GET_CRED_VERSION_V5"; + + BEGIN_TEST("cc_get_cred_version"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + // try one created with v5 creds + if (!err) { + err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + if (!err) { + check_once_cc_get_cred_version(context, ccache, CC_CRED_V5, CC_NOERROR, "v5 creds"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + + if (ccache) { + cc_destroy(context, &ccache); + ccache = NULL; + } + + err = CC_NOERROR; + + // try one created with v4 creds + if (!err) { + err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V4, 0, &ccache); + } + if (!err) { + check_once_cc_get_cred_version(context, ccache, CC_CRED_V4, CC_NOERROR, "v4 creds"); + } + else { + log_error("cc_context_create_new_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_destroy(context, &ccache); + ccache = NULL; + } + + if (context) { cc_shutdown(&context); } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_get_cred_version(apiCB *context, ccache_p *ccache, cc_int32 expected_cred_vers, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + + cc_result possible_return_values[3] = { + CC_NOERROR, + CC_BAD_PARM, + CC_NO_EXIST, + }; + + cc_int32 stored_cred_vers = 0; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_get_cred_version(context, ccache, &stored_cred_vers); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(stored_cred_vers != expected_cred_vers, NULL); + } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_get_name(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + + BEGIN_TEST("cc_get_name"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches_v2(context); + } + + // try with unique ccache (which happens to be default) + if (!err) { + err = cc_create(context, "0", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + if (!err) { + check_once_cc_get_name(context, ccache, "0", CC_NOERROR, "unique ccache (which happens to be default)"); + } + else { + log_error("cc_context_create_ccache failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_close(context, &ccache); + ccache = NULL; + } + + // try with unique ccache (which is not default) + if (!err) { + err = cc_context_create_ccache(context, "1", CC_CRED_V5, "foo@BAR.ORG", &ccache); + } + if (!err) { + check_once_cc_get_name(context, ccache, "1", CC_NOERROR, "unique ccache (which is not default)"); + } + else { + log_error("cc_context_create_ccache failed, can't complete test"); + failure_count++; + } + + // try with bad param + if (!err) { + check_once_cc_get_name(context, ccache, NULL, CC_BAD_PARM, "NULL param"); + } + if (ccache) { + cc_close(context, &ccache); + ccache = NULL; + } + + if (context) { + err = destroy_all_ccaches_v2(context); + cc_shutdown(&context); + } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_int32 check_once_cc_get_name(apiCB *context, ccache_p *ccache, const char *expected_name, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + + cc_result possible_return_values[4] = { + CC_NOERROR, + CC_NOMEM, + CC_BAD_PARM, + CC_NO_EXIST, + }; + + char *stored_name = NULL; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (expected_name == NULL) { // we want to try with a NULL param + err = cc_get_name(context, ccache, NULL); + } + else { + err = cc_get_name(context, ccache, &stored_name); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(strcmp(stored_name, expected_name), NULL); + } + + if (stored_name) { cc_free_name(context, &stored_name); } + + END_CHECK_ONCE; + + return err; +} + + +// --------------------------------------------------------------------------- + +int check_cc_get_principal(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5"; + char *name_v4 = "TEST_CC_GET_PRINCIPAL_V4"; + + BEGIN_TEST("cc_get_principal"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches_v2(context); + } + + // try with krb5 principal + if (!err) { + err = cc_create(context, name_v5, "foo/BAR@BAZ.ORG", CC_CRED_V5, 0, &ccache); + } + if (!err) { + check_once_cc_get_principal(context, ccache, "foo/BAR@BAZ.ORG", CC_NOERROR, "trying to get krb5 princ for krb5 ccache"); + } + else { + log_error("cc_create failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_close(context, &ccache); + ccache = NULL; + } + + // try with krb4 principal + if (!err) { + err = cc_create(context, name_v4, "foo.BAR@BAZ.ORG", CC_CRED_V4, 0, &ccache); + } + if (!err) { + check_once_cc_get_principal(context, ccache, "foo.BAR@BAZ.ORG", CC_NOERROR, "trying to get krb4 princ for krb4 ccache"); + } + else { + log_error("cc_create failed, can't complete test"); + failure_count++; + } + + // try with bad param + if (!err) { + check_once_cc_get_principal(context, ccache, NULL, CC_BAD_PARM, "passed null out param"); + } + + if (ccache) { + cc_close(context, &ccache); + ccache = NULL; + } + + if (context) { + err = destroy_all_ccaches_v2(context); + cc_shutdown(&context); + } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_get_principal(apiCB *context, + ccache_p *ccache, + const char *expected_principal, + cc_int32 expected_err, + const char *description) { + cc_result err = CC_NOERROR; + char *stored_principal = NULL; + + cc_result possible_return_values[4] = { + CC_NOERROR, + CC_NOMEM, + CC_NO_EXIST, + CC_BAD_PARM + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + if (expected_principal == NULL) { // we want to try with a NULL param + err = cc_get_principal(context, ccache, NULL); + } + else { + err = cc_get_principal(context, ccache, &stored_principal); + } + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + check_if(strcmp(stored_principal, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal); + } + + if (stored_principal) { cc_free_principal(context, &stored_principal); } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_set_principal(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5"; + char *name_v4 = "TEST_CC_GET_PRINCIPAL_V4"; + + BEGIN_TEST("cc_set_principal"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches_v2(context); + } + + // bad params + if (!err) { + err = cc_create(context, name_v5, "foo@BAZ.ORG", CC_CRED_V5, 0, &ccache); + } + if (!err) { + check_once_cc_set_principal(context, ccache, CC_CRED_MAX, "foo/BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "CC_CRED_MAX (not allowed)"); + check_once_cc_set_principal(context, ccache, CC_CRED_V5, NULL, CC_BAD_PARM, "NULL principal"); + } + else { + log_error("cc_create failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_destroy(context, &ccache); + ccache = NULL; + } + + // empty ccache + + // replace v5 ccache's principal + if (!err) { + err = cc_create(context, name_v5, "foo@BAZ.ORG", CC_CRED_V5, 0, &ccache); + } + if (!err) { + check_once_cc_set_principal(context, ccache, CC_CRED_V5, "foo/BAZ@BAR.ORG", CC_NOERROR, "replace v5 only ccache's principal (empty ccache)"); + check_once_cc_set_principal(context, ccache, CC_CRED_V4, "foo.BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "replace v5 principal with v4"); + } + else { + log_error("cc_create failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_destroy(context, &ccache); + ccache = NULL; + } + + // replace v4 ccache's principal + if (!err) { + err = cc_create(context, name_v4, "foo@BAZ.ORG", CC_CRED_V4, 0, &ccache); + } + if (!err) { + check_once_cc_set_principal(context, ccache, CC_CRED_V4, "foo.BAZ@BAR.ORG", CC_NOERROR, "replace v4 only ccache's principal (empty ccache)"); + check_once_cc_set_principal(context, ccache, CC_CRED_V5, "foo/BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "replace v4 principal with v5"); + } + else { + log_error("cc_create failed, can't complete test"); + failure_count++; + } + if (ccache) { + cc_destroy(context, &ccache); + ccache = NULL; + } + + if (context) { + err = destroy_all_ccaches_v2(context); + cc_shutdown(&context); + } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_int32 check_once_cc_set_principal(apiCB *context, ccache_p *ccache, cc_int32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + char *stored_principal = NULL; + + cc_result possible_return_values[5] = { + CC_NOERROR, + CC_NOMEM, + CC_NO_EXIST, + CC_ERR_CRED_VERSION, + CC_BAD_PARM + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_set_principal(context, ccache, cred_vers, (char *) in_principal); + + // check returned error + check_err(err, expected_err, possible_return_values); + + if (!err) { + err = cc_get_principal(context, ccache, &stored_principal); + } + + // compare stored with input + if (!err) { + check_if(strcmp(stored_principal, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal); + } + + if (stored_principal) { cc_free_principal(context, &stored_principal); } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_store(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + ccache_p *dup_ccache = NULL; + cred_union creds_union; + char *name = NULL; + + BEGIN_TEST("cc_store"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches_v2(context); + } + + if (!err) { + err = cc_create(context, "TEST_CC_STORE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + + // cred with matching version and realm + if (!err) { + err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); + + if (!err) { + check_once_cc_store(context, ccache, creds_union, CC_NOERROR, "ok creds"); + release_v5_creds_union_compat(&creds_union); + } + } + + // invalid creds + if (!err) { + err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); + + if (!err) { + if (creds_union.cred.pV5Cred->client) { + free(creds_union.cred.pV5Cred->client); + creds_union.cred.pV5Cred->client = NULL; + } + check_once_cc_store(context, ccache, creds_union, CC_BAD_PARM, "invalid creds (NULL client string)"); + + release_v5_creds_union_compat(&creds_union); + } + } + + // bad creds version + if (!err) { + err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); + + if (!err) { + creds_union.cred_type = CC_CRED_MAX; + check_once_cc_store(context, ccache, creds_union, CC_ERR_CRED_VERSION, "CC_CRED_MAX (invalid) into a ccache with only v5 princ"); + creds_union.cred_type = CC_CRED_V4; + check_once_cc_store(context, ccache, creds_union, CC_ERR_CRED_VERSION, "v4 creds into a v5 ccache"); + creds_union.cred_type = CC_CRED_V5; + + release_v5_creds_union_compat(&creds_union); + } + } + + // non-existent ccache + if (ccache) { + err = cc_get_name(context, ccache, &name); + if (!err) { + err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache); + } + if (name) { cc_free_name(context, &name); } + if (dup_ccache) { cc_destroy(context, &dup_ccache); } + } + + if (!err) { + err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); + + if (!err) { + check_once_cc_store(context, ccache, creds_union, CC_NO_EXIST, "invalid ccache"); + + release_v5_creds_union_compat(&creds_union); + } + } + + if (ccache) { cc_close(context, &ccache); } + if (context) { + destroy_all_ccaches_v2(context); + cc_shutdown(&context); + } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_store(apiCB *context, ccache_p *ccache, const cred_union in_creds, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + ccache_cit *iterator = NULL; + int found = 0; + + cc_result possible_return_values[5] = { + CC_NOERROR, + CC_BAD_PARM, + CC_ERR_CACHE_FULL, + CC_ERR_CRED_VERSION, + CC_NO_EXIST + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_store(context, ccache, in_creds); + + // check returned error + check_err(err, expected_err, possible_return_values); + + // make sure credentials were truly stored + if (!err) { + err = cc_seq_fetch_creds_begin(context, ccache, &iterator); + } + while (!err && !found) { + cred_union *creds = NULL; + + err = cc_seq_fetch_creds_next(context, &creds, iterator); + if (!err) { + found = !compare_v5_creds_unions_compat(&in_creds, creds); + } + + if (creds) { cc_free_creds(context, &creds); } + } + + if (err == ccIteratorEnd) { + check_if(found, "stored credentials not found in ccache"); + err = ccNoError; + } + + if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } + + END_CHECK_ONCE; + + return err; +} + +// --------------------------------------------------------------------------- + +int check_cc_remove_cred(void) { + cc_result err = 0; + apiCB *context = NULL; + ccache_p *ccache = NULL; + cred_union *creds_array[10]; + ccache_cit *iterator = NULL; + char *name = NULL; + unsigned int i; + + BEGIN_TEST("cc_remove_cred"); + + err = cc_initialize(&context, ccapi_version_2, NULL, NULL); + + if (!err) { + err = destroy_all_ccaches_v2(context); + } + + if (!err) { + err = cc_create(context, "TEST_CC_REMOVE_CRED", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); + } + + // store 10 creds and retrieve their cc_credentials_t representations + for(i = 0; !err && (i < 10); i++) { + cred_union creds; + + new_v5_creds_union_compat(&creds, "BAR.ORG"); + err = cc_store(context, ccache, creds); + if (err) { + log_error("failure to store creds_union in remove_creds test"); + } + release_v5_creds_union_compat(&creds); + } + + if (!err) { + err = cc_seq_fetch_creds_begin(context, ccache, &iterator); + } + + for (i = 0; !err && i < 10; i++) { + creds_array[i] = NULL; + err = cc_seq_fetch_creds_next(context, &creds_array[i], iterator); + } + if (err == ccIteratorEnd) { err = ccNoError; } + + // remove 10 valid creds + for (i = 0; !err && (i < 10); i++) { + check_once_cc_remove_cred(context, ccache, *creds_array[i], CC_NOERROR, "10 ok creds"); + } + + // non-existent creds (remove same one twice) + check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NOTFOUND, "removed same creds twice"); + + // non-existent ccache + if (ccache) { + ccache_p *dup_ccache = NULL; + + err = cc_get_name(context, ccache, &name); + + if (!err) { + err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache); + } + + if (!err) { + err = cc_destroy(context, &dup_ccache); + check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NO_EXIST, "invalid ccache"); + } + + if (name) { cc_free_name(context, &name); } + } + + for(i = 0; i < 10 && creds_array[i]; i++) { + cc_free_creds(context, &creds_array[i]); + } + + + if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } + if (ccache) { cc_close(context, &ccache); } + if (context) { + destroy_all_ccaches_v2(context); + cc_shutdown(&context); + } + + END_TEST_AND_RETURN +} + +// --------------------------------------------------------------------------- + +cc_result check_once_cc_remove_cred(apiCB *context, ccache_p *ccache, cred_union in_creds, cc_int32 expected_err, const char *description) { + cc_result err = CC_NOERROR; + ccache_cit *iterator = NULL; + int found = 0; + + cc_result possible_return_values[5] = { + CC_NOERROR, + CC_BAD_PARM, + CC_ERR_CRED_VERSION, + CC_NOTFOUND, + CC_NO_EXIST + }; + + BEGIN_CHECK_ONCE(description); + +#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) + + err = cc_remove_cred(context, ccache, in_creds); + + // check returned error + check_err(err, expected_err, possible_return_values); + + // make sure credentials were truly stored + if (!err) { + err = cc_seq_fetch_creds_begin(context, ccache, &iterator); + } + + while (!err && !found) { + cred_union *creds = NULL; + + err = cc_seq_fetch_creds_next(context, &creds, iterator); + if (!err) { + found = !compare_v5_creds_unions_compat(&in_creds, creds); + } + + if (creds) { cc_free_creds(context, &creds); } + } + + if (err == ccIteratorEnd) { + check_if(!found, "credentials not removed from ccache"); + err = ccNoError; + } + + if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } + + END_CHECK_ONCE; + + return err; +} diff --git a/src/ccapi/test/test_ccapi_v2.h b/src/ccapi/test/test_ccapi_v2.h new file mode 100644 index 000000000..4596bb5d6 --- /dev/null +++ b/src/ccapi/test/test_ccapi_v2.h @@ -0,0 +1,51 @@ +#ifndef _TEST_CCAPI_V2_H_ +#define _TEST_CCAPI_V2_H_ + +#include "test_ccapi_globals.h" +#ifdef TARGET_OS_MAC +#include +#else +#include +#endif + + +int check_cc_shutdown(void); +cc_result check_once_cc_shutdown(apiCB **out_context, cc_result expected_err, const char *description); + +int check_cc_get_change_time(void); +cc_int32 check_once_cc_get_change_time(apiCB *context, cc_time_t *time, cc_result expected_err, const char *description); + +int check_cc_open(void); +cc_result check_once_cc_open(apiCB *context, const char *name, cc_int32 version, ccache_p **ccache, cc_result expected_err, const char *description); + +int check_cc_create(void); +cc_result check_once_cc_create(apiCB *context, const char *name, cc_int32 cred_vers, const char *principal, ccache_p **ccache, cc_int32 expected_err, const char *description); + +int check_cc_close(void); +cc_result check_once_cc_close(apiCB *context, ccache_p *ccache, cc_result expected_err, const char *description); + +int check_cc_destroy(void); +cc_result check_once_cc_destroy(apiCB *context, ccache_p *ccache, cc_int32 expected_err, const char *description); + +int check_cc_get_cred_version(void); +cc_result check_once_cc_get_cred_version(apiCB *context, ccache_p *ccache, cc_int32 expected_cred_vers, cc_int32 expected_err, const char *description); + +int check_cc_get_name(void); +cc_int32 check_once_cc_get_name(apiCB *context, ccache_p *ccache, const char *expected_name, cc_int32 expected_err, const char *description); + +int check_cc_get_principal(void); +cc_result check_once_cc_get_principal(apiCB *context, + ccache_p *ccache, + const char *expected_principal, + cc_int32 expected_err, + const char *description); + +int check_cc_set_principal(void); +cc_int32 check_once_cc_set_principal(apiCB *context, ccache_p *ccache, cc_int32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description); + +int check_cc_store(void); +cc_result check_once_cc_store(apiCB *context, ccache_p *ccache, const cred_union in_creds, cc_int32 expected_err, const char *description); + +int check_cc_remove_cred(void); +cc_result check_once_cc_remove_cred(apiCB *context, ccache_p *ccache, cred_union in_creds, cc_int32 expected_err, const char *description); +#endif /* _TEST_CCAPI_V2_H_ */