modify argtable parser to parse ints with spaces (#683)
authorOleg Moiseenko <olegmsn@gmail.com>
Mon, 1 Oct 2018 18:12:14 +0000 (21:12 +0300)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Mon, 1 Oct 2018 18:12:14 +0000 (20:12 +0200)
* 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

client/cliparser/cliparser.c
client/cliparser/cliparser.h
client/cmdhf14a.c
client/emv/cmdemv.c

index 87427db0a942861d14bf3fa0b0787395526cdfbc..56be2ca6af2717a217d485bef0fe79194c6b4ab6 100644 (file)
@@ -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;
index 169f102e9c3dc89487f3812ffab66f47d2003d3c..7c1ced207c98a3df9ae45abdeffabf90d0ba7bc8 100644 (file)
 #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();
 
index 2d76f1098f69c7bf30b87f010d142fb4d08d6536..94eb8ff3511ffc59fdc5692ae8d056d26c9ab7a3 100644 (file)
@@ -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,      "<APDU (hex)>", NULL),
+               arg_strx1(NULL, NULL,      "<APDU (hex)>", 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,      "<data (hex)>", NULL),
+               arg_strx1(NULL, NULL,      "<data (hex)>", NULL),
                arg_param_end
        };
        // defaults
index 93635f858abe0c2759972db1cc7f88c3642c7eb1..544632ef261d57375d521910d4eb216e352b6e2b 100644 (file)
@@ -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,      "<HEX applet AID>", NULL),
+               arg_strx0(NULL,  NULL,     "<HEX applet AID>", 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,      "<HEX PDOLdata/PDOL>", NULL),
+               arg_strx0(NULL,  NULL,     "<HEX PDOLdata/PDOL>", 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,      "<SFI 1byte HEX><SFIrec 1byte HEX>", NULL),
+               arg_strx1(NULL,  NULL,     "<SFI 1byte HEX><SFIrec 1byte HEX>", NULL),
                arg_param_end
        };
        CLIExecWithReturn(cmd, argtable, true);
@@ -335,7 +335,7 @@ int CmdHFEMVAC(const char *cmd) {
                arg_str0("dD",  "decision", "<aac|tc|arqc>", "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,       "<HEX CDOLdata>", NULL),
+               arg_strx1(NULL,  NULL,      "<HEX CDOLdata>", 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,      "<HEX DDOLdata>", NULL),
+               arg_strx1(NULL,  NULL,     "<HEX DDOLdata>", NULL),
                arg_param_end
        };
        CLIExecWithReturn(cmd, argtable, false);
Impressum, Datenschutz