]> err.no Git - yubikey-personalization.old/commitdiff
Make argument parsing testable.
authorFredrik Thulin <fredrik@yubico.com>
Thu, 13 Jan 2011 22:04:47 +0000 (23:04 +0100)
committerFredrik Thulin <fredrik@yubico.com>
Fri, 14 Jan 2011 10:26:47 +0000 (11:26 +0100)
ykpersonalize.c

index 1801f12a2fa08675d95de0f445441660f4d9a6ed..d4153e02d84b2d2021012319d3450ca70d500189 100644 (file)
@@ -174,87 +174,34 @@ static void report_yk_error()
        }
 }
 
-int main(int argc, char **argv)
+/*
+ * Parse all arguments supplied to this program and turn it into mainly
+ * a YKP_CONFIG (but return some other parameters as well, like
+ * access_code, verbose etc.).
+ *
+ * Done in this way to be testable (see tests/test_args_to_config.c).
+ */
+int args_to_config(int argc, char **argv, YKP_CONFIG *cfg,
+                  const char *infname, const char *outfname,
+                  bool *autocommit, char *salt,
+                  YK_STATUS *st, bool *verbose,
+                  unsigned char *access_code, bool *use_access_code,
+                  bool *aesviahash,
+                  int *exit_code)
 {
        char c;
-       FILE *inf = NULL; const char *infname = NULL;
-       FILE *outf = NULL; const char *outfname = NULL;
-       bool verbose = false;
-       bool aesviahash = false; const char *aeshash = NULL;
-       bool use_access_code = false, new_access_code = false;
-       unsigned char access_code[256];
-       YK_KEY *yk = 0;
-       YKP_CONFIG *cfg = ykp_create_config();
-       YK_STATUS *st = ykds_alloc();
-       bool autocommit = false;
-
-       bool error = false;
-       int exit_code = 0;
-
-       /* Options */
-       char *salt = NULL;
-
-       ykp_errno = 0;
-       yk_errno = 0;
-
-       /* Assume the worst */
-       error = true;
-
-       if (!yk_init()) {
-               exit_code = 1;
-               goto err;
-       }
-
-       if (argc == 2 && strcmp (argv[1], "-h") == 0) {
-               fputs(usage, stderr);
-               goto err;
-       }
-
-       if (!(yk = yk_open_first_key())) {
-               exit_code = 1;
-               goto err;
-       }
-
-       if (!yk_get_status(yk, st)) {
-               exit_code = 1;
-               goto err;
-       }
-
-       printf("Firmware version %d.%d.%d Touch level %d ",
-              ykds_version_major(st),
-              ykds_version_minor(st),
-              ykds_version_build(st),
-              ykds_touch_level(st));
-       if (ykds_pgm_seq(st))
-               printf("Program sequence %d\n",
-                      ykds_pgm_seq(st));
-       else
-               printf("Unconfigured\n");
-
-       if (!(yk_check_firmware_version(yk))) {
-               if (yk_errno == YK_EFIRMWARE) {
-                       printf("Unsupported firmware revision - some "
-                              "features may not be available\n"
-                              "Please see \n"
-                              "http://code.google.com/p/yubikey-personalization/wiki/Compatibility\n"
-                              "for more information.\n");
-               } else {
-                       goto err;
-               }
-       }
-
-       if (!ykp_configure_for(cfg, 1, st))
-               goto err;
+       const char *aeshash = NULL;
+       bool new_access_code = false;
 
        while((c = getopt(argc, argv, optstring)) != -1) {
                switch (c) {
                case '1':
                        if (!ykp_configure_for(cfg, 1, st))
-                               goto err;
+                               return 0;
                        break;
                case '2':
                        if (!ykp_configure_for(cfg, 2, st))
-                               goto err;
+                               return 0;
                        break;
                case 'i':
                        infname = optarg;
@@ -263,7 +210,7 @@ int main(int argc, char **argv)
                        outfname = optarg;
                        break;
                case 'a':
-                       aesviahash = true;
+                       *aesviahash = true;
                        aeshash = optarg;
                        break;
                case 'c': {
@@ -275,14 +222,14 @@ int main(int argc, char **argv)
                                fprintf(stderr,
                                        "Invalid access code string: %s\n",
                                        optarg);
-                               exit_code = 1;
-                               goto err;
+                               *exit_code = 1;
+                               return 0;
                        }
                        if (!new_access_code)
                                ykp_set_access_code(cfg,
                                                    access_code,
                                                    access_code_len);
-                       use_access_code = true;
+                       *use_access_code = true;
                        break;
                }
                case 'o':
@@ -300,8 +247,8 @@ int main(int argc, char **argv)
                                        fprintf(stderr,
                                                "Invalid fixed string: %s\n",
                                                fixed);
-                                       exit_code = 1;
-                                       goto err;
+                                       *exit_code = 1;
+                                       return 0;
                                }
                                ykp_set_fixed(cfg, fixedbin, fixedbinlen);
                        }
@@ -317,8 +264,8 @@ int main(int argc, char **argv)
                                        fprintf(stderr,
                                                "Invalid uid string: %s\n",
                                                uid);
-                                       exit_code = 1;
-                                       goto err;
+                                       *exit_code = 1;
+                                       return 0;
                                }
                                ykp_set_uid(cfg, uidbin, uidbinlen);
                        }
@@ -334,8 +281,8 @@ int main(int argc, char **argv)
                                        fprintf(stderr,
                                                "Invalid access code string: %s\n",
                                                acc);
-                                       exit_code = 1;
-                                       goto err;
+                                       *exit_code = 1;
+                                       return 0;
                                }
                                ykp_set_access_code(cfg, accbin, accbinlen);
                                new_access_code = true;
@@ -343,13 +290,13 @@ int main(int argc, char **argv)
 #define TKTFLAG(o, f)                                                  \
                        else if (strcmp(optarg, o) == 0) {              \
                                if (!ykp_set_tktflag_##f(cfg, true)) {  \
-                                       exit_code = 1;                  \
-                                       goto err;                       \
+                                       *exit_code = 1;                 \
+                                       return 0;               \
                                }                                       \
                        } else if (strcmp(optarg, "-" o) == 0) {        \
                                if (! ykp_set_tktflag_##f(cfg, false)) { \
-                                       exit_code = 1;                  \
-                                       goto err;                       \
+                                       *exit_code = 1;                 \
+                                       return 0;               \
                                }                                       \
                        }
                        TKTFLAG("tab-first", TAB_FIRST)
@@ -365,13 +312,13 @@ int main(int argc, char **argv)
 #define CFGFLAG(o, f)                                                  \
                        else if (strcmp(optarg, o) == 0) {              \
                                if (! ykp_set_cfgflag_##f(cfg, true)) { \
-                                       exit_code = 1;                  \
-                                       goto err;                       \
+                                       *exit_code = 1;                 \
+                                       return 0;                       \
                                }                                       \
                        } else if (strcmp(optarg, "-" o) == 0) {        \
                                if (! ykp_set_cfgflag_##f(cfg, false)) { \
-                                       exit_code = 1;                  \
-                                       goto err;                       \
+                                       *exit_code = 1;                 \
+                                       return 0;                       \
                                }                                       \
                        }
                        CFGFLAG("send-ref", SEND_REF)
@@ -393,24 +340,117 @@ int main(int argc, char **argv)
                                fprintf(stderr, "Unknown option '%s'\n",
                                        optarg);
                                fputs(usage, stderr);
-                               exit_code = 1;
-                               goto err;
+                               *exit_code = 1;
+                               return 0;
                        }
                        break;
                case 'v':
-                       verbose = true;
+                       *verbose = true;
                        break;
                case 'y':
-                       autocommit = true;
+                       *autocommit = true;
                        break;
                case 'h':
                default:
                        fputs(usage, stderr);
-                       exit_code = 0;
+                       *exit_code = 0;
+                       return 0;
+               }
+       }
+
+       if (*aesviahash) {
+               if (ykp_AES_key_from_hex(cfg, aeshash)) {
+                       fprintf(stderr, "Bad AES key: %s\n", aeshash);
+                       fflush(stderr);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+int main(int argc, char **argv)
+{
+       FILE *inf = NULL; const char *infname = NULL;
+       FILE *outf = NULL; const char *outfname = NULL;
+       bool verbose = false;
+       bool aesviahash = false;
+       bool use_access_code = false;
+       unsigned char access_code[256];
+       YK_KEY *yk = 0;
+       YKP_CONFIG *cfg = ykp_create_config();
+       YK_STATUS *st = ykds_alloc();
+       bool autocommit = false;
+
+       /* Options */
+       char *salt = NULL;
+
+       bool error = false;
+       int exit_code = 0;
+
+       ykp_errno = 0;
+       yk_errno = 0;
+
+       /* Assume the worst */
+       error = true;
+
+       if (!yk_init()) {
+               exit_code = 1;
+               goto err;
+       }
+
+       if (argc == 2 && strcmp (argv[1], "-h") == 0) {
+               fputs(usage, stderr);
+               goto err;
+       }
+
+       if (!(yk = yk_open_first_key())) {
+               exit_code = 1;
+               goto err;
+       }
+
+       if (!yk_get_status(yk, st)) {
+               exit_code = 1;
+               goto err;
+       }
+
+       printf("Firmware version %d.%d.%d Touch level %d ",
+              ykds_version_major(st),
+              ykds_version_minor(st),
+              ykds_version_build(st),
+              ykds_touch_level(st));
+       if (ykds_pgm_seq(st))
+               printf("Program sequence %d\n",
+                      ykds_pgm_seq(st));
+       else
+               printf("Unconfigured\n");
+
+       if (!(yk_check_firmware_version(yk))) {
+               if (yk_errno == YK_EFIRMWARE) {
+                       printf("Unsupported firmware revision - some "
+                              "features may not be available\n"
+                              "Please see \n"
+                              "http://code.google.com/p/yubikey-personalization/wiki/Compatibility\n"
+                              "for more information.\n");
+               } else {
                        goto err;
                }
        }
 
+       if (!ykp_configure_for(cfg, 1, st))
+               goto err;
+
+       /* Parse all arguments in a testable way */
+       if (! args_to_config(argc, argv, cfg,
+                            infname, outfname,
+                            &autocommit, salt,
+                            st, &verbose,
+                            access_code, &use_access_code,
+                            &aesviahash,
+                            &exit_code)) {
+               goto err;
+       }
+
        if (infname) {
                if (strcmp(infname, "-") == 0)
                        inf = stdin;
@@ -443,13 +483,7 @@ int main(int argc, char **argv)
        if (inf) {
                if (!ykp_read_config(cfg, reader, inf))
                        goto err;
-       } else if (aesviahash) {
-               if (ykp_AES_key_from_hex(cfg, aeshash)) {
-                       fprintf(stderr, "Bad AES key: %s\n", aeshash);
-                       fflush(stderr);
-                       goto err;
-               }
-       } else {
+       } else if (! aesviahash) {
                char passphrasebuf[256]; size_t passphraselen;
                fprintf(stderr, "Passphrase to create AES key: ");
                fflush(stderr);