From: Oleg Moiseenko Date: Mon, 1 Oct 2018 18:12:14 +0000 (+0300) Subject: modify argtable parser to parse ints with spaces (#683) X-Git-Tag: v3.1.0~8^2 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/11146fc1e1722ad8780d0589fc2f6a66fa198108?ds=sidebyside;hp=-c modify argtable parser to parse ints with spaces (#683) * modify argtable parser to parse ints with spaces * added arg_strx1 and arg_strx0 for x str arguments in one * added option to clue data in arg parser * add new argtable logic to emv commands and small fix * small fix in GPO help * small GPO fix --- 11146fc1e1722ad8780d0589fc2f6a66fa198108 diff --git a/client/cliparser/cliparser.c b/client/cliparser/cliparser.c index 87427db0..56be2ca6 100644 --- a/client/cliparser/cliparser.c +++ b/client/cliparser/cliparser.c @@ -80,6 +80,10 @@ enum ParserState { #define isSpace(c)(c == ' ' || c == '\t') int CLIParserParseString(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec) { + return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false); +} + +int CLIParserParseStringEx(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int argc = 0; char *argv[200] = {NULL}; @@ -99,7 +103,7 @@ int CLIParserParseString(const char* str, void* vargtable[], size_t vargtableLen for (int i = 0; i < len; i++) { switch(state){ case PS_FIRST: // first char - if (str[i] == '-'){ // first char before space is '-' - next element - option + if (!clueData || str[i] == '-'){ // first char before space is '-' - next element - option OR not "clueData" for not-option fields state = PS_OPTION; if (spaceptr) { @@ -149,10 +153,23 @@ void CLIParserFree() { // convertors int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) { *datalen = 0; - if (!strlen(argstr->sval[0])) + if (!argstr->count) + return 0; + + char buf[256] = {0}; + int ibuf = 0; + + for (int i = 0; i < argstr->count; i++) { + int len = strlen(argstr->sval[i]); + memcpy(&buf[ibuf], argstr->sval[i], len); + ibuf += len; + } + buf[ibuf] = 0; + + if (!ibuf) return 0; - switch(param_gethex_to_eol(argstr->sval[0], 0, data, maxdatalen, datalen)) { + switch(param_gethex_to_eol(buf, 0, data, maxdatalen, datalen)) { case 1: printf("Parameter error: Invalid HEX value.\n"); return 1; diff --git a/client/cliparser/cliparser.h b/client/cliparser/cliparser.h index 169f102e..7c1ced20 100644 --- a/client/cliparser/cliparser.h +++ b/client/cliparser/cliparser.h @@ -21,12 +21,16 @@ #define arg_get_str(n)((struct arg_str*)argtable[n]) #define arg_get_str_len(n)(strlen(((struct arg_str*)argtable[n])->sval[0])) +#define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary))) +#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary))) + #define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return 0;} #define CLIGetStrBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return 1;} #define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return 1;} extern int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp); extern int CLIParserParseString(const char* str, void* argtable[], size_t vargtableLen, bool allowEmptyExec); +extern int CLIParserParseStringEx(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData); extern int CLIParserParseArg(int argc, char **argv, void* argtable[], size_t vargtableLen, bool allowEmptyExec); extern void CLIParserFree(); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 2d76f109..94eb8ff3 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -742,7 +742,7 @@ int CmdHF14AAPDU(const char *cmd) { arg_lit0("sS", "select", "activate field and select card"), arg_lit0("kK", "keep", "leave the signal field ON after receive response"), arg_lit0("tT", "tlv", "executes TLV decoder if it possible"), - arg_str1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, false); @@ -807,7 +807,7 @@ int CmdHF14ACmdRaw(const char *cmd) { arg_int0("t", "timeout", NULL, "timeout in ms"), arg_lit0("T", "topaz", "use Topaz protocol to send command"), arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), - arg_str1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; // defaults diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 93635f85..544632ef 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -49,7 +49,7 @@ int CmdHFEMVSelect(const char *cmd) { arg_lit0("kK", "keep", "keep field for next command"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results"), - arg_str0(NULL, NULL, "", NULL), + arg_strx0(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -183,7 +183,7 @@ int CmdHFEMVGPO(const char *cmd) { CLIParserInit("hf emv gpo", "Executes Get Processing Options command. It returns data in TLV format (0x77 - format2) or plain format (0x80 - format1).\nNeeds a EMV applet to be selected.", "Usage:\n\thf emv gpo -k -> execute GPO\n" - "\thf emv gpo -st 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"); + "\thf emv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"); // here need to add load params from file and gen pdol void* argtable[] = { @@ -193,7 +193,7 @@ int CmdHFEMVGPO(const char *cmd) { arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (NOT WORK!!!)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), - arg_str0(NULL, NULL, "", NULL), + arg_strx0(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -215,7 +215,7 @@ int CmdHFEMVGPO(const char *cmd) { // calc PDOL struct tlv *pdol_data_tlv = NULL; struct tlv data_tlv = { - .tag = 0x01, + .tag = 0x83, .len = datalen, .value = (uint8_t *)data, }; @@ -281,7 +281,7 @@ int CmdHFEMVReadRecord(const char *cmd) { arg_lit0("kK", "keep", "keep field ON for next command"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), - arg_str1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, true); @@ -335,7 +335,7 @@ int CmdHFEMVAC(const char *cmd) { arg_str0("dD", "decision", "", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), - arg_str1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, false); @@ -457,7 +457,7 @@ int CmdHFEMVInternalAuthenticate(const char *cmd) { arg_lit0("kK", "keep", "keep field ON for next command"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), - arg_str1(NULL, NULL, "", NULL), + arg_strx1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(cmd, argtable, false);