dnie-tool: cleanup

- remove command line option '--card-driver';
- instead force driver 'dnie' and fail if card is not a DNIe card
- overhaul option parsing
  - remove unused variable 'long_optind'
  - bail out with usage message on all unknown/unhandled args
  - correctly terminate option parsing (no infinite loop)
- slight refactoring
  - avoid magic constant '0x0f'
  - make variable 'tries_left' more local
  - move dependent code into if block
This commit is contained in:
Peter Marschall 2020-01-06 18:36:37 +01:00
parent 58ecb4aba2
commit a0adbc9ef2
2 changed files with 49 additions and 77 deletions

View File

@ -95,21 +95,6 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--card-driver</option> <replaceable>name</replaceable>,
<option>-c</option> <replaceable>name</replaceable>
</term>
<listitem>
<para>
Use the given card driver.
The default is to auto-detect the correct card driver.
The literal value <literal>?</literal> lists
all available card drivers and terminates
<command>dnie-tool</command>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--wait</option>,

View File

@ -36,6 +36,7 @@
#include "libopensc/opensc.h"
#include "libopensc/errors.h"
#include "libopensc/cardctl.h"
#include "libopensc/cards.h"
#include "libopensc/pkcs15.h"
#include "util.h"
@ -54,7 +55,6 @@ static const char *app_name = "dnie-tool";
static const struct option options[] = {
{"reader", 1, NULL, 'r'},
{"card-driver", 1, NULL, 'c'},
{"wait", 0, NULL, 'w'},
{"pin", 1, NULL, 'p'},
{"idesp", 0, NULL, 'i'},
@ -68,7 +68,6 @@ static const struct option options[] = {
static const char *option_help[] = {
"Uses reader number <arg> [0]",
"Uses card driver <arg> [auto-detect; '?' for list]",
"Wait for a card to be inserted",
"Specify PIN",
"Retrieve IDESP",
@ -86,7 +85,6 @@ int main(int argc, char* argv[])
int opt_wait = 0;
const char *opt_pin = NULL;
const char *opt_reader = NULL;
const char *opt_driver = NULL;
int opt_operation = OP_NONE;
int verbose = 0;
@ -94,25 +92,16 @@ int main(int argc, char* argv[])
sc_context_t *ctx = NULL;
sc_context_param_t ctx_param;
sc_card_t *card = NULL;
int c, long_optind, r, tries_left;
int c, r;
char *data[] = { NULL, NULL, NULL, NULL, NULL };
sc_serial_number_t serial;
while (1) {
c = getopt_long(argc, argv, "r:c:wp:iVdsav",
options, &long_optind);
if (c == -1)
break;
while ((c = getopt_long(argc, argv, "r:wp:iVdsav", options, (int *) 0)) != -1) {
switch (c) {
case '?':
util_print_usage_and_die(app_name, options, option_help, NULL);
case 'r':
opt_reader = optarg;
break;
case 'c':
opt_driver = optarg;
break;
case 'w':
opt_wait = 1;
break;
@ -137,6 +126,8 @@ int main(int argc, char* argv[])
case 'v':
verbose++;
break;
default:
util_print_usage_and_die(app_name, options, option_help, NULL);
}
}
@ -146,23 +137,16 @@ int main(int argc, char* argv[])
if (r) {
fprintf(stderr, "Error: Failed to establish context: %s\n",
sc_strerror(r));
err = -1;
goto dnie_tool_end;
}
if (opt_driver != NULL) {
/* special card driver value "?" means: list available drivers */
if (strncmp("?", opt_driver, sizeof("?")) == 0) {
err = util_list_card_drivers(ctx);
goto dnie_tool_end;
}
err = sc_set_card_driver(ctx, opt_driver);
if (err) {
fprintf(stderr, "Driver '%s' not found!\n",
opt_driver);
err = -1;
goto dnie_tool_end;
}
/* force DNIe card driver */
err = sc_set_card_driver(ctx, "dnie");
if (err) {
fprintf(stderr, "DNIe card driver not found!\n");
err = -1;
goto dnie_tool_end;
}
if (util_connect_card(ctx, &card, opt_reader, opt_wait, verbose) ) {
@ -171,13 +155,16 @@ int main(int argc, char* argv[])
goto dnie_tool_end;
}
if ( strcmp(card->name,"dnie") ) {
fprintf(stderr, "Error: Card seems not to be a DNIe\n");
err=-1;
/* fail if card is not a DNIe card */
if (card->type < SC_CARD_TYPE_DNIE_BASE || card->type >= SC_CARD_TYPE_DNIE_BASE+1000) {
fprintf(stderr, "Card type %X: not a DNIe card\n", card->type);
err = -1;
goto dnie_tool_end;
}
if ( opt_pin ) {
int tries_left;
/* verify */
r = sc_verify(card, SC_AC_CHV, 0,
(u8*)opt_pin, strlen(opt_pin), &tries_left);
@ -192,44 +179,44 @@ int main(int argc, char* argv[])
}
}
if (opt_operation==0) {
fprintf(stderr,"Error: No operation specified");
err = -1;
goto dnie_tool_end;
}
if (opt_operation & 0x0f) {
if (opt_operation & (OP_GET_DATA | OP_GET_IDESP | OP_GET_VERSION | OP_GET_SERIALNR)) {
r = sc_card_ctl(card, SC_CARDCTL_DNIE_GET_INFO, data);
if ( r != SC_SUCCESS ) {
fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
err = -1;
goto dnie_tool_end;
}
}
if (opt_operation & OP_GET_DATA) {
printf("DNIe Number: %s\n",data[0]);
printf("SurName: %s\n",data[1]);
printf("Name: %s\n",data[2]);
}
if (opt_operation & OP_GET_IDESP) {
if (data[3]==NULL)
printf("IDESP: (Not available)\n");
else printf("IDESP: %s\n",data[3]);
}
if (opt_operation & OP_GET_VERSION) {
if (data[4]==NULL)
printf("DNIe Version: (Not available)\n");
else printf("DNIe Version: %s\n",data[4]);
}
if (opt_operation & OP_GET_SERIALNR) {
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if ( r != SC_SUCCESS ) {
fprintf(stderr,"Error: Get serial failed: %s\n",sc_strerror(r));
err = -1;
goto dnie_tool_end;
if (opt_operation & OP_GET_DATA) {
printf("DNIe Number: %s\n",data[0]);
printf("Surname: %s\n",data[1]);
printf("Name: %s\n",data[2]);
}
printf("Serial number: ");
util_hex_dump(stdout, serial.value, serial.len, NULL);
putchar('\n');
if (opt_operation & OP_GET_IDESP) {
if (data[3]==NULL)
printf("IDESP: (Not available)\n");
else printf("IDESP: %s\n",data[3]);
}
if (opt_operation & OP_GET_VERSION) {
if (data[4]==NULL)
printf("DNIe Version: (Not available)\n");
else printf("DNIe Version: %s\n",data[4]);
}
if (opt_operation & OP_GET_SERIALNR) {
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if ( r != SC_SUCCESS ) {
fprintf(stderr,"Error: Get serial failed: %s\n",sc_strerror(r));
err = -1;
goto dnie_tool_end;
}
printf("Serial number: ");
util_hex_dump(stdout, serial.value, serial.len, NULL);
putchar('\n');
}
}
else {
fprintf(stderr,"Error: No operation specified");
err = -1;
}
dnie_tool_end: