From 9e877bda4678e372094c17cc10a2f76ded2039a5 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Mon, 15 Oct 2012 18:47:50 +0200 Subject: [PATCH] add new binary ykinfo can be used to get serial, version or touch level from the command line --- .gitignore | 2 + Makefile.am | 5 +- ykinfo.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 ykinfo.c diff --git a/.gitignore b/.gitignore index 1243d26..1b6f56f 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,5 @@ ykpers.lo ykpers.o ykpersonalize ykpersonalize.o +ykinfo +ykinfo.o diff --git a/Makefile.am b/Makefile.am index a6e9ece..84eec95 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,7 +62,7 @@ endif # The command line tools. -bin_PROGRAMS = ykpersonalize ykchalresp +bin_PROGRAMS = ykpersonalize ykchalresp ykinfo ykpersonalize_SOURCES = ykpersonalize.c ykpers-args.h ykpers-args.c ykpersonalize_LDADD = ./libykpers-1.la ./ykcore/libykcore.la @@ -70,6 +70,9 @@ ykpersonalize_LDADD = ./libykpers-1.la ./ykcore/libykcore.la ykchalresp_SOURCES = ykchalresp.c ykchalresp_LDADD = ./libykpers-1.la ./ykcore/libykcore.la +ykinfo_SOURCES = ykinfo.c +ykinfo_LDADD = ./ykcore/libykcore.la + dist_man1_MANS = ykpersonalize.1 ykchalresp.1 # Dist docs from wiki. diff --git a/ykinfo.c b/ykinfo.c new file mode 100644 index 0000000..1d4e6aa --- /dev/null +++ b/ykinfo.c @@ -0,0 +1,223 @@ +/* -*- mode:C; c-file-style: "bsd" -*- */ +/* + * Copyright (c) 2012 Yubico AB. + * All rights reserved. + * + * Some basic code copied from ykchalresp.c. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include + +const char *usage = + "Usage: ykinfo [options]\n" + "\n" + "Options :\n" + "\n" + "\t-s Get serial in decimal from YubiKey\n" + "\t-m Get serial in modhex from YubiKey\n" + "\t-H Get serial in hex from YubiKey\n" + "\t-v Get version from YubiKey\n" + "\t-t Get touchlevel from YubiKey\n" + "\n" + "\t-q Only output information from YubiKey\n" + "\n" + "\t-h help (this text)\n" + "\n" + "\n" + ; +const char *optstring = "smHvtqh"; + +static void report_yk_error(void) +{ + if (yk_errno) { + if (yk_errno == YK_EUSBERR) { + fprintf(stderr, "USB error: %s\n", + yk_usb_strerror()); + } else { + fprintf(stderr, "Yubikey core error: %s\n", + yk_strerror(yk_errno)); + } + } +} + +static int parse_args(int argc, char **argv, + bool *serial_dec, bool *serial_modhex, bool *serial_hex, + bool *version, bool *touch_level, bool *quiet, + int *exit_code) +{ + int c; + + while((c = getopt(argc, argv, optstring)) != -1) { + switch (c) { + case 's': + *serial_dec = true; + break; + case 'm': + *serial_modhex = true; + break; + case 'H': + *serial_hex = true; + break; + case 'v': + *version = true; + break; + case 't': + *touch_level = true; + break; + case 'q': + *quiet = true; + break; + case 'h': + default: + fputs(usage, stderr); + *exit_code = 0; + return 0; + } + } + + if (!*serial_dec && !*serial_modhex && !*serial_hex && + !*version && !*touch_level) { + /* no options at all */ + fputs("You must give at least one option.\n", stderr); + fputs(usage, stderr); + return 0; + } + + return 1; +} + + +int main(int argc, char **argv) +{ + YK_KEY *yk = 0; + bool error = true; + int exit_code = 0; + + /* Options */ + bool serial_dec = false; + bool serial_modhex = false; + bool serial_hex = false; + bool version = false; + bool touch_level = false; + + bool quiet = false; + + yk_errno = 0; + + if (! parse_args(argc, argv, + &serial_dec, &serial_modhex, &serial_hex, + &version, &touch_level, &quiet, + &exit_code)) + exit(exit_code); + + if (!yk_init()) { + exit_code = 1; + goto err; + } + + if (!(yk = yk_open_first_key())) { + exit_code = 1; + goto err; + } + + if(serial_dec || serial_modhex || serial_hex) { + unsigned int serial; + int ret = yk_get_serial(yk, 1, 0, &serial); + if(!ret) { + exit_code = 1; + goto err; + } + if(serial_dec) { + if(!quiet) + printf("serial: "); + printf("%d\n", serial); + } + if(serial_hex) { + if(!quiet) + printf("serial_hex: "); + printf("%x\n", serial); + } + if(serial_modhex) { + char buf[64]; + char hex_serial[64]; + char modhex_serial[64]; + + snprintf(buf, 64, "%x", serial); + yubikey_hex_decode(hex_serial, buf, strlen(buf)); + yubikey_modhex_encode(modhex_serial, hex_serial, strlen(hex_serial)); + if(!quiet) + printf("serial_modhex: "); + printf("%s\n", modhex_serial); + } + } + if(version || touch_level) { + YK_STATUS *st = ykds_alloc(); + if(!yk_get_status(yk, st)) { + ykds_free(st); + exit_code = 1; + goto err; + } + + if(version) { + if(!quiet) + printf("version: "); + printf("%d.%d.%d\n", ykds_version_major(st), ykds_version_minor(st), ykds_version_build(st)); + } + if(touch_level) { + if(!quiet) + printf("touch_level: "); + printf("%d\n", ykds_touch_level(st)); + } + ykds_free(st); + } + + exit_code = 0; + error = false; + +err: + if (error || exit_code != 0) { + report_yk_error(); + } + + if (yk && !yk_close_key(yk)) { + report_yk_error(); + exit_code = 2; + } + + if (!yk_release()) { + report_yk_error(); + exit_code = 2; + } + + exit(exit_code); +} -- 2.39.5