}
}
-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;
outfname = optarg;
break;
case 'a':
- aesviahash = true;
+ *aesviahash = true;
aeshash = optarg;
break;
case 'c': {
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':
fprintf(stderr,
"Invalid fixed string: %s\n",
fixed);
- exit_code = 1;
- goto err;
+ *exit_code = 1;
+ return 0;
}
ykp_set_fixed(cfg, fixedbin, fixedbinlen);
}
fprintf(stderr,
"Invalid uid string: %s\n",
uid);
- exit_code = 1;
- goto err;
+ *exit_code = 1;
+ return 0;
}
ykp_set_uid(cfg, uidbin, uidbinlen);
}
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;
#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)
#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)
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;
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);