From 930c140ddef071a401606e3580f193ef1d0c637e Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 17 Jan 2011 12:44:09 +0100 Subject: [PATCH] Only allow choosing slot once. Choosing slot resets cfgFlags etc. which violates the principle of least astonishments if done more than once (think setting a bunch of flags, and then setting slot). --- tests/test_args_to_config.c | 91 +++++++++++++++++++++++++++++++++++-- ykpersonalize.c | 53 +++++++++++++++++++-- 2 files changed, 138 insertions(+), 6 deletions(-) diff --git a/tests/test_args_to_config.c b/tests/test_args_to_config.c index 2b96e08..87e78ad 100644 --- a/tests/test_args_to_config.c +++ b/tests/test_args_to_config.c @@ -76,8 +76,10 @@ void _check_success(int rc, YKP_CONFIG *cfg, unsigned char expected[], int calle struct config_st *ycfg; bool config_matches_expected = false; - if (rc != 1) - printf ("Error returned : %i/%i (%s)\n", rc, ykp_errno, ykp_strerror(ykp_errno)); + if (rc != 1) { + fprintf(stderr, "TEST FAILED (line %i of %s)\n", caller_line, __FILE__); + fprintf(stderr, "Error returned : %i/%i (%s)\n", rc, ykp_errno, ykp_strerror(ykp_errno)); + } assert(rc == 1); ycfg = (struct config_st *) ykp_core_config(cfg); @@ -350,7 +352,6 @@ int _test_extended_flags1() char *argv[] = { "unittest", "-2", "-a303132333435363738393a3b3c3d3e3f40414243", - "-o-append-cr", "-o-static-ticket", "-o-strong-pw1", "-o-strong-pw2", "-o-man-update", "-ochal-resp", "-ochal-hmac", "-ohmac-lt64", "-oserial-api-visible", NULL }; @@ -363,6 +364,86 @@ int _test_extended_flags1() free(st); } +int _test_two_slots1() +{ + YKP_CONFIG *cfg = ykp_create_config(); + YK_STATUS *st = _test_init_st(2, 2, 0); + int rc = 0; + + /* Test that it is not possible to choose slot more than once */ + char *argv[] = { + "unittest", "-1", "-1", + NULL + }; + int argc = sizeof argv/sizeof argv[0] - 1; + + rc = _test_config(cfg, st, argc, argv); + assert(rc == 0); + + ykp_free_config(cfg); + free(st); +} + +int _test_two_slots2() +{ + YKP_CONFIG *cfg = ykp_create_config(); + YK_STATUS *st = _test_init_st(2, 2, 0); + int rc = 0; + + /* Test that it is not possible to choose slot more than once */ + char *argv[] = { + "unittest", "-2", "-1", + NULL + }; + int argc = sizeof argv/sizeof argv[0] - 1; + + rc = _test_config(cfg, st, argc, argv); + assert(rc == 0); + + ykp_free_config(cfg); + free(st); +} + +int _test_two_modes_at_once1() +{ + YKP_CONFIG *cfg = ykp_create_config(); + YK_STATUS *st = _test_init_st(2, 2, 0); + int rc = 0; + + /* Test that it is not possible to choose mode (OATH-HOTP/CHAL-RESP) more than once */ + char *argv[] = { + "unittest", "-ochal-resp", "-ooath-hotp", + NULL + }; + int argc = sizeof argv/sizeof argv[0] - 1; + + rc = _test_config(cfg, st, argc, argv); + assert(rc == 0); + + ykp_free_config(cfg); + free(st); +} + +int _test_two_modes_at_once2() +{ + YKP_CONFIG *cfg = ykp_create_config(); + YK_STATUS *st = _test_init_st(2, 2, 0); + int rc = 0; + + /* Test that it is not possible to choose mode (OATH-HOTP/CHAL-RESP) more than once */ + char *argv[] = { + "unittest", "-ochal-resp", "-ochal-resp", + NULL + }; + int argc = sizeof argv/sizeof argv[0] - 1; + + rc = _test_config(cfg, st, argc, argv); + assert(rc == 0); + + ykp_free_config(cfg); + free(st); +} + int main (int argc, char **argv) { _test_config_slot1(); @@ -372,6 +453,10 @@ int main (int argc, char **argv) _test_non_config_args(); _test_oath_hotp_nist_160_bits(); _test_extended_flags1(); + _test_two_slots1(); + _test_two_slots2(); + _test_two_modes_at_once1(); + _test_two_modes_at_once2(); return 0; } diff --git a/ykpersonalize.c b/ykpersonalize.c index 9aeef4f..3b61480 100644 --- a/ykpersonalize.c +++ b/ykpersonalize.c @@ -208,16 +208,66 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, char c; const char *aeshash = NULL; bool new_access_code = false; + bool slot_chosen = false; + bool mode_chosen = false; + bool option_seen = false; + + struct config_st *ycfg; + ycfg = (struct config_st *) ykp_core_config(cfg); while((c = getopt(argc, argv, optstring)) != -1) { + if (c == 'o') { + if (strcmp(optarg, "oath-hotp") == 0 || + strcmp(optarg, "chal-resp") == 0) { + if (mode_chosen) { + fprintf(stderr, "You may only choose mode (-ooath-hotp / " + "-ochal-resp) once.\n"); + *exit_code = 1; + return 0; + } + + if (option_seen) { + fprintf(stderr, "Mode choosing flags (oath-hotp / chal-resp) " + "must be set prior to any other options (-o).\n"); + *exit_code = 1; + return 0; + } + + /* The default flags (particularly for slot 2) does not apply to + * these new modes of operation found in Yubikey >= 2.1. Therefor, + * we reset them here and, as a consequence of that, require the + * mode choosing options to be specified before any other. + */ + ycfg->tktFlags = 0; + ycfg->cfgFlags = 0; + ycfg->extFlags = 0; + + mode_chosen = 1; + } + + option_seen = true; + } + switch (c) { case '1': + if (slot_chosen) { + fprintf(stderr, "You may only choose slot (-1 / -2) once.\n"); + *exit_code = 1; + return 0; + } if (!ykp_configure_for(cfg, 1, st)) return 0; + slot_chosen = true; break; case '2': + if (slot_chosen) { + fprintf(stderr, "You may only choose slot (-1 / -2) once.\n"); + *exit_code = 1; + return 0; + } if (!ykp_configure_for(cfg, 2, st)) return 0; + slot_chosen = true; break; case 'i': *infname = optarg; @@ -398,11 +448,8 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, if (*aesviahash) { int long_key_valid = false; - struct config_st *ycfg; int res = 0; - ycfg = (struct config_st *) ykp_core_config(cfg); - /* for OATH-HOTP, 160 bits key is also valid */ if ((ycfg->tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP) long_key_valid = true; -- 2.39.5