diff --git a/src/sso/test/Makefile.am b/src/sso/test/Makefile.am index 56096ad0c5699abb1efb3f60372ef066c3cbb761..babef4e45a4a52e0ea86d320e10c973e2f682ff3 100644 --- a/src/sso/test/Makefile.am +++ b/src/sso/test/Makefile.am @@ -1,5 +1,7 @@ include $(top_srcdir)/Makefile.defs +AUTOMAKE_OPTIONS = serial-tests + check_PROGRAMS = \ sso_unittest \ tweetnacl_unittest diff --git a/src/sso/test/fuzz_signed.c b/src/sso/test/fuzz_signed.c index b5e025b7abf1376fe6c78cc8dcfbefea7277cc54..f567bd44f325e2c6d7b95f447abcb8e9a6ded8bd 100644 --- a/src/sso/test/fuzz_signed.c +++ b/src/sso/test/fuzz_signed.c @@ -32,6 +32,8 @@ static inline const unsigned char *get_secret_key() { return secret_key; } +static char *static_groups[] = {"g1", "g2", NULL}; + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { unsigned char *buf; unsigned char *b64buf; @@ -52,6 +54,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { r = sso_ticket_open(&tkt, (const char *)b64buf, get_public_key()); if (r == SSO_OK) { + sso_validate(tkt, "svc", "domain", NULL, static_groups); sso_ticket_free(tkt); } diff --git a/src/sso/test/sso_unittest.cc b/src/sso/test/sso_unittest.cc index 4c668574fe31c5c41e6d8051f63495c6c4a6edda..f3a721bb0682967e3f0a7f0fe7bbf4ec0978a6ef 100644 --- a/src/sso/test/sso_unittest.cc +++ b/src/sso/test/sso_unittest.cc @@ -98,13 +98,19 @@ protected: char *sign_ticket(sso_ticket_t t) { char buf[1024]; EXPECT_EQ(0, sso_ticket_sign(t, secret_key, buf, sizeof(buf))); + return strdup(buf); + } + + // Return a signed ticket, for test data generation. + char *sign_and_free_ticket(sso_ticket_t t) { + char *res = sign_ticket(t); // No further use for the original ticket. sso_ticket_free(t); - return strdup(buf); + return res; } // Sign a ticket with a random secret key. - char *sign_ticket_with_random_key(sso_ticket_t t) { + char *sign_and_free_ticket_with_random_key(sso_ticket_t t) { unsigned char pk[SSO_PUBLIC_KEY_SIZE], sk[SSO_SECRET_KEY_SIZE]; sso_generate_keys(pk, sk); char buf[1024]; @@ -177,20 +183,20 @@ struct open_testdata { TEST_F(SSO, Open) { const char *groups[] = {"users", "wheel", "daemon", NULL}; struct open_testdata td[] = { - {sign_ticket( + {sign_and_free_ticket( sso_ticket_new("user", "service/", "domain", NULL, NULL, 7200)), 0}, - {sign_ticket( + {sign_and_free_ticket( sso_ticket_new("user", "service/", "domain", NULL, groups, 7200)), 0}, - {sign_ticket(sso_ticket_new("user", "", "", NULL, NULL, 7200)), 0}, + {sign_and_free_ticket(sso_ticket_new("user", "", "", NULL, NULL, 7200)), 0}, {sign_string("5|user|service/|domain|1414402999|"), SSO_ERR_UNSUPPORTED_VERSION}, {sign_string("4|definitely not a ticket"), SSO_ERR_DESERIALIZATION}, {sign_string("4||||||"), 0}, - {sign_ticket_with_random_key( + {sign_and_free_ticket_with_random_key( sso_ticket_new("user", "service/", "domain", NULL, NULL, 7200)), SSO_ERR_BAD_SIGNATURE}, @@ -332,6 +338,43 @@ TEST_F(SSO, Validation) { } } +static bool is_ticket_equal(sso_ticket_t a, sso_ticket_t b) { + return (!strcmp(a->user, b->user) && + !strcmp(a->service, b->service) && + !strcmp(a->domain, b->domain) && + !strcmp(a->nonce ?: "NULL", b->nonce ?: "NULL") && + a->expires == b->expires); +} + +TEST_F(SSO, Serialization) { + const char *groups_ok[] = {"users", "admins", NULL}; + const char *groups_fail[] = {"users", "others", NULL}; + + sso_ticket_t td[] = { + sso_ticket_new("user", "service/", "domain", NULL, groups_ok, 7200), + sso_ticket_new("user", "service/", "domain", NULL, NULL, 7200), + sso_ticket_new("user", "service/", "domain", NULL, groups_fail, 7200), + sso_ticket_new("user", "service/", "other", NULL, groups_ok, 7200), + sso_ticket_new("user", "other/", "domain", NULL, groups_ok, 7200), + sso_ticket_new("user", "service/", "domain", NULL, NULL, -1000), + sso_ticket_new("user", "service/", "domain", "testnonce", NULL, 7200), + sso_ticket_new("user", "service/", "domain", "badnonce", NULL, 7200), + sso_ticket_new("user", "service/", "domain", NULL, NULL, 7200), + NULL, + }; + + for (sso_ticket_t *tdp = td; *tdp; tdp++) { + sso_ticket_t cur = *tdp, deserialized = NULL; + char *serialized; + + serialized = sign_ticket(cur); + EXPECT_EQ(SSO_OK, sso_ticket_open(&deserialized, serialized, public_key)); + EXPECT_NE(cur, deserialized); + EXPECT_EQ(true, is_ticket_equal(cur, deserialized)); + free(serialized); + } +} + } // namespace int main(int argc, char **argv) {