]> err.no Git - yubikey-personalization.old/commitdiff
Rewrite, using better error checking and reporting
authorRichard Levitte <levitte@lp.se>
Sat, 4 Oct 2008 13:03:53 +0000 (13:03 +0000)
committerRichard Levitte <levitte@lp.se>
Sat, 4 Oct 2008 13:03:53 +0000 (13:03 +0000)
ykpersonalize.c

index b8f39ceb650d5b22df28bf9bd0136978aaaf8673..2289293de9e0abe6c990460e8954c592278f5b80 100644 (file)
@@ -64,41 +64,29 @@ static int writer(const char *buf, size_t count, void *stream)
 main(int argc, char **argv)
 {
        char c;
-       FILE *inf = NULL;
-       FILE *outf = NULL;
+       FILE *inf = NULL; const char *infname = NULL;
+       FILE *outf = NULL; const char *outfname = NULL;
        bool verbose = false;
        CONFIG *cfg = ykp_create_config();
 
+       bool error = false;
+       int exit_code = 0;
+
+       if (!cfg) {
+               fprintf(stderr, "Out of memory!\n");
+               exit(1);
+       }
+
        /* Options */
        char *salt = NULL;
 
        while((c = getopt(argc, argv, optstring)) != -1) {
                switch (c) {
                case 'i':
-                       if (strcmp(optarg, "-") == 0)
-                               inf = stdin;
-                       else
-                               inf = fopen(optarg, "r");
-                       if (inf == NULL) {
-                               fprintf(stderr,
-                                       "Couldn't open %s for reading: %s\n",
-                                       optarg,
-                                       strerror(errno));
-                               exit(1);
-                       }
+                       infname = optarg;
                        break;
                case 's':
-                       if (strcmp(optarg, "-") == 0)
-                               outf = stdout;
-                       else
-                               outf = fopen(optarg, "r");
-                       if (outf == NULL) {
-                               fprintf(stderr,
-                                       "Couldn't open %s for writing: %s\n",
-                                       optarg,
-                                       strerror(errno));
-                               exit(1);
-                       }
+                       outfname = optarg;
                        break;
                case 'o':
                        if (strncmp(optarg, "salt=", 5) == 0)
@@ -112,6 +100,7 @@ main(int argc, char **argv)
                        break;
                case 'v':
                        verbose = true;
+                       break;
                case 'h':
                default:
                        fprintf(stderr, usage);
@@ -120,27 +109,117 @@ main(int argc, char **argv)
                }
        }
 
-       if (inf) {
-               ykp_read_config(cfg, reader, inf);
-               fclose(inf);
-       } else {
-               char passphrasebuf[256]; size_t passphraselen;
-               fprintf(stderr, "Passphrase to create AES key: ");
-               fflush(stderr);
-               fgets(passphrasebuf, sizeof(passphrasebuf), stdin);
-               passphraselen = strlen(passphrasebuf);
-               if (passphrasebuf[passphraselen - 1] == '\n')
-                       passphrasebuf[passphraselen - 1] == '\0';
-               ykp_AES_key_from_passphrase(cfg, passphrasebuf, salt);
+       if (infname) {
+               if (strcmp(infname, "-") == 0)
+                       inf = stdin;
+               else
+                       inf = fopen(infname, "r");
+               if (inf == NULL) {
+                       fprintf(stderr,
+                               "Couldn't open %s for reading: %s\n",
+                               infname,
+                               strerror(errno));
+                       exit(1);
+               }
        }
 
-       if (outf) {
-               ykp_write_config(cfg, writer, outf);
-               fclose(outf);
-       } else {
-               /* Output to key, and that's a different story! */
+       if (outfname) {
+               if (strcmp(outfname, "-") == 0)
+                       outf = stdout;
+               else
+                       outf = fopen(outfname, "w");
+               if (outf == NULL) {
+                       fprintf(stderr,
+                               "Couldn't open %s for writing: %s\n",
+                               outfname,
+                               strerror(errno));
+                       exit(1);
+               }
        }
 
+       /* Using a do-while loop that never loops provides a practical
+          way to bail out on error without using goto... */
+       do {
+               /* Assume the worst */
+               error = true;
+
+               exit_code = 0;
+               ykp_errno = 0;
+               yk_errno = 0;
+
+               if (inf) {
+                       if (!ykp_read_config(cfg, reader, inf))
+                               break;
+               } else {
+                       char passphrasebuf[256]; size_t passphraselen;
+                       fprintf(stderr, "Passphrase to create AES key: ");
+                       fflush(stderr);
+                       fgets(passphrasebuf, sizeof(passphrasebuf), stdin);
+                       passphraselen = strlen(passphrasebuf);
+                       if (passphrasebuf[passphraselen - 1] == '\n')
+                               passphrasebuf[passphraselen - 1] == '\0';
+                       if (!ykp_AES_key_from_passphrase(cfg,
+                                                        passphrasebuf, salt))
+                               break;
+               }
+
+               if (outf) {
+                       if (!ykp_write_config(cfg, writer, outf))
+                               break;
+               } else {
+                       YUBIKEY *yk;
+
+                       /* Assume the worst */
+                       exit_code = 2;
+
+                       if (verbose)
+                               printf("Attempting to write configuration to the yubikey...");
+                       if (!yk_init())
+                               break;
+
+                       if (!(yk = yk_open_first_key()))
+                               break;
+
+                       if (yk_write_config(yk, cfg, NULL)) {
+                               if (verbose)
+                                       printf(" success\n");
+                               ykp_write_config(cfg, writer, stdout);
+                               exit_code = 0;
+                       } else {
+                               printf(" failure\n");
+                       }
+                       if (!yk_close_key(yk))
+                               break;
+
+                       if (!yk_release())
+                               break;
+               }
+               error = false;
+       } while(false);
+
        if (salt)
                free(salt);
+       if (inf)
+               fclose(inf);
+       if (outf)
+               fclose(outf);
+
+       if (error) {
+               if (ykp_errno)
+                       fprintf(stderr, "Yubikey personalization error: %s\n",
+                               ykp_strerror(ykp_errno));
+               if (yk_errno) {
+                       if (yk_errno == YK_EUSBERR) {
+                               fprintf(stderr, "USB error: %s\n",
+                                       usb_strerror());
+                       } else {
+                               fprintf(stderr, "Yubikey core error: %s\n",
+                                       yk_strerror(yk_errno));
+                       }
+               }
+               if (exit_code)
+                       exit(exit_code);
+               exit(1);
+       }
+       exit(0);
 }