diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f0253e58..ffcac2de5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) - Fixed `data asn1` - now handles bad input better (@iceman1001) - Added new public key for signature MIFARE Plus Troika (@iceman100) - Fixed the client build on Android (@wh201906) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index bcdb4b3d8..e5e8f946c 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -11,10 +11,10 @@ #include "cliparser.h" #include #include -#include // Get color constants -#include // get PrintAndLogEx -#include // tolower -#include // PRIu64 +#include // color constants +#include // PrintAndLogEx +#include // tolower +#include // PRIu64 #ifndef ARRAYLEN # define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) @@ -22,10 +22,10 @@ // Custom Colors // To default the color return s -#define _SectionTagColor_(s) _GREEN_(s) -#define _ExampleColor_(s) _YELLOW_(s) -#define _CommandColor_(s) _RED_(s) -#define _DescriptionColor_(s) _CYAN_(s) +#define _SectionTagColor_(s) _GREEN_(s) +#define _ExampleColor_(s) _YELLOW_(s) +#define _CommandColor_(s) _RED_(s) +#define _DescriptionColor_(s) _CYAN_(s) #define _ArgColor_(s) s #define _ArgHelpColor_(s) s // End Custom Colors @@ -34,65 +34,78 @@ int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { *ctx = calloc(sizeof(CLIParserContext), sizeof(uint8_t)); - if (!*ctx) { + if (*ctx == NULL) { PrintAndLogEx(ERR, "ERROR: Insufficient memory\n"); return 2; } + (*ctx)->argtable = NULL; (*ctx)->argtableLen = 0; (*ctx)->programName = vprogramName; (*ctx)->programHint = vprogramHint; (*ctx)->programHelp = vprogramHelp; memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf)); - return 0; + + return PM3_SUCCESS; } void CLIParserPrintHelp(CLIParserContext *ctx) { - if (ctx->programHint) + if (ctx->programHint) { PrintAndLogEx(NORMAL, "\n"_DescriptionColor_("%s"), ctx->programHint); + } PrintAndLogEx(NORMAL, "\n"_SectionTagColor_("usage:")); PrintAndLogEx(NORMAL, " "_CommandColor_("%s")NOLF, ctx->programName); arg_print_syntax(stdout, ctx->argtable, "\n\n"); PrintAndLogEx(NORMAL, _SectionTagColor_("options:")); - arg_print_glossary(stdout, ctx->argtable, " "_ArgColor_("%-30s")" "_ArgHelpColor_("%s")"\n"); - PrintAndLogEx(NORMAL, ""); - if (ctx->programHelp) { - PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:")); - char *buf = NULL; - int idx = 0; - buf = realloc(buf, strlen(ctx->programHelp) + 1); // more then enough as we are splitting - char *p2; // pointer to split example from comment. + if (ctx->programHelp) { + + // allocate more then enough memory as we are splitting + char *s = calloc(strlen(ctx->programHelp) + 1, sizeof(uint8_t)); + if (s == NULL) { + PrintAndLogEx(FAILED, "cannot allocate memory"); + return; + } + + PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:")); + + // pointer to split example from comment. + char *p2; + + int idx = 0; int egWidth = 30; for (int i = 0; i <= strlen(ctx->programHelp); i++) { // <= so to get string terminator. - buf[idx++] = ctx->programHelp[i]; + + s[idx++] = ctx->programHelp[i]; + if ((ctx->programHelp[i] == '\n') || (ctx->programHelp[i] == 0x00)) { - buf[idx - 1] = 0x00; - p2 = strstr(buf, "->"); // See if the example has a comment. + + s[idx - 1] = 0x00; + p2 = strstr(s, "->"); // See if the example has a comment. + if (p2 != NULL) { *(p2 - 1) = 0x00; - if (strlen(buf) > 28) - egWidth = strlen(buf) + 5; + if (strlen(s) > 28) + egWidth = strlen(s) + 5; else egWidth = 30; - PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, buf, p2); + PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, s, p2); } else { - PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, buf); + PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, s); } + idx = 0; } } - + free(s); PrintAndLogEx(NORMAL, ""); - free(buf); } - fflush(stdout); } @@ -127,7 +140,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta return 3; } - return 0; + return PM3_SUCCESS; } enum ParserState { @@ -144,21 +157,25 @@ int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int argc = 0; - char *argv[200] = {NULL}; + char *argv[MAX_INPUT_ARG_LENGTH] = {NULL}; int len = strlen(str); + memset(ctx->buf, 0x00, ARRAYLEN(ctx->buf)); + char *bufptr = ctx->buf; char *bufptrend = ctx->buf + ARRAYLEN(ctx->buf) - 1; char *spaceptr = NULL; enum ParserState state = PS_FIRST; argv[argc++] = bufptr; - // param0 = program name - memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00 + // param0 = program name + with 0x00 + memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); + bufptr += strlen(ctx->programName) + 1; - if (len) + if (len) { argv[argc++] = bufptr; + } // parse params for (int i = 0; i < len; i++) { @@ -214,10 +231,9 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen = 0; int tmplen = 0; - uint8_t tmpstr[(256 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; // concat all strings in argstr into tmpstr[] - // int res = CLIParamStrToBuf(argstr, tmpstr, sizeof(tmpstr), &tmplen); if (res || (tmplen == 0)) { return res; @@ -242,7 +258,7 @@ int CLIParamBinToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen = 0; int tmplen = 0; - uint8_t tmpstr[(256 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; // concat all strings in argstr into tmpstr[] // @@ -268,7 +284,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int if (!argstr->count) return 0; - uint8_t tmpstr[(512 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; int ibuf = 0; for (int i = 0; i < argstr->count; i++) { @@ -303,7 +319,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, int *value) { char data[200] = {0}; - int datalen = 0; + int datalen = 200; int res = CLIParamStrToBuf(argstr, (uint8_t *)data, sizeof(data), &datalen); if (res) return res; @@ -316,7 +332,7 @@ int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array int val = -1; int cntr = 0; - for (int i = 0; i < CLI_MAX_OPTLIST_LEN && option_array[i].text != NULL; i++) { + for (int i = 0; (i < CLI_MAX_OPTLIST_LEN) && (option_array[i].text != NULL); i++) { // exact match if (strcmp(option_array[i].text, data) == 0) { *value = option_array[i].code; @@ -346,9 +362,10 @@ int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array const char *CLIGetOptionListStr(const CLIParserOption *option_array, int value) { static const char *errmsg = "n/a"; - for (int i = 0; i < CLI_MAX_OPTLIST_LEN && option_array[i].text != NULL; i++) { - if (option_array[i].code == value) + for (int i = 0; (i < CLI_MAX_OPTLIST_LEN) && (option_array[i].text != NULL); i++) { + if (option_array[i].code == value) { return option_array[i].text; + } } return errmsg; } diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index f50fec2ee..812b44506 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -12,6 +12,7 @@ #define __CLIPARSER_H #include "argtable3.h" #include +#include #include "util.h" #define arg_param_begin arg_lit0("h", "help", "This help") @@ -53,13 +54,16 @@ #define CLIGetOptionListWithReturn(ctx, paramnum, option_array, option_array_len, value) if (CLIGetOptionList(arg_get_str((ctx), (paramnum)), (option_array), (option_array_len), (value))) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define MAX_INPUT_ARG_LENGTH 4096 + + typedef struct { void **argtable; size_t argtableLen; const char *programName; const char *programHint; const char *programHelp; - char buf[1024 + 60]; + char buf[MAX_INPUT_ARG_LENGTH + 60]; } CLIParserContext; #define CLI_MAX_OPTLIST_LEN 50 diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 724bc5c65..3d153022d 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2915,8 +2915,8 @@ static int CmdAsn1Decoder(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); - int dlen = 256; - uint8_t data[256]; + int dlen = 2048; + uint8_t data[2048]; CLIGetHexWithReturn(ctx, 1, data, &dlen); CLIParserFree(ctx); @@ -2927,8 +2927,6 @@ static int CmdAsn1Decoder(const char *Cmd) { return PM3_SUCCESS; } - - static int CmdDiff(const char *Cmd) { CLIParserContext *ctx; diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 1c360e832..39a6c98ad 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -25,6 +25,9 @@ #include "comms.h" #include "util_posix.h" // msleep + +#define MAX_PM3_INPUT_ARGS_LENGTH 4096 + bool AlwaysAvailable(void) { return true; } @@ -36,54 +39,55 @@ bool IfPm3Present(void) { } bool IfPm3Rdv4Fw(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return (g_pm3_capabilities.is_rdv4); } bool IfPm3Flash(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_flash) + if (g_pm3_capabilities.compiled_with_flash == false) return false; return g_pm3_capabilities.hw_available_flash; } bool IfPm3Smartcard(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_smartcard) + if (g_pm3_capabilities.compiled_with_smartcard == false) return false; return g_pm3_capabilities.hw_available_smartcard; } bool IfPm3FpcUsart(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_fpc_usart; } bool IfPm3FpcUsartHost(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_fpc_usart_host; } bool IfPm3FpcUsartHostFromUsb(void) { // true if FPC USART Host support and if talking from USB-CDC interface - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_fpc_usart_host) + if (g_pm3_capabilities.compiled_with_fpc_usart_host == false) return false; return !g_conn.send_via_fpc_usart; } bool IfPm3FpcUsartDevFromUsb(void) { // true if FPC USART developer support and if talking from USB-CDC interface - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_fpc_usart_dev) + if (g_pm3_capabilities.compiled_with_fpc_usart_dev == false) return false; + return !g_conn.send_via_fpc_usart; } @@ -93,103 +97,101 @@ bool IfPm3FpcUsartFromUsb(void) { } bool IfPm3Lf(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_lf; } bool IfPm3Hitag(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hitag; } bool IfPm3EM4x50(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_em4x50; } bool IfPm3EM4x70(void) { - - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_em4x70; } bool IfPm3Hfsniff(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hfsniff; } bool IfPm3Hfplot(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hfplot; } bool IfPm3Iso14443a(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443a; } bool IfPm3Iso14443b(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443b; } bool IfPm3Iso14443(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443a || g_pm3_capabilities.compiled_with_iso14443b; } bool IfPm3Iso15693(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso15693; } bool IfPm3Felica(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_felica; } bool IfPm3Legicrf(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_legicrf; } bool IfPm3Iclass(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iclass; } bool IfPm3NfcBarcode(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_nfcbarcode; } bool IfPm3Lcd(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_lcd; } bool IfPm3Zx8211(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_zx8211; } - void CmdsHelp(const command_t Commands[]) { if (Commands[0].Name == NULL) return; int i = 0; @@ -259,7 +261,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { } - char cmd_name[128]; + char cmd_name[128] = {0}; memset(cmd_name, 0, sizeof(cmd_name)); int len = 0; @@ -275,8 +277,10 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { // find args, check for -h / --help int tmplen = len; - while (Cmd[tmplen] == ' ') + while (Cmd[tmplen] == ' ') { ++tmplen; + } + bool request_help = (strcmp(Cmd + tmplen, "-h") == 0) || (strcmp(Cmd + tmplen, "--help") == 0); int i = 0; @@ -305,12 +309,15 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { matches++; } } - if (matches == 1) i = last_match; + if (matches == 1) { + i = last_match; + } } if (Commands[i].Name) { - while (Cmd[len] == ' ') + while (Cmd[len] == ' ') { ++len; + } return Commands[i].Parse(Cmd + len); } else { // show help for selected hierarchy or if command not recognised @@ -320,7 +327,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { return PM3_SUCCESS; } -static char pparent[512] = {0}; +static char pparent[MAX_PM3_INPUT_ARGS_LENGTH] = {0}; static char *parent = pparent; void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) { @@ -346,11 +353,13 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) const char *cmd_offline = "N"; - if (cmds[i].IsAvailable()) + if (cmds[i].IsAvailable()) { cmd_offline = "Y"; - if (markdown) + } + + if (markdown) { PrintAndLogEx(NORMAL, "|`%s%-*s`|%-*s|`%s`", parent, w_cmd - (int)strlen(parent) - 2, cmds[i].Name, w_off, cmd_offline, cmds[i].Help); - else if (full_help) { + } else if (full_help) { PrintAndLogEx(NORMAL, "---------------------------------------------------------------------------------------"); PrintAndLogEx(NORMAL, _RED_("%s%-*s\n") "available offline: %s", parent, w_cmd - (int)strlen(parent), cmds[i].Name, cmds[i].IsAvailable() ? _GREEN_("yes") : _RED_("no")); cmds[i].Parse("--help"); @@ -374,15 +383,17 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) } else { PrintAndLogEx(NORMAL, "### %s%s\n\n %s\n", parent, cmds[i].Name, cmds[i].Help); } - char currentparent[512] = {0}; + + char currentparent[MAX_PM3_INPUT_ARGS_LENGTH] = {0}; snprintf(currentparent, sizeof currentparent, "%s%s ", parent, cmds[i].Name); + char *old_parent = parent; parent = currentparent; // This is what causes the recursion, since commands Parse-implementation // in turn calls the CmdsParse above. - if (markdown) + if (markdown) { cmds[i].Parse("XX_internal_command_dump_markdown_XX"); - else if (full_help) { + } else if (full_help) { cmds[i].Parse("XX_internal_command_dump_full_XX"); } else { cmds[i].Parse("XX_internal_command_dump_XX");