From 928d787970d62bdb1f460e7b5f02b819f8b19b15 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 7 Nov 2020 23:21:06 +0100 Subject: [PATCH 01/69] print uid in 14a reader @ mode --- client/src/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index e402cb48e..d6cbcd2de 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -551,8 +551,8 @@ static int CmdHF14AReader(const char *Cmd) { res = PM3_ESOFT; goto plot; } + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); if (!(silent && continuous)) { - PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02x %02x"), card.atqa[1], card.atqa[0]); PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02x [%" PRIu64 "]"), card.sak, resp.oldarg[0]); From 358ecbd0f4f7c698d4337ec93681c079de68103c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 7 Nov 2020 23:23:45 +0100 Subject: [PATCH 02/69] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e63bead6f..53aab0422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Change many commands to cliparser (@iceman1001, @tcprst, @mwalker33,...) - ... + - Added compilation options for 256k Proxmark versions, see doc (@doegox) - Added support for 10b UID in `hf 14a sim` (@doegox) - Added `HF_TCPRST` standalone mode which read and emulate IKEA Rothult cards (@tcprst) - Add Gallagher key checking/KDF on MIFARE Desfire (@NZSmartie) From 983c3a3a637a1d493d69ffa1b93d3eedf4a4b077 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Sun, 8 Nov 2020 21:03:33 +1100 Subject: [PATCH 03/69] Detect with wakeup Detect with wake option to address init deley or AOR set. --- client/src/cmdlft55xx.c | 88 ++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 23 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index ab1a86fbd..e34d14718 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1024,6 +1024,9 @@ static void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { PrintAndLogEx(NORMAL, msg); } +// Define prototype to call from within detect. +static int CmdT55xxWakeUp (const char *Cmd); + static int CmdT55xxDetect(const char *Cmd) { bool errors = false; @@ -1032,9 +1035,16 @@ static int CmdT55xxDetect(const char *Cmd) { bool try_with_pwd = false; bool try_all_dl_modes = true; bool found = false; + bool usewake = false; uint64_t password = -1; uint8_t cmdp = 0; uint8_t downlink_mode = 0; + char wakecmd[20] = { 0x00 }; + struct timespec sleepperiod; + + // Setup the 90ms time value to sleep for after the wake, to allow delay init to complete (~70ms) + sleepperiod.tv_sec = 0; + sleepperiod.tv_nsec = 90000000; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1042,6 +1052,7 @@ static int CmdT55xxDetect(const char *Cmd) { return usage_t55xx_detect(); case 'p': password = param_get32ex(Cmd, cmdp + 1, 0, 16); + sprintf (wakecmd,"p %08x q",(uint32_t)(password & 0xFFFFFFFF)); usepwd = true; cmdp += 2; break; @@ -1064,6 +1075,7 @@ static int CmdT55xxDetect(const char *Cmd) { } if (errors) return usage_t55xx_detect(); + // detect called so clear data blocks T55x7_ClearAllBlockData(); @@ -1072,38 +1084,61 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - // do ... while to check without password then loop back if password supplied + // do ... while not found and not yet tried with wake (for AOR or Init Delay) do { + // do ... while to check without password then loop back if password supplied + do { - if (try_all_dl_modes) { - for (uint8_t m = downlink_mode; m < 4; m++) { + if (try_all_dl_modes) { + for (uint8_t m = downlink_mode; m < 4; m++) { + if (usewake) { + // call wake + if (try_with_pwd) + CmdT55xxWakeUp (wakecmd); + else + CmdT55xxWakeUp ("q"); + // sleep 90 ms + nanosleep (&sleepperiod, &sleepperiod); + } - if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, (try_with_pwd && usepwd), password, m) == false) - continue; + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, (try_with_pwd && usepwd), password, m) == false) + continue; - if (t55xxTryDetectModulationEx(m, T55XX_PrintConfig, 0, (try_with_pwd && usepwd) ? password : -1) == false) - continue; + if (t55xxTryDetectModulationEx(m, T55XX_PrintConfig, 0, (try_with_pwd && usepwd) ? password : -1) == false) + continue; - found = true; + found = true; - break; + break; + } + } else { + if (usewake) { + // call wake + if (try_with_pwd) + CmdT55xxWakeUp (wakecmd); + else + CmdT55xxWakeUp ("q"); + // sleep 90 ms + nanosleep (&sleepperiod, &sleepperiod); + } + + if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + found = t55xxTryDetectModulationEx(downlink_mode, T55XX_PrintConfig, 0, (usepwd) ? password : -1); + } } - } else { - if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { - found = t55xxTryDetectModulationEx(downlink_mode, T55XX_PrintConfig, 0, (usepwd) ? password : -1); - } - } - // toggle so we loop back if not found and try with pwd - if (!found && usepwd) - try_with_pwd = !try_with_pwd; + // toggle so we loop back if not found and try with pwd + if (!found && usepwd) + try_with_pwd = !try_with_pwd; - // force exit as detect block has been found - if (found) - try_with_pwd = false; - - } while (try_with_pwd); + // force exit as detect block has been found + if (found) + try_with_pwd = false; + } while (try_with_pwd); + // Toggle so we loop back and try with wakeup. + usewake = !usewake; + } while (!found && usewake); } else { found = t55xxTryDetectModulation(downlink_mode, T55XX_PrintConfig); } @@ -1619,6 +1654,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; uint8_t downlink_mode = config.downlink_mode; + bool quiet = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1635,6 +1671,10 @@ static int CmdT55xxWakeUp(const char *Cmd) { cmdp += 2; break; + case 'q': + quiet = true; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -1659,7 +1699,9 @@ static int CmdT55xxWakeUp(const char *Cmd) { return PM3_ETIMEOUT; } - PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); + if (!quiet) + PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); + return PM3_SUCCESS; } From f894560325b2d81381fb341d1ac50f01c80168be Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Nov 2020 18:59:36 +0100 Subject: [PATCH 04/69] hf mfdes fixes --- client/src/cmdhfmfdes.c | 91 ++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 135798737..9a74aa2ca 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1278,7 +1278,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat {"DESFire EV3", "041DB46C145D0A36539C6544BD6D9B0AA62FF91EC48CBC6ABAE36E0089A46F0D08C8A715EA40A63313B92E90DDC1730230E0458A33276FB743"}, {"NTAG424DNA, NTAG424DNATT, DESFire Light EV2", "04B304DC4C615F5326FE9383DDEC9AA892DF3A57FA7FFB3276192BC0EAA252ED45A865E3B093A3D0DCE5BE29E92F1392CE7DE321E3E5C52B3B"}, {"DESFire Light", "040E98E117AAA36457F43173DC920A8757267F44CE4EC5ADD3C54075571AEBBF7B942A9774A1D94AD02572427E5AE0A2DD36591B1FB34FCF3D"}, - {"Mifare Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"} + {"MIFARE Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"} }; @@ -1654,9 +1654,7 @@ static int handler_desfire_createapp(aidhdr_t *aidhdr, bool usename, bool usefid if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create aid -> %s"), GetErrorString(res, &sw)); DropField(); - return res; } - return res; } @@ -1669,7 +1667,6 @@ static int handler_desfire_deleteapp(const uint8_t *aid) { if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't delete aid -> %s"), GetErrorString(res, &sw)); DropField(); - return res; } return res; } @@ -2230,12 +2227,12 @@ static int CmdHF14ADesSelectApp(const char *Cmd) { } int res = handler_desfire_select_application(aid); + DropField(); if (res != PM3_SUCCESS) { - DropField(); PrintAndLogEx(ERR, "Error on selecting aid."); - return res; + } else { + PrintAndLogEx(SUCCESS, "Successfully selected aid."); } - PrintAndLogEx(SUCCESS, "Successfully selected aid."); return res; } @@ -2363,7 +2360,9 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { res = handler_desfire_createapp(&aidhdr, usename, usefid); DropField(); - PrintAndLogEx(SUCCESS, "Successfully created aid."); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Successfully created aid."); + } return res; } @@ -2399,9 +2398,11 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { uint8_t rootaid[3] = {0x00, 0x00, 0x00}; int res = handler_desfire_select_application(rootaid); if (res != PM3_SUCCESS) { DropField(); return res;} - res = handler_desfire_deleteapp(aid); + res = handler_desfire_deleteapp(aid); DropField(); - PrintAndLogEx(SUCCESS, "Successfully deleted aid."); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Successfully deleted aid."); + } return res; } @@ -3603,6 +3604,20 @@ static int DecodeFileSettings(uint8_t *src, int src_len, int maclen) { } static int CmdHF14ADesDump(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes dump", + "Tries to dump all files on a DESFire tag", + "hf mfdes dump"); + + void *argtable[] = { + arg_param_begin, +// arg_strx0("a", "aid", "", "Use specific AID (3 hex bytes, big endian)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + (void)Cmd; // Cmd is not used so far DropField(); @@ -3629,7 +3644,7 @@ static int CmdHF14ADesDump(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-- Mifare DESFire Dump ----------------------"); + PrintAndLogEx(INFO, "-- " _CYAN_("MIFARE DESFire Dump") " ----------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); for (uint32_t i = 0; i < app_ids_len; i += 3) { @@ -3791,7 +3806,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-- Mifare DESFire Enumerate applications --------------------"); + PrintAndLogEx(INFO, "-- MIFARE DESFire Enumerate applications --------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") " application%c", app_ids_len / 3, (app_ids_len == 3) ? ' ' : 's'); @@ -3868,7 +3883,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) { uint8_t newkeylength = 8; CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes changekey", - "Changes Mifare DESFire Key\n" + "Changes MIFARE DESFire Key\n" "Make sure to select aid or authenticate aid before running this command.", "hf mfdes changekey -n 0 -t 1 -k 0000000000000000 -u 1 -j 0102030405060708 -> DES,keynumber 0" ); @@ -3969,7 +3984,7 @@ static int CmdHF14ADesAuth(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes auth", - "Authenticates Mifare DESFire using Key", + "Authenticates MIFARE DESFire using Key", "hf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 -> AES,keynumber 0, aid 0x803201\n" "hf mfdes auth -m 2 -t 2 -a 000000 -n 1 -k 00000000000000000000000000000000 -> 3DES,keynumber 1, aid 0x000000\n" "hf mfdes auth -m 1 -t 1 -a 000000 -n 2 -k 0000000000000000 -> DES,keynumber 2, aid 0x000000\n" @@ -4348,7 +4363,7 @@ static int CmdHF14aDesChk(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes chk", - "Checks keys with Mifare Desfire card.", + "Checks keys with MIFARE DESFire card.", "hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n" "hf mfdes chk -d mfdes_default_keys -> check keys from dictionary against all existing aid on card\n" "hf mfdes chk -d mfdes_default_keys -a 123456 -> check keys from dictionary against aid 0x123456\n" @@ -4587,7 +4602,7 @@ static int CmdHF14aDesChk(const char *Cmd) { // save keys to json if ((jsonnamelen > 0) && result) { - // Mifare Desfire info + // MIFARE DESFire info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; @@ -4644,7 +4659,6 @@ static int CmdHF14aDesNDEF(const char *Cmd) { arg_litn("v", "verbose", 0, 2, "show technical data"), arg_str0("", "aid", "", "replace default aid for NDEF"), arg_str0("k", "key", "", "replace default key for NDEF"), - arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -4657,22 +4671,24 @@ static int CmdHF14aDesNDEF(const char *Cmd) { uint8_t key[16] = {0}; int keylen; CLIGetHexWithReturn(ctx, 3, key, &keylen); - bool keyB = arg_get_lit(ctx, 4); CLIParserFree(ctx); - uint16_t ndefAID = 0xe103; - if (aidlen == 2) - ndefAID = (aid[0] << 8) + aid[1]; + uint32_t ndefAID = 0xEEEE10; + if (aidlen == 2) { + ndefAID = (aid[0] << 16) | (aid[1] << 8) | aid[2]; + } + // set default NDEF key uint8_t ndefkey[16] = {0}; memcpy(ndefkey, g_mifarep_ndef_key, 16); + + // user supplied key if (keylen == 16) { memcpy(ndefkey, key, 16); } - uint8_t data[4096] = {0}; - int datalen = 0; + int file_ids_len = 0; for (int j = (int)file_ids_len - 1; j >= 0; j--) { PrintAndLogEx(SUCCESS, "\n\n Fileid %d (0x%02x)", file_ids[j], file_ids[j]); @@ -4680,7 +4696,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) { uint8_t filesettings[20] = {0}; uint32_t fileset_len = 0; - res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); + int res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); if (res != PM3_SUCCESS) continue; int maclen = 0; // To be implemented @@ -4698,19 +4714,20 @@ static int CmdHF14aDesNDEF(const char *Cmd) { return PM3_EMALLOC; } - fdata.data = data; - int res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE, filesettings[1]); - if (res == PM3_SUCCESS) { - uint32_t len = le24toh(fdata.length); - NDEFDecodeAndPrint(data, datalen, verbose); + fdata.data = data; + res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE, filesettings[1]); + if (res == PM3_SUCCESS) { + uint32_t len = le24toh(fdata.length); + NDEFDecodeAndPrint(data, datalen, verbose); - } else { - PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); - res = handler_desfire_select_application(aid); - if (res != PM3_SUCCESS) continue; + } else { + PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); + res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; + } + + free(data); } - - free(data); } // PrintAndLogEx(INFO, "reading data from tag"); @@ -4722,14 +4739,14 @@ static int CmdHF14aDesNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("DESfire NDEF raw") " ----------------"); + PrintAndLogEx(INFO, "--- " _CYAN_("DESFire NDEF raw") " ----------------"); dump_buffer(data, datalen, stdout, 1); } + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details"); return PM3_SUCCESS; } */ - /* static int CmdHF14aDesMAD(const char *Cmd) { DropField(); From a41e71d03dbe80880b46a89259324af7158904a9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Nov 2020 09:36:27 +0100 Subject: [PATCH 05/69] fix #946, unsecured card use crc16, secured MAC --- armsrc/iclass.c | 74 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 03f7dcbba..803972e05 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1776,13 +1776,19 @@ void iClass_Dump(uint8_t *msg) { BigBuf_free(); } -static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac) { +static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, bool use_mac) { // write command: cmd, 1 blockno, 8 data, 4 mac - uint8_t write[16] = { 0x80 | ICLASS_CMD_UPDATE, blockno }; + uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, blockno }; + uint8_t write_len = 14; memcpy(write + 2, data, 8); - memcpy(write + 10, mac, 4); - AddCrc(write + 1, 13); + + if (use_mac) { + memcpy(write + 10, mac, 4); + } else { + AddCrc(write + 1, 9); + write_len -= 2; + } uint8_t resp[10] = {0}; uint32_t eof_time = 0, start_time = 0; @@ -1819,7 +1825,8 @@ void iClass_WriteBlock(uint8_t *msg) { iclass_writeblock_req_t *payload = (iclass_writeblock_req_t *)msg; - uint8_t write[16] = { 0x80 | ICLASS_CMD_UPDATE, payload->req.blockno }; + uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, payload->req.blockno }; + uint8_t write_len = 14; Iso15693InitReader(); @@ -1844,23 +1851,30 @@ void iClass_WriteBlock(uint8_t *msg) { } } - // calc new mac for write - uint8_t wb[9]; - wb[0] = payload->req.blockno; - memcpy(wb + 1, payload->data, 8); - - if (payload->req.use_replay) { - doMAC_N(wb, sizeof(wb), payload->req.key + 4, mac); + // new block data + memcpy(write + 2, payload->data, 8); + + uint8_t pagemap = get_pagemap(&hdr); + if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { + // Unsecured tags uses CRC16, but don't include the UPDATE operation code + // byte0 = update op + // byte1 = block no + // byte2..9 = new block data + AddCrc(write + 1, 9); + write_len -= 2; } else { + // Secure tags uses MAC + uint8_t wb[9]; + wb[0] = payload->req.blockno; + memcpy(wb + 1, payload->data, 8); + if (payload->req.use_credit_key) doMAC_N(wb, sizeof(wb), hdr.key_c, mac); else doMAC_N(wb, sizeof(wb), hdr.key_d, mac); - } - memcpy(write + 2, payload->data, 8); // data - memcpy(write + 10, mac, sizeof(mac)); // mac - AddCrc(write + 1, 13); + memcpy(write + 10, mac, sizeof(mac)); + } start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; @@ -1869,7 +1883,7 @@ void iClass_WriteBlock(uint8_t *msg) { uint8_t tries = 3; while (tries-- > 0) { - iclass_send_as_reader(write, sizeof(write), &start_time, &eof_time); + iclass_send_as_reader(write, write_len, &start_time, &eof_time); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured res = false; @@ -1961,22 +1975,30 @@ void iClass_Restore(iclass_restore_req_t *msg) { } // main loop + bool use_mac; for (uint8_t i = 0; i < msg->item_cnt; i++) { iclass_restore_item_t item = msg->blocks[i]; - // calc new mac for data, using 1b blockno, 8b data, - uint8_t wb[9] = {0}; - wb[0] = item.blockno; - memcpy(wb + 1, item.data, 8); + uint8_t pagemap = get_pagemap(&hdr); + if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { + // Unsecured tags uses CRC16 + use_mac = false; + } else { + // Secure tags uses MAC + use_mac = true; + uint8_t wb[9] = {0}; + wb[0] = item.blockno; + memcpy(wb + 1, item.data, 8); - if (msg->req.use_credit_key) - doMAC_N(wb, sizeof(wb), hdr.key_c, mac); - else - doMAC_N(wb, sizeof(wb), hdr.key_d, mac); + if (msg->req.use_credit_key) + doMAC_N(wb, sizeof(wb), hdr.key_c, mac); + else + doMAC_N(wb, sizeof(wb), hdr.key_d, mac); + } // data + mac - if (iclass_writeblock_ext(item.blockno, item.data, mac)) { + if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac)) { Dbprintf("Write block [%02x] " _GREEN_("successful"), item.blockno); written++; } else { From 3cd2c0b47bc4738e2953978aa373e53126ba0238 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Nov 2020 09:58:30 +0100 Subject: [PATCH 06/69] allow to write tags in unsecured pagemode --- client/src/cmdhficlass.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 38a313186..82bdbf5d0 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1760,7 +1760,7 @@ write_dump: return PM3_SUCCESS; } -static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose) { +static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode) { iclass_writeblock_req_t payload = { .req.use_raw = rawkey, @@ -1769,7 +1769,7 @@ static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bo .req.use_replay = replay, .req.blockno = blockno, .req.send_reply = true, - .req.do_auth = true, + .req.do_auth = use_secure_pagemode, }; memcpy(payload.req.key, KEY, 8); memcpy(payload.data, bldata, sizeof(payload.data)); @@ -1804,6 +1804,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { bool use_replay = false; bool errors = false; bool verbose = false; + bool use_secure_pagemode = false; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1848,6 +1849,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { PrintAndLogEx(WARNING, "\nERROR: Credit Key is incorrect length\n"); errors = true; } + use_secure_pagemode = true; cmdp += 2; break; case 'r': @@ -1880,9 +1882,9 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { errors = true; } - if (errors || cmdp < 6) return usage_hf_iclass_writeblock(); + if (errors || cmdp < 4) return usage_hf_iclass_writeblock(); - int isok = iclass_write_block(blockno, bldata, KEY, use_credit_key, elite, rawkey, use_replay, verbose); + int isok = iclass_write_block(blockno, bldata, KEY, use_credit_key, elite, rawkey, use_replay, verbose, use_secure_pagemode); switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Wrote block %02X successful", blockno); @@ -3565,10 +3567,11 @@ int info_iclass(void) { PrintAndLogEx(INFO, "------------------------ " _CYAN_("Fingerprint") " -----------------------"); uint8_t aia[8]; - if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) + if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { memcpy(aia, ns_hdr->app_issuer_area, sizeof(aia)); - else + } else { memcpy(aia, hdr->app_issuer_area, sizeof(aia)); + } // if CSN ends with FF12E0, it's inside HID CSN range. bool isHidRange = (memcmp(hdr->csn + 5, "\xFF\x12\xE0", 3) == 0); @@ -3583,11 +3586,13 @@ int info_iclass(void) { if (se_enabled) PrintAndLogEx(SUCCESS, " Credential... " _GREEN_("iCLASS SE")); } else { - PrintAndLogEx(SUCCESS, " CSN..-....... " _YELLOW_("outside HID range")); + PrintAndLogEx(SUCCESS, " CSN.......... " _YELLOW_("outside HID range")); } uint8_t cardtype = get_mem_config(hdr); PrintAndLogEx(SUCCESS, " Card type.... " _GREEN_("%s"), card_types[cardtype]); + + } DropField(); From 7cae4e969bf0546038ab3ec0b4fbf2f9ca0f338b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Nov 2020 10:02:47 +0100 Subject: [PATCH 07/69] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53aab0422..e9bb8d98f 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] + - Fix 'hf iclass wrbl' - dealing with tags in unsecured vs secured pagemode now is correct (@iceman1001) - Change many commands to cliparser (@iceman1001, @tcprst, @mwalker33,...) - ... - Added compilation options for 256k Proxmark versions, see doc (@doegox) From eec3bc595bcfc74da6e92190573eb1c7e972c44b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Nov 2020 10:48:37 +0100 Subject: [PATCH 08/69] coverity warning --- common/lz4/lz4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lz4/lz4.c b/common/lz4/lz4.c index da5bbf1e2..0b7df1fb0 100644 --- a/common/lz4/lz4.c +++ b/common/lz4/lz4.c @@ -1586,7 +1586,7 @@ int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, * cost to copy the dictionary's tables into the active context, * so that the compression loop is only looking into one table. */ - LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(LZ4_stream_t)); + LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(*streamPtr)); result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); } else { result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration); From 089ae507be1c5caeac98b6a9d19cead8536bace9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Nov 2020 15:24:19 +0100 Subject: [PATCH 09/69] structs needs to be PACKED --- client/src/cmdhfmfdes.c | 87 +++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 9a74aa2ca..871c9d115 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -60,7 +60,7 @@ uint8_t k3kdefaultkeys[1][24] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 struct desfire_tag mf_state = {.session_key = NULL, .authentication_scheme = AS_LEGACY, .authenticated_key_no = NOT_YET_AUTHENTICATED, .crypto_buffer = NULL, .crypto_buffer_size = 0, .selected_application = 0}; static desfiretag_t tag = &mf_state; -typedef struct { +typedef struct mfdes_authinput { uint8_t mode; uint8_t algo; uint8_t keyno; @@ -94,7 +94,6 @@ typedef struct { uint8_t details[14]; } PACKED mfdes_info_res_t; - typedef struct mfdes_value { uint8_t fileno; //01 uint8_t value[16]; @@ -340,11 +339,19 @@ typedef enum { NTAG413DNA, } nxp_cardtype_t; -typedef struct { +typedef struct dfname { uint8_t aid[3]; uint8_t fid[2]; uint8_t name[16]; -} dfname_t; +} PACKED dfname_t; + +typedef struct aidhdr { + uint8_t aid[3]; + uint8_t keysetting1; + uint8_t keysetting2; + uint8_t fid[2]; + uint8_t name[16]; +} PACKED aidhdr_t; static int CmdHelp(const char *Cmd); @@ -1544,9 +1551,14 @@ static int handler_desfire_dfnames(dfname_t *dest, uint8_t *dfname_count) { static int handler_desfire_select_application(uint8_t *aid) { if (g_debugMode > 1) { - if (aid == NULL) PrintAndLogEx(ERR, "AID=NULL"); + if (aid == NULL) { + PrintAndLogEx(ERR, "AID=NULL"); + } } - if (aid == NULL) return PM3_EINVARG; + if (aid == NULL) { + return PM3_EINVARG; + } + sAPDU apdu = {0x90, MFDES_SELECT_APPLICATION, 0x00, 0x00, 0x03, aid}; //0x5a uint32_t recv_len = 0; uint16_t sw = 0; @@ -1620,37 +1632,38 @@ static int handler_desfire_filesettings(uint8_t file_id, uint8_t *dest, uint32_t return res; } -typedef struct { - uint8_t aid[3]; - uint8_t keysetting1; - uint8_t keysetting2; - uint8_t fid[2]; - uint8_t name[16]; -} aidhdr_t; - static int handler_desfire_createapp(aidhdr_t *aidhdr, bool usename, bool usefid) { if (aidhdr == NULL) return PM3_EINVARG; sAPDU apdu = {0x90, MFDES_CREATE_APPLICATION, 0x00, 0x00, sizeof(aidhdr_t), (uint8_t *)aidhdr}; // 0xCA - if (!usename) { - apdu.Lc = apdu.Lc - 16; + if (usename == false) { + apdu.Lc = apdu.Lc - sizeof(aidhdr->name); } - if (!usefid) { - apdu.Lc = apdu.Lc - 2; + if (usefid == false) { + apdu.Lc = apdu.Lc - sizeof(aidhdr->fid); } uint8_t *data = NULL; - if (!usefid && usename) { - data = (uint8_t *)malloc(apdu.Lc); + + // skip over FID if not used. + if (usefid == false && usename) { + data = calloc(apdu.Lc, sizeof(uint8_t)); apdu.data = data; - memcpy(data, aidhdr, apdu.Lc); - memcpy(&data[3 + 1 + 1], aidhdr->name, 16); + + memcpy(data, aidhdr->aid, sizeof(aidhdr->aid)); + data[3] = aidhdr->keysetting1; + data[4] = aidhdr->keysetting2; + memcpy(data + 5, aidhdr->name, sizeof(aidhdr->name)); + + PrintAndLogEx(INFO, "new data: %s", sprint_hex_inrow(data, apdu.Lc)); } uint16_t sw = 0; uint32_t recvlen = 0; int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); - if (data != NULL) free(data); + if (data != NULL) { + free(data); + } if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create aid -> %s"), GetErrorString(res, &sw)); DropField(); @@ -1659,7 +1672,9 @@ static int handler_desfire_createapp(aidhdr_t *aidhdr, bool usename, bool usefid } static int handler_desfire_deleteapp(const uint8_t *aid) { - if (aid == NULL) return PM3_EINVARG; + if (aid == NULL) { + return PM3_EINVARG; + } sAPDU apdu = {0x90, MFDES_DELETE_APPLICATION, 0x00, 0x00, 3, (uint8_t *)aid}; // 0xDA uint16_t sw = 0; uint32_t recvlen = 0; @@ -2240,7 +2255,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes createaid", "Create Application ID", - "hf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test" + "hf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E --name Test" ); void *argtable[] = { @@ -2249,7 +2264,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { arg_strx0("f", "fid", "", "File ID to create (optional)"), arg_strx0("k", "ks1", "", "Key Setting 1 (Application Master Key Settings)"), arg_strx0("l", "ks2", "", "Key Setting 2"), - arg_str0("n", "name", "", "App ISO-4 Name (optional)"), + arg_str0(NULL, "name", "", "App ISO-4 Name (optional)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2347,9 +2362,20 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { aidhdr.keysetting1 = keysetting1[0]; aidhdr.keysetting2 = keysetting2[0]; - if (usefid) memcpy(aidhdr.fid, fid, sizeof(fid)); + if (usefid) + memcpy(aidhdr.fid, fid, sizeof(aidhdr.fid)); - if (usename) memcpy(aidhdr.name, name, sizeof(name)); + if (usename) + memcpy(aidhdr.name, name, sizeof(aidhdr.name)); + + PrintAndLogEx(INFO, "Creating AID using:"); + PrintAndLogEx(INFO, "AID %s", sprint_hex_inrow(aidhdr.aid, sizeof(aidhdr.aid))); + PrintAndLogEx(INFO, "Key set1 0x%02X", aidhdr.keysetting1); + PrintAndLogEx(INFO, "Key Set2 0x%02X", aidhdr.keysetting2); + if (usefid) + PrintAndLogEx(INFO, "FID %s", sprint_hex_inrow(aidhdr.fid, sizeof(aidhdr.fid))); + if (usename) + PrintAndLogEx(INFO, "DF Name %s", aidhdr.name); uint8_t rootaid[3] = {0x00, 0x00, 0x00}; int res = handler_desfire_select_application(rootaid); @@ -2397,7 +2423,10 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { uint8_t rootaid[3] = {0x00, 0x00, 0x00}; int res = handler_desfire_select_application(rootaid); - if (res != PM3_SUCCESS) { DropField(); return res;} + if (res != PM3_SUCCESS) { + DropField(); + return res; + } res = handler_desfire_deleteapp(aid); DropField(); if (res == PM3_SUCCESS) { From c9642d53c4eae651b3ce8ca5fb95bd4585d9b941 Mon Sep 17 00:00:00 2001 From: Jamie Fiedler Date: Tue, 10 Nov 2020 15:02:57 -0500 Subject: [PATCH 10/69] bsd/gnu-safe file byte calc --- recovery/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recovery/Makefile b/recovery/Makefile index 1ef142eda..e6e3f7041 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -11,7 +11,7 @@ FWMAXSIZE = $(shell echo $$(($(PLATFORM_SIZE)*1024))) BINS = bootrom.bin fullimage.bin $(INSTALLFW) all: $(BINS) - @FWSIZE=$$(stat -c "%s" $(INSTALLFW));\ + @FWSIZE=$$(wc -c < $(INSTALLFW));\ if [ $$FWSIZE -gt $(FWMAXSIZE) ]; then \ echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; \ echo "ERROR: Firmware image too large for your platform! $$FWSIZE > $(FWMAXSIZE)"; \ From e959d0e2297c136fc5b5edd541c37a0cbad571ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Nov 2020 21:54:33 +0100 Subject: [PATCH 11/69] link to clocks --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 330faaef6..9717c30c7 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ |[Notes on file formats used with Proxmark3](/doc/extensions_notes.md)|[Notes on MFU binary format](/doc/mfu_binary_format_notes.md)|[Notes on FPGA & ARM](/doc/fpga_arm_notes.md)| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|[Notes on Magic cards](/doc/magic_cards_notes.md)| |[Notes on Color usage](/doc/colors_notes.md)|[Makefile vs CMake](/doc/md/Development/Makefile-vs-CMake.md)|[Notes on Cloner guns](/doc/cloner_notes.md)| -|[Notes on cliparser usage](/doc/cliparser.md)||| +|[Notes on cliparser usage](/doc/cliparser.md)|[Notes on clocks](/doc/clocks.md)|| ## Build for non-RDV4 Proxmark3 platforms From eadacd82f53be5880e8bd7555b5d7a80f52ef10f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 28 May 2020 02:13:21 +0200 Subject: [PATCH 12/69] SWIG experiments Squash of the following commits (a full rebase was too hard :( ) * ef309cfdf N - SWIG: create pm3.c (5 months ago) * 05ba6a73f N - swig pm3_device -> pm3 (5 months ago) * d59630183 N - swig: move pm3.i (5 months ago) * 6adcfad75 N - Fix historic make & cmake (5 months ago) * bcbef2edf N - Fix typo with script_embedded (5 months ago) * 538ee4dab N - Better SWIG integration: autogen func & attributes (5 months ago) * 756b62466 N - SWIG: few helper scripts (5 months ago) * 47ba4acd0 N - SWIG %extend (5 months ago) * 21841cb9d N - simplify scripts (5 months ago) * 78c4f7929 N - Revert "SWIG experiments: introduce context" (5 months ago) * 1562b75fc N - SWIG experiments: introduce context (5 months ago) * a503dfcd9 N - SWIG experiments (5 months ago) --- client/CMakeLists.txt | 3 +- client/Makefile | 5 +- client/android/pm3_main.c | 2 +- client/deps/hardnested.cmake | 1 + client/deps/hardnested/Makefile | 2 +- .../experimental_client_with_swig/.gitignore | 1 + .../00make_swig.sh | 4 + .../01make_client.sh | 10 + .../01make_client_continue.sh | 6 + .../02a_run_test_lua.sh | 3 + .../02b_run_test_py.sh | 7 + .../CMakeLists.txt | 573 +++ .../testembedded.lua | 4 + .../testembedded.py | 6 + client/experimental_lib/.gitignore | 1 + client/experimental_lib/00make_swig.sh | 4 + .../experimental_lib/01make_lib_continue.sh | 7 + client/experimental_lib/CMakeLists.txt | 557 +++ .../experimental_lib/example_c/01make_test.sh | 3 + .../experimental_lib/example_c/02run_test.sh | 3 + client/experimental_lib/example_c/test.c | 8 + .../example_lua/01link_lib.sh | 3 + .../example_lua/02run_test.sh | 8 + client/experimental_lib/example_lua/test.lua | 6 + .../experimental_lib/example_py/01link_lib.sh | 3 + .../experimental_lib/example_py/02run_test.sh | 11 + .../example_py/02run_test_interactive.sh | 3 + client/experimental_lib/example_py/test.py | 6 + client/include/pm3.h | 11 + client/src/cmdhw.c | 8 +- client/src/cmdscript.c | 17 +- client/src/comms.c | 13 +- client/src/comms.h | 13 +- client/src/flash.c | 4 +- client/src/pm3.c | 55 + client/src/pm3.i | 39 + client/src/pm3.py | 80 + client/src/pm3_luawrap.c | 3259 ++++++++++++++ client/src/pm3_pywrap.c | 3781 +++++++++++++++++ client/src/proxmark3.c | 43 +- client/src/proxmark3.h | 1 + client/src/ui.h | 2 + 42 files changed, 8542 insertions(+), 34 deletions(-) create mode 100644 client/experimental_client_with_swig/.gitignore create mode 100755 client/experimental_client_with_swig/00make_swig.sh create mode 100755 client/experimental_client_with_swig/01make_client.sh create mode 100755 client/experimental_client_with_swig/01make_client_continue.sh create mode 100755 client/experimental_client_with_swig/02a_run_test_lua.sh create mode 100755 client/experimental_client_with_swig/02b_run_test_py.sh create mode 100644 client/experimental_client_with_swig/CMakeLists.txt create mode 100755 client/experimental_client_with_swig/testembedded.lua create mode 100755 client/experimental_client_with_swig/testembedded.py create mode 100644 client/experimental_lib/.gitignore create mode 100755 client/experimental_lib/00make_swig.sh create mode 100755 client/experimental_lib/01make_lib_continue.sh create mode 100644 client/experimental_lib/CMakeLists.txt create mode 100755 client/experimental_lib/example_c/01make_test.sh create mode 100755 client/experimental_lib/example_c/02run_test.sh create mode 100644 client/experimental_lib/example_c/test.c create mode 100755 client/experimental_lib/example_lua/01link_lib.sh create mode 100755 client/experimental_lib/example_lua/02run_test.sh create mode 100755 client/experimental_lib/example_lua/test.lua create mode 100755 client/experimental_lib/example_py/01link_lib.sh create mode 100755 client/experimental_lib/example_py/02run_test.sh create mode 100755 client/experimental_lib/example_py/02run_test_interactive.sh create mode 100755 client/experimental_lib/example_py/test.py create mode 100644 client/include/pm3.h create mode 100644 client/src/pm3.c create mode 100644 client/src/pm3.i create mode 100644 client/src/pm3.py create mode 100644 client/src/pm3_luawrap.c create mode 100644 client/src/pm3_pywrap.c diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ed5802185..77181f8bf 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -289,6 +289,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/graph.c ${PM3_ROOT}/client/src/jansson_path.c ${PM3_ROOT}/client/src/preferences.c + ${PM3_ROOT}/client/src/pm3.c ${PM3_ROOT}/client/src/pm3_binlib.c ${PM3_ROOT}/client/src/pm3_bitlib.c ${PM3_ROOT}/client/src/prng.c @@ -361,7 +362,7 @@ if (NOT SKIPPYTHON EQUAL 1) add_definitions(-DHAVE_PYTHON) set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) - set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) endif (PYTHON3EMBED_FOUND) endif (NOT SKIPPYTHON EQUAL 1) diff --git a/client/Makefile b/client/Makefile index dcfadb340..333cbad08 100644 --- a/client/Makefile +++ b/client/Makefile @@ -289,7 +289,7 @@ endif CFLAGS ?= $(DEFCFLAGS) # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: PM3CFLAGS = $(CFLAGS) -PM3CFLAGS += -I./src -I../include -I../common -I../common_fpga $(INCLUDES) +PM3CFLAGS += -I./src -I./include -I../include -I../common -I../common_fpga $(INCLUDES) # WIP Testing #PM3CFLAGS += -std=c11 -pedantic @@ -318,7 +318,7 @@ endif CXXFLAGS ?= -Wall -Werror -O3 PM3CXXFLAGS = $(CXXFLAGS) -PM3CXXFLAGS += -I../include +PM3CXXFLAGS += -I../include -I./include ifeq ($(QT_FOUND),1) PM3CFLAGS += -DHAVE_GUI @@ -540,6 +540,7 @@ SRCS = aiddesfire.c \ mifare/mifaredefault.c \ mifare/mifarehost.c \ mifare/ndef.c \ + pm3.c \ pm3_binlib.c \ pm3_bitlib.c \ preferences.c \ diff --git a/client/android/pm3_main.c b/client/android/pm3_main.c index 5fa056a44..3d2ef917d 100644 --- a/client/android/pm3_main.c +++ b/client/android/pm3_main.c @@ -64,7 +64,7 @@ int push_cmdscriptfile(char *path, bool stayafter) { return PM3_SUCCESS; } static bool OpenPm3(void) { if (conn.run) { return true; } // Open with LocalSocket. Not a tcp connection! - bool ret = OpenProxmark("socket:"PM3_LOCAL_SOCKET_SERVER, false, 1000, false, 115200); + bool ret = OpenProxmark(session.current_device, "socket:"PM3_LOCAL_SOCKET_SERVER, false, 1000, false, 115200); return ret; } diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index f9248b82d..dc569641c 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -118,6 +118,7 @@ set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common ../../include + ../include ../src jansson) target_include_directories(pm3rrg_rdv4_hardnested INTERFACE hardnested) diff --git a/client/deps/hardnested/Makefile b/client/deps/hardnested/Makefile index 079516977..624eb730f 100644 --- a/client/deps/hardnested/Makefile +++ b/client/deps/hardnested/Makefile @@ -1,5 +1,5 @@ MYSRCPATHS = -MYINCLUDES = -I../../../common -I../../../include -I../../src -I../jansson +MYINCLUDES = -I../../../common -I../../../include -I../../src -I../../include -I../jansson MYCFLAGS = MYDEFS = MYSRCS = hardnested_bruteforce.c diff --git a/client/experimental_client_with_swig/.gitignore b/client/experimental_client_with_swig/.gitignore new file mode 100644 index 000000000..567609b12 --- /dev/null +++ b/client/experimental_client_with_swig/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/client/experimental_client_with_swig/00make_swig.sh b/client/experimental_client_with_swig/00make_swig.sh new file mode 100755 index 000000000..6c752d024 --- /dev/null +++ b/client/experimental_client_with_swig/00make_swig.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i +swig -python -o ../src/pm3_pywrap.c ../src/pm3.i diff --git a/client/experimental_client_with_swig/01make_client.sh b/client/experimental_client_with_swig/01make_client.sh new file mode 100755 index 000000000..667a6351e --- /dev/null +++ b/client/experimental_client_with_swig/01make_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +rm -rf build +mkdir build +( + cd build + cmake .. + make -j +) + diff --git a/client/experimental_client_with_swig/01make_client_continue.sh b/client/experimental_client_with_swig/01make_client_continue.sh new file mode 100755 index 000000000..4c85bb9dc --- /dev/null +++ b/client/experimental_client_with_swig/01make_client_continue.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +( + cd build + make -j +) diff --git a/client/experimental_client_with_swig/02a_run_test_lua.sh b/client/experimental_client_with_swig/02a_run_test_lua.sh new file mode 100755 index 000000000..bca993a44 --- /dev/null +++ b/client/experimental_client_with_swig/02a_run_test_lua.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02b_run_test_py.sh b/client/experimental_client_with_swig/02b_run_test_py.sh new file mode 100755 index 000000000..fcaf4c8f8 --- /dev/null +++ b/client/experimental_client_with_swig/02b_run_test_py.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +#/usr/local/lib/python3/dist-packages/pm3.py +#/usr/lib/python3/dist-packages/pm3.py + +# need access to pm3.py +PYTHONPATH=../src build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py" diff --git a/client/experimental_client_with_swig/CMakeLists.txt b/client/experimental_client_with_swig/CMakeLists.txt new file mode 100644 index 000000000..a871e528e --- /dev/null +++ b/client/experimental_client_with_swig/CMakeLists.txt @@ -0,0 +1,573 @@ +# Usage: +# mkdir build +# cd build +# cmake .. (see below for options) +# make (VERBOSE=1 if needed) +# +# MINGW: +# On ProxSpace 3.4: +# cmake -G"MSYS Makefiles" .. +# On Proxspace 3.3 or less, you need to install cmake: +# pacman -S mingw-w64-x86_64-cmake +# /mingw64/bin/cmake -G"MSYS Makefiles" .. +# +# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version) +# cmake \ +# -DCMAKE_TOOLCHAIN_FILE=/build/cmake/android.toolchain.cmake \ +# -DANDROID_ABI=armeabi-v7a \ +# -DANDROID_NATIVE_API_LEVEL=android-19 \ +# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 .. + +message(STATUS "CMake ${CMAKE_VERSION}") +cmake_minimum_required(VERSION 3.10) +project(proxmark3) +SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +if(CMAKE_VERSION VERSION_LESS "3.7.0") + set(CMAKE_INCLUDE_CURRENT_DIR ON) +endif() + +find_package(PkgConfig) + +if (NOT SKIPQT EQUAL 1) + if(APPLE AND EXISTS /usr/local/opt/qt5) + # Homebrew installs Qt5 (up to at least 5.11.0) in + # /usr/local/qt5. Ensure that it can be found by CMake + # since it is not in the default /usr/local prefix. + # Add it to PATHS so that it doesn't override the + # CMAKE_PREFIX_PATH environment variable. + # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, + # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) + list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) + endif(APPLE AND EXISTS /usr/local/opt/qt5) + set(QT_PACKAGELIST + Qt5Core + Qt5Widgets + Qt5Gui + ) + set(Qt5_FOUND ON) + foreach(_qt_package IN LISTS QT_PACKAGELIST) + find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) + set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES}) + if(NOT ${_qt_package}_FOUND) + set(Qt5_FOUND OFF) + endif(NOT ${_qt_package}_FOUND) + endforeach() +endif (NOT SKIPQT EQUAL 1) + +if (NOT SKIPBT EQUAL 1) + pkg_search_module(BLUEZ QUIET bluez) +endif (NOT SKIPBT EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + pkg_search_module(PYTHON3 QUIET python3) + pkg_search_module(PYTHON3EMBED QUIET python3-embed) +endif (NOT SKIPPYTHON EQUAL 1) + +# If cross-compiled, we need to init source and build. +if (CMAKE_TOOLCHAIN_FILE) + set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w") + set(EMBED_READLINE ON) + set(EMBED_BZIP2 ON) +endif (CMAKE_TOOLCHAIN_FILE) + +if (EMBED_READLINE OR EMBED_BZIP2) + include(ExternalProject) +endif (EMBED_READLINE OR EMBED_BZIP2) + +if (NOT SKIPREADLINE EQUAL 1) + if (APPLE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) + find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) + endif (APPLE) + if (EMBED_READLINE) + ExternalProject_Add(ncurses + URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz + PREFIX deps/ncurses + DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses + CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib + BUILD_IN_SOURCE ON + BUILD_COMMAND make libs + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(ncurses configure build install) + + ExternalProject_Add(readline + URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz + PREFIX deps/readline + DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline + CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static + BUILD_IN_SOURCE ON + BUILD_COMMAND make + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(readline configure build install) + set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/) + set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a) + else (EMBED_READLINE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h) + find_library(READLINE_LIBRARIES readline) + endif (EMBED_READLINE) + if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) + set(READLINE_FOUND ON) + endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) +endif (NOT SKIPREADLINE EQUAL 1) + +if (NOT SKIPJANSSONSYSTEM EQUAL 1) + pkg_check_modules(PC_JANSSON QUIET jansson) + find_path(JANSSON_INCLUDE_DIRS + NAMES jansson.h + HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS}) + find_library(JANSSON_LIBRARIES + NAMES jansson libjansson + HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS}) + if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) + set(JANSSON_FOUND ON) + endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) +endif (NOT SKIPJANSSONSYSTEM EQUAL 1) + +if(EMBED_BZIP2) + set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) + ExternalProject_Add(bzip2 + GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2 + GIT_TAG platform-tools-30.0.2 + PREFIX deps/bzip2 + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 + CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x + BUILD_IN_SOURCE ON + BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(bzip2 configure build install) + set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) + set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a) + set(BZIP2_FOUND ON) +else(EMBED_BZIP2) + find_package (BZip2 REQUIRED) +endif(EMBED_BZIP2) + +if (NOT SKIPWHEREAMISYSTEM EQUAL 1) + find_path(WHEREAMI_INCLUDE_DIRS whereami.h) + find_library(WHEREAMI_LIBRARIES whereami) + if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) + set(WHEREAMI_FOUND ON) + endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) +endif (NOT SKIPWHEREAMISYSTEM EQUAL 1) + +add_subdirectory(${PM3_ROOT}/client/deps deps) + +set (TARGET_SOURCES + ${PM3_ROOT}/common/commonutil.c + ${PM3_ROOT}/common/util_posix.c + ${PM3_ROOT}/common/parity.c + ${PM3_ROOT}/common/bucketsort.c + ${PM3_ROOT}/common/crapto1/crapto1.c + ${PM3_ROOT}/common/crapto1/crypto1.c + ${PM3_ROOT}/common/crc.c + ${PM3_ROOT}/common/crc16.c + ${PM3_ROOT}/common/crc32.c + ${PM3_ROOT}/common/crc64.c + ${PM3_ROOT}/common/lfdemod.c + ${PM3_ROOT}/common/legic_prng.c + ${PM3_ROOT}/common/iso15693tools.c + ${PM3_ROOT}/common/cardhelper.c + ${PM3_ROOT}/common/generator.c + ${PM3_ROOT}/client/src/crypto/asn1dump.c + ${PM3_ROOT}/client/src/crypto/asn1utils.c + ${PM3_ROOT}/client/src/crypto/libpcrypto.c + ${PM3_ROOT}/client/src/emv/test/cda_test.c + ${PM3_ROOT}/client/src/emv/test/crypto_test.c + ${PM3_ROOT}/client/src/emv/test/cryptotest.c + ${PM3_ROOT}/client/src/emv/test/dda_test.c + ${PM3_ROOT}/client/src/emv/test/sda_test.c + ${PM3_ROOT}/client/src/emv/apduinfo.c + ${PM3_ROOT}/client/src/emv/cmdemv.c + ${PM3_ROOT}/client/src/emv/crypto.c + ${PM3_ROOT}/client/src/emv/crypto_polarssl.c + ${PM3_ROOT}/client/src/emv/dol.c + ${PM3_ROOT}/client/src/emv/dump.c + ${PM3_ROOT}/client/src/emv/emv_pk.c + ${PM3_ROOT}/client/src/emv/emv_pki.c + ${PM3_ROOT}/client/src/emv/emv_pki_priv.c + ${PM3_ROOT}/client/src/emv/emv_roca.c + ${PM3_ROOT}/client/src/emv/emv_tags.c + ${PM3_ROOT}/client/src/emv/emvcore.c + ${PM3_ROOT}/client/src/emv/emvjson.c + ${PM3_ROOT}/client/src/emv/tlv.c + ${PM3_ROOT}/client/src/fido/additional_ca.c + ${PM3_ROOT}/client/src/fido/cbortools.c + ${PM3_ROOT}/client/src/fido/cose.c + ${PM3_ROOT}/client/src/fido/fidocore.c + ${PM3_ROOT}/client/src/loclass/cipher.c + ${PM3_ROOT}/client/src/loclass/cipherutils.c + ${PM3_ROOT}/client/src/loclass/elite_crack.c + ${PM3_ROOT}/client/src/loclass/hash1_brute.c + ${PM3_ROOT}/client/src/loclass/ikeys.c + ${PM3_ROOT}/client/src/mifare/mad.c + ${PM3_ROOT}/client/src/mifare/mfkey.c + ${PM3_ROOT}/client/src/mifare/mifare4.c + ${PM3_ROOT}/client/src/mifare/mifaredefault.c + ${PM3_ROOT}/client/src/mifare/mifarehost.c + ${PM3_ROOT}/client/src/mifare/ndef.c + ${PM3_ROOT}/client/src/mifare/desfire_crypto.c + ${PM3_ROOT}/client/src/uart/uart_posix.c + ${PM3_ROOT}/client/src/uart/uart_win32.c + ${PM3_ROOT}/client/src/ui/overlays.ui + ${PM3_ROOT}/client/src/aiddesfire.c + ${PM3_ROOT}/client/src/aidsearch.c + ${PM3_ROOT}/client/src/cmdanalyse.c + ${PM3_ROOT}/client/src/cmdcrc.c + ${PM3_ROOT}/client/src/cmddata.c + ${PM3_ROOT}/client/src/cmdflashmem.c + ${PM3_ROOT}/client/src/cmdflashmemspiffs.c + ${PM3_ROOT}/client/src/cmdhf.c + ${PM3_ROOT}/client/src/cmdhf14a.c + ${PM3_ROOT}/client/src/cmdhf14b.c + ${PM3_ROOT}/client/src/cmdhf15.c + ${PM3_ROOT}/client/src/cmdhfcryptorf.c + ${PM3_ROOT}/client/src/cmdhfepa.c + ${PM3_ROOT}/client/src/cmdhffelica.c + ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhficlass.c + ${PM3_ROOT}/client/src/cmdhflegic.c + ${PM3_ROOT}/client/src/cmdhflist.c + ${PM3_ROOT}/client/src/cmdhflto.c + ${PM3_ROOT}/client/src/cmdhfmf.c + ${PM3_ROOT}/client/src/cmdhfmfdes.c + ${PM3_ROOT}/client/src/cmdhfmfhard.c + ${PM3_ROOT}/client/src/cmdhfmfp.c + ${PM3_ROOT}/client/src/cmdhfmfu.c + ${PM3_ROOT}/client/src/cmdhfst.c + ${PM3_ROOT}/client/src/cmdhfthinfilm.c + ${PM3_ROOT}/client/src/cmdhftopaz.c + ${PM3_ROOT}/client/src/cmdhfwaveshare.c + ${PM3_ROOT}/client/src/cmdhw.c + ${PM3_ROOT}/client/src/cmdlf.c + ${PM3_ROOT}/client/src/cmdlfawid.c + ${PM3_ROOT}/client/src/cmdlfcotag.c + ${PM3_ROOT}/client/src/cmdlfdestron.c + ${PM3_ROOT}/client/src/cmdlfem4x.c + ${PM3_ROOT}/client/src/cmdlfem4x05.c + ${PM3_ROOT}/client/src/cmdlfem4x50.c + ${PM3_ROOT}/client/src/cmdlffdxb.c + ${PM3_ROOT}/client/src/cmdlfgallagher.c + ${PM3_ROOT}/client/src/cmdlfguard.c + ${PM3_ROOT}/client/src/cmdlfhid.c + ${PM3_ROOT}/client/src/cmdlfhitag.c + ${PM3_ROOT}/client/src/cmdlfidteck.c + ${PM3_ROOT}/client/src/cmdlfindala.c + ${PM3_ROOT}/client/src/cmdlfio.c + ${PM3_ROOT}/client/src/cmdlfjablotron.c + ${PM3_ROOT}/client/src/cmdlfkeri.c + ${PM3_ROOT}/client/src/cmdlfmotorola.c + ${PM3_ROOT}/client/src/cmdlfnedap.c + ${PM3_ROOT}/client/src/cmdlfnexwatch.c + ${PM3_ROOT}/client/src/cmdlfnoralsy.c + ${PM3_ROOT}/client/src/cmdlfpac.c + ${PM3_ROOT}/client/src/cmdlfparadox.c + ${PM3_ROOT}/client/src/cmdlfpcf7931.c + ${PM3_ROOT}/client/src/cmdlfpresco.c + ${PM3_ROOT}/client/src/cmdlfpyramid.c + ${PM3_ROOT}/client/src/cmdlfsecurakey.c + ${PM3_ROOT}/client/src/cmdlft55xx.c + ${PM3_ROOT}/client/src/cmdlfti.c + ${PM3_ROOT}/client/src/cmdlfviking.c + ${PM3_ROOT}/client/src/cmdlfvisa2000.c + ${PM3_ROOT}/client/src/cmdmain.c + ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdscript.c + ${PM3_ROOT}/client/src/cmdsmartcard.c + ${PM3_ROOT}/client/src/cmdtrace.c + ${PM3_ROOT}/client/src/cmdusart.c + ${PM3_ROOT}/client/src/cmdwiegand.c + ${PM3_ROOT}/client/src/comms.c + ${PM3_ROOT}/client/src/fileutils.c + ${PM3_ROOT}/client/src/flash.c + ${PM3_ROOT}/client/src/graph.c + ${PM3_ROOT}/client/src/jansson_path.c + ${PM3_ROOT}/client/src/preferences.c + ${PM3_ROOT}/client/src/pm3.c + ${PM3_ROOT}/client/src/pm3_binlib.c + ${PM3_ROOT}/client/src/pm3_bitlib.c + ${PM3_ROOT}/client/src/prng.c + ${PM3_ROOT}/client/src/scandir.c + ${PM3_ROOT}/client/src/scripting.c + ${PM3_ROOT}/client/src/tea.c + ${PM3_ROOT}/client/src/ui.c + ${PM3_ROOT}/client/src/util.c + ${PM3_ROOT}/client/src/wiegand_formats.c + ${PM3_ROOT}/client/src/wiegand_formatutils.c + ${CMAKE_BINARY_DIR}/version.c + ) + +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/version.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c + DEPENDS ${PM3_ROOT}/common/default_version.c +) + +set(ADDITIONAL_SRC "") +set(ADDITIONAL_LNK "") +set(ADDITIONAL_DIRS "") +set(ADDITIONAL_LNKDIRS "") +set(X86_CPUS x86 x86_64 i686) + +message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") + +if (APPLE) + message(STATUS "Apple device detected.") + set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") +endif (APPLE) + +if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTORCC ON) + set(CMAKE_AUTOUIC ON) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/proxgui.cpp + ${PM3_ROOT}/client/src/proxguiqt.cpp + ${TARGET_SOURCES}) + + add_definitions("-DHAVE_GUI") + set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK}) +else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + set(TARGET_SOURCES + ${PM3_ROOT}/client/src/guidummy.cpp + ${TARGET_SOURCES}) +endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + +if (NOT SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + add_definitions("-DHAVE_BLUEZ") + set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK}) + endif (BLUEZ_FOUND) +endif(NOT SKIPBT EQUAL 1) + +if (JANSSON_FOUND) + set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK}) +endif (JANSSON_FOUND) + +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + elseif (PYTHON3_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + endif (PYTHON3EMBED_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +if (NOT SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + add_definitions("-DHAVE_READLINE") + set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK}) + endif (READLINE_FOUND) +endif(NOT SKIPREADLINE EQUAL 1) + +if (BZIP2_FOUND) + set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK}) +endif (BZIP2_FOUND) + +if (WHEREAMI_FOUND) + set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK}) +endif (WHEREAMI_FOUND) + +message(STATUS "===================================================================") +if (SKIPQT EQUAL 1) + message(STATUS "GUI support: skipped") +else (SKIPQT EQUAL 1) + if (Qt5_FOUND) + message(STATUS "GUI support: QT5 found, enabled") + else (Qt5_FOUND) + message(STATUS "GUI support: QT5 not found, disabled") + endif (Qt5_FOUND) +endif (SKIPQT EQUAL 1) + +if (SKIPBT EQUAL 1) + message(STATUS "native BT support: skipped") +else (SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + message(STATUS "native BT support: Bluez found, enabled") + else (BLUEZ_FOUND) + message(STATUS "native BT support: Bluez not found, disabled") + endif (BLUEZ_FOUND) +endif(SKIPBT EQUAL 1) + +if (EMBED_BZIP2) + message(STATUS "Bzip2 library: embedded") +else (EMBED_BZIP2) + message(STATUS "Bzip2 library: system library found") +endif (EMBED_BZIP2) + +if (SKIPJANSSONSYSTEM EQUAL 1) + message(STATUS "Jansson library: local library forced") +else (SKIPJANSSONSYSTEM EQUAL 1) + if (JANSSON_FOUND) + message(STATUS "Jansson library: system library found") + else (JANSSON_FOUND) + message(STATUS "Jansson library: system library not found, using local library") + endif (JANSSON_FOUND) +endif (SKIPJANSSONSYSTEM EQUAL 1) + +if (SKIPPYTHON EQUAL 1) + message(STATUS "Python3 library: skipped") +else (SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + message(STATUS "Python3 library: Python3 embed found, enabled") + elseif (PYTHON_FOUND) + message(STATUS "Python3 library: Python3 found, enabled") + else (PYTHON3EMBED_FOUND) + message(STATUS "Python3 library: Python3 not found, disabled") + endif (PYTHON3EMBED_FOUND) +endif(SKIPPYTHON EQUAL 1) + +if (SKIPREADLINE EQUAL 1) + message(STATUS "Readline library: skipped") +else (SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + if (EMBED_READLINE) + message(STATUS "Readline library: embedded") + else (EMBED_READLINE) + message(STATUS "Readline library: system library found") + endif (EMBED_READLINE) + else (READLINE_FOUND) + message(STATUS "Readline library: Readline not found, disabled") + endif (READLINE_FOUND) +endif(SKIPREADLINE EQUAL 1) + +if (SKIPWHEREAMISYSTEM EQUAL 1) + message(STATUS "Whereami library: local library forced") +else (SKIPWHEREAMISYSTEM EQUAL 1) + if (WHEREAMI_FOUND) + message(STATUS "Whereami library: system library found") + else (WHEREAMI_FOUND) + message(STATUS "Whereami library: system library not found, using local library") + endif (WHEREAMI_FOUND) +endif (SKIPWHEREAMISYSTEM EQUAL 1) +message(STATUS "===================================================================") + +# Lua SWIG +if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_luawrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_LUA_SWIG) + message("Lua SWIG wrapper found") +endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + +# Python SWIG +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_pywrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_PYTHON_SWIG) + message("Python SWIG wrapper found") + endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +add_executable(proxmark3 + ${PM3_ROOT}/client/src/proxmark3.c + ${TARGET_SOURCES} + ${ADDITIONAL_SRC} +) + +target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) +if (EMBED_READLINE) + if (NOT SKIPREADLINE EQUAL 1) + add_dependencies(proxmark3 ncurses readline) + endif (NOT SKIPREADLINE EQUAL 1) +endif (EMBED_READLINE) +if (EMBED_BZIP2) + add_dependencies(proxmark3 bzip2) +endif (EMBED_BZIP2) + +if (MINGW) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + # FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32 + # but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html + target_compile_definitions(proxmark3 PRIVATE _ISOC99_SOURCE) + + set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") +endif (MINGW) + +target_include_directories(proxmark3 PRIVATE + ${PM3_ROOT}/common + ${PM3_ROOT}/common_fpga + ${PM3_ROOT}/include + ${PM3_ROOT}/client/src + ${PM3_ROOT}/client/include + ${ADDITIONAL_DIRS} +) + +if (NOT APPLE) + # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. + set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) +endif (NOT APPLE) + +if (NOT JANSSON_FOUND) + set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK}) +endif (NOT JANSSON_FOUND) +if (NOT WHEREAMI_FOUND) + set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK}) +endif (NOT WHEREAMI_FOUND) + +target_link_libraries(proxmark3 PRIVATE + m + pm3rrg_rdv4_mbedtls + pm3rrg_rdv4_cliparser + pm3rrg_rdv4_lua + pm3rrg_rdv4_tinycbor + pm3rrg_rdv4_amiibo + pm3rrg_rdv4_reveng + pm3rrg_rdv4_hardnested + ${ADDITIONAL_LNK}) + +if (NOT SKIPPTHREAD EQUAL 1) + target_link_libraries(proxmark3 PRIVATE pthread) +endif (NOT SKIPPTHREAD EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + # OSX have a hard time compiling python3 dependency with older cmake. + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (NOT CMAKE_VERSION VERSION_LESS 3.13) + target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS}) + elseif (APPLE) + message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" ) + endif (NOT CMAKE_VERSION VERSION_LESS 3.13) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +install(TARGETS proxmark3 DESTINATION "bin") +install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3") + +add_custom_command(OUTPUT lualibs/pm3_cmd.lua + COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua" + COMMENT "Creating lualibs/pm3_cmd.lua" + ) + +add_custom_command(OUTPUT lualibs/mfc_default_keys.lua + COMMAND "awk -f default_keys_dic2lua.awk mfc_default_keys.dic > lualibs/mfc_default_keys.lua" + COMMENT "Creating lualibs/mfc_default_keys.lua" + ) + +#"make package" will trigger this +SET(CPACK_GENERATOR "DEB") +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Iceman") +INCLUDE(CPack) diff --git a/client/experimental_client_with_swig/testembedded.lua b/client/experimental_client_with_swig/testembedded.lua new file mode 100755 index 000000000..469bfff7a --- /dev/null +++ b/client/experimental_client_with_swig/testembedded.lua @@ -0,0 +1,4 @@ +local pm3 = require("pm3") +p=pm3.pm3() +p:console("hw status") +print(p.name) diff --git a/client/experimental_client_with_swig/testembedded.py b/client/experimental_client_with_swig/testembedded.py new file mode 100755 index 000000000..12ae8b741 --- /dev/null +++ b/client/experimental_client_with_swig/testembedded.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import pm3 +p=pm3.pm3() +p.console("hw status") +print("Device:", p.name) diff --git a/client/experimental_lib/.gitignore b/client/experimental_lib/.gitignore new file mode 100644 index 000000000..567609b12 --- /dev/null +++ b/client/experimental_lib/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/client/experimental_lib/00make_swig.sh b/client/experimental_lib/00make_swig.sh new file mode 100755 index 000000000..6c752d024 --- /dev/null +++ b/client/experimental_lib/00make_swig.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i +swig -python -o ../src/pm3_pywrap.c ../src/pm3.i diff --git a/client/experimental_lib/01make_lib_continue.sh b/client/experimental_lib/01make_lib_continue.sh new file mode 100755 index 000000000..7869bdefa --- /dev/null +++ b/client/experimental_lib/01make_lib_continue.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +( + cd build + make -j +) + diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt new file mode 100644 index 000000000..505d1ea1b --- /dev/null +++ b/client/experimental_lib/CMakeLists.txt @@ -0,0 +1,557 @@ +# Usage: +# mkdir build +# cd build +# cmake .. (see below for options) +# make (VERBOSE=1 if needed) +# +# MINGW: +# On ProxSpace 3.4: +# cmake -G"MSYS Makefiles" .. +# On Proxspace 3.3 or less, you need to install cmake: +# pacman -S mingw-w64-x86_64-cmake +# /mingw64/bin/cmake -G"MSYS Makefiles" .. +# +# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version) +# cmake \ +# -DCMAKE_TOOLCHAIN_FILE=/build/cmake/android.toolchain.cmake \ +# -DANDROID_ABI=armeabi-v7a \ +# -DANDROID_NATIVE_API_LEVEL=android-19 \ +# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 .. + +message(STATUS "CMake ${CMAKE_VERSION}") +cmake_minimum_required(VERSION 3.10) +project(proxmark3) +SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +if(CMAKE_VERSION VERSION_LESS "3.7.0") + set(CMAKE_INCLUDE_CURRENT_DIR ON) +endif() + +find_package(PkgConfig) + +if (NOT SKIPQT EQUAL 1) + if(APPLE AND EXISTS /usr/local/opt/qt5) + # Homebrew installs Qt5 (up to at least 5.11.0) in + # /usr/local/qt5. Ensure that it can be found by CMake + # since it is not in the default /usr/local prefix. + # Add it to PATHS so that it doesn't override the + # CMAKE_PREFIX_PATH environment variable. + # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, + # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) + list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) + endif(APPLE AND EXISTS /usr/local/opt/qt5) + set(QT_PACKAGELIST + Qt5Core + Qt5Widgets + Qt5Gui + ) + set(Qt5_FOUND ON) + foreach(_qt_package IN LISTS QT_PACKAGELIST) + find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) + set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES}) + if(NOT ${_qt_package}_FOUND) + set(Qt5_FOUND OFF) + endif(NOT ${_qt_package}_FOUND) + endforeach() +endif (NOT SKIPQT EQUAL 1) + +if (NOT SKIPBT EQUAL 1) + pkg_search_module(BLUEZ QUIET bluez) +endif (NOT SKIPBT EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + pkg_search_module(PYTHON3 QUIET python3) + pkg_search_module(PYTHON3EMBED QUIET python3-embed) +endif (NOT SKIPPYTHON EQUAL 1) + +# If cross-compiled, we need to init source and build. +if (CMAKE_TOOLCHAIN_FILE) + set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w") + set(EMBED_READLINE ON) + set(EMBED_BZIP2 ON) +endif (CMAKE_TOOLCHAIN_FILE) + +if (EMBED_READLINE OR EMBED_BZIP2) + include(ExternalProject) +endif (EMBED_READLINE OR EMBED_BZIP2) + +if (NOT SKIPREADLINE EQUAL 1) + if (APPLE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) + find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) + endif (APPLE) + if (EMBED_READLINE) + ExternalProject_Add(ncurses + URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz + PREFIX deps/ncurses + DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses + CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib + BUILD_IN_SOURCE ON + BUILD_COMMAND make libs + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(ncurses configure build install) + + ExternalProject_Add(readline + URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz + PREFIX deps/readline + DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline + CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static + BUILD_IN_SOURCE ON + BUILD_COMMAND make + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(readline configure build install) + set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/) + set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a) + else (EMBED_READLINE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h) + find_library(READLINE_LIBRARIES readline) + endif (EMBED_READLINE) + if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) + set(READLINE_FOUND ON) + endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) +endif (NOT SKIPREADLINE EQUAL 1) + +if (NOT SKIPJANSSONSYSTEM EQUAL 1) + pkg_check_modules(PC_JANSSON QUIET jansson) + find_path(JANSSON_INCLUDE_DIRS + NAMES jansson.h + HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS}) + find_library(JANSSON_LIBRARIES + NAMES jansson libjansson + HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS}) + if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) + set(JANSSON_FOUND ON) + endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) +endif (NOT SKIPJANSSONSYSTEM EQUAL 1) + +if(EMBED_BZIP2) + set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) + ExternalProject_Add(bzip2 + GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2 + GIT_TAG platform-tools-30.0.2 + PREFIX deps/bzip2 + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 + CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x + BUILD_IN_SOURCE ON + BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Add_StepTargets(bzip2 configure build install) + set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) + set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a) + set(BZIP2_FOUND ON) +else(EMBED_BZIP2) + find_package (BZip2 REQUIRED) +endif(EMBED_BZIP2) + +if (NOT SKIPWHEREAMISYSTEM EQUAL 1) + find_path(WHEREAMI_INCLUDE_DIRS whereami.h) + find_library(WHEREAMI_LIBRARIES whereami) + if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) + set(WHEREAMI_FOUND ON) + endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) +endif (NOT SKIPWHEREAMISYSTEM EQUAL 1) + +add_subdirectory(${PM3_ROOT}/client/deps deps) + +set (TARGET_SOURCES + ${PM3_ROOT}/common/commonutil.c + ${PM3_ROOT}/common/util_posix.c + ${PM3_ROOT}/common/parity.c + ${PM3_ROOT}/common/bucketsort.c + ${PM3_ROOT}/common/crapto1/crapto1.c + ${PM3_ROOT}/common/crapto1/crypto1.c + ${PM3_ROOT}/common/crc.c + ${PM3_ROOT}/common/crc16.c + ${PM3_ROOT}/common/crc32.c + ${PM3_ROOT}/common/crc64.c + ${PM3_ROOT}/common/lfdemod.c + ${PM3_ROOT}/common/legic_prng.c + ${PM3_ROOT}/common/iso15693tools.c + ${PM3_ROOT}/common/cardhelper.c + ${PM3_ROOT}/common/generator.c + ${PM3_ROOT}/client/src/crypto/asn1dump.c + ${PM3_ROOT}/client/src/crypto/asn1utils.c + ${PM3_ROOT}/client/src/crypto/libpcrypto.c + ${PM3_ROOT}/client/src/emv/test/cda_test.c + ${PM3_ROOT}/client/src/emv/test/crypto_test.c + ${PM3_ROOT}/client/src/emv/test/cryptotest.c + ${PM3_ROOT}/client/src/emv/test/dda_test.c + ${PM3_ROOT}/client/src/emv/test/sda_test.c + ${PM3_ROOT}/client/src/emv/apduinfo.c + ${PM3_ROOT}/client/src/emv/cmdemv.c + ${PM3_ROOT}/client/src/emv/crypto.c + ${PM3_ROOT}/client/src/emv/crypto_polarssl.c + ${PM3_ROOT}/client/src/emv/dol.c + ${PM3_ROOT}/client/src/emv/dump.c + ${PM3_ROOT}/client/src/emv/emv_pk.c + ${PM3_ROOT}/client/src/emv/emv_pki.c + ${PM3_ROOT}/client/src/emv/emv_pki_priv.c + ${PM3_ROOT}/client/src/emv/emv_roca.c + ${PM3_ROOT}/client/src/emv/emv_tags.c + ${PM3_ROOT}/client/src/emv/emvcore.c + ${PM3_ROOT}/client/src/emv/emvjson.c + ${PM3_ROOT}/client/src/emv/tlv.c + ${PM3_ROOT}/client/src/fido/additional_ca.c + ${PM3_ROOT}/client/src/fido/cbortools.c + ${PM3_ROOT}/client/src/fido/cose.c + ${PM3_ROOT}/client/src/fido/fidocore.c + ${PM3_ROOT}/client/src/loclass/cipher.c + ${PM3_ROOT}/client/src/loclass/cipherutils.c + ${PM3_ROOT}/client/src/loclass/elite_crack.c + ${PM3_ROOT}/client/src/loclass/hash1_brute.c + ${PM3_ROOT}/client/src/loclass/ikeys.c + ${PM3_ROOT}/client/src/mifare/mad.c + ${PM3_ROOT}/client/src/mifare/mfkey.c + ${PM3_ROOT}/client/src/mifare/mifare4.c + ${PM3_ROOT}/client/src/mifare/mifaredefault.c + ${PM3_ROOT}/client/src/mifare/mifarehost.c + ${PM3_ROOT}/client/src/mifare/ndef.c + ${PM3_ROOT}/client/src/mifare/desfire_crypto.c + ${PM3_ROOT}/client/src/uart/uart_posix.c + ${PM3_ROOT}/client/src/uart/uart_win32.c + ${PM3_ROOT}/client/src/ui/overlays.ui + ${PM3_ROOT}/client/src/aiddesfire.c + ${PM3_ROOT}/client/src/aidsearch.c + ${PM3_ROOT}/client/src/cmdanalyse.c + ${PM3_ROOT}/client/src/cmdcrc.c + ${PM3_ROOT}/client/src/cmddata.c + ${PM3_ROOT}/client/src/cmdflashmem.c + ${PM3_ROOT}/client/src/cmdflashmemspiffs.c + ${PM3_ROOT}/client/src/cmdhf.c + ${PM3_ROOT}/client/src/cmdhf14a.c + ${PM3_ROOT}/client/src/cmdhf14b.c + ${PM3_ROOT}/client/src/cmdhf15.c + ${PM3_ROOT}/client/src/cmdhfcryptorf.c + ${PM3_ROOT}/client/src/cmdhfepa.c + ${PM3_ROOT}/client/src/cmdhffelica.c + ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhficlass.c + ${PM3_ROOT}/client/src/cmdhflegic.c + ${PM3_ROOT}/client/src/cmdhflist.c + ${PM3_ROOT}/client/src/cmdhflto.c + ${PM3_ROOT}/client/src/cmdhfmf.c + ${PM3_ROOT}/client/src/cmdhfmfdes.c + ${PM3_ROOT}/client/src/cmdhfmfhard.c + ${PM3_ROOT}/client/src/cmdhfmfp.c + ${PM3_ROOT}/client/src/cmdhfmfu.c + ${PM3_ROOT}/client/src/cmdhfst.c + ${PM3_ROOT}/client/src/cmdhfthinfilm.c + ${PM3_ROOT}/client/src/cmdhftopaz.c + ${PM3_ROOT}/client/src/cmdhfwaveshare.c + ${PM3_ROOT}/client/src/cmdhw.c + ${PM3_ROOT}/client/src/cmdlf.c + ${PM3_ROOT}/client/src/cmdlfawid.c + ${PM3_ROOT}/client/src/cmdlfcotag.c + ${PM3_ROOT}/client/src/cmdlfdestron.c + ${PM3_ROOT}/client/src/cmdlfem4x.c + ${PM3_ROOT}/client/src/cmdlfem4x05.c + ${PM3_ROOT}/client/src/cmdlfem4x50.c + ${PM3_ROOT}/client/src/cmdlffdxb.c + ${PM3_ROOT}/client/src/cmdlfgallagher.c + ${PM3_ROOT}/client/src/cmdlfguard.c + ${PM3_ROOT}/client/src/cmdlfhid.c + ${PM3_ROOT}/client/src/cmdlfhitag.c + ${PM3_ROOT}/client/src/cmdlfidteck.c + ${PM3_ROOT}/client/src/cmdlfindala.c + ${PM3_ROOT}/client/src/cmdlfio.c + ${PM3_ROOT}/client/src/cmdlfjablotron.c + ${PM3_ROOT}/client/src/cmdlfkeri.c + ${PM3_ROOT}/client/src/cmdlfmotorola.c + ${PM3_ROOT}/client/src/cmdlfnedap.c + ${PM3_ROOT}/client/src/cmdlfnexwatch.c + ${PM3_ROOT}/client/src/cmdlfnoralsy.c + ${PM3_ROOT}/client/src/cmdlfpac.c + ${PM3_ROOT}/client/src/cmdlfparadox.c + ${PM3_ROOT}/client/src/cmdlfpcf7931.c + ${PM3_ROOT}/client/src/cmdlfpresco.c + ${PM3_ROOT}/client/src/cmdlfpyramid.c + ${PM3_ROOT}/client/src/cmdlfsecurakey.c + ${PM3_ROOT}/client/src/cmdlft55xx.c + ${PM3_ROOT}/client/src/cmdlfti.c + ${PM3_ROOT}/client/src/cmdlfviking.c + ${PM3_ROOT}/client/src/cmdlfvisa2000.c + ${PM3_ROOT}/client/src/cmdmain.c + ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdscript.c + ${PM3_ROOT}/client/src/cmdsmartcard.c + ${PM3_ROOT}/client/src/cmdtrace.c + ${PM3_ROOT}/client/src/cmdusart.c + ${PM3_ROOT}/client/src/cmdwiegand.c + ${PM3_ROOT}/client/src/comms.c + ${PM3_ROOT}/client/src/fileutils.c + ${PM3_ROOT}/client/src/flash.c + ${PM3_ROOT}/client/src/graph.c + ${PM3_ROOT}/client/src/jansson_path.c + ${PM3_ROOT}/client/src/preferences.c + ${PM3_ROOT}/client/src/pm3.c + ${PM3_ROOT}/client/src/pm3_binlib.c + ${PM3_ROOT}/client/src/pm3_bitlib.c + ${PM3_ROOT}/client/src/prng.c + ${PM3_ROOT}/client/src/scandir.c + ${PM3_ROOT}/client/src/scripting.c + ${PM3_ROOT}/client/src/tea.c + ${PM3_ROOT}/client/src/ui.c + ${PM3_ROOT}/client/src/util.c + ${PM3_ROOT}/client/src/wiegand_formats.c + ${PM3_ROOT}/client/src/wiegand_formatutils.c + ${CMAKE_BINARY_DIR}/version.c + ) + +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/version.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c + DEPENDS ${PM3_ROOT}/common/default_version.c +) + +set(ADDITIONAL_SRC "") +set(ADDITIONAL_LNK "") +set(ADDITIONAL_DIRS "") +set(ADDITIONAL_LNKDIRS "") +set(X86_CPUS x86 x86_64 i686) + +message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") + +if (APPLE) + message(STATUS "Apple device detected.") + set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") +endif (APPLE) + +if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTORCC ON) + set(CMAKE_AUTOUIC ON) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/proxgui.cpp + ${PM3_ROOT}/client/src/proxguiqt.cpp + ${TARGET_SOURCES}) + + add_definitions("-DHAVE_GUI") + set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK}) +else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + set(TARGET_SOURCES + ${PM3_ROOT}/client/src/guidummy.cpp + ${TARGET_SOURCES}) +endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) + +if (NOT SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + add_definitions("-DHAVE_BLUEZ") + set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK}) + endif (BLUEZ_FOUND) +endif(NOT SKIPBT EQUAL 1) + +if (JANSSON_FOUND) + set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK}) +endif (JANSSON_FOUND) + +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + elseif (PYTHON3_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + endif (PYTHON3EMBED_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +if (NOT SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + add_definitions("-DHAVE_READLINE") + set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK}) + endif (READLINE_FOUND) +endif(NOT SKIPREADLINE EQUAL 1) + +if (BZIP2_FOUND) + set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK}) +endif (BZIP2_FOUND) + +if (WHEREAMI_FOUND) + set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK}) +endif (WHEREAMI_FOUND) + +message(STATUS "===================================================================") +if (SKIPQT EQUAL 1) + message(STATUS "GUI support: skipped") +else (SKIPQT EQUAL 1) + if (Qt5_FOUND) + message(STATUS "GUI support: QT5 found, enabled") + else (Qt5_FOUND) + message(STATUS "GUI support: QT5 not found, disabled") + endif (Qt5_FOUND) +endif (SKIPQT EQUAL 1) + +if (SKIPBT EQUAL 1) + message(STATUS "native BT support: skipped") +else (SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + message(STATUS "native BT support: Bluez found, enabled") + else (BLUEZ_FOUND) + message(STATUS "native BT support: Bluez not found, disabled") + endif (BLUEZ_FOUND) +endif(SKIPBT EQUAL 1) + +if (EMBED_BZIP2) + message(STATUS "Bzip2 library: embedded") +else (EMBED_BZIP2) + message(STATUS "Bzip2 library: system library found") +endif (EMBED_BZIP2) + +if (SKIPJANSSONSYSTEM EQUAL 1) + message(STATUS "Jansson library: local library forced") +else (SKIPJANSSONSYSTEM EQUAL 1) + if (JANSSON_FOUND) + message(STATUS "Jansson library: system library found") + else (JANSSON_FOUND) + message(STATUS "Jansson library: system library not found, using local library") + endif (JANSSON_FOUND) +endif (SKIPJANSSONSYSTEM EQUAL 1) + +if (SKIPPYTHON EQUAL 1) + message(STATUS "Python3 library: skipped") +else (SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + message(STATUS "Python3 library: Python3 embed found, enabled") + elseif (PYTHON_FOUND) + message(STATUS "Python3 library: Python3 found, enabled") + else (PYTHON3EMBED_FOUND) + message(STATUS "Python3 library: Python3 not found, disabled") + endif (PYTHON3EMBED_FOUND) +endif(SKIPPYTHON EQUAL 1) + +if (SKIPREADLINE EQUAL 1) + message(STATUS "Readline library: skipped") +else (SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + if (EMBED_READLINE) + message(STATUS "Readline library: embedded") + else (EMBED_READLINE) + message(STATUS "Readline library: system library found") + endif (EMBED_READLINE) + else (READLINE_FOUND) + message(STATUS "Readline library: Readline not found, disabled") + endif (READLINE_FOUND) +endif(SKIPREADLINE EQUAL 1) + +if (SKIPWHEREAMISYSTEM EQUAL 1) + message(STATUS "Whereami library: local library forced") +else (SKIPWHEREAMISYSTEM EQUAL 1) + if (WHEREAMI_FOUND) + message(STATUS "Whereami library: system library found") + else (WHEREAMI_FOUND) + message(STATUS "Whereami library: system library not found, using local library") + endif (WHEREAMI_FOUND) +endif (SKIPWHEREAMISYSTEM EQUAL 1) +message(STATUS "===================================================================") + +# Lua SWIG +if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_luawrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_LUA_SWIG) + message("Lua SWIG wrapper found") +endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + +# Python SWIG +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_pywrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_PYTHON_SWIG) + message("Python SWIG wrapper found") + endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +add_library(pm3rrg_rdv4 SHARED + ${PM3_ROOT}/client/src/proxmark3.c + ${TARGET_SOURCES} + ${ADDITIONAL_SRC} +) + +target_compile_definitions(pm3rrg_rdv4 PRIVATE LIBPM3) + +target_compile_options(pm3rrg_rdv4 PUBLIC -Wall -Werror -O3) +if (EMBED_READLINE) + if (NOT SKIPREADLINE EQUAL 1) + add_dependencies(pm3rrg_rdv4 ncurses readline) + endif (NOT SKIPREADLINE EQUAL 1) +endif (EMBED_READLINE) +if (EMBED_BZIP2) + add_dependencies(pm3rrg_rdv4 bzip2) +endif (EMBED_BZIP2) + +if (MINGW) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + # FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32 + # but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html + target_compile_definitions(pm3rrg_rdv4 PRIVATE _ISOC99_SOURCE) + + set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") +endif (MINGW) + +target_include_directories(pm3rrg_rdv4 PRIVATE + ${PM3_ROOT}/common + ${PM3_ROOT}/common_fpga + ${PM3_ROOT}/include + ${PM3_ROOT}/client/src + ${PM3_ROOT}/client/include + ${ADDITIONAL_DIRS} +) + +if (NOT APPLE) + # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. + set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) +endif (NOT APPLE) + +if (NOT JANSSON_FOUND) + set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK}) +endif (NOT JANSSON_FOUND) +if (NOT WHEREAMI_FOUND) + set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK}) +endif (NOT WHEREAMI_FOUND) + +target_link_libraries(pm3rrg_rdv4 PRIVATE + m + pm3rrg_rdv4_mbedtls + pm3rrg_rdv4_cliparser + pm3rrg_rdv4_lua + pm3rrg_rdv4_tinycbor + pm3rrg_rdv4_amiibo + pm3rrg_rdv4_reveng + pm3rrg_rdv4_hardnested + ${ADDITIONAL_LNK}) + +if (NOT SKIPPTHREAD EQUAL 1) + target_link_libraries(pm3rrg_rdv4 PRIVATE pthread) +endif (NOT SKIPPTHREAD EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + # OSX have a hard time compiling python3 dependency with older cmake. + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (NOT CMAKE_VERSION VERSION_LESS 3.13) + target_link_directories(pm3rrg_rdv4 PRIVATE ${ADDITIONAL_LNKDIRS}) + elseif (APPLE) + message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" ) + endif (NOT CMAKE_VERSION VERSION_LESS 3.13) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) diff --git a/client/experimental_lib/example_c/01make_test.sh b/client/experimental_lib/example_c/01make_test.sh new file mode 100755 index 000000000..1ce6357ff --- /dev/null +++ b/client/experimental_lib/example_c/01make_test.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +gcc -o test test.c -I../../include -lpm3rrg_rdv4 -L../build -lpthread diff --git a/client/experimental_lib/example_c/02run_test.sh b/client/experimental_lib/example_c/02run_test.sh new file mode 100755 index 000000000..a3e4ec057 --- /dev/null +++ b/client/experimental_lib/example_c/02run_test.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +LD_LIBRARY_PATH=../build ./test diff --git a/client/experimental_lib/example_c/test.c b/client/experimental_lib/example_c/test.c new file mode 100644 index 000000000..a3cf212dc --- /dev/null +++ b/client/experimental_lib/example_c/test.c @@ -0,0 +1,8 @@ +#include "pm3.h" + +int main(int argc, char *argv[]) { + pm3 *p; + p = pm3_open("/dev/ttyACM0"); + pm3_console(p, "hw status"); + pm3_close(p); +} diff --git a/client/experimental_lib/example_lua/01link_lib.sh b/client/experimental_lib/example_lua/01link_lib.sh new file mode 100755 index 000000000..5f9fb5f68 --- /dev/null +++ b/client/experimental_lib/example_lua/01link_lib.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +ln -fs ../build/libpm3rrg_rdv4.so pm3.so diff --git a/client/experimental_lib/example_lua/02run_test.sh b/client/experimental_lib/example_lua/02run_test.sh new file mode 100755 index 000000000..32fb1ae55 --- /dev/null +++ b/client/experimental_lib/example_lua/02run_test.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# pm3.so somewhere in default LUA_CPATH : +# /usr/local/lib/lua/5.2/pm3.so +# /usr/lib/lua/5.2/pm3.so +# ./pm3.so + +./test.lua diff --git a/client/experimental_lib/example_lua/test.lua b/client/experimental_lib/example_lua/test.lua new file mode 100755 index 000000000..be12f1d5b --- /dev/null +++ b/client/experimental_lib/example_lua/test.lua @@ -0,0 +1,6 @@ +#!/usr/bin/env lua + +local pm3 = require("pm3") +p=pm3.pm3("/dev/ttyACM0") +p:console("hw status") +print(p.name) diff --git a/client/experimental_lib/example_py/01link_lib.sh b/client/experimental_lib/example_py/01link_lib.sh new file mode 100755 index 000000000..8cd153d41 --- /dev/null +++ b/client/experimental_lib/example_py/01link_lib.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +ln -fs ../build/libpm3rrg_rdv4.so _pm3.so diff --git a/client/experimental_lib/example_py/02run_test.sh b/client/experimental_lib/example_py/02run_test.sh new file mode 100755 index 000000000..67ab20525 --- /dev/null +++ b/client/experimental_lib/example_py/02run_test.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +#/usr/local/lib/python3/dist-packages/_pm3.cpython-38.so +#/usr/local/lib/python3/dist-packages/_pm3.abi3.so +#/usr/local/lib/python3/dist-packages/pm3.py +#/usr/lib/python3/dist-packages/_pm3.cpython-38.so +#/usr/lib/python3/dist-packages/_pm3.abi3.so +#/usr/lib/python3/dist-packages/pm3.py + +# need access to pm3.py +PYTHONPATH=../../src ./test.py diff --git a/client/experimental_lib/example_py/02run_test_interactive.sh b/client/experimental_lib/example_py/02run_test_interactive.sh new file mode 100755 index 000000000..701dbb5cf --- /dev/null +++ b/client/experimental_lib/example_py/02run_test_interactive.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +PYTHONPATH=../../src ipython3 -i ./test.py diff --git a/client/experimental_lib/example_py/test.py b/client/experimental_lib/example_py/test.py new file mode 100755 index 000000000..39cee5301 --- /dev/null +++ b/client/experimental_lib/example_py/test.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import pm3 +p=pm3.pm3("/dev/ttyACM0") +p.console("hw status") +print("Device:", p.name) diff --git a/client/include/pm3.h b/client/include/pm3.h new file mode 100644 index 000000000..cfdb69944 --- /dev/null +++ b/client/include/pm3.h @@ -0,0 +1,11 @@ +#ifndef LIBPM3_H +#define LIBPM3_H + +typedef struct pm3_device pm3; + +pm3 *pm3_open(char *port); +int pm3_console(pm3* dev, char *cmd); +const char *pm3_name_get(pm3* dev); +void pm3_close(pm3* dev); +pm3 *pm3_get_current_dev(void); +#endif // LIBPM3_H diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 2743df820..3f2b3407a 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -666,15 +666,15 @@ static int CmdConnect(const char *Cmd) { } if (session.pm3_present) { - CloseProxmark(); + CloseProxmark(session.current_device); } // 10 second timeout - OpenProxmark(port, false, 10, false, baudrate); + OpenProxmark(&session.current_device, port, false, 10, false, baudrate); - if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) { + if (session.pm3_present && (TestProxmark(session.current_device) != PM3_SUCCESS)) { PrintAndLogEx(ERR, _RED_("ERROR:") " cannot communicate with the Proxmark3\n"); - CloseProxmark(); + CloseProxmark(session.current_device); return PM3_ENOTTY; } return PM3_SUCCESS; diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 40c4f3aa6..b66516296 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -9,7 +9,6 @@ //----------------------------------------------------------------------------- // 2020, added Python support (@iceman1001) - #include #include @@ -32,7 +31,15 @@ #include "ui.h" #include "fileutils.h" +#ifdef HAVE_LUA_SWIG +extern int luaopen_pm3(lua_State* L); +#endif + #ifdef HAVE_PYTHON +#ifdef HAVE_PYTHON_SWIG +extern PyObject* PyInit__pm3(void); +#endif // HAVE_PYTHON_SWIG + // Partly ripped from PyRun_SimpleFileExFlags // but does not terminate client on sys.exit // and print exit code only if != 0 @@ -274,7 +281,9 @@ static int CmdScriptRun(const char *Cmd) { //Add the 'bit' library set_bit_library(lua_state); - +#ifdef HAVE_LUA_SWIG + luaL_requiref(lua_state, "pm3", luaopen_pm3, 1); +#endif error = luaL_loadfile(lua_state, script_path); free(script_path); if (!error) { @@ -355,6 +364,10 @@ static int CmdScriptRun(const char *Cmd) { // optional but recommended Py_SetProgramName(program); +#ifdef HAVE_PYTHON_SWIG + // hook Proxmark3 API + PyImport_AppendInittab("_pm3", PyInit__pm3); +#endif Py_Initialize(); //int argc, char ** argv diff --git a/client/src/comms.c b/client/src/comms.c index 416225c0f..57a03afe7 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "uart/uart.h" #include "ui.h" @@ -541,7 +542,7 @@ bool IsCommunicationThreadDead(void) { return ret; } -bool OpenProxmark(char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) { +bool OpenProxmark(pm3_device **dev, char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) { if (!wait_for_port) { PrintAndLogEx(INFO, "Using UART port " _YELLOW_("%s"), port); @@ -588,15 +589,17 @@ bool OpenProxmark(char *port, bool wait_for_port, int timeout, bool flash_mode, pthread_create(&communication_thread, NULL, &uart_communication, &conn); __atomic_clear(&comm_thread_dead, __ATOMIC_SEQ_CST); - session.pm3_present = true; + session.pm3_present = true; // TODO support for multiple devices fflush(stdout); + *dev = malloc(sizeof(pm3_device)); + (*dev)->conn = &conn; // TODO conn shouldn't be global return true; } } // check if we can communicate with Pm3 -int TestProxmark(void) { +int TestProxmark(pm3_device *dev) { PacketResponseNG resp; uint16_t len = 32; @@ -659,8 +662,8 @@ int TestProxmark(void) { return PM3_SUCCESS; } -void CloseProxmark(void) { - conn.run = false; +void CloseProxmark(pm3_device *dev) { + dev->conn->run = false; #ifdef __BIONIC__ if (communication_thread != 0) { diff --git a/client/src/comms.h b/client/src/comms.h index 9fcf1b7a6..3ee691a30 100644 --- a/client/src/comms.h +++ b/client/src/comms.h @@ -65,6 +65,12 @@ typedef struct { extern communication_arg_t conn; +typedef struct pm3_device pm3_device; +struct pm3_device { + communication_arg_t *conn; + int script_embedded; +}; + void *uart_receiver(void *targ); void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); @@ -74,9 +80,10 @@ void clearCommandBuffer(void); #define FLASHMODE_SPEED 460800 bool IsCommunicationThreadDead(void); -bool OpenProxmark(char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed); -int TestProxmark(void); -void CloseProxmark(void); +typedef struct pm3_device pm3_device; +bool OpenProxmark(pm3_device **dev, char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed); +int TestProxmark(pm3_device *dev); +void CloseProxmark(pm3_device *dev); bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout, bool show_warning); bool WaitForResponseTimeout(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout); diff --git a/client/src/flash.c b/client/src/flash.c index 95fc4b7aa..1541b8d17 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -373,11 +373,11 @@ static int enter_bootloader(char *serial_port_name) { PrintAndLogEx(SUCCESS, "Press and hold down button NOW if your bootloader requires it."); } msleep(100); - CloseProxmark(); + CloseProxmark(session.current_device); // Let time to OS to make the port disappear msleep(1000); - if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { + if (OpenProxmark(&session.current_device, serial_port_name, true, 60, true, FLASHMODE_SPEED)) { PrintAndLogEx(NORMAL, _GREEN_(" found")); return PM3_SUCCESS; } else { diff --git a/client/src/pm3.c b/client/src/pm3.c new file mode 100644 index 000000000..14f0b00ad --- /dev/null +++ b/client/src/pm3.c @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// User API +//----------------------------------------------------------------------------- + +#include "pm3.h" + +#include + +#include "proxmark3.h" +#include "cmdmain.h" +#include "ui.h" +#include "usart_defs.h" +#include "util_posix.h" +#include "comms.h" + +pm3_device* pm3_open(char *port) { + pm3_init(); + OpenProxmark(&session.current_device, port, false, 20, false, USART_BAUD_RATE); + if (session.pm3_present && (TestProxmark(session.current_device) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, _RED_("ERROR:") " cannot communicate with the Proxmark\n"); + CloseProxmark(session.current_device); + } + + if ((port != NULL) && (!session.pm3_present)) + exit(EXIT_FAILURE); + + if (!session.pm3_present) + PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") " mode"); + // For now, there is no real device context: + return session.current_device; +} + +void pm3_close(pm3_device* dev) { + // Clean up the port + if (session.pm3_present) { + clearCommandBuffer(); + SendCommandNG(CMD_QUIT_SESSION, NULL, 0); + msleep(100); // Make sure command is sent before killing client + CloseProxmark(dev); + } +} + +int pm3_console(pm3_device* dev, char *Cmd) { + // For now, there is no real device context: + (void) dev; + return CommandReceived(Cmd); +} + +const char *pm3_name_get(pm3_device* dev) { + return dev->conn->serial_port_name; +} + +pm3_device* pm3_get_current_dev(void) { + return session.current_device; +} diff --git a/client/src/pm3.i b/client/src/pm3.i new file mode 100644 index 000000000..5b4a1fb47 --- /dev/null +++ b/client/src/pm3.i @@ -0,0 +1,39 @@ +%module pm3 +%{ +/* Include the header in the wrapper code */ +#include "pm3.h" +#include "comms.h" +%} + +/* Strip "pm3_" from API functions for SWIG */ +%rename("%(strip:[pm3_])s") ""; +%feature("immutable","1") pm3_current_dev; +typedef struct { + %extend { + pm3() { + printf("SWIG pm3 constructor, get current pm3\n"); + pm3_device * p = pm3_get_current_dev(); + p->script_embedded = 1; + return p; + } + pm3(char *port) { + printf("SWIG pm3 constructor with port, open pm3\n"); + pm3_device * p = pm3_open(port); + p->script_embedded = 0; + return p; + } + ~pm3() { + if ($self->script_embedded) { + printf("SWIG pm3 destructor, nothing to do\n"); + } else { + printf("SWIG pm3 destructor, close pm3\n"); + pm3_close($self); + } + } + int console(char *cmd); + char const * const name; + } +} pm3; +//%nodefaultctor device; +//%nodefaultdtor device; +/* Parse the header file to generate wrappers */ diff --git a/client/src/pm3.py b/client/src/pm3.py new file mode 100644 index 000000000..1c321a2ec --- /dev/null +++ b/client/src/pm3.py @@ -0,0 +1,80 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 4.0.1 +# +# Do not make changes to this file unless you know what you are doing--modify +# the SWIG interface file instead. + +from sys import version_info as _swig_python_version_info +if _swig_python_version_info < (2, 7, 0): + raise RuntimeError("Python 2.7 or later required") + +# Import the low-level C/C++ module +if __package__ or "." in __name__: + from . import _pm3 +else: + import _pm3 + +try: + import builtins as __builtin__ +except ImportError: + import __builtin__ + +def _swig_repr(self): + try: + strthis = "proxy of " + self.this.__repr__() + except __builtin__.Exception: + strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + + +def _swig_setattr_nondynamic_instance_variable(set): + def set_instance_attr(self, name, value): + if name == "thisown": + self.this.own(value) + elif name == "this": + set(self, name, value) + elif hasattr(self, name) and isinstance(getattr(type(self), name), property): + set(self, name, value) + else: + raise AttributeError("You cannot add instance attributes to %s" % self) + return set_instance_attr + + +def _swig_setattr_nondynamic_class_variable(set): + def set_class_attr(cls, name, value): + if hasattr(cls, name) and not isinstance(getattr(cls, name), property): + set(cls, name, value) + else: + raise AttributeError("You cannot add class attributes to %s" % cls) + return set_class_attr + + +def _swig_add_metaclass(metaclass): + """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass""" + def wrapper(cls): + return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy()) + return wrapper + + +class _SwigNonDynamicMeta(type): + """Meta class to enforce nondynamic attributes (no new attributes) for a class""" + __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__) + + +class pm3(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def __init__(self, *args): + _pm3.pm3_swiginit(self, _pm3.new_pm3(*args)) + __swig_destroy__ = _pm3.delete_pm3 + + def console(self, cmd): + return _pm3.pm3_console(self, cmd) + name = property(_pm3.pm3_name_get) + +# Register pm3 in _pm3: +_pm3.pm3_swigregister(pm3) + + + diff --git a/client/src/pm3_luawrap.c b/client/src/pm3_luawrap.c new file mode 100644 index 000000000..2dc4a8dc0 --- /dev/null +++ b/client/src/pm3_luawrap.c @@ -0,0 +1,3259 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + + +#ifndef SWIGLUA +#define SWIGLUA +#endif + +#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_LUA +#define SWIG_LUA_MODULE_GLOBAL + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic C API SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. + + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 +#define SWIG_POINTER_NO_NULL 0x4 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The SWIG conversion methods, as ConvertPtr, return an integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old versions of SWIG, code such as the following was usually written: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + which is the same really, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + also requires SWIG_ConvertPtr to return new result values, such as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + SWIG errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() +*/ + +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast(r) (r) +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCmp(const char *nb, const char *tb) { + int equiv = 1; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (equiv != 0 && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = SWIG_TypeNameComp(nb, ne, tb, te); + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0; +} + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + size_t l = 0; + size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + const unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + char d = *(c++); + unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = (unsigned char)((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = (unsigned char)((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (unsigned char)(d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (unsigned char)(d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + +/* ----------------------------------------------------------------------------- + * luarun.swg + * + * This file contains the runtime support for Lua modules + * and includes code for managing global variables and pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lua.h" +#include "lauxlib.h" +#include /* for malloc */ +#include /* for a few sanity tests */ + +/* ----------------------------------------------------------------------------- + * Lua flavors + * ----------------------------------------------------------------------------- */ + +#define SWIG_LUA_FLAVOR_LUA 1 +#define SWIG_LUA_FLAVOR_ELUA 2 +#define SWIG_LUA_FLAVOR_ELUAC 3 + +#if !defined(SWIG_LUA_TARGET) +# error SWIG_LUA_TARGET not defined +#endif + +#if defined(SWIG_LUA_ELUA_EMULATE) + +struct swig_elua_entry; + +typedef struct swig_elua_key { + int type; + union { + const char* strkey; + lua_Number numkey; + } key; +} swig_elua_key; + +typedef struct swig_elua_val { + int type; + union { + lua_Number number; + const struct swig_elua_entry *table; + const char *string; + lua_CFunction function; + struct { + char member; + long lvalue; + void *pvalue; + swig_type_info **ptype; + } userdata; + } value; +} swig_elua_val; + +typedef struct swig_elua_entry { + swig_elua_key key; + swig_elua_val value; +} swig_elua_entry; + +#define LSTRKEY(x) {LUA_TSTRING, {.strkey = x} } +#define LNUMKEY(x) {LUA_TNUMBER, {.numkey = x} } +#define LNILKEY {LUA_TNIL, {.strkey = 0} } + +#define LNUMVAL(x) {LUA_TNUMBER, {.number = x} } +#define LFUNCVAL(x) {LUA_TFUNCTION, {.function = x} } +#define LROVAL(x) {LUA_TTABLE, {.table = x} } +#define LNILVAL {LUA_TNIL, {.string = 0} } +#define LSTRVAL(x) {LUA_TSTRING, {.string = x} } + +#define LUA_REG_TYPE swig_elua_entry + +#define SWIG_LUA_ELUA_EMUL_METATABLE_KEY "__metatable" + +#define lua_pushrotable(L,p)\ + lua_newtable(L);\ + assert(p);\ + SWIG_Lua_elua_emulate_register(L,(swig_elua_entry*)(p)); + +#define SWIG_LUA_CONSTTAB_POINTER(B,C,D)\ + LSTRKEY(B), {LUA_TUSERDATA, { .userdata={0,0,(void*)(C),&D} } } + +#define SWIG_LUA_CONSTTAB_BINARY(B,S,C,D)\ + LSTRKEY(B), {LUA_TUSERDATA, { .userdata={1,S,(void*)(C),&D} } } +#endif + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +# define SWIG_LUA_CONSTTAB_INT(B, C) LSTRKEY(B), LNUMVAL(C) +# define SWIG_LUA_CONSTTAB_FLOAT(B, C) LSTRKEY(B), LNUMVAL(C) +# define SWIG_LUA_CONSTTAB_STRING(B, C) LSTRKEY(B), LSTRVAL(C) +# define SWIG_LUA_CONSTTAB_CHAR(B, C) LSTRKEY(B), LNUMVAL(C) + /* Those two types of constants are not supported in elua */ + +#ifndef SWIG_LUA_CONSTTAB_POINTER +#warning eLua does not support pointers as constants. By default, nil will be used as value +#define SWIG_LUA_CONSTTAB_POINTER(B,C,D) LSTRKEY(B), LNILVAL +#endif + +#ifndef SWIG_LUA_CONSTTAB_BINARY +#warning eLua does not support pointers to member as constants. By default, nil will be used as value +#define SWIG_LUA_CONSTTAB_BINARY(B, S, C, D) LSTRKEY(B), LNILVAL +#endif +#else /* SWIG_LUA_FLAVOR_LUA */ +# define SWIG_LUA_CONSTTAB_INT(B, C) SWIG_LUA_INT, (char *)B, (long)C, 0, 0, 0 +# define SWIG_LUA_CONSTTAB_FLOAT(B, C) SWIG_LUA_FLOAT, (char *)B, 0, (double)C, 0, 0 +# define SWIG_LUA_CONSTTAB_STRING(B, C) SWIG_LUA_STRING, (char *)B, 0, 0, (void *)C, 0 +# define SWIG_LUA_CONSTTAB_CHAR(B, C) SWIG_LUA_CHAR, (char *)B, (long)C, 0, 0, 0 +# define SWIG_LUA_CONSTTAB_POINTER(B,C,D)\ + SWIG_LUA_POINTER, (char *)B, 0, 0, (void *)C, &D +# define SWIG_LUA_CONSTTAB_BINARY(B, S, C, D)\ + SWIG_LUA_BINARY, (char *)B, S, 0, (void *)C, &D +#endif + +#ifndef SWIG_LUA_ELUA_EMULATE +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +# define LRO_STRVAL(v) {{.p = (char *) v}, LUA_TSTRING} +# define LSTRVAL LRO_STRVAL +#endif +#endif /* SWIG_LUA_ELUA_EMULATE*/ + +#ifndef SWIG_LUA_ELUA_EMULATE +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) + +#ifndef MIN_OPT_LEVEL +#define MIN_OPT_LEVEL 2 +#endif + +#include "lrodefs.h" +#include "lrotable.h" +#endif +#endif /* SWIG_LUA_ELUA_EMULATE*/ +/* ----------------------------------------------------------------------------- + * compatibility defines + * ----------------------------------------------------------------------------- */ + +/* History of Lua C API length functions: In Lua 5.0 (and before?) + there was "lua_strlen". In Lua 5.1, this was renamed "lua_objlen", + but a compatibility define of "lua_strlen" was added. In Lua 5.2, + this function was again renamed, to "lua_rawlen" (to emphasize that + it doesn't call the "__len" metamethod), and the compatibility + define of lua_strlen was removed. All SWIG uses have been updated + to "lua_rawlen", and we add our own defines of that here for older + versions of Lua. */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 +# define lua_rawlen lua_strlen +#elif LUA_VERSION_NUM == 501 +# define lua_rawlen lua_objlen +#endif + + +/* lua_pushglobaltable is the recommended "future-proof" way to get + the global table for Lua 5.2 and later. Here we define + lua_pushglobaltable ourselves for Lua versions before 5.2. */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif + +/* lua_absindex was introduced in Lua 5.2 */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 +# define lua_absindex(L,i) ((i)>0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1) +#endif + +/* lua_rawsetp was introduced in Lua 5.2 */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 +#define lua_rawsetp(L,index,ptr)\ + lua_pushlightuserdata(L,(void*)(ptr));\ + lua_insert(L,-2);\ + lua_rawset(L,index); + +#define lua_rawgetp(L,index,ptr)\ + lua_pushlightuserdata(L,(void*)(ptr));\ + lua_rawget(L,index); + +#endif + +/* -------------------------------------------------------------------------- + * Helper functions for error handling + * -------------------------------------------------------------------------- */ + +/* Push the string STR on the Lua stack, like lua_pushstring, but + prefixed with the location of the innermost Lua call-point + (as formatted by luaL_where). */ +SWIGRUNTIME void +SWIG_Lua_pusherrstring (lua_State *L, const char *str) +{ + luaL_where (L, 1); + lua_pushstring (L, str); + lua_concat (L, 2); +} + +/* Push a formatted string generated from FMT and following args on + the Lua stack, like lua_pushfstring, but prefixed with the + location of the innermost Lua call-point (as formatted by luaL_where). */ +SWIGRUNTIME void +SWIG_Lua_pushferrstring (lua_State *L, const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); +} + + +/* ----------------------------------------------------------------------------- + * global swig types + * ----------------------------------------------------------------------------- */ +/* Constant table */ +#define SWIG_LUA_INT 1 +#define SWIG_LUA_FLOAT 2 +#define SWIG_LUA_STRING 3 +#define SWIG_LUA_POINTER 4 +#define SWIG_LUA_BINARY 5 +#define SWIG_LUA_CHAR 6 + +/* Structure for variable linking table */ +typedef struct { + const char *name; + lua_CFunction get; + lua_CFunction set; +} swig_lua_var_info; + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +typedef const LUA_REG_TYPE swig_lua_method; +typedef const LUA_REG_TYPE swig_lua_const_info; +#else /* Normal lua */ +typedef luaL_Reg swig_lua_method; + +/* Constant information structure */ +typedef struct { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_lua_const_info; + +#endif + +typedef struct { + const char *name; + lua_CFunction getmethod; + lua_CFunction setmethod; +} swig_lua_attribute; + + +struct swig_lua_class; +/* Can be used to create namespaces. Currently used to wrap class static methods/variables/constants */ +typedef struct swig_lua_namespace { + const char *name; + swig_lua_method *ns_methods; + swig_lua_attribute *ns_attributes; + swig_lua_const_info *ns_constants; + struct swig_lua_class **ns_classes; + struct swig_lua_namespace **ns_namespaces; +} swig_lua_namespace; + +typedef struct swig_lua_class { + const char *name; /* Name that this class has in Lua */ + const char *fqname; /* Fully qualified name - Scope + class name */ + swig_type_info **type; + lua_CFunction constructor; + void (*destructor)(void *); + swig_lua_method *methods; + swig_lua_attribute *attributes; + swig_lua_namespace *cls_static; + swig_lua_method *metatable; /* 0 for -eluac */ + struct swig_lua_class **bases; + const char **base_names; +} swig_lua_class; + +/* this is the struct for wrapping all pointers in SwigLua +*/ +typedef struct { + swig_type_info *type; + int own; /* 1 if owned & must be destroyed */ + void *ptr; +} swig_lua_userdata; + +/* this is the struct for wrapping arbitrary packed binary data +(currently it is only used for member function pointers) +the data ordering is similar to swig_lua_userdata, but it is currently not possible +to tell the two structures apart within SWIG, other than by looking at the type +*/ +typedef struct { + swig_type_info *type; + int own; /* 1 if owned & must be destroyed */ + char data[1]; /* arbitrary amount of data */ +} swig_lua_rawdata; + +/* Common SWIG API */ +#define SWIG_NewPointerObj(L, ptr, type, owner) SWIG_Lua_NewPointerObj(L, (void *)ptr, type, owner) +#define SWIG_ConvertPtr(L,idx, ptr, type, flags) SWIG_Lua_ConvertPtr(L,idx,ptr,type,flags) +#define SWIG_MustGetPtr(L,idx, type,flags, argnum,fnname) SWIG_Lua_MustGetPtr(L,idx, type,flags, argnum,fnname) +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(L, idx, ptr, sz, ty) SWIG_Lua_ConvertPacked(L, idx, ptr, sz, ty) +#define SWIG_NewMemberObj(L, ptr, sz, type) SWIG_Lua_NewPackedObj(L, ptr, sz, type) + +/* Runtime API */ +#define SWIG_GetModule(clientdata) SWIG_Lua_GetModule((lua_State*)(clientdata)) +#define SWIG_SetModule(clientdata, pointer) SWIG_Lua_SetModule((lua_State*) (clientdata), pointer) +#define SWIG_MODULE_CLIENTDATA_TYPE lua_State* + +/* Contract support */ +#define SWIG_contract_assert(expr, msg) \ + if (!(expr)) { SWIG_Lua_pusherrstring(L, (char *) msg); goto fail; } else + + +/* helper #defines */ +#define SWIG_fail {goto fail;} +#define SWIG_fail_arg(func_name,argnum,type) \ + {SWIG_Lua_pushferrstring(L,"Error in %s (arg %d), expected '%s' got '%s'",\ + func_name,argnum,type,SWIG_Lua_typename(L,argnum));\ + goto fail;} +#define SWIG_fail_ptr(func_name,argnum,type) \ + SWIG_fail_arg(func_name,argnum,(type && type->str)?type->str:"void*") +#define SWIG_check_num_args(func_name,a,b) \ + if (lua_gettop(L)b) \ + {SWIG_Lua_pushferrstring(L,"Error in %s expected %d..%d args, got %d",func_name,a,b,lua_gettop(L));\ + goto fail;} + + +#define SWIG_Lua_get_table(L,n) \ + (lua_pushstring(L, n), lua_rawget(L,-2)) + +#define SWIG_Lua_add_function(L,n,f) \ + (lua_pushstring(L, n), \ + lua_pushcfunction(L, f), \ + lua_rawset(L,-3)) + +#define SWIG_Lua_add_boolean(L,n,b) \ + (lua_pushstring(L, n), \ + lua_pushboolean(L, b), \ + lua_rawset(L,-3)) + +/* special helper for allowing 'nil' for usertypes */ +#define SWIG_isptrtype(L,I) (lua_isuserdata(L,I) || lua_isnil(L,I)) + +#ifdef __cplusplus +/* Special helper for member function pointers +it gets the address, casts it, then dereferences it */ +/*#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a))) */ +#endif + +/* storing/access of swig_module_info */ +SWIGRUNTIME swig_module_info * +SWIG_Lua_GetModule(lua_State *L) { + swig_module_info *ret = 0; + lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); + lua_rawget(L,LUA_REGISTRYINDEX); + if (lua_islightuserdata(L,-1)) + ret=(swig_module_info*)lua_touserdata(L,-1); + lua_pop(L,1); /* tidy */ + return ret; +} + +SWIGRUNTIME void +SWIG_Lua_SetModule(lua_State *L, swig_module_info *module) { + /* add this all into the Lua registry: */ + lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); + lua_pushlightuserdata(L,(void*)module); + lua_rawset(L,LUA_REGISTRYINDEX); +} + +/* ----------------------------------------------------------------------------- + * global variable support code: modules + * ----------------------------------------------------------------------------- */ + +/* this function is called when trying to set an immutable. +default action is to print an error. +This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */ +SWIGINTERN int SWIG_Lua_set_immutable(lua_State *L) +{ +/* there should be 1 param passed in: the new value */ +#ifndef SWIGLUA_IGNORE_SET_IMMUTABLE + lua_pop(L,1); /* remove it */ + luaL_error(L,"This variable is immutable"); +#endif + return 0; /* should not return anything */ +} + +#ifdef SWIG_LUA_ELUA_EMULATE + +SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *type, int own); +SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_type_info *type); +static int swig_lua_elua_emulate_unique_key; + +/* This function emulates eLua rotables behaviour. It loads a rotable definition into the usual lua table. */ +SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_entry *table) +{ + int i, table_parsed, parsed_tables_array, target_table; + assert(lua_istable(L,-1)); + target_table = lua_gettop(L); + /* Get the registry where we put all parsed tables to avoid loops */ + lua_rawgetp(L, LUA_REGISTRYINDEX, &swig_lua_elua_emulate_unique_key); + if(lua_isnil(L,-1)) { + lua_pop(L,1); + lua_newtable(L); + lua_pushvalue(L,-1); + lua_rawsetp(L,LUA_REGISTRYINDEX,(void*)(&swig_lua_elua_emulate_unique_key)); + } + parsed_tables_array = lua_gettop(L); + lua_pushvalue(L,target_table); + lua_rawsetp(L, parsed_tables_array, table); + table_parsed = 0; + const int SWIGUNUSED pairs_start = lua_gettop(L); + for(i = 0;table[i].key.type != LUA_TNIL || table[i].value.type != LUA_TNIL;i++) + { + const swig_elua_entry *entry = table + i; + int is_metatable = 0; + switch(entry->key.type) { + case LUA_TSTRING: + lua_pushstring(L,entry->key.key.strkey); + if(strcmp(entry->key.key.strkey, SWIG_LUA_ELUA_EMUL_METATABLE_KEY) == 0) + is_metatable = 1; + break; + case LUA_TNUMBER: + lua_pushnumber(L,entry->key.key.numkey); + break; + case LUA_TNIL: + lua_pushnil(L); + break; + default: + assert(0); + } + switch(entry->value.type) { + case LUA_TSTRING: + lua_pushstring(L,entry->value.value.string); + break; + case LUA_TNUMBER: + lua_pushnumber(L,entry->value.value.number); + break; + case LUA_TFUNCTION: + lua_pushcfunction(L,entry->value.value.function); + break; + case LUA_TTABLE: + lua_rawgetp(L,parsed_tables_array, entry->value.value.table); + table_parsed = !lua_isnil(L,-1); + if(!table_parsed) { + lua_pop(L,1); /*remove nil */ + lua_newtable(L); + SWIG_Lua_elua_emulate_register(L,entry->value.value.table); + } + if(is_metatable) { + assert(lua_istable(L,-1)); + lua_pushvalue(L,-1); + lua_setmetatable(L,target_table); + } + + break; + case LUA_TUSERDATA: + if(entry->value.value.userdata.member) + SWIG_NewMemberObj(L,entry->value.value.userdata.pvalue, + entry->value.value.userdata.lvalue, + *(entry->value.value.userdata.ptype)); + else + SWIG_NewPointerObj(L,entry->value.value.userdata.pvalue, + *(entry->value.value.userdata.ptype),0); + break; + case LUA_TNIL: + lua_pushnil(L); + break; + default: + assert(0); + } + assert(lua_gettop(L) == pairs_start + 2); + lua_rawset(L,target_table); + } + lua_pop(L,1); /* Removing parsed tables storage */ + assert(lua_gettop(L) == target_table); +} + +SWIGINTERN void SWIG_Lua_elua_emulate_register_clear(lua_State *L) +{ + lua_pushnil(L); + lua_rawsetp(L, LUA_REGISTRYINDEX, &swig_lua_elua_emulate_unique_key); +} + +SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L); + +SWIGINTERN int SWIG_Lua_emulate_elua_getmetatable(lua_State *L) +{ + SWIG_check_num_args("getmetatable(SWIG eLua emulation)", 1, 1); + SWIG_Lua_get_class_registry(L); + lua_getfield(L,-1,"lua_getmetatable"); + lua_remove(L,-2); /* remove the registry*/ + assert(!lua_isnil(L,-1)); + lua_pushvalue(L,1); + assert(lua_gettop(L) == 3); /* object | function | object again */ + lua_call(L,1,1); + if(!lua_isnil(L,-1)) /*There is an ordinary metatable */ + return 1; + /*if it is a table, then emulate elua behaviour - check for __metatable attribute of a table*/ + assert(lua_gettop(L) == 2); + if(lua_istable(L,-2)) { + lua_pop(L,1); /*remove the nil*/ + lua_getfield(L,-1, SWIG_LUA_ELUA_EMUL_METATABLE_KEY); + } + assert(lua_gettop(L) == 2); + return 1; + +fail: + lua_error(L); + return 0; +} + +SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L) +{ + SWIG_Lua_get_class_registry(L); + lua_pushglobaltable(L); + lua_pushstring(L,"lua_getmetatable"); + lua_getfield(L,-2,"getmetatable"); + assert(!lua_isnil(L,-1)); + lua_rawset(L,-4); + lua_pushstring(L, "getmetatable"); + lua_pushcfunction(L, SWIG_Lua_emulate_elua_getmetatable); + lua_rawset(L,-3); + lua_pop(L,2); + +} +/* END OF REMOVE */ + +#endif +/* ----------------------------------------------------------------------------- + * global variable support code: namespaces and modules (which are the same thing) + * ----------------------------------------------------------------------------- */ + +SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L) +{ +/* there should be 2 params passed in + (1) table (not the meta table) + (2) string name of the attribute +*/ + assert(lua_istable(L,-2)); /* just in case */ + lua_getmetatable(L,-2); + assert(lua_istable(L,-1)); + SWIG_Lua_get_table(L,".get"); /* find the .get table */ + assert(lua_istable(L,-1)); + /* look for the key in the .get table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + lua_remove(L,-2); /* stack tidy, remove .get table */ + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_call(L,0,1); /* 1 value in (userdata),1 out (result) */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + lua_pop(L,1); /* remove whatever was there */ + /* ok, so try the .fn table */ + SWIG_Lua_get_table(L,".fn"); /* find the .get table */ + assert(lua_istable(L,-1)); /* just in case */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); /* look for the fn */ + lua_remove(L,-2); /* stack tidy, remove .fn table */ + if (lua_isfunction(L,-1)) /* note: whether it's a C function or lua function */ + { /* found it so return the fn & let lua call it */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + lua_pop(L,1); /* remove whatever was there */ + return 0; +} + +SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L) +{ +/* there should be 3 params passed in + (1) table (not the meta table) + (2) string name of the attribute + (3) any for the new value +*/ + + assert(lua_istable(L,1)); + lua_getmetatable(L,1); /* get the meta table */ + assert(lua_istable(L,-1)); + + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + if (lua_istable(L,-1)) + { + /* look for the key in the .set table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_pushvalue(L,3); /* value */ + lua_call(L,1,0); + return 0; + } + lua_pop(L,1); /* remove the value */ + } + lua_pop(L,1); /* remove the value .set table */ + lua_pop(L,1); /* remote metatable */ + lua_rawset(L,-3); + return 0; +} + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) /* In elua this is useless */ +SWIGINTERN void SWIG_Lua_InstallConstants(lua_State *L, swig_lua_const_info constants[]); /* forward declaration */ +SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFunction getFn,lua_CFunction setFn); /* forward declaration */ +SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss); + +/* helper function - register namespace methods and attributes into namespace */ +SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *ns) +{ + int i; + /* There must be namespace table (not metatable) at the top of the stack */ + assert(lua_istable(L,-1)); + SWIG_Lua_InstallConstants(L, ns->ns_constants); + + /* add methods to the namespace/module table */ + for(i=0;ns->ns_methods[i].name;i++){ + SWIG_Lua_add_function(L,ns->ns_methods[i].name,ns->ns_methods[i].func); + } + lua_getmetatable(L,-1); + + /* add fns */ + for(i=0;ns->ns_attributes[i].name;i++){ + SWIG_Lua_add_variable(L,ns->ns_attributes[i].name,ns->ns_attributes[i].getmethod,ns->ns_attributes[i].setmethod); + } + + /* clear stack - remove metatble */ + lua_pop(L,1); + return 0; +} + +/* Register all classes in the namespace */ +SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace *ns) +{ + swig_lua_class **classes; + + /* There must be a module/namespace table at the top of the stack */ + assert(lua_istable(L,-1)); + + classes = ns->ns_classes; + + if( classes != 0 ) { + while(*classes != 0) { + SWIG_Lua_class_register(L, *classes); + classes++; + } + } +} + +/* Helper function. Creates namespace table and adds it to module table + if 'reg' is true, then will register namespace table to parent one (must be on top of the stack + when function is called). + Function always returns newly registered table on top of the stack. +*/ +SWIGINTERN void SWIG_Lua_namespace_register(lua_State *L, swig_lua_namespace *ns, int reg) +{ + swig_lua_namespace **sub_namespace; + /* 1 argument - table on the top of the stack */ + const int SWIGUNUSED begin = lua_gettop(L); + assert(lua_istable(L,-1)); /* just in case. This is supposed to be module table or parent namespace table */ + lua_checkstack(L,5); + lua_newtable(L); /* namespace itself */ + lua_newtable(L); /* metatable for namespace */ + + /* add a table called ".get" */ + lua_pushstring(L,".get"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".set" */ + lua_pushstring(L,".set"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".fn" */ + lua_pushstring(L,".fn"); + lua_newtable(L); + lua_rawset(L,-3); + + /* add accessor fns for using the .get,.set&.fn */ + SWIG_Lua_add_function(L,"__index",SWIG_Lua_namespace_get); + SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_namespace_set); + + lua_setmetatable(L,-2); /* set metatable */ + + /* Register all functions, variables etc */ + SWIG_Lua_add_namespace_details(L,ns); + /* Register classes */ + SWIG_Lua_add_namespace_classes(L,ns); + + sub_namespace = ns->ns_namespaces; + if( sub_namespace != 0) { + while(*sub_namespace != 0) { + SWIG_Lua_namespace_register(L, *sub_namespace, 1); + lua_pop(L,1); /* removing sub-namespace table */ + sub_namespace++; + } + } + + if (reg) { + lua_pushstring(L,ns->name); + lua_pushvalue(L,-2); + lua_rawset(L,-4); /* add namespace to module table */ + } + assert(lua_gettop(L) == begin+1); +} +#endif /* SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA */ + +/* ----------------------------------------------------------------------------- + * global variable support code: classes + * ----------------------------------------------------------------------------- */ + +SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname); + +typedef int (*swig_lua_base_iterator_func)(lua_State*,swig_type_info*, int, int *ret); + +SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info * SWIGUNUSED swig_type, + int first_arg, swig_lua_base_iterator_func func, int *const ret) +{ + /* first_arg - position of the object in stack. Everything that is above are arguments + * and is passed to every evocation of the func */ + int last_arg = lua_gettop(L);/* position of last argument */ + int original_metatable = last_arg + 1; + size_t bases_count; + int result = SWIG_ERROR; + int bases_table; + (void)swig_type; + lua_getmetatable(L,first_arg); + + /* initialise base search */ +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) + SWIG_Lua_get_table(L,".bases"); + assert(lua_istable(L,-1)); + bases_count = lua_rawlen(L,-1); + bases_table = lua_gettop(L); +#else + /* In elua .bases table doesn't exist. Use table from swig_lua_class */ + (void)bases_table; + assert(swig_type!=0); + swig_module_info *module=SWIG_GetModule(L); + swig_lua_class **bases= ((swig_lua_class*)(swig_type->clientdata))->bases; + const char **base_names= ((swig_lua_class*)(swig_type->clientdata))->base_names; + bases_count = 0; + for(;base_names[bases_count]; + bases_count++);/* get length of bases */ +#endif + + if(ret) + *ret = 0; + if(bases_count>0) + { + int to_remove; + size_t i; + int j; + int subcall_last_arg; + int subcall_first_arg = lua_gettop(L) + 1;/* Here a copy of first_arg and arguments begin */ + int valid = 1; + swig_type_info *base_swig_type = 0; + for(j=first_arg;j<=last_arg;j++) + lua_pushvalue(L,j); + subcall_last_arg = lua_gettop(L); + + /* Trick: temporarily replacing original metatable with metatable for base class and call getter */ + for(i=0;ifqname); + base_swig_type = SWIG_TypeQueryModule(module,module,base_names[i]); + assert(base_swig_type != 0); + } +#endif + + if(!valid) + continue; + assert(lua_isuserdata(L, subcall_first_arg)); + assert(lua_istable(L,-1)); + lua_setmetatable(L,subcall_first_arg); /* Set new metatable */ + assert(lua_gettop(L) == subcall_last_arg); + result = func(L, base_swig_type,subcall_first_arg, ret); /* Forward call */ + if(result != SWIG_ERROR) { + break; + } + } + /* Restore original metatable */ + lua_pushvalue(L,original_metatable); + lua_setmetatable(L,first_arg); + /* Clear - remove everything between last_arg and subcall_last_arg including */ + to_remove = subcall_last_arg - last_arg; + for(j=0;jtype; + result = SWIG_Lua_class_do_get(L,type,1,&ret); + if(result == SWIG_OK) + return ret; + + result = SWIG_Lua_class_do_get_item(L,type,1,&ret); + if(result == SWIG_OK) + return ret; + + return 0; +} + +/* helper for the class.set method, performs the lookup of class attributes + * It returns error code. Number of function return values is passed inside 'ret' + */ +SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int first_arg, int *ret) +{ +/* there should be 3 params passed in + (1) table (not the meta table) + (2) string name of the attribute + (3) any for the new value + */ + + int bases_search_result; + int substack_start = lua_gettop(L) - 3; + lua_checkstack(L,5); + assert(lua_isuserdata(L,substack_start+1)); /* just in case */ + lua_getmetatable(L,substack_start+1); /* get the meta table */ + assert(lua_istable(L,-1)); /* just in case */ + if(ret) + *ret = 0; /* it is setter - number of return values is always 0 */ + + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + if (lua_istable(L,-1)) + { + /* look for the key in the .set table */ + lua_pushvalue(L,substack_start+2); /* key */ + lua_rawget(L,-2); + lua_remove(L,-2); /* tidy stack, remove .set table */ + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_pushvalue(L,substack_start+1); /* userdata */ + lua_pushvalue(L,substack_start+3); /* value */ + lua_call(L,2,0); + lua_remove(L,substack_start+4); /*remove metatable*/ + return SWIG_OK; + } + lua_pop(L,1); /* remove the value */ + } else { + lua_pop(L,1); /* remove the answer for .set table request*/ + } + /* NEW: looks for the __setitem() fn + this is a user provided set fn */ + SWIG_Lua_get_table(L,"__setitem"); /* find the fn */ + if (lua_iscfunction(L,-1)) /* if its there */ + { /* found it so call the fn & return its value */ + lua_pushvalue(L,substack_start+1); /* the userdata */ + lua_pushvalue(L,substack_start+2); /* the parameter */ + lua_pushvalue(L,substack_start+3); /* the value */ + lua_call(L,3,0); /* 3 values in ,0 out */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return SWIG_OK; + } + lua_pop(L,1); /* remove value */ + + lua_pop(L,1); /* remove metatable */ + /* Search among bases */ + bases_search_result = SWIG_Lua_iterate_bases(L,type,first_arg,SWIG_Lua_class_do_set,ret); + if(ret) + assert(*ret == 0); + assert(lua_gettop(L) == substack_start + 3); + return bases_search_result; +} + +/* This is the actual method exported to Lua. It calls SWIG_Lua_class_do_set and correctly + * handles return values. + */ +SWIGINTERN int SWIG_Lua_class_set(lua_State *L) +{ +/* There should be 3 params passed in + (1) table (not the meta table) + (2) string name of the attribute + (3) any for the new value + */ + int ret = 0; + int result; + swig_lua_userdata *usr; + swig_type_info *type; + assert(lua_isuserdata(L,1)); + usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ + type = usr->type; + result = SWIG_Lua_class_do_set(L,type,1,&ret); + if(result != SWIG_OK) { + SWIG_Lua_pushferrstring(L,"Assignment not possible. No setter/member with this name. For custom assignments implement __setitem method."); + lua_error(L); + } else { + assert(ret==0); + } + return 0; +} + +/* the class.destruct method called by the interpreter */ +SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L) +{ +/* there should be 1 params passed in + (1) userdata (not the meta table) */ + swig_lua_userdata *usr; + swig_lua_class *clss; + assert(lua_isuserdata(L,-1)); /* just in case */ + usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ + /* if must be destroyed & has a destructor */ + if (usr->own) /* if must be destroyed */ + { + clss=(swig_lua_class*)usr->type->clientdata; /* get the class */ + if (clss && clss->destructor) /* there is a destroy fn */ + { + clss->destructor(usr->ptr); /* bye bye */ + } + } + return 0; +} + +/* the class.__tostring method called by the interpreter and print */ +SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L) +{ +/* there should be 1 param passed in + (1) userdata (not the metatable) */ + swig_lua_userdata* userData; + assert(lua_isuserdata(L,1)); /* just in case */ + userData = (swig_lua_userdata*)lua_touserdata(L,1); /* get the userdata address */ + + lua_pushfstring(L, "", userData->type->str, userData->ptr); + return 1; +} + +/* to manually disown some userdata */ +SWIGINTERN int SWIG_Lua_class_disown(lua_State *L) +{ +/* there should be 1 params passed in + (1) userdata (not the meta table) */ + swig_lua_userdata *usr; + assert(lua_isuserdata(L,-1)); /* just in case */ + usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ + + usr->own = 0; /* clear our ownership */ + return 0; +} + +/* lua callable function to compare userdata's value +the issue is that two userdata may point to the same thing +but to lua, they are different objects */ +SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L) +{ + int result; + swig_lua_userdata *usr1,*usr2; + if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */ + return 0; /* nil reply */ + usr1=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ + usr2=(swig_lua_userdata*)lua_touserdata(L,2); /* get data */ + /*result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); only works if type is the same*/ + result=(usr1->ptr==usr2->ptr); + lua_pushboolean(L,result); + return 1; +} + +/* populate table at the top of the stack with metamethods that ought to be inherited */ +SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L) +{ + SWIG_Lua_add_boolean(L, "__add", 1); + SWIG_Lua_add_boolean(L, "__sub", 1); + SWIG_Lua_add_boolean(L, "__mul", 1); + SWIG_Lua_add_boolean(L, "__div", 1); + SWIG_Lua_add_boolean(L, "__mod", 1); + SWIG_Lua_add_boolean(L, "__pow", 1); + SWIG_Lua_add_boolean(L, "__unm", 1); + SWIG_Lua_add_boolean(L, "__len", 1 ); + SWIG_Lua_add_boolean(L, "__concat", 1 ); + SWIG_Lua_add_boolean(L, "__eq", 1); + SWIG_Lua_add_boolean(L, "__lt", 1); + SWIG_Lua_add_boolean(L, "__le", 1); + SWIG_Lua_add_boolean(L, "__call", 1); + SWIG_Lua_add_boolean(L, "__tostring", 1); + SWIG_Lua_add_boolean(L, "__gc", 0); +} + +/* creates the swig registry */ +SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L) +{ + /* create main SWIG registry table */ + lua_pushstring(L,"SWIG"); + lua_newtable(L); + /* populate it with some predefined data */ + + /* .library table. Placeholder */ + lua_pushstring(L,".library"); + lua_newtable(L); + { + /* list of metamethods that class inherits from its bases */ + lua_pushstring(L,"inheritable_metamethods"); + lua_newtable(L); + /* populate with list of metamethods */ + SWIG_Lua_populate_inheritable_metamethods(L); + lua_rawset(L,-3); + } + lua_rawset(L,-3); + + lua_rawset(L,LUA_REGISTRYINDEX); +} + +/* gets the swig registry (or creates it) */ +SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L) +{ + /* add this all into the swig registry: */ + lua_pushstring(L,"SWIG"); + lua_rawget(L,LUA_REGISTRYINDEX); /* get the registry */ + if (!lua_istable(L,-1)) /* not there */ + { /* must be first time, so add it */ + lua_pop(L,1); /* remove the result */ + SWIG_Lua_create_class_registry(L); + /* then get it */ + lua_pushstring(L,"SWIG"); + lua_rawget(L,LUA_REGISTRYINDEX); + } +} + +SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L) +{ + SWIG_Lua_get_class_registry(L); + lua_pushstring(L, ".library"); + lua_rawget(L,-2); + assert( !lua_isnil(L,-1) ); + lua_pushstring(L, "inheritable_metamethods"); + lua_rawget(L,-2); + + /* Remove class registry and library table */ + lua_remove(L,-2); + lua_remove(L,-2); +} + +/* Helper function to get the classes metatable from the register */ +SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname) +{ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,cname); /* get the name */ + lua_rawget(L,-2); /* get it */ + lua_remove(L,-2); /* tidy up (remove registry) */ +} + +/* Set up the base classes pointers. +Each class structure has a list of pointers to the base class structures. +This function fills them. +It cannot be done at compile time, as this will not work with hireachies +spread over more than one swig file. +Therefore it must be done at runtime, querying the SWIG type system. +*/ +SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L,swig_lua_class *clss) +{ + int i=0; + swig_module_info *module=SWIG_GetModule(L); + for(i=0;clss->base_names[i];i++) + { + if (clss->bases[i]==0) /* not found yet */ + { + /* lookup and cache the base class */ + swig_type_info *info = SWIG_TypeQueryModule(module,module,clss->base_names[i]); + if (info) clss->bases[i] = (swig_lua_class *) info->clientdata; + } + } +} + +#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) +/* Merges two tables */ +SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int source) +{ + /* iterating */ + lua_pushnil(L); + while (lua_next(L,source) != 0) { + /* -1 - value, -2 - index */ + /* have to copy to assign */ + lua_pushvalue(L,-2); /* copy of index */ + lua_pushvalue(L,-2); /* copy of value */ + lua_rawset(L, target); + lua_pop(L,1); + /* only key is left */ + } +} + +/* Merges two tables with given name. original - index of target metatable, base - index of source metatable */ +SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char* name, int original, int base) +{ + /* push original[name], then base[name] */ + lua_pushstring(L,name); + lua_rawget(L,original); + int original_table = lua_gettop(L); + lua_pushstring(L,name); + lua_rawget(L,base); + int base_table = lua_gettop(L); + SWIG_Lua_merge_tables_by_index(L, original_table, base_table); + /* clearing stack */ + lua_pop(L,2); +} + +/* Function takes all symbols from base and adds it to derived class. It's just a helper. */ +SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cls) +{ + /* There is one parameter - original, i.e. 'derived' class metatable */ + assert(lua_istable(L,-1)); + int original = lua_gettop(L); + SWIG_Lua_get_class_metatable(L,base_cls->fqname); + int base = lua_gettop(L); + SWIG_Lua_merge_tables(L, ".fn", original, base ); + SWIG_Lua_merge_tables(L, ".set", original, base ); + SWIG_Lua_merge_tables(L, ".get", original, base ); + lua_pop(L,1); +} + +/* Function squashes all symbols from 'clss' bases into itself */ +SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss) +{ + int i; + SWIG_Lua_get_class_metatable(L,clss->fqname); + for(i=0;clss->base_names[i];i++) + { + if (clss->bases[i]==0) /* Somehow it's not found. Skip it */ + continue; + /* Thing is: all bases are already registered. Thus they have already executed + * this function. So we just need to squash them into us, because their bases + * are already squashed into them. No need for recursion here! + */ + SWIG_Lua_class_squash_base(L, clss->bases[i]); + } + lua_pop(L,1); /*tidy stack*/ +} +#endif + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) /* In elua this is useless */ +/* helper add a variable to a registered class */ +SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFunction getFn,lua_CFunction setFn) +{ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".get"); /* find the .get table */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_function(L,name,getFn); + lua_pop(L,1); /* tidy stack (remove table) */ + if (setFn) + { + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_function(L,name,setFn); + lua_pop(L,1); /* tidy stack (remove table) */ + } +} + +/* helper to recursively add class static details (static attributes, operations and constants) */ +SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *clss) +{ + int i = 0; + /* The class namespace table must be on the top of the stack */ + assert(lua_istable(L,-1)); + /* call all the base classes first: we can then override these later: */ + for(i=0;clss->bases[i];i++) + { + SWIG_Lua_add_class_static_details(L,clss->bases[i]); + } + + SWIG_Lua_add_namespace_details(L, clss->cls_static); +} + +SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss); /* forward declaration */ + +/* helper to recursively add class details (attributes & operations) */ +SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_class *clss) +{ + int i; + size_t bases_count = 0; + /* Add bases to .bases table */ + SWIG_Lua_get_table(L,".bases"); + assert(lua_istable(L,-1)); /* just in case */ + for(i=0;clss->bases[i];i++) + { + SWIG_Lua_get_class_metatable(L,clss->bases[i]->fqname); + /* Base class must be already registered */ + assert(lua_istable(L,-1)); + lua_rawseti(L,-2,i+1); /* In lua indexing starts from 1 */ + bases_count++; + } + assert(lua_rawlen(L,-1) == bases_count); + lua_pop(L,1); /* remove .bases table */ + /* add attributes */ + for(i=0;clss->attributes[i].name;i++){ + SWIG_Lua_add_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod); + } + /* add methods to the metatable */ + SWIG_Lua_get_table(L,".fn"); /* find the .fn table */ + assert(lua_istable(L,-1)); /* just in case */ + for(i=0;clss->methods[i].name;i++){ + SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].func); + } + lua_pop(L,1); /* tidy stack (remove table) */ + /* add operator overloads + This adds methods from metatable array to metatable. Can mess up garbage + collectind if someone defines __gc method + */ + if(clss->metatable) { + for(i=0;clss->metatable[i].name;i++) { + SWIG_Lua_add_function(L,clss->metatable[i].name,clss->metatable[i].func); + } + } + +#if !defined(SWIG_LUA_SQUASH_BASES) + /* Adding metamethods that are defined in base classes. If bases were squashed + * then it is obviously unnecessary + */ + SWIG_Lua_add_class_user_metamethods(L, clss); +#endif +} + +/* Helpers to add user defined class metamedhods - __add, __sub etc. The helpers are needed + for the following issue: Lua runtime checks for metamethod existence with rawget function + ignoring our SWIG-provided __index and __newindex functions. Thus our inheritance-aware method + search algorithm doesn't work in such case. (Not to say that Lua runtime queries metamethod directly + in metatable and not in object). + Current solution is this: if somewhere in hierarchy metamethod __x is defined, then all descendants + are automatically given a special proxy __x that calls the real __x method. + Obvious idea - to copy __x instead of creating __x-proxy is wrong because if someone changes __x in runtime, + those changes must be reflected in all descendants. +*/ + +SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration*/ + +/* The real function that resolves a metamethod. + * Function searches given class and all it's bases(recursively) for first instance of something that is + * not equal to SWIG_Lua_resolve_metatmethod. (Almost always this 'something' is actual metamethod implementation + * and it is a SWIG-generated C function.). It returns value on the top of the L and there is no garbage below the + * answer. + * Returns 1 if found, 0 otherwise. + * clss is class which metatable we will search for method + * metamethod_name_idx is index in L where metamethod name (as string) lies + * skip_check allows to skip searching metamethod in givel clss and immideatelly go to searching in bases. skip_check + * is not caried to subsequent recursive calls - false is always passed. It is set to true only at first call from + * SWIG_Lua_resolve_metamethod + * */ +SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx, + int skip_check) +{ + /* This function is called recursively */ + int result = 0; + int i = 0; + + if (!skip_check) { + SWIG_Lua_get_class_metatable(L, clss->fqname); + lua_pushvalue(L, metamethod_name_idx); + lua_rawget(L,-2); + /* If this is cfunction and it is equal to SWIG_Lua_resolve_metamethod then + * this isn't the function we are looking for :) + * lua_tocfunction will return NULL if not cfunction + */ + if (!lua_isnil(L,-1) && lua_tocfunction(L,-1) != SWIG_Lua_resolve_metamethod ) { + lua_remove(L,-2); /* removing class metatable */ + return 1; + } + lua_pop(L,2); /* remove class metatable and query result */ + } + + /* Forwarding calls to bases */ + for(i=0;clss->bases[i];i++) + { + result = SWIG_Lua_do_resolve_metamethod(L, clss->bases[i], metamethod_name_idx, 0); + if (result) + break; + } + + return result; +} + +/* The proxy function for metamethod. All parameters are passed as cclosure. Searches for actual method + * and calls it */ +SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L) +{ + int numargs; + int metamethod_name_idx; + const swig_lua_class* clss; + int result; + + lua_checkstack(L,5); + numargs = lua_gettop(L); /* number of arguments to pass to actual metamethod */ + + /* Get upvalues from closure */ + lua_pushvalue(L, lua_upvalueindex(1)); /*Get function name*/ + metamethod_name_idx = lua_gettop(L); + + lua_pushvalue(L, lua_upvalueindex(2)); + clss = (const swig_lua_class*)(lua_touserdata(L,-1)); + lua_pop(L,1); /* remove lightuserdata with clss from stack */ + + /* Actual work */ + result = SWIG_Lua_do_resolve_metamethod(L, clss, metamethod_name_idx, 1); + if (!result) { + SWIG_Lua_pushferrstring(L,"The metamethod proxy is set, but it failed to find actual metamethod. Memory corruption is most likely explanation."); + lua_error(L); + return 0; + } + + lua_remove(L,-2); /* remove metamethod key */ + lua_insert(L,1); /* move function to correct position */ + lua_call(L, numargs, LUA_MULTRET); + return lua_gettop(L); /* return all results */ +} + + +/* If given metamethod must be present in given class, then creates appropriate proxy + * Returns 1 if successfully added, 0 if not added because no base class has it, -1 + * if method is defined in the class metatable itself + */ +SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index) +{ + int key_index; + int success = 0; + int i = 0; + + /* metamethod name - on the top of the stack */ + assert(lua_isstring(L,-1)); + + key_index = lua_gettop(L); + + /* Check whether method is already defined in metatable */ + lua_pushvalue(L,key_index); /* copy of the key */ + lua_gettable(L,metatable_index); + if( !lua_isnil(L,-1) ) { + lua_pop(L,1); + return -1; + } + lua_pop(L,1); + + /* Iterating over immediate bases */ + for(i=0;clss->bases[i];i++) + { + const swig_lua_class *base = clss->bases[i]; + SWIG_Lua_get_class_metatable(L, base->fqname); + lua_pushvalue(L, key_index); + lua_rawget(L, -2); + if( !lua_isnil(L,-1) ) { + lua_pushvalue(L, key_index); + + /* Add proxy function */ + lua_pushvalue(L, key_index); /* first closure value is function name */ + lua_pushlightuserdata(L, clss); /* second closure value is swig_lua_class structure */ + lua_pushcclosure(L, SWIG_Lua_resolve_metamethod, 2); + + lua_rawset(L, metatable_index); + success = 1; + } + lua_pop(L,1); /* remove function or nil */ + lua_pop(L,1); /* remove base class metatable */ + + if( success ) + break; + } + + return success; +} + +SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss) +{ + int metatable_index; + int metamethods_info_index; + int tostring_undefined; + int eq_undefined = 0; + + SWIG_Lua_get_class_metatable(L, clss->fqname); + metatable_index = lua_gettop(L); + SWIG_Lua_get_inheritable_metamethods(L); + assert(lua_istable(L,-1)); + metamethods_info_index = lua_gettop(L); + lua_pushnil(L); /* first key */ + while(lua_next(L, metamethods_info_index) != 0 ) { + /* key at index -2, value at index -1 */ + const int is_inheritable = lua_toboolean(L,-2); + lua_pop(L,1); /* remove value - we don't need it anymore */ + + if(is_inheritable) { /* if metamethod is inheritable */ + SWIG_Lua_add_class_user_metamethod(L,clss,metatable_index); + } + } + + lua_pop(L,1); /* remove inheritable metatmethods table */ + + /* Special handling for __tostring method */ + lua_pushstring(L, "__tostring"); + lua_pushvalue(L,-1); + lua_rawget(L,metatable_index); + tostring_undefined = lua_isnil(L,-1); + lua_pop(L,1); + if( tostring_undefined ) { + lua_pushcfunction(L, SWIG_Lua_class_tostring); + lua_rawset(L, metatable_index); + } else { + lua_pop(L,1); /* remove copy of the key */ + } + + /* Special handling for __eq method */ + lua_pushstring(L, "__eq"); + lua_pushvalue(L,-1); + lua_rawget(L,metatable_index); + eq_undefined = lua_isnil(L,-1); + lua_pop(L,1); + if( eq_undefined ) { + lua_pushcfunction(L, SWIG_Lua_class_equal); + lua_rawset(L, metatable_index); + } else { + lua_pop(L,1); /* remove copy of the key */ + } + /* Warning: __index and __newindex are SWIG-defined. For user-defined operator[] + * a __getitem/__setitem method should be defined + */ + lua_pop(L,1); /* pop class metatable */ +} + +/* Register class static methods,attributes etc as well as constructor proxy */ +SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *clss) +{ + const int SWIGUNUSED begin = lua_gettop(L); + lua_checkstack(L,5); /* just in case */ + assert(lua_istable(L,-1)); /* just in case */ + assert(strcmp(clss->name, clss->cls_static->name) == 0); /* in class those 2 must be equal */ + + SWIG_Lua_namespace_register(L,clss->cls_static, 1); + + assert(lua_istable(L,-1)); /* just in case */ + + /* add its constructor to module with the name of the class + so you can do MyClass(...) as well as new_MyClass(...) + BUT only if a constructor is defined + (this overcomes the problem of pure virtual classes without constructors)*/ + if (clss->constructor) + { + lua_getmetatable(L,-1); + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_function(L,"__call", clss->constructor); + lua_pop(L,1); + } + + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_class_static_details(L, clss); + + /* clear stack */ + lua_pop(L,1); + assert( lua_gettop(L) == begin ); +} + +/* Performs the instance (non-static) class registration process. Metatable for class is created + * and added to the class registry. + */ +SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *clss) +{ + const int SWIGUNUSED begin = lua_gettop(L); + int i; + /* if name already there (class is already registered) then do nothing */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,clss->fqname); /* get the name */ + lua_rawget(L,-2); + if(!lua_isnil(L,-1)) { + lua_pop(L,2); + assert(lua_gettop(L)==begin); + return; + } + lua_pop(L,2); /* tidy stack */ + /* Recursively initialize all bases */ + for(i=0;clss->bases[i];i++) + { + SWIG_Lua_class_register_instance(L,clss->bases[i]); + } + /* Again, get registry and push name */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,clss->fqname); /* get the name */ + lua_newtable(L); /* create the metatable */ +#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) + /* If squashing is requested, then merges all bases metatable into this one. + * It would get us all special methods: __getitem, __add etc. + * This would set .fn, .type, and other .xxx incorrectly, but we will overwrite it right away + */ + { + int new_metatable_index = lua_absindex(L,-1); + for(i=0;clss->bases[i];i++) + { + int base_metatable; + SWIG_Lua_get_class_metatable(L,clss->bases[i]->fqname); + base_metatable = lua_absindex(L,-1); + SWIG_Lua_merge_tables_by_index(L,new_metatable_index, base_metatable); + lua_pop(L,1); + } + } + /* And now we will overwrite all incorrectly set data */ +#endif + /* add string of class name called ".type" */ + lua_pushstring(L,".type"); + lua_pushstring(L,clss->fqname); + lua_rawset(L,-3); + /* add a table called bases */ + lua_pushstring(L,".bases"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".get" */ + lua_pushstring(L,".get"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".set" */ + lua_pushstring(L,".set"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".fn" */ + lua_pushstring(L,".fn"); + lua_newtable(L); + /* add manual disown method */ + SWIG_Lua_add_function(L,"__disown",SWIG_Lua_class_disown); + lua_rawset(L,-3); + /* add accessor fns for using the .get,.set&.fn */ + SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get); + SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set); + SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct); + /* add it */ + lua_rawset(L,-3); /* metatable into registry */ + lua_pop(L,1); /* tidy stack (remove registry) */ + assert(lua_gettop(L) == begin); + +#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) + /* Now merge all symbols from .fn, .set, .get etc from bases to our tables */ + SWIG_Lua_class_squash_bases(L,clss); +#endif + SWIG_Lua_get_class_metatable(L,clss->fqname); + SWIG_Lua_add_class_instance_details(L,clss); /* recursive adding of details (atts & ops) */ + lua_pop(L,1); /* tidy stack (remove class metatable) */ + assert( lua_gettop(L) == begin ); +} + +SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss) +{ + int SWIGUNUSED begin; + assert(lua_istable(L,-1)); /* This is a table (module or namespace) where classes will be added */ + SWIG_Lua_class_register_instance(L,clss); + SWIG_Lua_class_register_static(L,clss); + + /* Add links from static part to instance part and vice versa */ + /* [SWIG registry] [Module] + * "MyClass" ----> [MyClass metatable] <===== "MyClass" -+> [static part] + * ".get" ----> ... | | getmetatable()----| + * ".set" ----> ... | | | + * ".static" --------------)----------------/ [static part metatable] + * | ".get" --> ... + * | ".set" --> .... + * |=============================== ".instance" + */ + begin = lua_gettop(L); + lua_pushstring(L,clss->cls_static->name); + lua_rawget(L,-2); /* get class static table */ + assert(lua_istable(L,-1)); + lua_getmetatable(L,-1); + assert(lua_istable(L,-1)); /* get class static metatable */ + lua_pushstring(L,".instance"); /* prepare key */ + + SWIG_Lua_get_class_metatable(L,clss->fqname); /* get class metatable */ + assert(lua_istable(L,-1)); + lua_pushstring(L,".static"); /* prepare key */ + lua_pushvalue(L, -4); /* push static class TABLE */ + assert(lua_istable(L,-1)); + lua_rawset(L,-3); /* assign static class table(!NOT metatable) as ".static" member of class metatable */ + lua_rawset(L,-3); /* assign class metatable as ".instance" member of class static METATABLE */ + lua_pop(L,2); + assert(lua_gettop(L) == begin); +} +#endif /* SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA */ + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_class *clss) +{ + const int SWIGUNUSED begin = lua_gettop(L); + int i; + /* if name already there (class is already registered) then do nothing */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,clss->fqname); /* get the name */ + lua_rawget(L,-2); + if(!lua_isnil(L,-1)) { + lua_pop(L,2); + assert(lua_gettop(L)==begin); + return; + } + lua_pop(L,2); /* tidy stack */ + /* Recursively initialize all bases */ + for(i=0;clss->bases[i];i++) + { + SWIG_Lua_elua_class_register_instance(L,clss->bases[i]); + } + /* Again, get registry and push name */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,clss->fqname); /* get the name */ + assert(clss->metatable); + lua_pushrotable(L, (void*)(clss->metatable)); /* create the metatable */ + lua_rawset(L,-3); + lua_pop(L,1); + assert(lua_gettop(L) == begin); +} +#endif /* elua && eluac */ + +/* ----------------------------------------------------------------------------- + * Class/structure conversion fns + * ----------------------------------------------------------------------------- */ + +/* helper to add metatable to new lua object */ +SWIGINTERN void SWIG_Lua_AddMetatable(lua_State *L,swig_type_info *type) +{ + if (type->clientdata) /* there is clientdata: so add the metatable */ + { + SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->fqname); + if (lua_istable(L,-1)) + { + lua_setmetatable(L,-2); + } + else + { + lua_pop(L,1); + } + } +} + +/* pushes a new object into the lua stack */ +SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *type, int own) +{ + swig_lua_userdata *usr; + if (!ptr){ + lua_pushnil(L); + return; + } + usr=(swig_lua_userdata*)lua_newuserdata(L,sizeof(swig_lua_userdata)); /* get data */ + usr->ptr=ptr; /* set the ptr */ + usr->type=type; + usr->own=own; +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) + SWIG_Lua_AddMetatable(L,type); /* add metatable */ +#endif +} + +/* takes a object from the lua stack & converts it into an object of the correct type + (if possible) */ +SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags) +{ + swig_lua_userdata *usr; + swig_cast_info *cast; + /* special case: lua nil => NULL pointer */ + if (lua_isnil(L,index)) + { + *ptr=0; + return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK; + } + usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */ + if (usr) + { + if (flags & SWIG_POINTER_DISOWN) /* must disown the object */ + { + usr->own=0; + } + if (!type) /* special cast void*, no casting fn */ + { + *ptr=usr->ptr; + return SWIG_OK; /* ok */ + } + cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */ + if (cast) + { + int newmemory = 0; + *ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + return SWIG_OK; /* ok */ + } + } + return SWIG_ERROR; /* error */ +} + +SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *type,int flags, + int argnum,const char *func_name){ + void *result; + if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){ + luaL_error (L,"Error in %s, expected a %s at argument number %d\n", + func_name,(type && type->str)?type->str:"void*",argnum); + } + return result; +} + +/* pushes a packed userdata. user for member fn pointers only */ +SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_type_info *type) +{ + swig_lua_rawdata *raw; + assert(ptr); /* not acceptable to pass in a NULL value */ + raw=(swig_lua_rawdata*)lua_newuserdata(L,sizeof(swig_lua_rawdata)-1+size); /* alloc data */ + raw->type=type; + raw->own=0; + memcpy(raw->data,ptr,size); /* copy the data */ + SWIG_Lua_AddMetatable(L,type); /* add metatable */ +} + +/* converts a packed userdata. user for member fn pointers only */ +SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L,int index,void *ptr,size_t size,swig_type_info *type) +{ + swig_lua_rawdata *raw; + raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */ + if (!raw) return SWIG_ERROR; /* error */ + if (type==0 || type==raw->type) /* void* or identical type */ + { + memcpy(ptr,raw->data,size); /* copy it */ + return SWIG_OK; /* ok */ + } + return SWIG_ERROR; /* error */ +} + +/* a function to get the typestring of a piece of data */ +SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp) +{ + swig_lua_userdata *usr; + if (lua_isuserdata(L,tp)) + { + usr=(swig_lua_userdata*)lua_touserdata(L,tp); /* get data */ + if (usr && usr->type && usr->type->str) + return usr->type->str; + return "userdata (unknown type)"; + } + return lua_typename(L,lua_type(L,tp)); +} + +/* lua callable function to get the userdata's type */ +SWIGRUNTIME int SWIG_Lua_type(lua_State *L) +{ + lua_pushstring(L,SWIG_Lua_typename(L,1)); + return 1; +} + +/* ----------------------------------------------------------------------------- + * global variable support code: class/struct typemap functions + * ----------------------------------------------------------------------------- */ + +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) +/* Install Constants */ +SWIGINTERN void +SWIG_Lua_InstallConstants(lua_State *L, swig_lua_const_info constants[]) { + int i; + for (i = 0; constants[i].type; i++) { + switch(constants[i].type) { + case SWIG_LUA_INT: + lua_pushstring(L,constants[i].name); + lua_pushinteger(L,(lua_Integer)constants[i].lvalue); + lua_rawset(L,-3); + break; + case SWIG_LUA_FLOAT: + lua_pushstring(L,constants[i].name); + lua_pushnumber(L,(lua_Number)constants[i].dvalue); + lua_rawset(L,-3); + break; + case SWIG_LUA_CHAR: + lua_pushstring(L,constants[i].name); + { + char c = (char)constants[i].lvalue; + lua_pushlstring(L,&c,1); + } + lua_rawset(L,-3); + break; + case SWIG_LUA_STRING: + lua_pushstring(L,constants[i].name); + lua_pushstring(L,(char *) constants[i].pvalue); + lua_rawset(L,-3); + break; + case SWIG_LUA_POINTER: + lua_pushstring(L,constants[i].name); + SWIG_NewPointerObj(L,constants[i].pvalue, *(constants[i]).ptype,0); + lua_rawset(L,-3); + break; + case SWIG_LUA_BINARY: + lua_pushstring(L,constants[i].name); + SWIG_NewMemberObj(L,constants[i].pvalue,constants[i].lvalue,*(constants[i]).ptype); + lua_rawset(L,-3); + break; + default: + break; + } + } +} +#endif + +/* ----------------------------------------------------------------------------- + * executing lua code from within the wrapper + * ----------------------------------------------------------------------------- */ + +#ifndef SWIG_DOSTRING_FAIL /* Allows redefining of error function */ +#define SWIG_DOSTRING_FAIL(S) fprintf(stderr,"%s\n",S) +#endif +/* Executes a C string in Lua which is a really simple way of calling lua from C +Unfortunately lua keeps changing its APIs, so we need a conditional compile +In lua 5.0.X it's lua_dostring() +In lua 5.1.X it's luaL_dostring() +*/ +SWIGINTERN int +SWIG_Lua_dostring(lua_State *L, const char *str) { + int ok,top; + if (str==0 || str[0]==0) return 0; /* nothing to do */ + top=lua_gettop(L); /* save stack */ +#if (defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM>=501)) + ok=luaL_dostring(L,str); /* looks like this is lua 5.1.X or later, good */ +#else + ok=lua_dostring(L,str); /* might be lua 5.0.x, using lua_dostring */ +#endif + if (ok!=0) { + SWIG_DOSTRING_FAIL(lua_tostring(L,-1)); + } + lua_settop(L,top); /* restore the stack */ + return ok; +} + +#ifdef __cplusplus +} +#endif + +/* ------------------------------ end luarun.swg ------------------------------ */ + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_pm3 swig_types[0] +static swig_type_info *swig_types[2]; +static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#define SWIG_name "pm3" +#define SWIG_init luaopen_pm3 +#define SWIG_init_user luaopen_pm3_user + +#define SWIG_LUACODE luaopen_pm3_luacode + +/* Include the header in the wrapper code */ +#include "pm3.h" +#include "comms.h" + +SWIGINTERN pm3 *new_pm3__SWIG_0(void){ + printf("SWIG pm3 constructor, get current pm3\n"); + pm3_device * p = pm3_get_current_dev(); + p->script_embedded = 1; + return p; + } + +SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) { + int ret = lua_isstring(L, idx); + if (!ret) + ret = lua_isnil(L, idx); + return ret; +} + +SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ + printf("SWIG pm3 constructor with port, open pm3\n"); + pm3_device * p = pm3_open(port); + p->script_embedded = 0; + return p; + } +SWIGINTERN void delete_pm3(pm3 *self){ + if (self->script_embedded) { + printf("SWIG pm3 destructor, nothing to do\n"); + } else { + printf("SWIG pm3 destructor, close pm3\n"); + pm3_close(self); + } + } +#ifdef __cplusplus +extern "C" { +#endif +static int _wrap_new_pm3__SWIG_0(lua_State* L) { + int SWIG_arg = 0; + pm3 *result = 0 ; + + SWIG_check_num_args("pm3::pm3",0,0) + result = (pm3 *)new_pm3__SWIG_0(); + SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_new_pm3__SWIG_1(lua_State* L) { + int SWIG_arg = 0; + char *arg1 = (char *) 0 ; + pm3 *result = 0 ; + + SWIG_check_num_args("pm3::pm3",1,1) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("pm3::pm3",1,"char *"); + arg1 = (char *)lua_tostring(L, 1); + result = (pm3 *)new_pm3__SWIG_1(arg1); + SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_new_pm3(lua_State* L) { + int argc; + int argv[2]={ + 1,2 + }; + + argc = lua_gettop(L); + if (argc == 0) { + return _wrap_new_pm3__SWIG_0(L); + } + if (argc == 1) { + int _v; + { + _v = SWIG_lua_isnilstring(L,argv[0]); + } + if (_v) { + return _wrap_new_pm3__SWIG_1(L); + } + } + + SWIG_Lua_pusherrstring(L,"Wrong arguments for overloaded function 'new_pm3'\n" + " Possible C/C++ prototypes are:\n" + " pm3::pm3()\n" + " pm3::pm3(char *)\n"); + lua_error(L);return 0; +} + + +static int _wrap_pm3_console(lua_State* L) { + int SWIG_arg = 0; + pm3 *arg1 = (pm3 *) 0 ; + char *arg2 = (char *) 0 ; + int result; + + SWIG_check_num_args("pm3::console",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("pm3::console",1,"pm3 *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("pm3::console",2,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_pm3,0))){ + SWIG_fail_ptr("pm3_console",1,SWIGTYPE_p_pm3); + } + + arg2 = (char *)lua_tostring(L, 2); + result = (int)pm3_console(arg1,arg2); + lua_pushnumber(L, (lua_Number) result); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_pm3_name_get(lua_State* L) { + int SWIG_arg = 0; + pm3 *arg1 = (pm3 *) 0 ; + char *result = 0 ; + + SWIG_check_num_args("pm3::name",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("pm3::name",1,"pm3 *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_pm3,0))){ + SWIG_fail_ptr("pm3_name_get",1,SWIGTYPE_p_pm3); + } + + result = (char *)pm3_name_get(arg1); + lua_pushstring(L,(const char *)result); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static void swig_delete_pm3(void *obj) { +pm3 *arg1 = (pm3 *) obj; +delete_pm3(arg1); +} +static int _proxy__wrap_new_pm3(lua_State *L) { + assert(lua_istable(L,1)); + lua_pushcfunction(L,_wrap_new_pm3); + assert(!lua_isnil(L,-1)); + lua_replace(L,1); /* replace our table with real constructor */ + lua_call(L,lua_gettop(L)-1,1); + return 1; +} +static swig_lua_attribute swig_pm3_attributes[] = { + { "name", _wrap_pm3_name_get, SWIG_Lua_set_immutable }, + {0,0,0} +}; +static swig_lua_method swig_pm3_methods[]= { + { "console", _wrap_pm3_console}, + {0,0} +}; +static swig_lua_method swig_pm3_meta[] = { + {0,0} +}; + +static swig_lua_attribute swig_pm3_Sf_SwigStatic_attributes[] = { + {0,0,0} +}; +static swig_lua_const_info swig_pm3_Sf_SwigStatic_constants[]= { + {0,0,0,0,0,0} +}; +static swig_lua_method swig_pm3_Sf_SwigStatic_methods[]= { + {0,0} +}; +static swig_lua_class* swig_pm3_Sf_SwigStatic_classes[]= { + 0 +}; + +static swig_lua_namespace swig_pm3_Sf_SwigStatic = { + "pm3", + swig_pm3_Sf_SwigStatic_methods, + swig_pm3_Sf_SwigStatic_attributes, + swig_pm3_Sf_SwigStatic_constants, + swig_pm3_Sf_SwigStatic_classes, + 0 +}; +static swig_lua_class *swig_pm3_bases[] = {0}; +static const char *swig_pm3_base_names[] = {0}; +static swig_lua_class _wrap_class_pm3 = { "pm3", "pm3", &SWIGTYPE_p_pm3,_proxy__wrap_new_pm3, swig_delete_pm3, swig_pm3_methods, swig_pm3_attributes, &swig_pm3_Sf_SwigStatic, swig_pm3_meta, swig_pm3_bases, swig_pm3_base_names }; + +static swig_lua_attribute swig_SwigModule_attributes[] = { + {0,0,0} +}; +static swig_lua_const_info swig_SwigModule_constants[]= { + {0,0,0,0,0,0} +}; +static swig_lua_method swig_SwigModule_methods[]= { + {0,0} +}; +static swig_lua_class* swig_SwigModule_classes[]= { +&_wrap_class_pm3, + 0 +}; +static swig_lua_namespace* swig_SwigModule_namespaces[] = { + 0 +}; + +static swig_lua_namespace swig_SwigModule = { + "pm3", + swig_SwigModule_methods, + swig_SwigModule_attributes, + swig_SwigModule_constants, + swig_SwigModule_classes, + swig_SwigModule_namespaces +}; +#ifdef __cplusplus +} +#endif + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_pm3 = {"_p_pm3", "pm3 *", 0, 0, (void*)&_wrap_class_pm3, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_pm3, +}; + +static swig_cast_info _swigc__p_pm3[] = { {&_swigt__p_pm3, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_pm3, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned statically to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int init; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + iter=module_head; + do { + if (iter==&swig_module) { + /* Our module is already in the list, so there's nothing more to do. */ + return; + } + iter=iter->next; + } while (iter!= module_head); + + /* otherwise we must add our module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpreters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %lu\n", (unsigned long)swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ /* c-mode */ +#endif +} +#endif + + + +/* Forward declaration of where the user's %init{} gets inserted */ +void SWIG_init_user(lua_State* L ); + +#ifdef __cplusplus +extern "C" { +#endif +/* this is the initialization function + added at the very end of the code + the function is always called SWIG_init, but an earlier #define will rename it +*/ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) +LUALIB_API int SWIG_init(lua_State* L) +#else +SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */ +#endif +{ +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) /* valid for both Lua and eLua */ + int i; + int globalRegister = 0; + /* start with global table */ + lua_pushglobaltable (L); + /* SWIG's internal initialisation */ + SWIG_InitializeModule((void*)L); + SWIG_PropagateClientData(); +#endif + +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) || defined(SWIG_LUA_ELUA_EMULATE) + /* add a global fn */ + SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type); + SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_class_equal); +#endif + +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) + /* set up base class pointers (the hierarchy) */ + for (i = 0; swig_types[i]; i++){ + if (swig_types[i]->clientdata){ + SWIG_Lua_init_base_class(L,(swig_lua_class*)(swig_types[i]->clientdata)); + } + } +#ifdef SWIG_LUA_MODULE_GLOBAL + globalRegister = 1; +#endif + + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) + SWIG_Lua_namespace_register(L,&swig_SwigModule, globalRegister); +#endif + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) + for (i = 0; swig_types[i]; i++){ + if (swig_types[i]->clientdata){ + SWIG_Lua_elua_class_register_instance(L,(swig_lua_class*)(swig_types[i]->clientdata)); + } + } +#endif + +#if defined(SWIG_LUA_ELUA_EMULATE) + lua_newtable(L); + SWIG_Lua_elua_emulate_register(L,swig_SwigModule.ns_methods); + SWIG_Lua_elua_emulate_register_clear(L); + if(globalRegister) { + lua_pushstring(L,swig_SwigModule.name); + lua_pushvalue(L,-2); + lua_rawset(L,-4); + } +#endif + +#endif + +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) + /* invoke user-specific initialization */ + SWIG_init_user(L); + /* end module */ + /* Note: We do not clean up the stack here (Lua will do this for us). At this + point, we have the globals table and out module table on the stack. Returning + one value makes the module table the result of the require command. */ + return 1; +#else + return 0; +#endif +} + +#ifdef __cplusplus +} +#endif + + +const char* SWIG_LUACODE= + ""; + +void SWIG_init_user(lua_State* L) +{ + /* exec Lua code if applicable */ + SWIG_Lua_dostring(L,SWIG_LUACODE); +} + diff --git a/client/src/pm3_pywrap.c b/client/src/pm3_pywrap.c new file mode 100644 index 000000000..a3a5812ff --- /dev/null +++ b/client/src/pm3_pywrap.c @@ -0,0 +1,3781 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + + +#ifndef SWIGPYTHON +#define SWIGPYTHON +#endif + +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + + +#if defined(__GNUC__) && defined(_WIN32) && !defined(SWIG_PYTHON_NO_HYPOT_WORKAROUND) +/* Workaround for '::hypot' has not been declared', see https://bugs.python.org/issue11566 */ +# include +#endif + +#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG) +/* Use debug wrappers with the Python release dll */ +# undef _DEBUG +# include +# define _DEBUG 1 +#else +# include +#endif + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic C API SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. + + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 +#define SWIG_POINTER_NO_NULL 0x4 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The SWIG conversion methods, as ConvertPtr, return an integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old versions of SWIG, code such as the following was usually written: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + which is the same really, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + also requires SWIG_ConvertPtr to return new result values, such as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + SWIG errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() +*/ + +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast(r) (r) +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCmp(const char *nb, const char *tb) { + int equiv = 1; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (equiv != 0 && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = SWIG_TypeNameComp(nb, ne, tb, te); + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0; +} + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + size_t l = 0; + size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + const unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + unsigned char *u = (unsigned char *) ptr; + const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + char d = *(c++); + unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = (unsigned char)((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = (unsigned char)((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (unsigned char)(d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (unsigned char)(d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + +/* Compatibility macros for Python 3 */ +#if PY_VERSION_HEX >= 0x03000000 + +#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) +#define PyInt_Check(x) PyLong_Check(x) +#define PyInt_AsLong(x) PyLong_AsLong(x) +#define PyInt_FromLong(x) PyLong_FromLong(x) +#define PyInt_FromSize_t(x) PyLong_FromSize_t(x) +#define PyString_Check(name) PyBytes_Check(name) +#define PyString_FromString(x) PyUnicode_FromString(x) +#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) +#define PyString_AsString(str) PyBytes_AsString(str) +#define PyString_Size(str) PyBytes_Size(str) +#define PyString_InternFromString(key) PyUnicode_InternFromString(key) +#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE +#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x) +#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) + +#endif + +#ifndef Py_TYPE +# define Py_TYPE(op) ((op)->ob_type) +#endif + +/* SWIG APIs for compatibility of both Python 2 & 3 */ + +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_Python_str_FromFormat PyUnicode_FromFormat +#else +# define SWIG_Python_str_FromFormat PyString_FromFormat +#endif + + +/* Warning: This function will allocate a new string in Python 3, + * so please call SWIG_Python_str_DelForPy3(x) to free the space. + */ +SWIGINTERN char* +SWIG_Python_str_AsChar(PyObject *str) +{ +#if PY_VERSION_HEX >= 0x03000000 + char *newstr = 0; + str = PyUnicode_AsUTF8String(str); + if (str) { + char *cstr; + Py_ssize_t len; + PyBytes_AsStringAndSize(str, &cstr, &len); + newstr = (char *) malloc(len+1); + memcpy(newstr, cstr, len+1); + Py_XDECREF(str); + } + return newstr; +#else + return PyString_AsString(str); +#endif +} + +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) ) +#else +# define SWIG_Python_str_DelForPy3(x) +#endif + + +SWIGINTERN PyObject* +SWIG_Python_str_FromChar(const char *c) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromString(c); +#else + return PyString_FromString(c); +#endif +} + +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +// SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user +// interface files check for it. +# define SWIGPY_USE_CAPSULE +# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME) + +#if PY_VERSION_HEX < 0x03020000 +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) +#define Py_hash_t long +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + const char *tmp = SWIG_Python_str_AsChar(old_str); + PyErr_Clear(); + Py_XINCREF(type); + if (tmp) + PyErr_Format(type, "%s %s", tmp, mesg); + else + PyErr_Format(type, "%s", mesg); + SWIG_Python_str_DelForPy3(tmp); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_SetString(PyExc_RuntimeError, mesg); + } +} + +SWIGRUNTIME int +SWIG_Python_TypeErrorOccurred(PyObject *obj) +{ + PyObject *error; + if (obj) + return 0; + error = PyErr_Occurred(); + return error && PyErr_GivenExceptionMatches(error, PyExc_TypeError); +} + +SWIGRUNTIME void +SWIG_Python_RaiseOrModifyTypeError(const char *message) +{ + if (SWIG_Python_TypeErrorOccurred(NULL)) { + /* Use existing TypeError to preserve stacktrace and enhance with given message */ + PyObject *newvalue; + PyObject *type = NULL, *value = NULL, *traceback = NULL; + PyErr_Fetch(&type, &value, &traceback); +#if PY_VERSION_HEX >= 0x03000000 + newvalue = PyUnicode_FromFormat("%S\nAdditional information:\n%s", value, message); +#else + newvalue = PyString_FromFormat("%s\nAdditional information:\n%s", PyString_AsString(value), message); +#endif + Py_XDECREF(value); + PyErr_Restore(type, newvalue, traceback); + } else { + /* Raise TypeError using given message */ + PyErr_SetString(PyExc_TypeError, message); + } +} + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# define SWIG_PYTHON_USE_GIL +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + const char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +} +#endif + + +/* ----------------------------------------------------------------------------- + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +#if PY_VERSION_HEX < 0x02070000 /* 2.7.0 */ +# error "This version of SWIG only supports Python >= 2.7" +#endif + +#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03020000 +# error "This version of SWIG only supports Python 3 >= 3.2" +#endif + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) + +#ifdef SWIGPYTHON_BUILTIN +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags) +#else +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) +#endif + +#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) + +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata) +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +#if defined(SWIGPYTHON_BUILTIN) + +SWIGINTERN void +SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) { + PyObject *s = PyString_InternFromString(key); + PyList_Append(seq, s); + Py_DECREF(s); +} + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) { + PyDict_SetItemString(d, name, obj); + Py_DECREF(obj); + if (public_interface) + SwigPyBuiltin_AddPublicSymbol(public_interface, name); +} + +#else + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, name, obj); + Py_DECREF(obj); +} + +#endif + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +} + +/* Unpack the argument tuple */ + +SWIGINTERN Py_ssize_t +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + if (min <= 1 && max >= 1) { + Py_ssize_t i; + objs[0] = args; + for (i = 1; i < max; ++i) { + objs[i] = 0; + } + return 2; + } + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + Py_ssize_t i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2) +#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN) + +#ifdef __cplusplus +extern "C" { +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* SwigPyClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; + PyTypeObject *pytype; +} SwigPyClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; + int fail = data ? data->implicitconv : 0; + if (fail) + PyErr_SetString(PyExc_TypeError, "Implicit conversion is prohibited for explicit constructors."); + return fail; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME SwigPyClientData * +SwigPyClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { + data->newraw = PyObject_GetAttrString(data->klass, "__new__"); + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); + data->delargs = !(flags & (METH_O)); + } else { + data->delargs = 0; + } + data->implicitconv = 0; + data->pytype = 0; + return data; + } +} + +SWIGRUNTIME void +SwigPyClientData_Del(SwigPyClientData *data) { + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== SwigPyObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +#ifdef SWIGPYTHON_BUILTIN + PyObject *dict; +#endif +} SwigPyObject; + + +#ifdef SWIGPYTHON_BUILTIN + +SWIGRUNTIME PyObject * +SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + + if (!sobj->dict) + sobj->dict = PyDict_New(); + + Py_INCREF(sobj->dict); + return sobj->dict; +} + +#endif + +SWIGRUNTIME PyObject * +SwigPyObject_long(SwigPyObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +SwigPyObject_format(const char* fmt, SwigPyObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) { + PyObject *ofmt = SWIG_Python_str_FromChar(fmt); + if (ofmt) { +#if PY_VERSION_HEX >= 0x03000000 + res = PyUnicode_Format(ofmt,args); +#else + res = PyString_Format(ofmt,args); +#endif + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +SwigPyObject_oct(SwigPyObject *v) +{ + return SwigPyObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +SwigPyObject_hex(SwigPyObject *v) +{ + return SwigPyObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +SwigPyObject_repr(SwigPyObject *v) +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *repr = SWIG_Python_str_FromFormat("", (name ? name : "unknown"), (void *)v); + if (v->next) { + PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); +# if PY_VERSION_HEX >= 0x03000000 + PyObject *joined = PyUnicode_Concat(repr, nrep); + Py_DecRef(repr); + Py_DecRef(nrep); + repr = joined; +# else + PyString_ConcatAndDel(&repr,nrep); +# endif + } + return repr; +} + +/* We need a version taking two PyObject* parameters so it's a valid + * PyCFunction to use in swigobject_methods[]. */ +SWIGRUNTIME PyObject * +SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) +{ + return SwigPyObject_repr((SwigPyObject*)v); +} + +SWIGRUNTIME int +SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +/* Added for Python 3.x, would it also be useful for Python 2.x? */ +SWIGRUNTIME PyObject* +SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) +{ + PyObject* res; + if( op != Py_EQ && op != Py_NE ) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0); + return res; +} + + +SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void); + +#ifdef SWIGPYTHON_BUILTIN +static swig_type_info *SwigPyObject_stype = 0; +SWIGRUNTIME PyTypeObject* +SwigPyObject_type(void) { + SwigPyClientData *cd; + assert(SwigPyObject_stype); + cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; + assert(cd); + assert(cd->pytype); + return cd->pytype; +} +#else +SWIGRUNTIME PyTypeObject* +SwigPyObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce(); + return type; +} +#endif + +SWIGRUNTIMEINLINE int +SwigPyObject_Check(PyObject *op) { +#ifdef SWIGPYTHON_BUILTIN + PyTypeObject *target_tp = SwigPyObject_type(); + if (PyType_IsSubtype(op->ob_type, target_tp)) + return 1; + return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0); +#else + return (Py_TYPE(op) == SwigPyObject_type()) + || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); +#endif +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +SwigPyObject_dealloc(PyObject *v) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + PyObject *next = sobj->next; + if (sobj->own == SWIG_POINTER_OWN) { + swig_type_info *ty = sobj->ty; + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + + /* PyObject_CallFunction() has the potential to silently drop + the active exception. In cases of unnamed temporary + variable or where we just finished iterating over a generator + StopIteration will be active right now, and this needs to + remain true upon return from SwigPyObject_dealloc. So save + and restore. */ + + PyObject *type = NULL, *value = NULL, *traceback = NULL; + PyErr_Fetch(&type, &value, &traceback); + + if (data->delargs) { + /* we need to create a temporary object to carry the destroy operation */ + PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + if (!res) + PyErr_WriteUnraisable(destroy); + + PyErr_Restore(type, value, traceback); + + Py_XDECREF(res); + } +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); + } +#endif + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +SwigPyObject_append(PyObject* v, PyObject* next) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + if (!SwigPyObject_Check(next)) { + PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject"); + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +SwigPyObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; + if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) { + return NULL; + } else { + SwigPyObject *sobj = (SwigPyObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { + if (PyObject_IsTrue(val)) { + SwigPyObject_acquire(v,args); + } else { + SwigPyObject_disown(v,args); + } + } + return obj; + } +} + +static PyMethodDef +swigobject_methods[] = { + {"disown", SwigPyObject_disown, METH_NOARGS, "releases ownership of the pointer"}, + {"acquire", SwigPyObject_acquire, METH_NOARGS, "acquires ownership of the pointer"}, + {"own", SwigPyObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, + {"append", SwigPyObject_append, METH_O, "appends another 'this' object"}, + {"next", SwigPyObject_next, METH_NOARGS, "returns the next 'this' object"}, + {"__repr__",SwigPyObject_repr2, METH_NOARGS, "returns object representation"}, + {0, 0, 0, 0} +}; + +SWIGRUNTIME PyTypeObject* +SwigPyObject_TypeOnce(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods SwigPyObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + /* nb_divide removed in Python 3 */ +#if PY_VERSION_HEX < 0x03000000 + (binaryfunc)0, /*nb_divide*/ +#endif + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ +#if PY_VERSION_HEX < 0x03000000 + 0, /*nb_coerce*/ +#endif + (unaryfunc)SwigPyObject_long, /*nb_int*/ +#if PY_VERSION_HEX < 0x03000000 + (unaryfunc)SwigPyObject_long, /*nb_long*/ +#else + 0, /*nb_reserved*/ +#endif + (unaryfunc)0, /*nb_float*/ +#if PY_VERSION_HEX < 0x03000000 + (unaryfunc)SwigPyObject_oct, /*nb_oct*/ + (unaryfunc)SwigPyObject_hex, /*nb_hex*/ +#endif +#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */ +#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ +#else + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#endif + }; + + static PyTypeObject swigpyobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "SwigPyObject", /* tp_name */ + sizeof(SwigPyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyObject_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ +#if PY_VERSION_HEX >= 0x03000000 + 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ +#else + (cmpfunc)SwigPyObject_compare, /* tp_compare */ +#endif + (reprfunc)SwigPyObject_repr, /* tp_repr */ + &SwigPyObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + swigpyobject_type = tmp; + type_init = 1; + if (PyType_Ready(&swigpyobject_type) < 0) + return NULL; + } + return &swigpyobject_type; +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own) +{ + SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} SwigPyPacked; + +SWIGRUNTIME PyObject * +SwigPyPacked_repr(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return SWIG_Python_str_FromFormat("", result, v->ty->name); + } else { + return SWIG_Python_str_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +SwigPyPacked_str(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); + } else { + return SWIG_Python_str_FromChar(v->ty->name); + } +} + +SWIGRUNTIME int +SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((const char *)v->pack, (const char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void); + +SWIGRUNTIME PyTypeObject* +SwigPyPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce(); + return type; +} + +SWIGRUNTIMEINLINE int +SwigPyPacked_Check(PyObject *op) { + return ((op)->ob_type == SwigPyPacked_TypeOnce()) + || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); +} + +SWIGRUNTIME void +SwigPyPacked_dealloc(PyObject *v) +{ + if (SwigPyPacked_Check(v)) { + SwigPyPacked *sobj = (SwigPyPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +SwigPyPacked_TypeOnce(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject swigpypacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX>=0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "SwigPyPacked", /* tp_name */ + sizeof(SwigPyPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ +#if PY_VERSION_HEX>=0x03000000 + 0, /* tp_reserved in 3.0.1 */ +#else + (cmpfunc)SwigPyPacked_compare, /* tp_compare */ +#endif + (reprfunc)SwigPyPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)SwigPyPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + swigpypacked_type = tmp; + type_init = 1; + if (PyType_Ready(&swigpypacked_type) < 0) + return NULL; + } + return &swigpypacked_type; +} + +SWIGRUNTIME PyObject * +SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (SwigPyPacked_Check(obj)) { + SwigPyPacked *sobj = (SwigPyPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +static PyObject *Swig_This_global = NULL; + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + if (Swig_This_global == NULL) + Swig_This_global = SWIG_Python_str_FromChar("this"); + return Swig_This_global; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +/* TODO: I don't know how to implement the fast getset in Python 3 right now */ +#if PY_VERSION_HEX>=0x03000000 +#define SWIG_PYTHON_SLOW_GETSET_THIS +#endif + +SWIGRUNTIME SwigPyObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + PyObject *obj; + + if (SwigPyObject_Check(pyobj)) + return (SwigPyObject *) pyobj; + +#ifdef SWIGPYTHON_BUILTIN + (void)obj; +# ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + pyobj = PyWeakref_GET_OBJECT(pyobj); + if (pyobj && SwigPyObject_Check(pyobj)) + return (SwigPyObject*) pyobj; + } +# endif + return NULL; +#else + + obj = 0; + +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !SwigPyObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + SwigPyObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (SwigPyObject *)obj; +#endif +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own == SWIG_POINTER_OWN) { + SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + int res; + SwigPyObject *sobj; + int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0; + + if (!obj) + return SWIG_ERROR; + if (obj == Py_None && !implicit_conv) { + if (ptr) + *ptr = 0; + return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK; + } + + res = SWIG_ERROR; + + sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (SwigPyObject *)sobj->next; + } else { + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) + *own = *own | sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + res = SWIG_OK; + } else { + if (implicit_conv) { + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + if (!SWIG_IsOK(res) && obj == Py_None) { + if (ptr) + *ptr = 0; + if (PyErr_Occurred()) + PyErr_Clear(); + res = SWIG_OK; + } + } + } + return res; +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + swig_cast_info *tc; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) + return SWIG_ERROR; + tc = SWIG_TypeCheck(desc,ty); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } + return SWIG_OK; + } +} + +/* Convert a packed pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, without calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) +{ + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { +#if PY_VERSION_HEX >= 0x03000000 + PyObject *empty_args = PyTuple_New(0); + if (empty_args) { + PyObject *empty_kwargs = PyDict_New(); + if (empty_kwargs) { + inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, empty_kwargs); + Py_DECREF(empty_kwargs); + if (inst) { + PyObject_SetAttr(inst, SWIG_This(), swig_this); + Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; + } + } + Py_DECREF(empty_args); + } +#else + PyObject *dict = PyDict_New(); + if (dict) { + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } +#endif + } + return inst; +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, "__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) { + return NULL; + } else { + SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + SwigPyObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) { + SwigPyClientData *clientdata; + PyObject * robj; + int own; + + if (!ptr) + return SWIG_Py_Void(); + + clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; + own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + if (clientdata && clientdata->pytype) { + SwigPyObject *newobj; + if (flags & SWIG_BUILTIN_TP_INIT) { + newobj = (SwigPyObject*) self; + if (newobj->ptr) { + PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0); + while (newobj->next) + newobj = (SwigPyObject *) newobj->next; + newobj->next = next_self; + newobj = (SwigPyObject *)next_self; +#ifdef SWIGPYTHON_BUILTIN + newobj->dict = 0; +#endif + } + } else { + newobj = PyObject_New(SwigPyObject, clientdata->pytype); +#ifdef SWIGPYTHON_BUILTIN + newobj->dict = 0; +#endif + } + if (newobj) { + newobj->ptr = ptr; + newobj->ty = type; + newobj->own = own; + newobj->next = 0; + return (PyObject*) newobj; + } + return SWIG_Py_Void(); + } + + assert(!(flags & SWIG_BUILTIN_TP_INIT)); + + robj = SwigPyObject_New(ptr, type, own); + if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + Py_DECREF(robj); + robj = inst; + } + return robj; +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +SWIGRUNTIME void +SWIG_Python_DestroyModule(PyObject *obj) +{ + swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME); + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; + if (data) SwigPyClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); + Swig_This_global = NULL; +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { +#if PY_VERSION_HEX >= 0x03000000 + /* Add a dummy module object into sys.modules */ + PyObject *module = PyImport_AddModule("swig_runtime_data" SWIG_RUNTIME_VERSION); +#else + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */ + PyObject *module = Py_InitModule("swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table); +#endif + PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = SWIG_Python_str_FromChar(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL); + } else { + swig_module_info *swig_module = SWIG_GetModule(0); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCapsule_New((void*) descriptor, NULL, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + const char *tmp = SWIG_Python_str_AsChar(old_str); + const char *errmesg = tmp ? tmp : "Invalid error message"; + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, errmesg); + } else { + PyErr_Format(type, "%s %s", errmesg, mesg); + } + SWIG_Python_str_DelForPy3(tmp); + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +SwigPyObject_GetDesc(PyObject *self) +{ + SwigPyObject *v = (SwigPyObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : ""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && SwigPyObject_Check(obj)) { + const char *otype = (const char *) SwigPyObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + SWIG_Python_str_DelForPy3(cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); +#if SWIG_POINTER_EXCEPTION + if (flags) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } +#endif + } + return result; +} + +#ifdef SWIGPYTHON_BUILTIN +SWIGRUNTIME int +SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { + PyTypeObject *tp = obj->ob_type; + PyObject *descr; + PyObject *encoded_name; + descrsetfunc f; + int res = -1; + +# ifdef Py_USING_UNICODE + if (PyString_Check(name)) { + name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL); + if (!name) + return -1; + } else if (!PyUnicode_Check(name)) +# else + if (!PyString_Check(name)) +# endif + { + PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name); + return -1; + } else { + Py_INCREF(name); + } + + if (!tp->tp_dict) { + if (PyType_Ready(tp) < 0) + goto done; + } + + descr = _PyType_Lookup(tp, name); + f = NULL; + if (descr != NULL) + f = descr->ob_type->tp_descr_set; + if (!f) { + if (PyString_Check(name)) { + encoded_name = name; + Py_INCREF(name); + } else { + encoded_name = PyUnicode_AsUTF8String(name); + if (!encoded_name) + return -1; + } + PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name)); + Py_DECREF(encoded_name); + } else { + res = f(descr, obj, value); + } + + done: + Py_DECREF(name); + return res; +} +#endif + + +#ifdef __cplusplus +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Method creation and docstring support functions */ + +SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name); +SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func); +SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func); + +#ifdef __cplusplus +} +#endif + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_char swig_types[0] +#define SWIGTYPE_p_pm3 swig_types[1] +static swig_type_info *swig_types[3]; +static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery + +/*----------------------------------------------- + @(target):= _pm3.so + ------------------------------------------------*/ +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_init PyInit__pm3 + +#else +# define SWIG_init init_pm3 + +#endif +#define SWIG_name "_pm3" + +#define SWIGVERSION 0x040001 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +/* Include the header in the wrapper code */ +#include "pm3.h" +#include "comms.h" + +SWIGINTERN pm3 *new_pm3__SWIG_0(void){ + printf("SWIG pm3 constructor, get current pm3\n"); + pm3_device * p = pm3_get_current_dev(); + p->script_embedded = 1; + return p; + } + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ +#if PY_VERSION_HEX>=0x03000000 +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + if (PyBytes_Check(obj)) +#else + if (PyUnicode_Check(obj)) +#endif +#else + if (PyString_Check(obj)) +#endif + { + char *cstr; Py_ssize_t len; + int ret = SWIG_OK; +#if PY_VERSION_HEX>=0x03000000 +#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + if (!alloc && cptr) { + /* We can't allow converting without allocation, since the internal + representation of string in Python 3 is UCS-2/UCS-4 but we require + a UTF-8 representation. + TODO(bhy) More detailed explanation */ + return SWIG_RuntimeError; + } + obj = PyUnicode_AsUTF8String(obj); + if (!obj) + return SWIG_TypeError; + if (alloc) + *alloc = SWIG_NEWOBJ; +#endif + PyBytes_AsStringAndSize(obj, &cstr, &len); +#else + PyString_AsStringAndSize(obj, &cstr, &len); +#endif + if (cptr) { + if (alloc) { + if (*alloc == SWIG_NEWOBJ) { + *cptr = (char *)memcpy(malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { +#if PY_VERSION_HEX>=0x03000000 +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + *cptr = PyBytes_AsString(obj); +#else + assert(0); /* Should never reach here with Unicode strings in Python 3 */ +#endif +#else + *cptr = SWIG_Python_str_AsChar(obj); + if (!*cptr) + ret = SWIG_TypeError; +#endif + } + } + if (psize) *psize = len + 1; +#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + Py_XDECREF(obj); +#endif + return ret; + } else { +#if defined(SWIG_PYTHON_2_UNICODE) +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) +#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once" +#endif +#if PY_VERSION_HEX<0x03000000 + if (PyUnicode_Check(obj)) { + char *cstr; Py_ssize_t len; + if (!alloc && cptr) { + return SWIG_RuntimeError; + } + obj = PyUnicode_AsUTF8String(obj); + if (!obj) + return SWIG_TypeError; + if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) { + if (cptr) { + if (alloc) *alloc = SWIG_NEWOBJ; + *cptr = (char *)memcpy(malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + } + if (psize) *psize = len + 1; + + Py_XDECREF(obj); + return SWIG_OK; + } else { + Py_XDECREF(obj); + } + } +#endif +#endif + + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + +SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ + printf("SWIG pm3 constructor with port, open pm3\n"); + pm3_device * p = pm3_open(port); + p->script_embedded = 0; + return p; + } +SWIGINTERN void delete_pm3(pm3 *self){ + if (self->script_embedded) { + printf("SWIG pm3 destructor, nothing to do\n"); + } else { + printf("SWIG pm3 destructor, close pm3\n"); + pm3_close(self); + } + } + +SWIGINTERNINLINE PyObject* + SWIG_From_int (int value) +{ + return PyInt_FromLong((long) value); +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_InternalNewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { +#if PY_VERSION_HEX >= 0x03000000 +#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) + return PyBytes_FromStringAndSize(carray, (Py_ssize_t)(size)); +#else + return PyUnicode_DecodeUTF8(carray, (Py_ssize_t)(size), "surrogateescape"); +#endif +#else + return PyString_FromStringAndSize(carray, (Py_ssize_t)(size)); +#endif + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_new_pm3__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) { + PyObject *resultobj = 0; + pm3 *result = 0 ; + + if ((nobjs < 0) || (nobjs > 0)) SWIG_fail; + result = (pm3 *)new_pm3__SWIG_0(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_pm3, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_pm3__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + pm3 *result = 0 ; + + if ((nobjs < 1) || (nobjs > 1)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(swig_obj[0], &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_pm3" "', argument " "1"" of type '" "char *""'"); + } + arg1 = (char *)(buf1); + result = (pm3 *)new_pm3__SWIG_1(arg1); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_pm3, SWIG_POINTER_NEW | 0 ); + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_pm3(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[2] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_pm3", 0, 1, argv))) SWIG_fail; + --argc; + if (argc == 0) { + return _wrap_new_pm3__SWIG_0(self, argc, argv); + } + if (argc == 1) { + int _v; + int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_pm3__SWIG_1(self, argc, argv); + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_pm3'.\n" + " Possible C/C++ prototypes are:\n" + " pm3::pm3()\n" + " pm3::pm3(char *)\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_delete_pm3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + pm3 *arg1 = (pm3 *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_pm3, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_pm3" "', argument " "1"" of type '" "pm3 *""'"); + } + arg1 = (pm3 *)(argp1); + delete_pm3(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_pm3_console(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + pm3 *arg1 = (pm3 *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject *swig_obj[2] ; + int result; + + if (!SWIG_Python_UnpackTuple(args, "pm3_console", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_pm3, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_console" "', argument " "1"" of type '" "pm3 *""'"); + } + arg1 = (pm3 *)(argp1); + res2 = SWIG_AsCharPtrAndSize(swig_obj[1], &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pm3_console" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)pm3_console(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_pm3_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + pm3 *arg1 = (pm3 *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + char *result = 0 ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_pm3, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_name_get" "', argument " "1"" of type '" "pm3 *""'"); + } + arg1 = (pm3 *)(argp1); + result = (char *)pm3_name_get(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *pm3_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_pm3, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *pm3_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +static PyMethodDef SwigMethods[] = { + { "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL}, + { "new_pm3", _wrap_new_pm3, METH_VARARGS, NULL}, + { "delete_pm3", _wrap_delete_pm3, METH_O, NULL}, + { "pm3_console", _wrap_pm3_console, METH_VARARGS, NULL}, + { "pm3_name_get", _wrap_pm3_name_get, METH_O, NULL}, + { "pm3_swigregister", pm3_swigregister, METH_O, NULL}, + { "pm3_swiginit", pm3_swiginit, METH_VARARGS, NULL}, + { NULL, NULL, 0, NULL } +}; + +static PyMethodDef SwigMethods_proxydocs[] = { + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_pm3 = {"_p_pm3", "pm3 *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_char, + &_swigt__p_pm3, +}; + +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_pm3[] = { {&_swigt__p_pm3, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_char, + _swigc__p_pm3, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned statically to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int init; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + iter=module_head; + do { + if (iter==&swig_module) { + /* Our module is already in the list, so there's nothing more to do. */ + return; + } + iter=iter->next; + } while (iter!= module_head); + + /* otherwise we must add our module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpreters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %lu\n", (unsigned long)swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_InternFromString(""); +#else + return PyString_FromString(""); +#endif + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { +#if PY_VERSION_HEX >= 0x03000000 + PyObject *str = PyUnicode_InternFromString("("); + PyObject *tail; + PyObject *joined; + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + tail = PyUnicode_FromString(var->name); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + if (var->next) { + tail = PyUnicode_InternFromString(", "); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + } + } + tail = PyUnicode_InternFromString(")"); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; +#else + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); +#endif + return str; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp = { +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(NULL, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + "swigvarlink", /* tp_name */ + sizeof(swig_varlinkobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) swig_varlink_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc) swig_varlink_getattr, /* tp_getattr */ + (setattrfunc) swig_varlink_setattr, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ +#if PY_VERSION_HEX >= 0x03040000 + 0, /* tp_finalize */ +#endif +#ifdef COUNT_ALLOCS + 0, /* tp_allocs */ + 0, /* tp_frees */ + 0, /* tp_maxalloc */ + 0, /* tp_prev */ + 0 /* tp_next */ +#endif + }; + varlink_type = tmp; + type_init = 1; + if (PyType_Ready(&varlink_type) < 0) + return NULL; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + memcpy(gv->name, name, size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *globals = 0; + if (!globals) { + globals = SWIG_newvarlink(); + } + return globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (!c) continue; + c = strstr(c, "swig_ptr: "); + if (c) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + memcpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + memcpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + + /* ----------------------------------------------------------------------------- + * Method creation and docstring support functions + * ----------------------------------------------------------------------------- */ + + /* ----------------------------------------------------------------------------- + * Function to find the method definition with the correct docstring for the + * proxy module as opposed to the low-level API + * ----------------------------------------------------------------------------- */ + + SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name) { + /* Find the function in the modified method table */ + size_t offset = 0; + int found = 0; + while (SwigMethods_proxydocs[offset].ml_meth != NULL) { + if (strcmp(SwigMethods_proxydocs[offset].ml_name, name) == 0) { + found = 1; + break; + } + offset++; + } + /* Use the copy with the modified docstring if available */ + return found ? &SwigMethods_proxydocs[offset] : NULL; + } + + /* ----------------------------------------------------------------------------- + * Wrapper of PyInstanceMethod_New() used in Python 3 + * It is exported to the generated module, used for -fastproxy + * ----------------------------------------------------------------------------- */ + + SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) { + if (PyCFunction_Check(func)) { + PyCFunctionObject *funcobj = (PyCFunctionObject *)func; + PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name); + if (ml) + func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module); + } +#if PY_VERSION_HEX >= 0x03000000 + return PyInstanceMethod_New(func); +#else + return PyMethod_New(func, NULL, NULL); +#endif + } + + /* ----------------------------------------------------------------------------- + * Wrapper of PyStaticMethod_New() + * It is exported to the generated module, used for -fastproxy + * ----------------------------------------------------------------------------- */ + + SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) { + if (PyCFunction_Check(func)) { + PyCFunctionObject *funcobj = (PyCFunctionObject *)func; + PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name); + if (ml) + func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module); + } + return PyStaticMethod_New(func); + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif + +SWIGEXPORT +#if PY_VERSION_HEX >= 0x03000000 +PyObject* +#else +void +#endif +SWIG_init(void) { + PyObject *m, *d, *md, *globals; + +#if PY_VERSION_HEX >= 0x03000000 + static struct PyModuleDef SWIG_module = { + PyModuleDef_HEAD_INIT, + SWIG_name, + NULL, + -1, + SwigMethods, + NULL, + NULL, + NULL, + NULL + }; +#endif + +#if defined(SWIGPYTHON_BUILTIN) + static SwigPyClientData SwigPyObject_clientdata = { + 0, 0, 0, 0, 0, 0, 0 + }; + static PyGetSetDef this_getset_def = { + (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL + }; + static SwigPyGetSet thisown_getset_closure = { + SwigPyObject_own, + SwigPyObject_own + }; + static PyGetSetDef thisown_getset_def = { + (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure + }; + PyTypeObject *builtin_pytype; + int builtin_base_count; + swig_type_info *builtin_basetype; + PyObject *tuple; + PyGetSetDescrObject *static_getset; + PyTypeObject *metatype; + PyTypeObject *swigpyobject; + SwigPyClientData *cd; + PyObject *public_interface, *public_symbol; + PyObject *this_descr; + PyObject *thisown_descr; + PyObject *self = 0; + int i; + + (void)builtin_pytype; + (void)builtin_base_count; + (void)builtin_basetype; + (void)tuple; + (void)static_getset; + (void)self; + + /* Metaclass is used to implement static member variables */ + metatype = SwigPyObjectType(); + assert(metatype); +#endif + + (void)globals; + + /* Create singletons now to avoid potential deadlocks with multi-threaded usage after module initialization */ + SWIG_This(); + SWIG_Python_TypeCache(); + SwigPyPacked_type(); +#ifndef SWIGPYTHON_BUILTIN + SwigPyObject_type(); +#endif + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + +#if PY_VERSION_HEX >= 0x03000000 + m = PyModule_Create(&SWIG_module); +#else + m = Py_InitModule(SWIG_name, SwigMethods); +#endif + + md = d = PyModule_GetDict(m); + (void)md; + + SWIG_InitializeModule(0); + +#ifdef SWIGPYTHON_BUILTIN + swigpyobject = SwigPyObject_TypeOnce(); + + SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject"); + assert(SwigPyObject_stype); + cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; + if (!cd) { + SwigPyObject_stype->clientdata = &SwigPyObject_clientdata; + SwigPyObject_clientdata.pytype = swigpyobject; + } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) { + PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules."); +# if PY_VERSION_HEX >= 0x03000000 + return NULL; +# else + return; +# endif + } + + /* All objects have a 'this' attribute */ + this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def); + (void)this_descr; + + /* All objects have a 'thisown' attribute */ + thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def); + (void)thisown_descr; + + public_interface = PyList_New(0); + public_symbol = 0; + (void)public_symbol; + + PyDict_SetItemString(md, "__all__", public_interface); + Py_DECREF(public_interface); + for (i = 0; SwigMethods[i].ml_name != NULL; ++i) + SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name); + for (i = 0; swig_const_table[i].name != 0; ++i) + SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name); +#endif + + SWIG_InstallConstants(d,swig_const_table); + +#if PY_VERSION_HEX >= 0x03000000 + return m; +#else + return; +#endif +} + diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 7554e41ca..113da7248 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -34,6 +34,7 @@ #include "flash.h" #include "preferences.h" +#ifndef LIBPM3 #define BANNERMSG1 " Iceman :coffee:" #define BANNERMSG2 " :snowflake: bleeding edge" #define BANNERMSG3 " https://github.com/rfidresearchgroup/proxmark3/" @@ -113,6 +114,7 @@ static void showBanner(void) { fflush(stdout); g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; } +#endif //LIBPM3 static const char *prompt_dev = ""; static const char *prompt_ctx = ""; @@ -134,7 +136,7 @@ static int check_comm(void) { rl_set_prompt(prompt_filtered); rl_forced_update_display(); #endif - CloseProxmark(); + CloseProxmark(session.current_device); } msleep(10); return 0; @@ -452,6 +454,7 @@ check_script: } } +#ifndef LIBPM3 static void dumpAllHelp(int markdown) { session.help_dump_mode = true; PrintAndLogEx(NORMAL, "\n%sProxmark3 command dump%s\n\n", markdown ? "# " : "", markdown ? "" : "\n======================"); @@ -462,6 +465,7 @@ static void dumpAllHelp(int markdown) { dumpCommandsRecursive(cmds, markdown); session.help_dump_mode = false; } +#endif //LIBPM3 static char *my_executable_path = NULL; static char *my_executable_directory = NULL; @@ -546,6 +550,7 @@ static void set_my_user_directory(void) { } } +#ifndef LIBPM3 static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, "\nsyntax: %s [-h|-t|-m]", exec_name); @@ -631,7 +636,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ PrintAndLogEx(SUCCESS, " "_YELLOW_("%s"), filepaths[i]); } - if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { + if (OpenProxmark(&session.current_device, serial_port_name, true, 60, true, FLASHMODE_SPEED)) { PrintAndLogEx(NORMAL, _GREEN_(" found")); } else { PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); @@ -669,7 +674,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ finish: ret = flash_stop_flashing(); - CloseProxmark(); + CloseProxmark(session.current_device); finish2: for (int i = 0 ; i < num_files; ++i) { if (filepaths[i] != NULL) @@ -682,6 +687,7 @@ finish2: PrintAndLogEx(NORMAL, "\nHave a nice day!"); return ret; } +#endif //LIBPM3 #if defined(_WIN32) static bool DetectWindowsAnsiSupport(void) { @@ -696,14 +702,28 @@ static bool DetectWindowsAnsiSupport(void) { return SetConsoleMode(hOut, dwMode) ? true : false; } -#endif +#endif //_WIN32 -int main(int argc, char *argv[]) { +void pm3_init(void) { srand(time(0)); session.pm3_present = false; session.help_dump_mode = false; session.incognito = false; + session.supports_colors = false; + session.emoji_mode = ALTTEXT; + session.stdinOnTTY = false; + session.stdoutOnTTY = false; + + // set global variables soon enough to get the log path + set_my_executable_path(); + set_my_user_directory(); + +} + +#ifndef LIBPM3 +int main(int argc, char *argv[]) { + pm3_init(); bool waitCOMPort = false; bool addLuaExec = false; bool stayInCommandLoop = false; @@ -737,10 +757,6 @@ int main(int argc, char *argv[]) { int flash_num_files = 0; char *flash_filenames[FLASH_MAX_FILES]; - // set global variables soon enough to get the log path - set_my_executable_path(); - set_my_user_directory(); - // color management: // 1. default = no color // 2. enable colors if OS seems to support colors and if stdin/stdout aren't redirected @@ -999,12 +1015,12 @@ int main(int argc, char *argv[]) { // try to open USB connection to Proxmark if (port != NULL) { - OpenProxmark(port, waitCOMPort, 20, false, speed); + OpenProxmark(&session.current_device, port, waitCOMPort, 20, false, speed); } - if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) { + if (session.pm3_present && (TestProxmark(session.current_device) != PM3_SUCCESS)) { PrintAndLogEx(ERR, _RED_("ERROR:") " cannot communicate with the Proxmark\n"); - CloseProxmark(); + CloseProxmark(session.current_device); } if ((port != NULL) && (!session.pm3_present)) @@ -1060,10 +1076,11 @@ int main(int argc, char *argv[]) { // Clean up the port if (session.pm3_present) { - CloseProxmark(); + CloseProxmark(session.current_device); } if (session.window_changed) // Plot/Overlay moved or resized preferences_save(); exit(EXIT_SUCCESS); } +#endif //LIBPM3 diff --git a/client/src/proxmark3.h b/client/src/proxmark3.h index 6d7e9dfb4..dc5bab2b9 100644 --- a/client/src/proxmark3.h +++ b/client/src/proxmark3.h @@ -49,6 +49,7 @@ int push_cmdscriptfile(char *path, bool stayafter); const char *get_my_executable_path(void); const char *get_my_executable_directory(void); const char *get_my_user_directory(void); +void pm3_init(void); void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); #ifdef __cplusplus diff --git a/client/src/ui.h b/client/src/ui.h index b30f6c868..1a8a14028 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -13,6 +13,7 @@ #include #include "common.h" +#include "comms.h" #include "ansi.h" #ifdef __cplusplus @@ -46,6 +47,7 @@ typedef struct { clientdebugLevel_t client_debug_level; // uint8_t device_debug_level; char *history_path; + pm3_device *current_device; } session_arg_t; extern session_arg_t session; From 8f67b511a61e951ddac1de3388faf0b06de52e1c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Nov 2020 18:01:04 +0100 Subject: [PATCH 13/69] textual, in prep for removing dump_buffer_simple --- client/src/cmdhffido.c | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 53cb10c98..818dc6f35 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -292,7 +292,7 @@ static int cmd_hf_fido_register(const char *cmd) { if (APDULogging) PrintAndLogEx(INFO, "---------------------------------------------------------------"); - PrintAndLogEx(NORMAL, "data len: %zu", len); + PrintAndLogEx(INFO, "data len: %zu", len); if (verbose2) { PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------"); @@ -312,13 +312,14 @@ static int cmd_hf_fido_register(const char *cmd) { int derp = 67 + keyHandleLen; int derLen = (buf[derp + 2] << 8) + buf[derp + 3] + 4; if (verbose2) { - PrintAndLogEx(NORMAL, "DER certificate[%d]:\n------------------DER-------------------", derLen); - dump_buffer_simple((const unsigned char *)&buf[derp], derLen, NULL); - PrintAndLogEx(NORMAL, "\n----------------DER---------------------"); + PrintAndLogEx(INFO, "DER certificate[%d]:"); + PrintAndLogEx(INFO, "------------------DER-------------------", derLen); + PrintAndLogEx(INFO, "%s", sprint_hex(buf + derp, derLen)); + PrintAndLogEx(INFO, "----------------DER---------------------"); } else { if (verbose) - PrintAndLogEx(NORMAL, "------------------DER-------------------"); - PrintAndLogEx(NORMAL, "DER certificate[%d]: %s...", derLen, sprint_hex(&buf[derp], 20)); + PrintAndLogEx(INFO, "------------------DER-------------------"); + PrintAndLogEx(INFO, "DER certificate[%d]: %s...", derLen, sprint_hex(&buf[derp], 20)); } // check and print DER certificate @@ -326,9 +327,9 @@ static int cmd_hf_fido_register(const char *cmd) { // print DER certificate in TLV view if (showDERTLV) { - PrintAndLogEx(NORMAL, "----------------DER TLV-----------------"); + PrintAndLogEx(INFO, "----------------DER TLV-----------------"); asn1_print(&buf[derp], derLen, " "); - PrintAndLogEx(NORMAL, "----------------DER TLV-----------------"); + PrintAndLogEx(INFO, "----------------DER TLV-----------------"); } FIDOCheckDERAndGetKey(&buf[derp], derLen, verbose, public_key, sizeof(public_key)); @@ -343,8 +344,8 @@ static int cmd_hf_fido_register(const char *cmd) { res = ecdsa_asn1_get_signature(&buf[hashp], len - hashp, rval, sval); if (!res) { if (verbose) { - PrintAndLogEx(NORMAL, " r: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, " s: %s", sprint_hex(sval, 32)); + PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); + PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); } uint8_t xbuf[4096] = {0}; @@ -357,7 +358,7 @@ static int cmd_hf_fido_register(const char *cmd) { &buf[1], 65, // user public key NULL, 0); (void)res; - //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); + //PrintAndLogEx(INFO, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[hashp], len - hashp, true); if (res) { if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { @@ -574,7 +575,7 @@ static int cmd_hf_fido_authenticate(const char *cmd) { return PM3_ESOFT; } - PrintAndLogEx(NORMAL, "---------------------------------------------------------------"); + PrintAndLogEx(INFO, "---------------------------------------------------------------"); PrintAndLogEx(SUCCESS, "User presence: %s", (buf[0] ? "verified" : "not verified")); uint32_t cntr = (uint32_t)bytes_to_num(&buf[1], 4); PrintAndLogEx(SUCCESS, "Counter: %d", cntr); @@ -586,8 +587,8 @@ static int cmd_hf_fido_authenticate(const char *cmd) { res = ecdsa_asn1_get_signature(&buf[5], len - 5, rval, sval); if (!res) { if (verbose) { - PrintAndLogEx(NORMAL, " r: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, " s: %s", sprint_hex(sval, 32)); + PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); + PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); } if (public_key_loaded) { uint8_t xbuf[4096] = {0}; @@ -599,7 +600,7 @@ static int cmd_hf_fido_authenticate(const char *cmd) { data, 32, // challenge parameter NULL, 0); (void)res; - //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); + //PrintAndLogEx(INFO, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true); if (res) { if (res == MBEDTLS_ERR_ECP_VERIFY_FAILED) { @@ -718,7 +719,7 @@ static int cmd_hf_fido_2make_credential(const char *cmd) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; } - PrintAndLogEx(NORMAL, "fname: %s\n", fname); + PrintAndLogEx(INFO, "fname: %s\n", fname); json_t *root = json_load_file(fname, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json error on line %d: %s", error.line, error.text); @@ -843,7 +844,7 @@ static int cmd_hf_fido_2get_assertion(const char *cmd) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; } - PrintAndLogEx(NORMAL, "fname: %s\n", fname); + PrintAndLogEx(INFO, "fname: %s\n", fname); json_t *root = json_load_file(fname, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json error on line %d: %s", error.line, error.text); @@ -876,9 +877,9 @@ static int cmd_hf_fido_2get_assertion(const char *cmd) { if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR get assertion request:"); - PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdGetAssertion, false, data, datalen); - PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); } res = FIDO2GetAssertion(data, datalen, buf, sizeof(buf), &len, &sw); @@ -901,9 +902,9 @@ static int cmd_hf_fido_2get_assertion(const char *cmd) { PrintAndLogEx(SUCCESS, "GetAssertion result (%zu b) OK.", len); if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR get assertion response:"); - PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdGetAssertion, true, &buf[1], len - 1); - PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); } // parse returned cbor From bf4cdf6eb794d0b8f53624505e9ab438e7d8d5a1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Nov 2020 18:05:05 +0100 Subject: [PATCH 14/69] remove dump_buffer_simple --- client/src/cmdhffido.c | 4 ++-- client/src/emv/dump.c | 14 ++------------ client/src/emv/dump.h | 1 - client/src/fido/fidocore.c | 23 ++++++++++++----------- 4 files changed, 16 insertions(+), 26 deletions(-) diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 818dc6f35..91c1a85b3 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -312,8 +312,8 @@ static int cmd_hf_fido_register(const char *cmd) { int derp = 67 + keyHandleLen; int derLen = (buf[derp + 2] << 8) + buf[derp + 3] + 4; if (verbose2) { - PrintAndLogEx(INFO, "DER certificate[%d]:"); - PrintAndLogEx(INFO, "------------------DER-------------------", derLen); + PrintAndLogEx(INFO, "DER certificate[%d]:", derLen); + PrintAndLogEx(INFO, "------------------DER-------------------"); PrintAndLogEx(INFO, "%s", sprint_hex(buf + derp, derLen)); PrintAndLogEx(INFO, "----------------DER---------------------"); } else { diff --git a/client/src/emv/dump.c b/client/src/emv/dump.c index edf60d34d..137fc5bdb 100644 --- a/client/src/emv/dump.c +++ b/client/src/emv/dump.c @@ -23,23 +23,13 @@ # define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} #endif -void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f) { - int i; - - if (!f) - f = stdout; - - for (i = 0; i < len; i ++) - fprintf(f, "%s%02hhX", i ? " " : "", ptr[i]); -} - void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level) { - int i, j; + int j; if (!f) f = stdout; - for (i = 0; i < len; i += 16) { + for (int i = 0; i < len; i += 16) { PRINT_INDENT(level); fprintf(f, "\t%02x:", i); for (j = 0; j < 16; j++) { diff --git a/client/src/emv/dump.h b/client/src/emv/dump.h index 5a71b9519..3a67c0855 100644 --- a/client/src/emv/dump.h +++ b/client/src/emv/dump.h @@ -20,7 +20,6 @@ #include // FILE -void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f); void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level); void dump_buffer_tab(const unsigned char *ptr, size_t len, FILE *f, int tabs); diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index 3cddbc5a9..26fa30dc4 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -274,7 +274,7 @@ int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *pu } if (verbose) - PrintAndLogEx(NORMAL, "------------------DER-------------------"); + PrintAndLogEx(INFO, "------------------DER-------------------"); mbedtls_x509_crt_free(&cert); mbedtls_x509_crt_free(&cacert); @@ -366,8 +366,8 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, int res = ecdsa_asn1_get_signature(sign, signLen, rval, sval); if (!res) { if (verbose) { - PrintAndLogEx(NORMAL, " r: %s", sprint_hex(rval, 32)); - PrintAndLogEx(NORMAL, " s: %s", sprint_hex(sval, 32)); + PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); + PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); } uint8_t clientDataHash[32] = {0}; @@ -488,9 +488,9 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b if (showCBOR) { PrintAndLogEx(INFO, "COSE structure:"); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- CBOR ------------------"); TinyCborPrintFIDOPackage(fido2COSEKey, true, &ubuf[55 + cridlen], cplen); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- CBOR ------------------"); } res = COSEGetECDSAKey(&ubuf[55 + cridlen], cplen, verbose, coseKey); @@ -542,11 +542,12 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b res = CborGetArrayBinStringValue(&mapsmt, der, sizeof(der), &derLen); cbor_check(res); if (verbose2) { - PrintAndLogEx(NORMAL, "DER certificate[%zu]:\n------------------DER-------------------", derLen); - dump_buffer_simple((const unsigned char *)der, derLen, NULL); - PrintAndLogEx(NORMAL, "\n----------------DER---------------------"); + PrintAndLogEx(INFO, "DER certificate[%zu]:", derLen); + PrintAndLogEx(INFO, "------------------DER-------------------"); + PrintAndLogEx(INFO, "%s", sprint_hex(der, derLen)); + PrintAndLogEx(INFO, "----------------DER---------------------"); } else { - PrintAndLogEx(NORMAL, "DER [%zu]: %s...", derLen, sprint_hex(der, MIN(derLen, 16))); + PrintAndLogEx(INFO, "DER [%zu]: %s...", derLen, sprint_hex(der, MIN(derLen, 16))); } JsonSaveBufAsHexCompact(root, "$.AppData.DER", der, derLen); } @@ -558,9 +559,9 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b // print DER certificate in TLV view if (showDERTLV) { - PrintAndLogEx(NORMAL, "----------------DER TLV-----------------"); + PrintAndLogEx(INFO, "----------------DER TLV-----------------"); asn1_print(der, derLen, " "); - PrintAndLogEx(NORMAL, "----------------DER TLV-----------------"); + PrintAndLogEx(INFO, "----------------DER TLV-----------------"); } FIDOCheckDERAndGetKey(der, derLen, verbose, public_key, sizeof(public_key)); JsonSaveBufAsHexCompact(root, "$.AppData.DERPublicKey", public_key, sizeof(public_key)); From 14ea72ca5db91b67a513c1289638773c65c93e01 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 11 Nov 2020 18:29:27 +0100 Subject: [PATCH 15/69] hf 14a apdu - textual --- client/src/cmdhf14a.c | 26 +++++++++++++++----------- client/src/emv/dump.h | 1 - 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index d6cbcd2de..0cb6006d4 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1027,7 +1027,7 @@ static int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool return 4; } - return 0; + return PM3_SUCCESS; } int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { @@ -1146,7 +1146,7 @@ static int CmdHF14AAPDU(const char *Cmd) { if (makeAPDU && headerlen != 4) { PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); CLIParserFree(ctx); - return 1; + return PM3_EINVARG; } extendedAPDU = arg_get_lit(ctx, 6); le = arg_get_int_def(ctx, 7, 0); @@ -1172,19 +1172,19 @@ static int CmdHF14AAPDU(const char *Cmd) { if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); CLIParserFree(ctx); - return 2; + return PM3_EINVARG; } } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); CLIParserFree(ctx); - return 3; + return PM3_EINVARG; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); CLIParserFree(ctx); - return 3; + return PM3_EINVARG; } // len = data + PCB(1b) + CRC(2b) @@ -1192,7 +1192,12 @@ static int CmdHF14AAPDU(const char *Cmd) { } CLIParserFree(ctx); - PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); + PrintAndLogEx(SUCCESS, "( " _YELLOW_("%s%s%s")" )", + activateField ? "select" : "", + leaveSignalON ? ", keep" : "", + decodeTLV ? ", TLV" : "" + ); + PrintAndLogEx(SUCCESS, ">>> %s", sprint_hex_inrow(data, datalen)); if (decodeAPDU) { APDUStruct apdu; @@ -1208,16 +1213,15 @@ static int CmdHF14AAPDU(const char *Cmd) { if (res) return res; - PrintAndLogEx(NORMAL, "<<<< %s", sprint_hex(data, datalen)); - - PrintAndLogEx(SUCCESS, "APDU response: %02x %02x - %s", data[datalen - 2], data[datalen - 1], GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1])); + PrintAndLogEx(SUCCESS, "<<< %s | %s", sprint_hex_inrow(data, datalen), sprint_ascii(data, datalen)); + PrintAndLogEx(SUCCESS, "<<< status: %02x %02x - %s", data[datalen - 2], data[datalen - 1], GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1])); // TLV decoder if (decodeTLV && datalen > 4) { TLVPrintFromBuffer(data, datalen - 2); } - return 0; + return PM3_SUCCESS; } static int CmdHF14ACmdRaw(const char *Cmd) { @@ -2038,7 +2042,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { break; } } else { - dump_buffer(&card.ats[pos], calen, NULL, 1); + PrintAndLogEx(SUCCESS, " %s", sprint_hex_inrow(card.ats + pos, calen)); } } diff --git a/client/src/emv/dump.h b/client/src/emv/dump.h index 3a67c0855..77cd489f3 100644 --- a/client/src/emv/dump.h +++ b/client/src/emv/dump.h @@ -21,6 +21,5 @@ #include // FILE void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level); -void dump_buffer_tab(const unsigned char *ptr, size_t len, FILE *f, int tabs); #endif From 4e6ba6fcf5cac8c347e0ee9f8f9bedc5199576d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 18:25:56 +0100 Subject: [PATCH 16/69] removing dump_buffer step1 --- client/src/emv/test/cda_test.c | 18 +++++------ client/src/emv/test/dda_test.c | 17 +++++----- client/src/emv/test/sda_test.c | 12 +++---- client/src/util.c | 58 +++++++++++++++++++++++++++------- client/src/util.h | 1 + 5 files changed, 70 insertions(+), 36 deletions(-) diff --git a/client/src/emv/test/cda_test.c b/client/src/emv/test/cda_test.c index acdde8bb4..b5a87952c 100644 --- a/client/src/emv/test/cda_test.c +++ b/client/src/emv/test/cda_test.c @@ -23,10 +23,10 @@ #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog +#include "util.h" // print_buffer struct emv_pk c_mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -172,7 +172,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -202,7 +202,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -231,7 +231,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "icc cert:"); - dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); + print_buffer(iccpk_data, iccpk_data_len, 1); } size_t iccpk_pk_len = iccpk_data[19]; @@ -260,7 +260,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash1.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) { @@ -287,7 +287,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "SDAD:"); - dump_buffer(sdad, sdad_len, stdout, 0); + print_buffer(sdad, sdad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -308,7 +308,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -331,7 +331,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(sdad + 5 + 8 + 1 + 8, h, 20)) { @@ -408,7 +408,7 @@ static int cda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "IDN:"); - dump_buffer(idn->value, idn->len, stdout, 0); + print_buffer(idn->value, idn->len, 1); } tlvdb_free(idndb); diff --git a/client/src/emv/test/dda_test.c b/client/src/emv/test/dda_test.c index 7bf6d4975..c36af108d 100644 --- a/client/src/emv/test/dda_test.c +++ b/client/src/emv/test/dda_test.c @@ -23,11 +23,10 @@ #include "dda_test.h" #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog - +#include "util.h" // print_buffer struct emv_pk mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -161,7 +160,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -191,7 +190,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -220,7 +219,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "icc cert:"); - dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); + print_buffer(iccpk_data, iccpk_data_len, 1); } size_t iccpk_pk_len = iccpk_data[19]; @@ -249,7 +248,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash1.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) { @@ -276,7 +275,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "sdad:"); - dump_buffer(sdad, sdad_len, stdout, 0); + print_buffer(sdad, sdad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -297,7 +296,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -356,7 +355,7 @@ static int dda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "IDN:"); - dump_buffer(idn->value, idn->len, stdout, 0); + print_buffer(idn->value, idn->len, 1); } tlvdb_free(idndb); diff --git a/client/src/emv/test/sda_test.c b/client/src/emv/test/sda_test.c index 04f3b70ae..731adb563 100644 --- a/client/src/emv/test/sda_test.c +++ b/client/src/emv/test/sda_test.c @@ -23,10 +23,10 @@ #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog +#include "util.h" // print_buffer #include "sda_test.h" struct emv_pk vsdc_01 = { @@ -122,7 +122,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -152,7 +152,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -179,7 +179,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "ssad:"); - dump_buffer(ssad, ssad_len, stdout, 0); + print_buffer(ssad, ssad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -200,7 +200,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -245,7 +245,7 @@ static int sda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "dac:"); - dump_buffer(dac->value, dac->len, stdout, 0); + print_buffer(dac->value, dac->len, 1); } tlvdb_free(dacdb); diff --git a/client/src/util.c b/client/src/util.c index 6a49a27dd..2e1cfb0bd 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -200,6 +200,52 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { PrintAndLogEx(NORMAL, ""); } +void print_buffer(const uint8_t *data, const size_t len, int level) { + + if (len < 1) + return; + + char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + int i; + for (i = 0; i < len; i += 16) { + + // (16 * 3) + (16) + + 1 + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%*s%02x: ", (level * 4), " ", i); + + hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, 16, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, 16)); + PrintAndLogEx(INFO, "%s", buf); + } + + // the last odd bytes + uint8_t mod = len % 16; + + if (mod) { + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%*s%02x: ", (level * 4), " ", i); + hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, mod, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + + // add the spaces... + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((16 - mod) * 3) , " "); + + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod)); + PrintAndLogEx(INFO, "%s", buf); + } +} + +void print_blocks(uint32_t *data, size_t len) { + PrintAndLogEx(SUCCESS, "Blk | Data "); + PrintAndLogEx(SUCCESS, "----+------------"); + + if (!data) { + PrintAndLogEx(ERR, "..empty data"); + } else { + for (uint8_t i = 0; i < len; i++) + PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); + } +} + char *sprint_hex(const uint8_t *data, const size_t len) { static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true); @@ -344,18 +390,6 @@ char *sprint_ascii(const uint8_t *data, const size_t len) { return sprint_ascii_ex(data, len, 0); } -void print_blocks(uint32_t *data, size_t len) { - PrintAndLogEx(SUCCESS, "Blk | Data "); - PrintAndLogEx(SUCCESS, "----+------------"); - - if (!data) { - PrintAndLogEx(ERR, "..empty data"); - } else { - for (uint8_t i = 0; i < len; i++) - PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); - } -} - int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) { char buf[4] = {0}; int indx = 0; diff --git a/client/src/util.h b/client/src/util.h index f65c94622..51100731e 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -50,6 +50,7 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len); char *sprint_ascii(const uint8_t *data, const size_t len); char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len); +void print_buffer(const uint8_t *data, const size_t len, int level); void print_blocks(uint32_t *data, size_t len); int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen); From 243d509203e7e741b087bfcae75e019ea4c29556 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 18:43:03 +0100 Subject: [PATCH 17/69] remove dump.c step2 --- client/CMakeLists.txt | 1 - client/Makefile | 1 - client/src/cmdhf14a.c | 1 - client/src/cmdhffido.c | 8 ++---- client/src/cmdhfmf.c | 3 +- client/src/cmdhfmfdes.c | 3 +- client/src/cmdhfmfp.c | 4 +-- client/src/cmdsmartcard.c | 4 +-- client/src/crypto/asn1dump.c | 1 - client/src/crypto/asn1utils.c | 3 +- client/src/emv/dump.c | 47 ------------------------------- client/src/emv/dump.h | 25 ---------------- client/src/emv/emv_pki.c | 13 ++++----- client/src/emv/emvcore.c | 3 +- client/src/emv/test/crypto_test.c | 1 - client/src/fido/fidocore.c | 1 - client/src/mifare/ndef.c | 7 ++--- 17 files changed, 21 insertions(+), 105 deletions(-) delete mode 100644 client/src/emv/dump.c delete mode 100644 client/src/emv/dump.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 77181f8bf..be8eaec5b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -188,7 +188,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c diff --git a/client/Makefile b/client/Makefile index 333cbad08..8e7ff3724 100644 --- a/client/Makefile +++ b/client/Makefile @@ -506,7 +506,6 @@ SRCS = aiddesfire.c \ emv/crypto.c\ emv/crypto_polarssl.c\ emv/dol.c \ - emv/dump.c \ emv/emv_pk.c\ emv/emv_pki.c\ emv/emv_pki_priv.c\ diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 0cb6006d4..52c320dd7 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -29,7 +29,6 @@ #include "aidsearch.h" #include "cmdhf.h" // handle HF plot #include "protocols.h" // MAGIC_GEN_1A -#include "emv/dump.h" // dump_buffer bool APDUInFramingEnable = true; diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 91c1a85b3..e196c2681 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -19,9 +19,7 @@ //----------------------------------------------------------------------------- #include "cmdhffido.h" - #include - #include "cmdparser.h" // command_t #include "commonutil.h" #include "comms.h" @@ -33,10 +31,10 @@ #include "crypto/libpcrypto.h" #include "fido/cbortools.h" #include "fido/fidocore.h" -#include "emv/dump.h" #include "ui.h" #include "cmdhf14a.h" #include "cmdtrace.h" +#include "util.h" static int CmdHelp(const char *Cmd); @@ -88,7 +86,7 @@ static int cmd_hf_fido_info(const char *cmd) { } else { PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F)."); PrintAndLogEx(INFO, "Non U2F authenticator version:"); - dump_buffer((const unsigned char *)buf, len, NULL, 0); + print_buffer((const unsigned char *)buf, len, 1); } } else { PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", (int)len, buf); @@ -296,7 +294,7 @@ static int cmd_hf_fido_register(const char *cmd) { if (verbose2) { PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------"); - dump_buffer((const unsigned char *)buf, len, NULL, 0); + print_buffer((const unsigned char *)buf, len, 1); PrintAndLogEx(INFO, "-------------" _CYAN_("data") " ----------------------"); } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b6a1592bb..82fc8a1c4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -16,7 +16,6 @@ #include "comms.h" // clearCommandBuffer #include "fileutils.h" #include "cmdtrace.h" -#include "emv/dump.h" #include "mifare/mifaredefault.h" // mifare default key array #include "cliparser.h" // argtable #include "hardnested_bf_core.h" // SetSIMDInstr @@ -5095,7 +5094,7 @@ static int CmdHFMFNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } NDEFDecodeAndPrint(data, datalen, verbose); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 871c9d115..358f61493 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -35,6 +35,7 @@ #include "mifare/mad.h" #include "generator.h" #include "aiddesfire.h" +#include "util.h" #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 @@ -4769,7 +4770,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("DESFire NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details"); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 5ef2ac826..1f0d47ae5 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -15,12 +15,12 @@ #include "commonutil.h" // ARRAYLEN #include "comms.h" #include "ui.h" +#include "util.h" #include "cmdhf14a.h" #include "mifare/mifare4.h" #include "mifare/mad.h" #include "mifare/ndef.h" #include "cliparser.h" -#include "emv/dump.h" #include "mifare/mifaredefault.h" #include "util_posix.h" #include "fileutils.h" @@ -1551,7 +1551,7 @@ static int CmdHFMFPNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } NDEFDecodeAndPrint(data, datalen, verbose); diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index ae9d018d4..ddeece950 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -18,8 +18,8 @@ #include "comms.h" // getfromdevice #include "emv/emvcore.h" // decodeTVL #include "crypto/libpcrypto.h" // sha512hash -#include "emv/dump.h" #include "ui.h" +#include "util.h" #include "fileutils.h" #include "crc16.h" // crc @@ -316,7 +316,7 @@ static void PrintATR(uint8_t *atr, size_t atrlen) { if (K > 1) { PrintAndLogEx(INFO, "\tHistorical bytes"); - dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1); + print_buffer(&atr[2 + T1len + TD1len + TDilen], K, 1); } } diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 91b04216a..42aab70bc 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -21,7 +21,6 @@ #include #include #include "emv/emv_tags.h" -#include "emv/dump.h" #include "emv/emvjson.h" #include "util.h" #include "proxmark3.h" diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 9e5826712..eede8ef0d 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -16,7 +16,6 @@ #include "ui.h" // Print... #include "emv/tlv.h" -#include "emv/dump.h" #include "asn1dump.h" #include "util.h" @@ -68,7 +67,7 @@ static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) bool candump = true; asn1_tag_dump(tlv, stdout, level, &candump); if (is_leaf && candump) { - dump_buffer(tlv->value, tlv->len, stdout, level); + print_buffer(tlv->value, tlv->len, level); } } diff --git a/client/src/emv/dump.c b/client/src/emv/dump.c deleted file mode 100644 index 137fc5bdb..000000000 --- a/client/src/emv/dump.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * libopenemv - a library to work with EMV family of smart cards - * Copyright (C) 2015 Dmitry Eremin-Solenikov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "dump.h" - -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif - -void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level) { - int j; - - if (!f) - f = stdout; - - for (int i = 0; i < len; i += 16) { - PRINT_INDENT(level); - fprintf(f, "\t%02x:", i); - for (j = 0; j < 16; j++) { - if (i + j < len) - fprintf(f, " %02hhx", ptr[i + j]); - else - fprintf(f, " "); - } - fprintf(f, " |"); - for (j = 0; j < 16 && i + j < len; j++) { - fprintf(f, "%c", (ptr[i + j] >= 0x20 && ptr[i + j] < 0x7f) ? ptr[i + j] : '.'); - } - fprintf(f, "\n"); - } -} diff --git a/client/src/emv/dump.h b/client/src/emv/dump.h deleted file mode 100644 index 77cd489f3..000000000 --- a/client/src/emv/dump.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * libopenemv - a library to work with EMV family of smart cards - * Copyright (C) 2015 Dmitry Eremin-Solenikov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#ifndef DUMP_H -#define DUMP_H - -#include "common.h" - -#include // FILE - -void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level); - -#endif diff --git a/client/src/emv/emv_pki.c b/client/src/emv/emv_pki.c index 0afcfe775..f06a5ea69 100644 --- a/client/src/emv/emv_pki.c +++ b/client/src/emv/emv_pki.c @@ -24,7 +24,6 @@ #include #include "crypto.h" -#include "dump.h" #include "util.h" #include "ui.h" @@ -73,7 +72,7 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, /* if (true){ PrintAndLogEx(SUCCESS, "Recovered data:\n"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); }*/ if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) { @@ -200,7 +199,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } /* Perform the rest of checks here */ @@ -375,7 +374,7 @@ struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3); @@ -409,7 +408,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } size_t idn_len = data[4]; @@ -445,7 +444,7 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } size_t idn_len = data[4]; @@ -511,7 +510,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } if (data[3] < 30 || data[3] > data_len - 4) { diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 23de78c7d..ecbb7c4f9 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -19,7 +19,6 @@ #include "ui.h" #include "cmdhf14a.h" #include "dol.h" -#include "dump.h" #include "emv_tags.h" #include "emvjson.h" #include "util_posix.h" @@ -160,7 +159,7 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { emv_tag_dump(tlv, stdout, level); if (is_leaf) { - dump_buffer(tlv->value, tlv->len, stdout, level); + print_buffer(tlv->value, tlv->len, level); } } diff --git a/client/src/emv/test/crypto_test.c b/client/src/emv/test/crypto_test.c index e3b8124f0..987a672da 100644 --- a/client/src/emv/test/crypto_test.c +++ b/client/src/emv/test/crypto_test.c @@ -24,7 +24,6 @@ #include "commonutil.h" // ARRAYLEN #include "../crypto.h" -#include "../dump.h" #include "util_posix.h" #include "ui.h" // printandlog diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index 26fa30dc4..d355779fe 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -22,7 +22,6 @@ #include "crypto/libpcrypto.h" #include "additional_ca.h" #include "cose.h" -#include "emv/dump.h" #include "ui.h" #include "util.h" diff --git a/client/src/mifare/ndef.c b/client/src/mifare/ndef.c index 785b822db..2839933e1 100644 --- a/client/src/mifare/ndef.c +++ b/client/src/mifare/ndef.c @@ -14,7 +14,6 @@ #include "ui.h" #include "util.h" // sprint_hex... -#include "emv/dump.h" #include "crypto/asn1utils.h" #include "pm3_cmd.h" @@ -375,15 +374,15 @@ static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { if (NDEFHeader.TypeLen) { PrintAndLogEx(INFO, "Type data:"); - dump_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, stdout, 1); + print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); } if (NDEFHeader.IDLen) { PrintAndLogEx(INFO, "ID data:"); - dump_buffer(NDEFHeader.ID, NDEFHeader.IDLen, stdout, 1); + print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); } if (NDEFHeader.PayloadLen) { PrintAndLogEx(INFO, "Payload data:"); - dump_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, stdout, 1); + print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); if (NDEFHeader.TypeLen) ndefDecodePayload(&NDEFHeader); } From 9b944229660b865906456e724cdef8088042a087 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 18:45:41 +0100 Subject: [PATCH 18/69] remove dump.c step3 --- client/android/CMakeLists.txt | 1 - client/experimental_client_with_swig/CMakeLists.txt | 1 - client/experimental_lib/CMakeLists.txt | 1 - 3 files changed, 3 deletions(-) diff --git a/client/android/CMakeLists.txt b/client/android/CMakeLists.txt index 3df923c3c..f459748b2 100644 --- a/client/android/CMakeLists.txt +++ b/client/android/CMakeLists.txt @@ -66,7 +66,6 @@ add_library(pm3rrg_rdv4 SHARED ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c diff --git a/client/experimental_client_with_swig/CMakeLists.txt b/client/experimental_client_with_swig/CMakeLists.txt index a871e528e..6d1667072 100644 --- a/client/experimental_client_with_swig/CMakeLists.txt +++ b/client/experimental_client_with_swig/CMakeLists.txt @@ -188,7 +188,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 505d1ea1b..454e08e00 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -188,7 +188,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c From 2323ff7f570f32b3f273e76e39881e62f95733f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 19:33:49 +0100 Subject: [PATCH 19/69] fix bad formatt string (thanks @vortix) --- client/lualibs/7816_error.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/lualibs/7816_error.lua b/client/lualibs/7816_error.lua index 15f4ef471..2ddf04133 100644 --- a/client/lualibs/7816_error.lua +++ b/client/lualibs/7816_error.lua @@ -68,7 +68,7 @@ end _errorcodes.tostring = function(command) if(type(command) == 'string') then - return ("%s (%d)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command) + return ("%s (%s)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command) end if(type(command) == 'number') then return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command) From bd7f1c6bfbc2b9928d1905db2f9ca6b9710d0c70 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 19:46:04 +0100 Subject: [PATCH 20/69] 7816_error - fix number to hex conversion (thanks @vortix) --- client/lualibs/7816_error.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/lualibs/7816_error.lua b/client/lualibs/7816_error.lua index 2ddf04133..34f9847ce 100644 --- a/client/lualibs/7816_error.lua +++ b/client/lualibs/7816_error.lua @@ -71,7 +71,8 @@ _errorcodes.tostring = function(command) return ("%s (%s)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command) end if(type(command) == 'number') then - return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command) + local hx = ("%04X"):format(command) + return ("%s (0x%s)"):format(_reverse_lookup[hx] or "ERROR UNDEFINED!", hx) end return ("Error, numeric or string argument expected, got : %s"):format(tostring(command)) end From a28e5a88d1e40dc7f411ec072917e14791278231 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 21:13:52 +0100 Subject: [PATCH 21/69] fix #1056 - swapendianess for filenames based on uid --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 8754c7a05..593eaaece 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1326,7 +1326,7 @@ static int CmdHF15Dump(const char *Cmd) { if (fileNameLen < 1) { PrintAndLogEx(INFO, "Using UID as filename"); fptr += sprintf(fptr, "hf-15-"); - FillFileNameByUID(fptr, uid, "-dump", sizeof(uid)); + FillFileNameByUID(fptr, SwapEndian64(uid, sizeof(uid), 8), "-dump", sizeof(uid)); } // detect blocksize from card :) From a28d407e3dca2a297e17a7115d173979e222f95a Mon Sep 17 00:00:00 2001 From: nyanotech Date: Thu, 12 Nov 2020 20:35:36 +0000 Subject: [PATCH 22/69] waveshare: fix dimensions of 2.7" screen, test 1.54" screen --- client/src/cmdhfwaveshare.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index 96547668f..791482722 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -83,9 +83,9 @@ static model_t models[] = { {"2.9 inch e-paper", 16, 296, 128}, {"4.2 inch e-paper", 100, 400, 300}, // tested {"7.5 inch e-paper", 120, 800, 480}, - {"2.7 inch e-paper", 121, 276, 176}, + {"2.7 inch e-paper", 121, 176, 276}, // tested {"2.13 inch e-paper B (with red)", 106, 212, 104}, - {"1.54 inch e-paper B (with red)", 100, 200, 200}, + {"1.54 inch e-paper B (with red)", 100, 200, 200}, // tested {"7.5 inch e-paper HD", 120, 880, 528}, }; From 0f4e31bfb0e1824619c84c06194458eb47f9f6ce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 21:51:05 +0100 Subject: [PATCH 23/69] adapt return codes --- client/src/cmdhffido.c | 4 ++-- client/src/crypto/asn1utils.c | 12 +++++------- client/src/crypto/libpcrypto.c | 4 ++-- client/src/emv/cmdemv.c | 8 ++++---- client/src/fido/fidocore.c | 2 +- client/src/mifare/ndef.c | 2 +- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index e196c2681..7535a5ef4 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -340,7 +340,7 @@ static int cmd_hf_fido_register(const char *cmd) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; res = ecdsa_asn1_get_signature(&buf[hashp], len - hashp, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); @@ -583,7 +583,7 @@ static int cmd_hf_fido_authenticate(const char *cmd) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; res = ecdsa_asn1_get_signature(&buf[5], len - 5, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index eede8ef0d..40db00425 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -12,18 +12,16 @@ #include #include #include - #include "ui.h" // Print... - #include "emv/tlv.h" #include "asn1dump.h" #include "util.h" int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) { if (!signature || !signaturelen || !rval || !sval) - return 1; + return PM3_EINVARG; - int res = 0; + int res = PM3_SUCCESS; unsigned char *p = signature; const unsigned char *end = p + signaturelen; size_t len; @@ -56,7 +54,7 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r // check size if (end != p) - return 2; + return PM3_ESOFT; } exit: @@ -79,10 +77,10 @@ int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) { tlvdb_free(t); } else { PrintAndLogEx(ERR, "Can't parse data as TLV tree"); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } diff --git a/client/src/crypto/libpcrypto.c b/client/src/crypto/libpcrypto.c index 3d8e7ffc4..cb73b3f5c 100644 --- a/client/src/crypto/libpcrypto.c +++ b/client/src/crypto/libpcrypto.c @@ -418,7 +418,7 @@ int ecdsa_nist_test(bool verbose) { // make signature res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); // PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen)); - if (res) + if (res != PM3_SUCCESS) goto exit; // check vectors @@ -483,7 +483,7 @@ int ecdsa_nist_test(bool verbose) { if (verbose) PrintAndLogEx(NORMAL, _GREEN_("passed\n")); - return 0; + return PM3_SUCCESS; exit: if (verbose) PrintAndLogEx(NORMAL, _RED_("failed\n")); diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index fa1e9618a..494956c51 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -1356,10 +1356,10 @@ static int CmdEMVExec(const char *Cmd) { // here must be AC2, but we dont make external authenticate ( /* // AC2 PRINT_INDENT(level); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) PrintAndLogEx(NORMAL, "\tAC2: AAC (Transaction declined)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) PrintAndLogEx(NORMAL, "\tAC2: TC (Transaction approved)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) PrintAndLogEx(NORMAL, "\tAC2: not requested (ARQC)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) PrintAndLogEx(NORMAL, "\tAC2: RFU"); */ } } diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index d355779fe..abe3f28ce 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -363,7 +363,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(sign, signLen, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); diff --git a/client/src/mifare/ndef.c b/client/src/mifare/ndef.c index 2839933e1..bd1109e80 100644 --- a/client/src/mifare/ndef.c +++ b/client/src/mifare/ndef.c @@ -180,7 +180,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } From e09c7a9a3ae6e9e8412748741c839ff91d6e47f3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Nov 2020 22:37:47 +0100 Subject: [PATCH 24/69] remove fprintf, fwrite , in prep for libpm3 --- client/src/crypto/asn1dump.c | 117 ++++++++++++++++------------------ client/src/crypto/asn1dump.h | 3 +- client/src/crypto/asn1utils.c | 2 +- 3 files changed, 57 insertions(+), 65 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 42aab70bc..f1addb9e2 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -27,10 +26,6 @@ #include "fileutils.h" #include "pm3_cmd.h" -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif - enum asn1_tag_t { ASN1_TAG_GENERIC, ASN1_TAG_BOOLEAN, @@ -108,65 +103,62 @@ static const struct asn1_tag *asn1_get_tag(const struct tlv *tlv) { return tag ? tag : &asn1_tags[0]; } -static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool longyear, bool *needdump) { +static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool longyear, bool *needdump) { int len = tlv->len; *needdump = false; int startindx = longyear ? 4 : 2; if (len > 4) { - fprintf(f, "\tvalue: '"); + PrintAndLogEx(NORMAL, " value: '" NOLF); while (true) { // year - if (!longyear) - fprintf(f, "20"); - fwrite(tlv->value, 1, longyear ? 4 : 2, f); - fprintf(f, "-"); + if (longyear == false) + PrintAndLogEx(NORMAL, "20" NOLF); + + PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx) ); + if (len < startindx + 2) break; + // month - fwrite(&tlv->value[startindx], 1, 2, f); - fprintf(f, "-"); + PrintAndLogEx(NORMAL, "%02x%02x-" NOLF, tlv->value[startindx], tlv->value[startindx + 1]); if (len < startindx + 4) break; + // day - fwrite(&tlv->value[startindx + 2], 1, 2, f); - fprintf(f, " "); + PrintAndLogEx(NORMAL, "%02x%02x " NOLF, tlv->value[startindx + 2], tlv->value[startindx + 3]); if (len < startindx + 6) break; // hour - fwrite(&tlv->value[startindx + 4], 1, 2, f); - fprintf(f, ":"); + PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 4], tlv->value[startindx + 5]); if (len < startindx + 8) break; // min - fwrite(&tlv->value[startindx + 6], 1, 2, f); - fprintf(f, ":"); + PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 6], tlv->value[startindx + 7]); if (len < startindx + 10) break; // sec - fwrite(&tlv->value[startindx + 8], 1, 2, f); + PrintAndLogEx(NORMAL, "%02x%02x" NOLF, tlv->value[startindx + 8], tlv->value[startindx + 9]); if (len < startindx + 11) break; // time zone - fprintf(f, " zone: %.*s", len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]); - + PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]); break; } - fprintf(f, "'\n"); + PrintAndLogEx(NORMAL, "'"); } else { - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); *needdump = true; } } -static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - fprintf(f, "\tvalue: '"); - fwrite(tlv->value, 1, tlv->len, f); - fprintf(f, "'\n"); +static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, " value: '" NOLF); + PrintAndLogEx(NORMAL, "%s'", sprint_hex(tlv->value, tlv->len)); } -static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool *needdump) { +static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool *needdump) { *needdump = false; for (size_t i = 0; i < tlv->len; i++) if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) { @@ -175,10 +167,10 @@ static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_ } if (*needdump) { - fprintf(f, "'\n"); + PrintAndLogEx(NORMAL, "'"); } else { - fprintf(f, "\t\t"); - asn1_tag_dump_string(tlv, tag, f, level); + PrintAndLogEx(NORMAL, " " NOLF); + asn1_tag_dump_string(tlv, tag, level); } } @@ -212,25 +204,26 @@ static unsigned long asn1_value_integer(const struct tlv *tlv, unsigned start, u return ret; } -static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); if (tlv->len > 0) { - fprintf(f, "\tvalue: %s\n", tlv->value[0] ? "true" : "false"); + PrintAndLogEx(NORMAL, " value: %s", tlv->value[0] ? "true" : "false"); } else { - fprintf(f, "n/a\n"); + PrintAndLogEx(NORMAL, "n/a"); } } -static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); if (tlv->len == 4) { int32_t val = 0; - for (size_t i = 0; i < tlv->len; i++) + for (size_t i = 0; i < tlv->len; i++) { val = (val << 8) + tlv->value[i]; - fprintf(f, "\tvalue4b: %d\n", val); + } + PrintAndLogEx(NORMAL, " value4b: %d", val); return; } - fprintf(f, "\tvalue: %lu\n", asn1_value_integer(tlv, 0, tlv->len * 2)); + PrintAndLogEx(NORMAL, " value: %lu", asn1_value_integer(tlv, 0, tlv->len * 2)); } static char *asn1_oid_description(const char *oid, bool with_group_desc) { @@ -276,77 +269,77 @@ error: return NULL; } -static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + mbedtls_asn1_buf asn1_buf; asn1_buf.len = tlv->len; asn1_buf.p = (uint8_t *)tlv->value; char pstr[300]; mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf); - fprintf(f, " %s", pstr); + + PrintAndLogEx(INFO, "%*s %s" NOLF, (level * 4), " ", pstr); char *jsondesc = asn1_oid_description(pstr, true); if (jsondesc) { - fprintf(f, " - %s", jsondesc); + PrintAndLogEx(NORMAL, " - %s" NOLF, jsondesc); } else { const char *ppstr; mbedtls_oid_get_attr_short_name(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } mbedtls_oid_get_sig_alg_desc(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } mbedtls_oid_get_extended_key_usage(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } } - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); } -bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump) { - if (!tlv) { - fprintf(f, "NULL\n"); +bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL\n"); return false; } const struct asn1_tag *tag = asn1_get_tag(tlv); - PRINT_INDENT(level); - fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name); + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); switch (tag->type) { case ASN1_TAG_GENERIC: - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); break; case ASN1_TAG_STRING: - asn1_tag_dump_string(tlv, tag, f, level); + asn1_tag_dump_string(tlv, tag, level); *candump = false; break; case ASN1_TAG_OCTET_STRING: - asn1_tag_dump_octet_string(tlv, tag, f, level, candump); + asn1_tag_dump_octet_string(tlv, tag, level, candump); break; case ASN1_TAG_BOOLEAN: - asn1_tag_dump_boolean(tlv, tag, f, level); + asn1_tag_dump_boolean(tlv, tag, level); *candump = false; break; case ASN1_TAG_INTEGER: - asn1_tag_dump_integer(tlv, tag, f, level); + asn1_tag_dump_integer(tlv, tag, level); *candump = false; break; case ASN1_TAG_UTC_TIME: - asn1_tag_dump_str_time(tlv, tag, f, level, false, candump); + asn1_tag_dump_str_time(tlv, tag, level, false, candump); break; case ASN1_TAG_STR_TIME: - asn1_tag_dump_str_time(tlv, tag, f, level, true, candump); + asn1_tag_dump_str_time(tlv, tag, level, true, candump); break; case ASN1_TAG_OBJECT_ID: - asn1_tag_dump_object_id(tlv, tag, f, level); + asn1_tag_dump_object_id(tlv, tag, level); *candump = false; break; }; diff --git a/client/src/crypto/asn1dump.h b/client/src/crypto/asn1dump.h index c7aef7e39..21caae36d 100644 --- a/client/src/crypto/asn1dump.h +++ b/client/src/crypto/asn1dump.h @@ -13,9 +13,8 @@ #include #include #include -#include #include "emv/tlv.h" -bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump); +bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump); #endif /* asn1utils.h */ diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 40db00425..a076f207d 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -63,7 +63,7 @@ exit: static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { bool candump = true; - asn1_tag_dump(tlv, stdout, level, &candump); + asn1_tag_dump(tlv, level, &candump); if (is_leaf && candump) { print_buffer(tlv->value, tlv->len, level); } From 45f93acf3d8d99ba6fbed12438392f37aadc785f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 12:19:24 +0100 Subject: [PATCH 25/69] remove fprintf, fwrite in emv --- client/src/emv/cmdemv.c | 2 +- client/src/emv/emv_tags.c | 216 +++++++++++++++++++------------------- client/src/emv/emv_tags.h | 3 +- client/src/emv/emvcore.c | 2 +- 4 files changed, 113 insertions(+), 110 deletions(-) diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index 494956c51..3e0fec872 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -1153,7 +1153,7 @@ static int CmdEMVExec(const char *Cmd) { // 9F27: Cryptogram Information Data (CID) const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL); if (CID) { - emv_tag_dump(CID, stdout, 0); + emv_tag_dump(CID, 1); PrintAndLogEx(NORMAL, "------------------------------"); if (CID->len > 0) { switch (CID->value[0] & EMVAC_AC_MASK) { diff --git a/client/src/emv/emv_tags.c b/client/src/emv/emv_tags.c index 296dcdf82..661df0e5e 100644 --- a/client/src/emv/emv_tags.c +++ b/client/src/emv/emv_tags.c @@ -18,15 +18,10 @@ #endif #include "emv_tags.h" - #include #include - #include "commonutil.h" - -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif +#include "ui.h" enum emv_tag_t { EMV_TAG_GENERIC, @@ -455,19 +450,21 @@ static const char *bitstrings[] = { "1.......", }; -static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, int level) { const struct emv_tag_bit *bits = tag->data; unsigned bit, byte; for (byte = 1; byte <= tlv->len; byte ++) { unsigned char val = tlv->value[byte - 1]; - PRINT_INDENT(level); - fprintf(f, "\tByte %u (%02x)\n", byte, val); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Byte %u (%02x)", byte, val); for (bit = 8; bit > 0; bit--, val <<= 1) { if (val & 0x80) { - PRINT_INDENT(level); - fprintf(f, "\t\t%s - '%s'\n", bitstrings[bit - 1], - bits->bit == EMV_BIT(byte, bit) ? bits->name : "Unknown"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %s - '%s'", + bitstrings[bit - 1], + (bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown" + ); } if (bits->bit == EMV_BIT(byte, bit)) bits ++; @@ -475,7 +472,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta } } -static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, int level) { const unsigned char *buf = tlv->value; size_t left = tlv->len; @@ -484,22 +481,20 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F const struct emv_tag *doltag; if (!tlv_parse_tl(&buf, &left, &doltlv)) { - PRINT_INDENT(level); - fprintf(f, "Invalid Tag-Len\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "Invalid Tag-Len"); continue; } doltag = emv_get_tag(&doltlv); - PRINT_INDENT(level); - fprintf(f, "\tTag %4x len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Tag %4x len %02zx ('%s')", doltlv.tag, doltlv.len, doltag->name); } } -static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - fprintf(f, "\tString value '"); - fwrite(tlv->value, 1, tlv->len, f); - fprintf(f, "'\n"); +static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(NORMAL, " String value '%s'", sprint_hex_inrow(tlv->value, tlv->len)); } static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) { @@ -532,17 +527,18 @@ static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, un return ret; } -static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tNumeric value %lu\n", emv_value_numeric(tlv, 0, tlv->len * 2)); +static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Numeric value %lu", emv_value_numeric(tlv, 0, tlv->len * 2)); } -static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tDate: 20%02lu.%lu.%lu\n", +static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Date: 20%02lu.%lu.%lu", emv_value_numeric(tlv, 0, 2), emv_value_numeric(tlv, 2, 4), - emv_value_numeric(tlv, 4, 6)); + emv_value_numeric(tlv, 4, 6) + ); } static uint32_t emv_get_binary(const unsigned char *S) { @@ -550,44 +546,44 @@ static uint32_t emv_get_binary(const unsigned char *S) { } // https://github.com/binaryfoo/emv-bertlv/blob/master/src/main/resources/fields/visa-cvr.txt -static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len != tlv->value[0] + 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID length!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len >= 2) { // AC1 - PRINT_INDENT(level); - if ((tlv->value[1] & 0xC0) == 0x00) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0xC0) == 0x40) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0xC0) == 0x80) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[1] & 0xC0) == 0xC0) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0xC0) == 0x00) PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[1] & 0xC0) == 0x40) PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[1] & 0xC0) == 0x80) PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[1] & 0xC0) == 0xC0) PrintAndLogEx(NORMAL, " AC1: RFU"); // AC2 - PRINT_INDENT(level); - if ((tlv->value[1] & 0x30) == 0x00) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0x30) == 0x10) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0x30) == 0x20) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((tlv->value[1] & 0x30) == 0x30) fprintf(f, "\tAC2: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0x30) == 0x00) PrintAndLogEx(NORMAL, " AC2: AAC (Transaction declined)"); + if ((tlv->value[1] & 0x30) == 0x10) PrintAndLogEx(NORMAL, " AC2: TC (Transaction approved)"); + if ((tlv->value[1] & 0x30) == 0x20) PrintAndLogEx(NORMAL, " AC2: not requested (ARQC)"); + if ((tlv->value[1] & 0x30) == 0x30) PrintAndLogEx(NORMAL, " AC2: RFU"); } if (tlv->len >= 3 && (tlv->value[2] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tPIN try: %x\n", tlv->value[2] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " PIN try: %x", tlv->value[2] >> 4); } if (tlv->len >= 4 && (tlv->value[3] & 0x0F)) { - PRINT_INDENT(level); - fprintf(f, "\tIssuer discretionary bits: %x\n", tlv->value[3] & 0x0F); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Issuer discretionary bits: %x", tlv->value[3] & 0x0F); } if (tlv->len >= 5 && (tlv->value[4] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tSuccessfully processed issuer script commands: %x\n", tlv->value[4] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Successfully processed issuer script commands: %x", tlv->value[4] >> 4); } // mask 0F 0F F0 0F @@ -610,68 +606,73 @@ static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, F }; if (data[0] || data[1] || data[2] || data[3]) - emv_tag_dump_bitmask(&bit_tlv, &bit_tag, f, level); + emv_tag_dump_bitmask(&bit_tlv, &bit_tag, level); } // EMV Book 3 -static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } - PRINT_INDENT(level); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) + PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) + PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) + PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) + PrintAndLogEx(NORMAL, " AC1: RFU"); if (tlv->value[0] & EMVCID_ADVICE) { - PRINT_INDENT(level); - fprintf(f, "\tAdvice required!\n"); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Advice required!"); } if (tlv->value[0] & EMVCID_REASON_MASK) { - PRINT_INDENT(level); - fprintf(f, "\tReason/advice/referral code: "); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Reason/advice/referral code: " NOLF); switch ((tlv->value[0] & EMVCID_REASON_MASK)) { case 0: - fprintf(f, "No information given\n"); + PrintAndLogEx(NORMAL, "No information given"); break; case 1: - fprintf(f, "Service not allowed\n"); + PrintAndLogEx(NORMAL, "Service not allowed"); break; case 2: - fprintf(f, "PIN Try Limit exceeded\n"); + PrintAndLogEx(NORMAL, "PIN Try Limit exceeded"); break; case 3: - fprintf(f, "Issuer authentication failed\n"); + PrintAndLogEx(NORMAL, "Issuer authentication failed"); break; default: - fprintf(f, "\tRFU: %2x\n", (tlv->value[0] & EMVCID_REASON_MASK)); + PrintAndLogEx(NORMAL, " RFU: %2x", (tlv->value[0] & EMVCID_REASON_MASK)); break; } } } -static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, int level) { uint32_t X, Y; int i; if (tlv->len < 10 || tlv->len % 2) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } X = emv_get_binary(tlv->value); Y = emv_get_binary(tlv->value + 4); - PRINT_INDENT(level); - fprintf(f, "\tX: %u\n", X); - PRINT_INDENT(level); - fprintf(f, "\tY: %u\n", Y); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " X: %u", X); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Y: %u", Y); for (i = 8; i < tlv->len; i += 2) { const char *method; @@ -746,73 +747,76 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t break; } - PRINT_INDENT(level); - fprintf(f, "\t%02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful\n", - tlv->value[i], tlv->value[i + 1], - method, condition, (tlv->value[i] & 0x40) ? "continue" : "fail"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful", + tlv->value[i], + tlv->value[i + 1], + method, + condition, + (tlv->value[i] & 0x40) ? "continue" : "fail" + ); } } -static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, int level) { if (tlv->len < 4 || tlv->len % 4) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } for (int i = 0; i < tlv->len / 4; i++) { - PRINT_INDENT(level); - fprintf(f, "SFI[%02x] start:%02x end:%02x offline:%02x\n", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "SFI[%02x] start:%02x end:%02x offline:%02x", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); } } -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) { - if (!tlv) { - fprintf(f, "NULL\n"); +bool emv_tag_dump(const struct tlv *tlv, int level) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL"); return false; } const struct emv_tag *tag = emv_get_tag(tlv); - PRINT_INDENT(level); - fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name); + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); switch (tag->type) { case EMV_TAG_GENERIC: - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); break; case EMV_TAG_BITMASK: - fprintf(f, "\n"); - emv_tag_dump_bitmask(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_bitmask(tlv, tag, level); break; case EMV_TAG_DOL: - fprintf(f, "\n"); - emv_tag_dump_dol(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_dol(tlv, tag, level); break; case EMV_TAG_CVM_LIST: - fprintf(f, "\n"); - emv_tag_dump_cvm_list(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvm_list(tlv, tag, level); break; case EMV_TAG_AFL: - fprintf(f, "\n"); - emv_tag_dump_afl(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_afl(tlv, tag, level); break; case EMV_TAG_STRING: - emv_tag_dump_string(tlv, tag, f, level); + emv_tag_dump_string(tlv, tag, level); break; case EMV_TAG_NUMERIC: - emv_tag_dump_numeric(tlv, tag, f, level); + emv_tag_dump_numeric(tlv, tag, level); break; case EMV_TAG_YYMMDD: - emv_tag_dump_yymmdd(tlv, tag, f, level); + emv_tag_dump_yymmdd(tlv, tag, level); break; case EMV_TAG_CVR: - fprintf(f, "\n"); - emv_tag_dump_cvr(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvr(tlv, tag, level); break; case EMV_TAG_CID: - fprintf(f, "\n"); - emv_tag_dump_cid(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cid(tlv, tag, level); break; }; diff --git a/client/src/emv/emv_tags.h b/client/src/emv/emv_tags.h index 235048b20..2da2cd2ef 100644 --- a/client/src/emv/emv_tags.h +++ b/client/src/emv/emv_tags.h @@ -17,7 +17,6 @@ #define TAGS_H #include "tlv.h" -#include // FILE // AC # define EMVAC_AC_MASK 0xC0 @@ -34,7 +33,7 @@ # define EMVCID_ADVICE 0x08 # define EMVCID_REASON_MASK 0x07 -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level); +bool emv_tag_dump(const struct tlv *tlv, int level); const char *emv_get_tag_name(const struct tlv *tlv); #endif diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index ecbb7c4f9..38347b7e0 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -157,7 +157,7 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { } static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { - emv_tag_dump(tlv, stdout, level); + emv_tag_dump(tlv, level); if (is_leaf) { print_buffer(tlv->value, tlv->len, level); } From 63a26e6091e74f4d0aff685dbda75f94e1cecf54 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 12:20:01 +0100 Subject: [PATCH 26/69] hf 14a raw - now uses cliparser --- client/src/cmdhf14a.c | 152 +++++++++++++----------------------------- 1 file changed, 48 insertions(+), 104 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 52c320dd7..3cac51520 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -245,20 +245,7 @@ static int usage_hf_14a_sniff(void) { PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sniff c r")); return PM3_SUCCESS; } -static int usage_hf_14a_raw(void) { - PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-k] [-a] [-T] [-t] [-b] <0A 0B 0C ... hex>"); - PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -r do not read response"); - PrintAndLogEx(NORMAL, " -c calculate and append CRC"); - PrintAndLogEx(NORMAL, " -k keep signal field ON after receive"); - PrintAndLogEx(NORMAL, " -a active signal field ON without select"); - PrintAndLogEx(NORMAL, " -s active signal field ON with select"); - PrintAndLogEx(NORMAL, " -b number of bits to send. Useful for send partial byte"); - PrintAndLogEx(NORMAL, " -t timeout in ms"); - PrintAndLogEx(NORMAL, " -T use Topaz protocol to send command"); - PrintAndLogEx(NORMAL, " -3 ISO14443-3 select only (skip RATS)"); - return PM3_SUCCESS; -} + static int usage_hf_14a_reader(void) { PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]"); PrintAndLogEx(NORMAL, " k keep the field active after command executed"); @@ -1117,14 +1104,14 @@ static int CmdHF14AAPDU(const char *Cmd) { CLIParserInit(&ctx, "hf 14a apdu", "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", "hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" - "hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n" - "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n" + "hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n" + "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n" "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n"); void *argtable[] = { arg_param_begin, arg_lit0("s", "select", "activate field and select card"), - arg_lit0("k", "keep", "leave the signal field ON after receive response"), + arg_lit0("k", "keep", "keep signal field ON after receive"), arg_lit0("t", "tlv", "executes TLV decoder if it possible"), arg_lit0("d", "decapdu", "decode apdu request if it possible"), arg_str0("m", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), @@ -1224,97 +1211,54 @@ static int CmdHF14AAPDU(const char *Cmd) { } static int CmdHF14ACmdRaw(const char *Cmd) { - bool reply = 1; - bool crc = false; - bool keep_field_on = false; - bool active = false; - bool active_select = false; - bool no_rats = false; - uint16_t numbits = 0; - bool bTimeout = false; - uint32_t timeout = 0; - bool topazmode = false; - char buf[5] = ""; - int i = 0; + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a raw", + "Sends an raw bytes over ISO14443a. With option to use TOPAZ 14a mode.", + "hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n" + "hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("a", NULL, "active signal field ON without select"), + arg_int0("b", NULL, "", "number of bits to send. Useful for send partial byte"), + arg_lit0("c", NULL, "calculate and append CRC"), + arg_lit0("k", NULL, "keep signal field ON after receive"), + arg_lit0("r", NULL, "do not read response"), + arg_lit0("s", NULL, "active signal field ON with select"), + arg_int0("t", "timeout", "", "timeout in milliseconds"), + arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), + arg_lit0(NULL, "topaz", "use Topaz protocol to send command"), + arg_strx1(NULL, NULL, "", "raw bytes to send"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + + bool active = arg_get_lit(ctx, 1); + uint16_t numbits = (uint16_t)arg_get_int_def(ctx, 2, 0); + bool crc = arg_get_lit(ctx, 3); + bool keep_field_on = arg_get_lit(ctx, 4); + bool reply = (arg_get_lit(ctx, 5) == false); + bool active_select = arg_get_lit(ctx, 6); + uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 7, 0); + bool no_rats = arg_get_lit(ctx, 8); + bool topazmode = arg_get_lit(ctx, 9); + + int datalen = 0; uint8_t data[PM3_CMD_DATA_SIZE]; - uint16_t datalen = 0; - uint32_t temp; + CLIGetHexWithReturn(ctx, 10, data, &datalen); + CLIParserFree(ctx); - if (strlen(Cmd) < 2) return usage_hf_14a_raw(); + bool bTimeout = (timeout) ? true : false; - // strip - while (*Cmd == ' ' || *Cmd == '\t') Cmd++; - - while (Cmd[i] != '\0') { - if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; } - if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': - case 'h': - return usage_hf_14a_raw(); - case 'r': - reply = false; - break; - case 'c': - crc = true; - break; - case 'k': - keep_field_on = true; - break; - case 'a': - active = true; - break; - case 's': - active_select = true; - break; - case 'b': - sscanf(Cmd + i + 2, "%u", &temp); - numbits = temp & 0xFFFF; - i += 3; - while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; } - i -= 2; - break; - case 't': - bTimeout = true; - sscanf(Cmd + i + 2, "%u", &temp); - timeout = temp; - i += 3; - while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; } - i -= 2; - break; - case 'T': - topazmode = true; - break; - case '3': - no_rats = true; - break; - default: - return usage_hf_14a_raw(); - } - i += 2; - continue; + // ensure we can add 2byte crc to input data + if (datalen >= sizeof(data) + 2) { + if (crc) { + PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data"); + return PM3_EINVARG; } - if ((Cmd[i] >= '0' && Cmd[i] <= '9') || - (Cmd[i] >= 'a' && Cmd[i] <= 'f') || - (Cmd[i] >= 'A' && Cmd[i] <= 'F')) { - buf[strlen(buf) + 1] = 0; - buf[strlen(buf)] = Cmd[i]; - i++; - - if (strlen(buf) >= 2) { - sscanf(buf, "%x", &temp); - data[datalen] = (uint8_t)(temp & 0xff); - *buf = 0; - if (++datalen >= sizeof(data)) { - if (crc) - PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data"); - break; - } - } - continue; - } - PrintAndLogEx(FAILED, "Invalid char on input"); - return PM3_ESOFT; } if (crc && datalen > 0 && datalen < sizeof(data) - 2) { From f8c956e4ce06e23a1b9377144d0f1eff9ac97744 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 16:05:02 +0100 Subject: [PATCH 27/69] less printf --- client/deps/cliparser/cliparser.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index f2d9fa8fd..f55b7a8f7 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -35,8 +35,7 @@ int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { *ctx = malloc(sizeof(CLIParserContext)); if (!*ctx) { - printf("ERROR: Insufficient memory\n"); - fflush(stdout); + PrintAndLogEx(ERR, "ERROR: Insufficient memory\n"); return 2; } (*ctx)->argtable = NULL; @@ -220,16 +219,15 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int res = param_gethex_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen); switch (res) { case 1: - printf("Parameter error: Invalid HEX value\n"); + PrintAndLogEx(ERR, "Parameter error: Invalid HEX value\n"); break; case 2: - printf("Parameter error: parameter too large\n"); + PrintAndLogEx(ERR, "Parameter error: parameter too large\n"); break; case 3: - printf("Parameter error: Hex string must have EVEN number of digits\n"); + PrintAndLogEx(ERR, "Parameter error: Hex string must have EVEN number of digits\n"); break; } - fflush(stdout); return res; } @@ -246,8 +244,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int len = strlen(argstr->sval[i]); if (len > ((sizeof(tmpstr) / 2) - ibuf)) { - printf("Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2)); - fflush(stdout); + PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2)); return 2; } @@ -263,8 +260,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return 0; if (ibuf > maxdatalen) { - printf("Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen); - fflush(stdout); + PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen); return 2; } From 1b697d2e428fb55018bccce4b60227a79b7f8db3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 16:08:48 +0100 Subject: [PATCH 28/69] less printf --- client/src/cmdlfem4x05.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index e1f8e10ad..93078178d 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -1882,7 +1882,8 @@ uint32_t static em4x05_Sniff_GetBlock(char *bits, bool fwd) { if (parity != (bits[35] - '0')) parityerror = true; - if (parityerror) printf("parity error : "); + if (parityerror) + PrintAndLogEx(ERR, "parity error : "); if (!fwd) { uint32_t t1 = value; @@ -1997,10 +1998,10 @@ int CmdEM4x05Sniff(const char *Cmd) { ((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) { memmove(bits, &bits[1], bitidx - 1); bitidx--; - printf("Trim leading 0\n"); + PrintAndLogEx(INFO, "Trim leading 0"); } bits[bitidx] = 0; - // printf ("==> %s\n",bits); + // logon if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) { haveData = true; @@ -2017,8 +2018,9 @@ int CmdEM4x05Sniff(const char *Cmd) { sprintf(cmdText, "Write"); tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); sprintf(blkAddr, "%d", tmpValue); - if (tmpValue == 2) + if (tmpValue == 2) { pwd = true; + } tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); sprintf(dataText, "%08X", tmpValue); } @@ -2057,8 +2059,9 @@ int CmdEM4x05Sniff(const char *Cmd) { } else { i = (CycleWidth - ZeroWidth) / 28; bits[bitidx++] = '0'; - for (int ii = 0; ii < i; ii++) + for (int ii = 0; ii < i; ii++) { bits[bitidx++] = '1'; + } } } } @@ -2068,15 +2071,14 @@ int CmdEM4x05Sniff(const char *Cmd) { // Print results if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){ if (pwd) - PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_YELLOW_("%8s")" | "_YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); else - PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_GREEN_("%8s")" | "_GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); } } // footer PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------"); PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; } From d9de790ea0f163492aa048e766b59a7fb19f88a5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 16:26:46 +0100 Subject: [PATCH 29/69] fix coverity 305865, add extra checks might quiet the coverity warning --- client/src/proxmark3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 113da7248..539b7a20b 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -898,7 +898,7 @@ int main(int argc, char *argv[]) { // execute pm3 command file if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--script-file") == 0) { - if (i + 1 == argc) { + if (i + 1 == argc || strlen(argv[i + 1]) == 0) { PrintAndLogEx(ERR, _RED_("ERROR:") " missing script file specification after -s\n"); show_help(false, exec_name); return 1; @@ -910,7 +910,7 @@ int main(int argc, char *argv[]) { // execute lua script if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lua") == 0) { addLuaExec = true; - if (i + 1 == argc) { + if (i + 1 == argc || strlen(argv[i + 1]) == 0) { PrintAndLogEx(ERR, _RED_("ERROR:") " missing lua script specification after -l\n"); show_help(false, exec_name); return 1; From 3afbcaff2f8398625ad386579f614066cd62ddb9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 16:27:29 +0100 Subject: [PATCH 30/69] fix coverity 305864, should be released when pointer is nulled --- client/src/emv/emvcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 38347b7e0..913316725 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -804,6 +804,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); + atc_db = NULL; return 9; } } else { From b4d8222c9aa9eb8ee5256c06d78c07d1766583fa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Nov 2020 22:32:46 +0100 Subject: [PATCH 31/69] Waveshare: tested diy '2.13 inch e-paper B (with red)' --- client/src/cmdhfwaveshare.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index 791482722..932012f98 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -84,7 +84,7 @@ static model_t models[] = { {"4.2 inch e-paper", 100, 400, 300}, // tested {"7.5 inch e-paper", 120, 800, 480}, {"2.7 inch e-paper", 121, 176, 276}, // tested - {"2.13 inch e-paper B (with red)", 106, 212, 104}, + {"2.13 inch e-paper B (with red)", 106, 104, 212}, // tested {"1.54 inch e-paper B (with red)", 100, 200, 200}, // tested {"7.5 inch e-paper HD", 120, 880, 528}, }; @@ -563,7 +563,6 @@ static int transceive_blocking(uint8_t *txBuf, uint16_t txBufLen, uint8_t *rxBuf PacketResponseNG resp; SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, txBufLen, 0, txBuf, txBufLen); rxBuf[0] = 1; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { if (resp.oldarg[0] > rxBufLen) { PrintAndLogEx(WARNING, "Received %"PRIu64 " bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen); @@ -856,7 +855,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } else if (model_nr == M2in13B) { //2.13inch B for (i = 0; i < 26; i++) { read_black(i, step8, model_nr, black); - ret = transceive_blocking(step8, 109, rx, 20, actrxlen, true); // cd 08 + ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08 if (ret != PM3_SUCCESS) { return ret; } @@ -920,7 +919,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { for (i = 0; i < 26; i++) { read_red(i, step13, model_nr, red); //memset(&step13[3], 0xfE, 106); - ret = transceive_blocking(step13, 109, rx, 20, actrxlen, true); + ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false); if (ret != PM3_SUCCESS) { return ret; } From 2f6261badb8281956a5447ab4a52a17256a3e6f0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 13 Nov 2020 22:34:04 +0100 Subject: [PATCH 32/69] ReaderIso14443a: save/restore timeout --- armsrc/iso14443a.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a70b9b953..806c63091 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1301,7 +1301,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { // We need to listen to the high-frequency, peak-detected path. iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - iso14a_set_timeout(201400); // 106 * 19ms default + iso14a_set_timeout(201400); // 106 * 19ms default *100? int len = 0; @@ -2903,9 +2903,11 @@ void ReaderIso14443a(PacketCommandNG *c) { goto OUT; } } - - if ((param & ISO14A_SET_TIMEOUT)) + uint32_t save_iso14a_timeout = 0; + if ((param & ISO14A_SET_TIMEOUT)) { + save_iso14a_timeout = iso14a_get_timeout(); iso14a_set_timeout(timeout); + } if ((param & ISO14A_APDU)) { uint8_t res; @@ -2969,6 +2971,10 @@ void ReaderIso14443a(PacketCommandNG *c) { if ((param & ISO14A_REQUEST_TRIGGER)) iso14a_set_trigger(false); + if ((param & ISO14A_SET_TIMEOUT)) { + iso14a_set_timeout(save_iso14a_timeout); + } + if ((param & ISO14A_NO_DISCONNECT)) return; From f37088095b394124c6a295a071145293a189cd69 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 11 Nov 2020 00:03:58 +0100 Subject: [PATCH 33/69] compile with swig files if available --- Makefile.defs | 2 +- client/CMakeLists.txt | 22 + client/Makefile | 55 ++ .../experimental_client_with_swig/.gitignore | 1 - .../00make_swig.sh | 5 +- ...1make_client.sh => 01make_client_cmake.sh} | 2 +- ...nue.sh => 01make_client_cmake_continue.sh} | 1 + .../02a_run_test_lua.sh | 3 - .../02a_run_test_lua_cmake.sh | 3 + ...un_test_py.sh => 02b_run_test_py_cmake.sh} | 2 +- .../02b_run_test_py_grabber_makefile.sh | 8 + .../CMakeLists.txt | 572 ------------------ .../output_grabber.py | 78 +++ .../testembedded_grab.py | 13 + client/src/pm3.i | 8 +- client/src/pm3_luawrap.c | 8 +- client/src/pm3_pywrap.c | 8 +- 17 files changed, 198 insertions(+), 593 deletions(-) delete mode 100644 client/experimental_client_with_swig/.gitignore rename client/experimental_client_with_swig/{01make_client.sh => 01make_client_cmake.sh} (92%) rename client/experimental_client_with_swig/{01make_client_continue.sh => 01make_client_cmake_continue.sh} (86%) delete mode 100755 client/experimental_client_with_swig/02a_run_test_lua.sh create mode 100755 client/experimental_client_with_swig/02a_run_test_lua_cmake.sh rename client/experimental_client_with_swig/{02b_run_test_py.sh => 02b_run_test_py_cmake.sh} (59%) create mode 100755 client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh delete mode 100644 client/experimental_client_with_swig/CMakeLists.txt create mode 100755 client/experimental_client_with_swig/output_grabber.py create mode 100755 client/experimental_client_with_swig/testembedded_grab.py diff --git a/Makefile.defs b/Makefile.defs index 16d5ec9e5..48567214b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -27,7 +27,7 @@ LD = g++ SH = sh BASH = bash PERL = perl -CCC =foo +SWIG = swig CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') CC_VERSION := $(or $(strip $(CC_VERSION)),0) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index be8eaec5b..34ad38d26 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -455,6 +455,28 @@ else (SKIPWHEREAMISYSTEM EQUAL 1) message(STATUS "Whereami library: system library not found, using local library") endif (WHEREAMI_FOUND) endif (SKIPWHEREAMISYSTEM EQUAL 1) + +# Lua SWIG +if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_luawrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_LUA_SWIG) + message(STATUS "Lua SWIG: wrapper found") +endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + +# Python SWIG +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_pywrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_PYTHON_SWIG) + message(STATUS "Python SWIG: wrapper found") + endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) message(STATUS "===================================================================") add_executable(proxmark3 diff --git a/client/Makefile b/client/Makefile index 8e7ff3724..b2c372f6f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -285,6 +285,19 @@ ifneq ($(SKIPREADLINE),1) READLINE_FOUND = 1 endif +######## +# SWIG # +######## + +ifneq ("$(wildcard src/pm3_luawrap.c)","") + SWIG_LUA_FOUND = 1 +endif +ifneq ($(SKIPPYTHON),1) + ifneq ("$(wildcard src/pm3_pywrap.c)","") + SWIG_PYTHON_FOUND = 1 + endif +endif + ####################################################################################################### CFLAGS ?= $(DEFCFLAGS) # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: @@ -315,6 +328,12 @@ ifeq ($(PYTHON_FOUND),1) PM3CFLAGS += -DHAVE_PYTHON endif +ifeq ($(SWIG_LUA_FOUND),1) + PM3CFLAGS += -DHAVE_LUA_SWIG +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + PM3CFLAGS += -DHAVE_PYTHON_SWIG +endif CXXFLAGS ?= -Wall -Werror -O3 PM3CXXFLAGS = $(CXXFLAGS) @@ -414,6 +433,13 @@ else endif endif +ifeq ($(SWIG_LUA_FOUND),1) + $(info Lua SWIG: wrapper found) +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + $(info Python SWIG: wrapper found) +endif + $(info compiler version: $(shell $(CC) --version|head -n 1)) $(info ===================================================================) @@ -572,6 +598,15 @@ SRCS += bucketsort.c \ parity.c \ util_posix.c +# swig + +ifeq ($(SWIG_LUA_FOUND),1) + SRCS += pm3_luawrap.c +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + SRCS += pm3_pywrap.c +endif + # gui ifeq ($(QT_FOUND),1) CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp @@ -711,6 +746,18 @@ ifneq ($(WHEREAMI_FOUND),1) $(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all endif +######## +# SWIG # +######## + +src/pm3_luawrap.c: pm3.i + $(info [=] GEN $@) + $(Q)$(SWIG) -lua -o $@ $< + +src/pm3_pywrap.c: pm3.i + $(info [=] GEN $@) + $(Q)$(SWIG) -python -o $@ $< + ######## # misc # ######## @@ -725,6 +772,14 @@ src/version.c: default_version.c # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) +# SWIG files emit a number of warnings, we've to ignore them +%wrap.o: %wrap.c +$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%wrap.d + $(info [-] CC $<) + $(Q)$(MKDIR) $(dir $@) + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $< + $(Q)$(POSTCOMPILE) + %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) diff --git a/client/experimental_client_with_swig/.gitignore b/client/experimental_client_with_swig/.gitignore deleted file mode 100644 index 567609b12..000000000 --- a/client/experimental_client_with_swig/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/client/experimental_client_with_swig/00make_swig.sh b/client/experimental_client_with_swig/00make_swig.sh index 6c752d024..626a87986 100755 --- a/client/experimental_client_with_swig/00make_swig.sh +++ b/client/experimental_client_with_swig/00make_swig.sh @@ -1,4 +1,5 @@ #!/bin/bash -swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i -swig -python -o ../src/pm3_pywrap.c ../src/pm3.i +cd .. +make src/pm3_luawrap.c +make src/pm3_pywrap.c diff --git a/client/experimental_client_with_swig/01make_client.sh b/client/experimental_client_with_swig/01make_client_cmake.sh similarity index 92% rename from client/experimental_client_with_swig/01make_client.sh rename to client/experimental_client_with_swig/01make_client_cmake.sh index 667a6351e..48a5bd4f2 100755 --- a/client/experimental_client_with_swig/01make_client.sh +++ b/client/experimental_client_with_swig/01make_client_cmake.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd .. rm -rf build mkdir build ( @@ -7,4 +8,3 @@ mkdir build cmake .. make -j ) - diff --git a/client/experimental_client_with_swig/01make_client_continue.sh b/client/experimental_client_with_swig/01make_client_cmake_continue.sh similarity index 86% rename from client/experimental_client_with_swig/01make_client_continue.sh rename to client/experimental_client_with_swig/01make_client_cmake_continue.sh index 4c85bb9dc..abd022c97 100755 --- a/client/experimental_client_with_swig/01make_client_continue.sh +++ b/client/experimental_client_with_swig/01make_client_cmake_continue.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd .. ( cd build make -j diff --git a/client/experimental_client_with_swig/02a_run_test_lua.sh b/client/experimental_client_with_swig/02a_run_test_lua.sh deleted file mode 100755 index bca993a44..000000000 --- a/client/experimental_client_with_swig/02a_run_test_lua.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh b/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh new file mode 100755 index 000000000..08ed58b6b --- /dev/null +++ b/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +../build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02b_run_test_py.sh b/client/experimental_client_with_swig/02b_run_test_py_cmake.sh similarity index 59% rename from client/experimental_client_with_swig/02b_run_test_py.sh rename to client/experimental_client_with_swig/02b_run_test_py_cmake.sh index fcaf4c8f8..4ef059045 100755 --- a/client/experimental_client_with_swig/02b_run_test_py.sh +++ b/client/experimental_client_with_swig/02b_run_test_py_cmake.sh @@ -4,4 +4,4 @@ #/usr/lib/python3/dist-packages/pm3.py # need access to pm3.py -PYTHONPATH=../src build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py" +PYTHONPATH=../src ../build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py" diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh new file mode 100755 index 000000000..59013cc22 --- /dev/null +++ b/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +#/usr/local/lib/python3/dist-packages/pm3.py +#/usr/lib/python3/dist-packages/pm3.py + +# need access to pm3.py +PYTHONPATH=../src ../proxmark3 /dev/ttyACM0 -c "script run testembedded_grab.py" -i + diff --git a/client/experimental_client_with_swig/CMakeLists.txt b/client/experimental_client_with_swig/CMakeLists.txt deleted file mode 100644 index 6d1667072..000000000 --- a/client/experimental_client_with_swig/CMakeLists.txt +++ /dev/null @@ -1,572 +0,0 @@ -# Usage: -# mkdir build -# cd build -# cmake .. (see below for options) -# make (VERBOSE=1 if needed) -# -# MINGW: -# On ProxSpace 3.4: -# cmake -G"MSYS Makefiles" .. -# On Proxspace 3.3 or less, you need to install cmake: -# pacman -S mingw-w64-x86_64-cmake -# /mingw64/bin/cmake -G"MSYS Makefiles" .. -# -# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version) -# cmake \ -# -DCMAKE_TOOLCHAIN_FILE=/build/cmake/android.toolchain.cmake \ -# -DANDROID_ABI=armeabi-v7a \ -# -DANDROID_NATIVE_API_LEVEL=android-19 \ -# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 .. - -message(STATUS "CMake ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 3.10) -project(proxmark3) -SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) - -if(CMAKE_VERSION VERSION_LESS "3.7.0") - set(CMAKE_INCLUDE_CURRENT_DIR ON) -endif() - -find_package(PkgConfig) - -if (NOT SKIPQT EQUAL 1) - if(APPLE AND EXISTS /usr/local/opt/qt5) - # Homebrew installs Qt5 (up to at least 5.11.0) in - # /usr/local/qt5. Ensure that it can be found by CMake - # since it is not in the default /usr/local prefix. - # Add it to PATHS so that it doesn't override the - # CMAKE_PREFIX_PATH environment variable. - # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, - # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) - list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) - endif(APPLE AND EXISTS /usr/local/opt/qt5) - set(QT_PACKAGELIST - Qt5Core - Qt5Widgets - Qt5Gui - ) - set(Qt5_FOUND ON) - foreach(_qt_package IN LISTS QT_PACKAGELIST) - find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) - set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES}) - if(NOT ${_qt_package}_FOUND) - set(Qt5_FOUND OFF) - endif(NOT ${_qt_package}_FOUND) - endforeach() -endif (NOT SKIPQT EQUAL 1) - -if (NOT SKIPBT EQUAL 1) - pkg_search_module(BLUEZ QUIET bluez) -endif (NOT SKIPBT EQUAL 1) - -if (NOT SKIPPYTHON EQUAL 1) - pkg_search_module(PYTHON3 QUIET python3) - pkg_search_module(PYTHON3EMBED QUIET python3-embed) -endif (NOT SKIPPYTHON EQUAL 1) - -# If cross-compiled, we need to init source and build. -if (CMAKE_TOOLCHAIN_FILE) - set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w") - set(EMBED_READLINE ON) - set(EMBED_BZIP2 ON) -endif (CMAKE_TOOLCHAIN_FILE) - -if (EMBED_READLINE OR EMBED_BZIP2) - include(ExternalProject) -endif (EMBED_READLINE OR EMBED_BZIP2) - -if (NOT SKIPREADLINE EQUAL 1) - if (APPLE) - find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) - find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) - endif (APPLE) - if (EMBED_READLINE) - ExternalProject_Add(ncurses - URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz - PREFIX deps/ncurses - DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses - CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib - BUILD_IN_SOURCE ON - BUILD_COMMAND make libs - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(ncurses configure build install) - - ExternalProject_Add(readline - URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz - PREFIX deps/readline - DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline - CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static - BUILD_IN_SOURCE ON - BUILD_COMMAND make - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(readline configure build install) - set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/) - set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a) - else (EMBED_READLINE) - find_path(READLINE_INCLUDE_DIRS readline/readline.h) - find_library(READLINE_LIBRARIES readline) - endif (EMBED_READLINE) - if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) - set(READLINE_FOUND ON) - endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) -endif (NOT SKIPREADLINE EQUAL 1) - -if (NOT SKIPJANSSONSYSTEM EQUAL 1) - pkg_check_modules(PC_JANSSON QUIET jansson) - find_path(JANSSON_INCLUDE_DIRS - NAMES jansson.h - HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS}) - find_library(JANSSON_LIBRARIES - NAMES jansson libjansson - HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS}) - if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) - set(JANSSON_FOUND ON) - endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) -endif (NOT SKIPJANSSONSYSTEM EQUAL 1) - -if(EMBED_BZIP2) - set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) - ExternalProject_Add(bzip2 - GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2 - GIT_TAG platform-tools-30.0.2 - PREFIX deps/bzip2 - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 - CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x - BUILD_IN_SOURCE ON - BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(bzip2 configure build install) - set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) - set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a) - set(BZIP2_FOUND ON) -else(EMBED_BZIP2) - find_package (BZip2 REQUIRED) -endif(EMBED_BZIP2) - -if (NOT SKIPWHEREAMISYSTEM EQUAL 1) - find_path(WHEREAMI_INCLUDE_DIRS whereami.h) - find_library(WHEREAMI_LIBRARIES whereami) - if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) - set(WHEREAMI_FOUND ON) - endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) -endif (NOT SKIPWHEREAMISYSTEM EQUAL 1) - -add_subdirectory(${PM3_ROOT}/client/deps deps) - -set (TARGET_SOURCES - ${PM3_ROOT}/common/commonutil.c - ${PM3_ROOT}/common/util_posix.c - ${PM3_ROOT}/common/parity.c - ${PM3_ROOT}/common/bucketsort.c - ${PM3_ROOT}/common/crapto1/crapto1.c - ${PM3_ROOT}/common/crapto1/crypto1.c - ${PM3_ROOT}/common/crc.c - ${PM3_ROOT}/common/crc16.c - ${PM3_ROOT}/common/crc32.c - ${PM3_ROOT}/common/crc64.c - ${PM3_ROOT}/common/lfdemod.c - ${PM3_ROOT}/common/legic_prng.c - ${PM3_ROOT}/common/iso15693tools.c - ${PM3_ROOT}/common/cardhelper.c - ${PM3_ROOT}/common/generator.c - ${PM3_ROOT}/client/src/crypto/asn1dump.c - ${PM3_ROOT}/client/src/crypto/asn1utils.c - ${PM3_ROOT}/client/src/crypto/libpcrypto.c - ${PM3_ROOT}/client/src/emv/test/cda_test.c - ${PM3_ROOT}/client/src/emv/test/crypto_test.c - ${PM3_ROOT}/client/src/emv/test/cryptotest.c - ${PM3_ROOT}/client/src/emv/test/dda_test.c - ${PM3_ROOT}/client/src/emv/test/sda_test.c - ${PM3_ROOT}/client/src/emv/apduinfo.c - ${PM3_ROOT}/client/src/emv/cmdemv.c - ${PM3_ROOT}/client/src/emv/crypto.c - ${PM3_ROOT}/client/src/emv/crypto_polarssl.c - ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/emv_pk.c - ${PM3_ROOT}/client/src/emv/emv_pki.c - ${PM3_ROOT}/client/src/emv/emv_pki_priv.c - ${PM3_ROOT}/client/src/emv/emv_roca.c - ${PM3_ROOT}/client/src/emv/emv_tags.c - ${PM3_ROOT}/client/src/emv/emvcore.c - ${PM3_ROOT}/client/src/emv/emvjson.c - ${PM3_ROOT}/client/src/emv/tlv.c - ${PM3_ROOT}/client/src/fido/additional_ca.c - ${PM3_ROOT}/client/src/fido/cbortools.c - ${PM3_ROOT}/client/src/fido/cose.c - ${PM3_ROOT}/client/src/fido/fidocore.c - ${PM3_ROOT}/client/src/loclass/cipher.c - ${PM3_ROOT}/client/src/loclass/cipherutils.c - ${PM3_ROOT}/client/src/loclass/elite_crack.c - ${PM3_ROOT}/client/src/loclass/hash1_brute.c - ${PM3_ROOT}/client/src/loclass/ikeys.c - ${PM3_ROOT}/client/src/mifare/mad.c - ${PM3_ROOT}/client/src/mifare/mfkey.c - ${PM3_ROOT}/client/src/mifare/mifare4.c - ${PM3_ROOT}/client/src/mifare/mifaredefault.c - ${PM3_ROOT}/client/src/mifare/mifarehost.c - ${PM3_ROOT}/client/src/mifare/ndef.c - ${PM3_ROOT}/client/src/mifare/desfire_crypto.c - ${PM3_ROOT}/client/src/uart/uart_posix.c - ${PM3_ROOT}/client/src/uart/uart_win32.c - ${PM3_ROOT}/client/src/ui/overlays.ui - ${PM3_ROOT}/client/src/aiddesfire.c - ${PM3_ROOT}/client/src/aidsearch.c - ${PM3_ROOT}/client/src/cmdanalyse.c - ${PM3_ROOT}/client/src/cmdcrc.c - ${PM3_ROOT}/client/src/cmddata.c - ${PM3_ROOT}/client/src/cmdflashmem.c - ${PM3_ROOT}/client/src/cmdflashmemspiffs.c - ${PM3_ROOT}/client/src/cmdhf.c - ${PM3_ROOT}/client/src/cmdhf14a.c - ${PM3_ROOT}/client/src/cmdhf14b.c - ${PM3_ROOT}/client/src/cmdhf15.c - ${PM3_ROOT}/client/src/cmdhfcryptorf.c - ${PM3_ROOT}/client/src/cmdhfepa.c - ${PM3_ROOT}/client/src/cmdhffelica.c - ${PM3_ROOT}/client/src/cmdhffido.c - ${PM3_ROOT}/client/src/cmdhficlass.c - ${PM3_ROOT}/client/src/cmdhflegic.c - ${PM3_ROOT}/client/src/cmdhflist.c - ${PM3_ROOT}/client/src/cmdhflto.c - ${PM3_ROOT}/client/src/cmdhfmf.c - ${PM3_ROOT}/client/src/cmdhfmfdes.c - ${PM3_ROOT}/client/src/cmdhfmfhard.c - ${PM3_ROOT}/client/src/cmdhfmfp.c - ${PM3_ROOT}/client/src/cmdhfmfu.c - ${PM3_ROOT}/client/src/cmdhfst.c - ${PM3_ROOT}/client/src/cmdhfthinfilm.c - ${PM3_ROOT}/client/src/cmdhftopaz.c - ${PM3_ROOT}/client/src/cmdhfwaveshare.c - ${PM3_ROOT}/client/src/cmdhw.c - ${PM3_ROOT}/client/src/cmdlf.c - ${PM3_ROOT}/client/src/cmdlfawid.c - ${PM3_ROOT}/client/src/cmdlfcotag.c - ${PM3_ROOT}/client/src/cmdlfdestron.c - ${PM3_ROOT}/client/src/cmdlfem4x.c - ${PM3_ROOT}/client/src/cmdlfem4x05.c - ${PM3_ROOT}/client/src/cmdlfem4x50.c - ${PM3_ROOT}/client/src/cmdlffdxb.c - ${PM3_ROOT}/client/src/cmdlfgallagher.c - ${PM3_ROOT}/client/src/cmdlfguard.c - ${PM3_ROOT}/client/src/cmdlfhid.c - ${PM3_ROOT}/client/src/cmdlfhitag.c - ${PM3_ROOT}/client/src/cmdlfidteck.c - ${PM3_ROOT}/client/src/cmdlfindala.c - ${PM3_ROOT}/client/src/cmdlfio.c - ${PM3_ROOT}/client/src/cmdlfjablotron.c - ${PM3_ROOT}/client/src/cmdlfkeri.c - ${PM3_ROOT}/client/src/cmdlfmotorola.c - ${PM3_ROOT}/client/src/cmdlfnedap.c - ${PM3_ROOT}/client/src/cmdlfnexwatch.c - ${PM3_ROOT}/client/src/cmdlfnoralsy.c - ${PM3_ROOT}/client/src/cmdlfpac.c - ${PM3_ROOT}/client/src/cmdlfparadox.c - ${PM3_ROOT}/client/src/cmdlfpcf7931.c - ${PM3_ROOT}/client/src/cmdlfpresco.c - ${PM3_ROOT}/client/src/cmdlfpyramid.c - ${PM3_ROOT}/client/src/cmdlfsecurakey.c - ${PM3_ROOT}/client/src/cmdlft55xx.c - ${PM3_ROOT}/client/src/cmdlfti.c - ${PM3_ROOT}/client/src/cmdlfviking.c - ${PM3_ROOT}/client/src/cmdlfvisa2000.c - ${PM3_ROOT}/client/src/cmdmain.c - ${PM3_ROOT}/client/src/cmdparser.c - ${PM3_ROOT}/client/src/cmdscript.c - ${PM3_ROOT}/client/src/cmdsmartcard.c - ${PM3_ROOT}/client/src/cmdtrace.c - ${PM3_ROOT}/client/src/cmdusart.c - ${PM3_ROOT}/client/src/cmdwiegand.c - ${PM3_ROOT}/client/src/comms.c - ${PM3_ROOT}/client/src/fileutils.c - ${PM3_ROOT}/client/src/flash.c - ${PM3_ROOT}/client/src/graph.c - ${PM3_ROOT}/client/src/jansson_path.c - ${PM3_ROOT}/client/src/preferences.c - ${PM3_ROOT}/client/src/pm3.c - ${PM3_ROOT}/client/src/pm3_binlib.c - ${PM3_ROOT}/client/src/pm3_bitlib.c - ${PM3_ROOT}/client/src/prng.c - ${PM3_ROOT}/client/src/scandir.c - ${PM3_ROOT}/client/src/scripting.c - ${PM3_ROOT}/client/src/tea.c - ${PM3_ROOT}/client/src/ui.c - ${PM3_ROOT}/client/src/util.c - ${PM3_ROOT}/client/src/wiegand_formats.c - ${PM3_ROOT}/client/src/wiegand_formatutils.c - ${CMAKE_BINARY_DIR}/version.c - ) - -add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/version.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c - DEPENDS ${PM3_ROOT}/common/default_version.c -) - -set(ADDITIONAL_SRC "") -set(ADDITIONAL_LNK "") -set(ADDITIONAL_DIRS "") -set(ADDITIONAL_LNKDIRS "") -set(X86_CPUS x86 x86_64 i686) - -message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") - -if (APPLE) - message(STATUS "Apple device detected.") - set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") -endif (APPLE) - -if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTORCC ON) - set(CMAKE_AUTOUIC ON) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/proxgui.cpp - ${PM3_ROOT}/client/src/proxguiqt.cpp - ${TARGET_SOURCES}) - - add_definitions("-DHAVE_GUI") - set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK}) -else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - set(TARGET_SOURCES - ${PM3_ROOT}/client/src/guidummy.cpp - ${TARGET_SOURCES}) -endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - -if (NOT SKIPBT EQUAL 1) - if (BLUEZ_FOUND) - add_definitions("-DHAVE_BLUEZ") - set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK}) - endif (BLUEZ_FOUND) -endif(NOT SKIPBT EQUAL 1) - -if (JANSSON_FOUND) - set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK}) -endif (JANSSON_FOUND) - -if (NOT SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND) - add_definitions(-DHAVE_PYTHON) - set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK}) - set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) - elseif (PYTHON3_FOUND) - add_definitions(-DHAVE_PYTHON) - set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) - set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) - endif (PYTHON3EMBED_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -if (NOT SKIPREADLINE EQUAL 1) - if (READLINE_FOUND) - add_definitions("-DHAVE_READLINE") - set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK}) - endif (READLINE_FOUND) -endif(NOT SKIPREADLINE EQUAL 1) - -if (BZIP2_FOUND) - set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK}) -endif (BZIP2_FOUND) - -if (WHEREAMI_FOUND) - set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK}) -endif (WHEREAMI_FOUND) - -message(STATUS "===================================================================") -if (SKIPQT EQUAL 1) - message(STATUS "GUI support: skipped") -else (SKIPQT EQUAL 1) - if (Qt5_FOUND) - message(STATUS "GUI support: QT5 found, enabled") - else (Qt5_FOUND) - message(STATUS "GUI support: QT5 not found, disabled") - endif (Qt5_FOUND) -endif (SKIPQT EQUAL 1) - -if (SKIPBT EQUAL 1) - message(STATUS "native BT support: skipped") -else (SKIPBT EQUAL 1) - if (BLUEZ_FOUND) - message(STATUS "native BT support: Bluez found, enabled") - else (BLUEZ_FOUND) - message(STATUS "native BT support: Bluez not found, disabled") - endif (BLUEZ_FOUND) -endif(SKIPBT EQUAL 1) - -if (EMBED_BZIP2) - message(STATUS "Bzip2 library: embedded") -else (EMBED_BZIP2) - message(STATUS "Bzip2 library: system library found") -endif (EMBED_BZIP2) - -if (SKIPJANSSONSYSTEM EQUAL 1) - message(STATUS "Jansson library: local library forced") -else (SKIPJANSSONSYSTEM EQUAL 1) - if (JANSSON_FOUND) - message(STATUS "Jansson library: system library found") - else (JANSSON_FOUND) - message(STATUS "Jansson library: system library not found, using local library") - endif (JANSSON_FOUND) -endif (SKIPJANSSONSYSTEM EQUAL 1) - -if (SKIPPYTHON EQUAL 1) - message(STATUS "Python3 library: skipped") -else (SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND) - message(STATUS "Python3 library: Python3 embed found, enabled") - elseif (PYTHON_FOUND) - message(STATUS "Python3 library: Python3 found, enabled") - else (PYTHON3EMBED_FOUND) - message(STATUS "Python3 library: Python3 not found, disabled") - endif (PYTHON3EMBED_FOUND) -endif(SKIPPYTHON EQUAL 1) - -if (SKIPREADLINE EQUAL 1) - message(STATUS "Readline library: skipped") -else (SKIPREADLINE EQUAL 1) - if (READLINE_FOUND) - if (EMBED_READLINE) - message(STATUS "Readline library: embedded") - else (EMBED_READLINE) - message(STATUS "Readline library: system library found") - endif (EMBED_READLINE) - else (READLINE_FOUND) - message(STATUS "Readline library: Readline not found, disabled") - endif (READLINE_FOUND) -endif(SKIPREADLINE EQUAL 1) - -if (SKIPWHEREAMISYSTEM EQUAL 1) - message(STATUS "Whereami library: local library forced") -else (SKIPWHEREAMISYSTEM EQUAL 1) - if (WHEREAMI_FOUND) - message(STATUS "Whereami library: system library found") - else (WHEREAMI_FOUND) - message(STATUS "Whereami library: system library not found, using local library") - endif (WHEREAMI_FOUND) -endif (SKIPWHEREAMISYSTEM EQUAL 1) -message(STATUS "===================================================================") - -# Lua SWIG -if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/pm3_luawrap.c - ${TARGET_SOURCES}) - add_definitions(-DHAVE_LUA_SWIG) - message("Lua SWIG wrapper found") -endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) - -# Python SWIG -if (NOT SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) - if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/pm3_pywrap.c - ${TARGET_SOURCES}) - add_definitions(-DHAVE_PYTHON_SWIG) - message("Python SWIG wrapper found") - endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) - endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -add_executable(proxmark3 - ${PM3_ROOT}/client/src/proxmark3.c - ${TARGET_SOURCES} - ${ADDITIONAL_SRC} -) - -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) -if (EMBED_READLINE) - if (NOT SKIPREADLINE EQUAL 1) - add_dependencies(proxmark3 ncurses readline) - endif (NOT SKIPREADLINE EQUAL 1) -endif (EMBED_READLINE) -if (EMBED_BZIP2) - add_dependencies(proxmark3 bzip2) -endif (EMBED_BZIP2) - -if (MINGW) - # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) - # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 - # FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32 - # but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html - target_compile_definitions(proxmark3 PRIVATE _ISOC99_SOURCE) - - set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") - set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") -endif (MINGW) - -target_include_directories(proxmark3 PRIVATE - ${PM3_ROOT}/common - ${PM3_ROOT}/common_fpga - ${PM3_ROOT}/include - ${PM3_ROOT}/client/src - ${PM3_ROOT}/client/include - ${ADDITIONAL_DIRS} -) - -if (NOT APPLE) - # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. - set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) -endif (NOT APPLE) - -if (NOT JANSSON_FOUND) - set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK}) -endif (NOT JANSSON_FOUND) -if (NOT WHEREAMI_FOUND) - set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK}) -endif (NOT WHEREAMI_FOUND) - -target_link_libraries(proxmark3 PRIVATE - m - pm3rrg_rdv4_mbedtls - pm3rrg_rdv4_cliparser - pm3rrg_rdv4_lua - pm3rrg_rdv4_tinycbor - pm3rrg_rdv4_amiibo - pm3rrg_rdv4_reveng - pm3rrg_rdv4_hardnested - ${ADDITIONAL_LNK}) - -if (NOT SKIPPTHREAD EQUAL 1) - target_link_libraries(proxmark3 PRIVATE pthread) -endif (NOT SKIPPTHREAD EQUAL 1) - -if (NOT SKIPPYTHON EQUAL 1) - # OSX have a hard time compiling python3 dependency with older cmake. - if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) - if (NOT CMAKE_VERSION VERSION_LESS 3.13) - target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS}) - elseif (APPLE) - message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" ) - endif (NOT CMAKE_VERSION VERSION_LESS 3.13) - endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -install(TARGETS proxmark3 DESTINATION "bin") -install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3") - -add_custom_command(OUTPUT lualibs/pm3_cmd.lua - COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua" - COMMENT "Creating lualibs/pm3_cmd.lua" - ) - -add_custom_command(OUTPUT lualibs/mfc_default_keys.lua - COMMAND "awk -f default_keys_dic2lua.awk mfc_default_keys.dic > lualibs/mfc_default_keys.lua" - COMMENT "Creating lualibs/mfc_default_keys.lua" - ) - -#"make package" will trigger this -SET(CPACK_GENERATOR "DEB") -SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Iceman") -INCLUDE(CPack) diff --git a/client/experimental_client_with_swig/output_grabber.py b/client/experimental_client_with_swig/output_grabber.py new file mode 100755 index 000000000..ad405c9d9 --- /dev/null +++ b/client/experimental_client_with_swig/output_grabber.py @@ -0,0 +1,78 @@ +import os +import sys +import threading +import time + +# From https://stackoverflow.com/a/29834357 +class OutputGrabber(object): + """ + Class used to grab standard output or another stream. + """ + escape_char = "\b" + + def __init__(self, stream=None, threaded=False): + self.origstream = stream + self.threaded = threaded + if self.origstream is None: + self.origstream = sys.stdout + self.origstreamfd = self.origstream.fileno() + self.capturedtext = "" + # Create a pipe so the stream can be captured: + self.pipe_out, self.pipe_in = os.pipe() + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def start(self): + """ + Start capturing the stream data. + """ + self.capturedtext = "" + # Save a copy of the stream: + self.streamfd = os.dup(self.origstreamfd) + # Replace the original stream with our write pipe: + os.dup2(self.pipe_in, self.origstreamfd) + if self.threaded: + # Start thread that will read the stream: + self.workerThread = threading.Thread(target=self.readOutput) + self.workerThread.start() + # Make sure that the thread is running and os.read() has executed: + time.sleep(0.01) + + def stop(self): + """ + Stop capturing the stream data and save the text in `capturedtext`. + """ + # Print the escape character to make the readOutput method stop: + self.origstream.write(self.escape_char) + # Flush the stream to make sure all our data goes in before + # the escape character: + self.origstream.flush() + if self.threaded: + # wait until the thread finishes so we are sure that + # we have until the last character: + self.workerThread.join() + else: + self.readOutput() + # Close the pipe: + os.close(self.pipe_in) + os.close(self.pipe_out) + # Restore the original stream: + os.dup2(self.streamfd, self.origstreamfd) + # Close the duplicate stream: + os.close(self.streamfd) + + def readOutput(self): + """ + Read the stream data (one byte at a time) + and save the text in `capturedtext`. + """ + while True: + char = os.read(self.pipe_out,1).decode(self.origstream.encoding) + if not char or self.escape_char in char: + break + self.capturedtext += char diff --git a/client/experimental_client_with_swig/testembedded_grab.py b/client/experimental_client_with_swig/testembedded_grab.py new file mode 100755 index 000000000..caec75769 --- /dev/null +++ b/client/experimental_client_with_swig/testembedded_grab.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import pm3 +from output_grabber import OutputGrabber + +out = OutputGrabber() +p=pm3.pm3() +print("Device:", p.name) +with out: + p.console("hw status") +for line in out.capturedtext.split('\n'): + if "Unique ID" in line: + print(line) diff --git a/client/src/pm3.i b/client/src/pm3.i index 5b4a1fb47..dc47563b2 100644 --- a/client/src/pm3.i +++ b/client/src/pm3.i @@ -11,22 +11,22 @@ typedef struct { %extend { pm3() { - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; } pm3(char *port) { - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } ~pm3() { if ($self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close($self); } } diff --git a/client/src/pm3_luawrap.c b/client/src/pm3_luawrap.c index 2dc4a8dc0..cc8ca7dcf 100644 --- a/client/src/pm3_luawrap.c +++ b/client/src/pm3_luawrap.c @@ -2687,7 +2687,7 @@ static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0}; #include "comms.h" SWIGINTERN pm3 *new_pm3__SWIG_0(void){ - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; @@ -2701,16 +2701,16 @@ SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) { } SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } SWIGINTERN void delete_pm3(pm3 *self){ if (self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close(self); } } diff --git a/client/src/pm3_pywrap.c b/client/src/pm3_pywrap.c index a3a5812ff..03a584e48 100644 --- a/client/src/pm3_pywrap.c +++ b/client/src/pm3_pywrap.c @@ -2672,7 +2672,7 @@ static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0}; #include "comms.h" SWIGINTERN pm3 *new_pm3__SWIG_0(void){ - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; @@ -2801,16 +2801,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } SWIGINTERN void delete_pm3(pm3 *self){ if (self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close(self); } } From c6662696703569e9b7040a57f4848022450fd8f7 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 11 Nov 2020 01:21:10 +0100 Subject: [PATCH 34/69] scripts --- .../01make_client_makefile.sh | 4 ++++ .../02a_run_test_lua_makefile.sh | 3 +++ .../02b_run_test_py_grabber_cmake.sh | 7 +++++++ .../02b_run_test_py_makefile.sh | 7 +++++++ 4 files changed, 21 insertions(+) create mode 100755 client/experimental_client_with_swig/01make_client_makefile.sh create mode 100755 client/experimental_client_with_swig/02a_run_test_lua_makefile.sh create mode 100755 client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh create mode 100755 client/experimental_client_with_swig/02b_run_test_py_makefile.sh diff --git a/client/experimental_client_with_swig/01make_client_makefile.sh b/client/experimental_client_with_swig/01make_client_makefile.sh new file mode 100755 index 000000000..93ab04ca2 --- /dev/null +++ b/client/experimental_client_with_swig/01make_client_makefile.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd .. +make -j diff --git a/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh b/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh new file mode 100755 index 000000000..bc19e7dfe --- /dev/null +++ b/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +../proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh new file mode 100755 index 000000000..2f13a6628 --- /dev/null +++ b/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +#/usr/local/lib/python3/dist-packages/pm3.py +#/usr/lib/python3/dist-packages/pm3.py + +# need access to pm3.py +PYTHONPATH=../src ../build/proxmark3 /dev/ttyACM1 -c "script run testembedded_grab.py" -i diff --git a/client/experimental_client_with_swig/02b_run_test_py_makefile.sh b/client/experimental_client_with_swig/02b_run_test_py_makefile.sh new file mode 100755 index 000000000..838331382 --- /dev/null +++ b/client/experimental_client_with_swig/02b_run_test_py_makefile.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +#/usr/local/lib/python3/dist-packages/pm3.py +#/usr/lib/python3/dist-packages/pm3.py + +# need access to pm3.py +PYTHONPATH=../src ../proxmark3 /dev/ttyACM0 -c "script run testembedded.py" From cc914ccac19d205360aafb25bc998bd0cceb3cc2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 11 Nov 2020 01:28:45 +0100 Subject: [PATCH 35/69] lib scripts --- client/experimental_lib/00make_swig.sh | 5 +- client/experimental_lib/CMakeLists.txt | 6 +- .../example_py/02run_test_grab_interactive.sh | 3 + .../example_py/output_grabber.py | 78 +++++++++++++++++++ .../experimental_lib/example_py/test_grab.py | 13 ++++ 5 files changed, 100 insertions(+), 5 deletions(-) create mode 100755 client/experimental_lib/example_py/02run_test_grab_interactive.sh create mode 100755 client/experimental_lib/example_py/output_grabber.py create mode 100755 client/experimental_lib/example_py/test_grab.py diff --git a/client/experimental_lib/00make_swig.sh b/client/experimental_lib/00make_swig.sh index 6c752d024..626a87986 100755 --- a/client/experimental_lib/00make_swig.sh +++ b/client/experimental_lib/00make_swig.sh @@ -1,4 +1,5 @@ #!/bin/bash -swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i -swig -python -o ../src/pm3_pywrap.c ../src/pm3.i +cd .. +make src/pm3_luawrap.c +make src/pm3_pywrap.c diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 454e08e00..2bc02fd4b 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -455,7 +455,6 @@ else (SKIPWHEREAMISYSTEM EQUAL 1) message(STATUS "Whereami library: system library not found, using local library") endif (WHEREAMI_FOUND) endif (SKIPWHEREAMISYSTEM EQUAL 1) -message(STATUS "===================================================================") # Lua SWIG if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) @@ -463,7 +462,7 @@ if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) ${PM3_ROOT}/client/src/pm3_luawrap.c ${TARGET_SOURCES}) add_definitions(-DHAVE_LUA_SWIG) - message("Lua SWIG wrapper found") + message(STATUS "Lua SWIG: wrapper found") endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) # Python SWIG @@ -474,10 +473,11 @@ if (NOT SKIPPYTHON EQUAL 1) ${PM3_ROOT}/client/src/pm3_pywrap.c ${TARGET_SOURCES}) add_definitions(-DHAVE_PYTHON_SWIG) - message("Python SWIG wrapper found") + message(STATUS "Python SWIG: wrapper found") endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) endif (NOT SKIPPYTHON EQUAL 1) +message(STATUS "===================================================================") add_library(pm3rrg_rdv4 SHARED ${PM3_ROOT}/client/src/proxmark3.c diff --git a/client/experimental_lib/example_py/02run_test_grab_interactive.sh b/client/experimental_lib/example_py/02run_test_grab_interactive.sh new file mode 100755 index 000000000..d7dd7dd16 --- /dev/null +++ b/client/experimental_lib/example_py/02run_test_grab_interactive.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +PYTHONPATH=../../src ipython3 -i ./test_grab.py diff --git a/client/experimental_lib/example_py/output_grabber.py b/client/experimental_lib/example_py/output_grabber.py new file mode 100755 index 000000000..ad405c9d9 --- /dev/null +++ b/client/experimental_lib/example_py/output_grabber.py @@ -0,0 +1,78 @@ +import os +import sys +import threading +import time + +# From https://stackoverflow.com/a/29834357 +class OutputGrabber(object): + """ + Class used to grab standard output or another stream. + """ + escape_char = "\b" + + def __init__(self, stream=None, threaded=False): + self.origstream = stream + self.threaded = threaded + if self.origstream is None: + self.origstream = sys.stdout + self.origstreamfd = self.origstream.fileno() + self.capturedtext = "" + # Create a pipe so the stream can be captured: + self.pipe_out, self.pipe_in = os.pipe() + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def start(self): + """ + Start capturing the stream data. + """ + self.capturedtext = "" + # Save a copy of the stream: + self.streamfd = os.dup(self.origstreamfd) + # Replace the original stream with our write pipe: + os.dup2(self.pipe_in, self.origstreamfd) + if self.threaded: + # Start thread that will read the stream: + self.workerThread = threading.Thread(target=self.readOutput) + self.workerThread.start() + # Make sure that the thread is running and os.read() has executed: + time.sleep(0.01) + + def stop(self): + """ + Stop capturing the stream data and save the text in `capturedtext`. + """ + # Print the escape character to make the readOutput method stop: + self.origstream.write(self.escape_char) + # Flush the stream to make sure all our data goes in before + # the escape character: + self.origstream.flush() + if self.threaded: + # wait until the thread finishes so we are sure that + # we have until the last character: + self.workerThread.join() + else: + self.readOutput() + # Close the pipe: + os.close(self.pipe_in) + os.close(self.pipe_out) + # Restore the original stream: + os.dup2(self.streamfd, self.origstreamfd) + # Close the duplicate stream: + os.close(self.streamfd) + + def readOutput(self): + """ + Read the stream data (one byte at a time) + and save the text in `capturedtext`. + """ + while True: + char = os.read(self.pipe_out,1).decode(self.origstream.encoding) + if not char or self.escape_char in char: + break + self.capturedtext += char diff --git a/client/experimental_lib/example_py/test_grab.py b/client/experimental_lib/example_py/test_grab.py new file mode 100755 index 000000000..7cec5a94f --- /dev/null +++ b/client/experimental_lib/example_py/test_grab.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import pm3 +from output_grabber import OutputGrabber + +out = OutputGrabber() +p=pm3.pm3("/dev/ttyACM1") +print("Device:", p.name) +with out: + p.console("hw status") +for line in out.capturedtext.split('\n'): + if "Unique ID" in line: + print(line) From e172c336528cd7885371458a0d2c21ec608c8220 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 00:16:01 +0100 Subject: [PATCH 36/69] pm3: look for cmake proxmark3 executable as well --- pm3 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pm3 b/pm3 index 4349ed643..b6ebbc52e 100755 --- a/pm3 +++ b/pm3 @@ -15,7 +15,14 @@ FULLIMAGE="fullimage.elf" BOOTIMAGE="bootrom.elf" # try pm3 dirs in current repo workdir if [ -d "$PM3PATH/client/" ]; then - CLIENT="$PM3PATH/client/proxmark3" + if [ -x "$PM3PATH/client/proxmark3" ]; then + CLIENT="$PM3PATH/client/proxmark3" + elif [ -x "$PM3PATH/client/build/proxmark3" ]; then + CLIENT="$PM3PATH/client/build/proxmark3" + else + echo >&2 "[!!] In devel workdir but no executable found, did you compile it?" + exit 1 + fi # try install dir elif [ -x "$PM3PATH/proxmark3" ]; then CLIENT="$PM3PATH/proxmark3" From 71b0c3ce314d5517845172d47a6ce05a9d9b3b1d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 00:19:16 +0100 Subject: [PATCH 37/69] Makefile: fix dep --- client/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index b2c372f6f..8012a71f5 100644 --- a/client/Makefile +++ b/client/Makefile @@ -774,7 +774,7 @@ print-%: ; @echo $* = $($*) # SWIG files emit a number of warnings, we've to ignore them %wrap.o: %wrap.c -$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%wrap.d +$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%.d $(info [-] CC $<) $(Q)$(MKDIR) $(dir $@) $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $< From 39a20b622629c0a046f26eaab5824a0dfad78544 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 00:23:25 +0100 Subject: [PATCH 38/69] scripts --- client/experimental_client_with_swig/02a_run_test_lua.sh | 3 +++ .../02a_run_test_lua_cmake.sh | 3 --- .../02a_run_test_lua_makefile.sh | 3 --- .../{02b_run_test_py_makefile.sh => 02b_run_test_py.sh} | 2 +- ...2b_run_test_py_cmake.sh => 02b_run_test_py_grabber.sh} | 2 +- .../02b_run_test_py_grabber_cmake.sh | 7 ------- .../02b_run_test_py_grabber_makefile.sh | 8 -------- 7 files changed, 5 insertions(+), 23 deletions(-) create mode 100755 client/experimental_client_with_swig/02a_run_test_lua.sh delete mode 100755 client/experimental_client_with_swig/02a_run_test_lua_cmake.sh delete mode 100755 client/experimental_client_with_swig/02a_run_test_lua_makefile.sh rename client/experimental_client_with_swig/{02b_run_test_py_makefile.sh => 02b_run_test_py.sh} (61%) rename client/experimental_client_with_swig/{02b_run_test_py_cmake.sh => 02b_run_test_py_grabber.sh} (59%) delete mode 100755 client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh delete mode 100755 client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh diff --git a/client/experimental_client_with_swig/02a_run_test_lua.sh b/client/experimental_client_with_swig/02a_run_test_lua.sh new file mode 100755 index 000000000..8e04b30f5 --- /dev/null +++ b/client/experimental_client_with_swig/02a_run_test_lua.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +../../pm3 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh b/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh deleted file mode 100755 index 08ed58b6b..000000000 --- a/client/experimental_client_with_swig/02a_run_test_lua_cmake.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -../build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh b/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh deleted file mode 100755 index bc19e7dfe..000000000 --- a/client/experimental_client_with_swig/02a_run_test_lua_makefile.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -../proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02b_run_test_py_makefile.sh b/client/experimental_client_with_swig/02b_run_test_py.sh similarity index 61% rename from client/experimental_client_with_swig/02b_run_test_py_makefile.sh rename to client/experimental_client_with_swig/02b_run_test_py.sh index 838331382..a962c7b22 100755 --- a/client/experimental_client_with_swig/02b_run_test_py_makefile.sh +++ b/client/experimental_client_with_swig/02b_run_test_py.sh @@ -4,4 +4,4 @@ #/usr/lib/python3/dist-packages/pm3.py # need access to pm3.py -PYTHONPATH=../src ../proxmark3 /dev/ttyACM0 -c "script run testembedded.py" +PYTHONPATH=../src ../../pm3 -c "script run testembedded.py" diff --git a/client/experimental_client_with_swig/02b_run_test_py_cmake.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh similarity index 59% rename from client/experimental_client_with_swig/02b_run_test_py_cmake.sh rename to client/experimental_client_with_swig/02b_run_test_py_grabber.sh index 4ef059045..06dc31717 100755 --- a/client/experimental_client_with_swig/02b_run_test_py_cmake.sh +++ b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh @@ -4,4 +4,4 @@ #/usr/lib/python3/dist-packages/pm3.py # need access to pm3.py -PYTHONPATH=../src ../build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py" +PYTHONPATH=../src ../../pm3 -c "script run testembedded_grab.py" -i diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh deleted file mode 100755 index 2f13a6628..000000000 --- a/client/experimental_client_with_swig/02b_run_test_py_grabber_cmake.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -#/usr/local/lib/python3/dist-packages/pm3.py -#/usr/lib/python3/dist-packages/pm3.py - -# need access to pm3.py -PYTHONPATH=../src ../build/proxmark3 /dev/ttyACM1 -c "script run testembedded_grab.py" -i diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh deleted file mode 100755 index 59013cc22..000000000 --- a/client/experimental_client_with_swig/02b_run_test_py_grabber_makefile.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -#/usr/local/lib/python3/dist-packages/pm3.py -#/usr/lib/python3/dist-packages/pm3.py - -# need access to pm3.py -PYTHONPATH=../src ../proxmark3 /dev/ttyACM0 -c "script run testembedded_grab.py" -i - From 923d2942c237721802f36dd0a0822cda7fe02237 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 00:44:18 +0100 Subject: [PATCH 39/69] py scripts --- client/Makefile | 1 + .../02b_run_test_py.sh | 6 +----- .../02b_run_test_py_grabber.sh | 6 +----- pm3 | 13 ++++++++++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/Makefile b/client/Makefile index 8012a71f5..a71c09c32 100644 --- a/client/Makefile +++ b/client/Makefile @@ -684,6 +684,7 @@ endif ifneq (,$(INSTALLSHARE)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) src/pm3.py $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/pyscripts endif @true diff --git a/client/experimental_client_with_swig/02b_run_test_py.sh b/client/experimental_client_with_swig/02b_run_test_py.sh index a962c7b22..e613a6adf 100755 --- a/client/experimental_client_with_swig/02b_run_test_py.sh +++ b/client/experimental_client_with_swig/02b_run_test_py.sh @@ -1,7 +1,3 @@ #!/bin/bash -#/usr/local/lib/python3/dist-packages/pm3.py -#/usr/lib/python3/dist-packages/pm3.py - -# need access to pm3.py -PYTHONPATH=../src ../../pm3 -c "script run testembedded.py" +../../pm3 -c "script run testembedded.py" diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh index 06dc31717..8aed5b8bb 100755 --- a/client/experimental_client_with_swig/02b_run_test_py_grabber.sh +++ b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh @@ -1,7 +1,3 @@ #!/bin/bash -#/usr/local/lib/python3/dist-packages/pm3.py -#/usr/lib/python3/dist-packages/pm3.py - -# need access to pm3.py -PYTHONPATH=../src ../../pm3 -c "script run testembedded_grab.py" -i +../../pm3 -c "script run testembedded_grab.py" -i diff --git a/pm3 b/pm3 index b6ebbc52e..27e992b11 100755 --- a/pm3 +++ b/pm3 @@ -11,6 +11,7 @@ FINDBTRFCOMM=true FINDBTDIRECT=true PM3PATH=$(dirname "$0") +EVALENV="" FULLIMAGE="fullimage.elf" BOOTIMAGE="bootrom.elf" # try pm3 dirs in current repo workdir @@ -23,17 +24,23 @@ if [ -d "$PM3PATH/client/" ]; then echo >&2 "[!!] In devel workdir but no executable found, did you compile it?" exit 1 fi + # Devel mode: point to workdir pm3.py module + EVALENV+=" PYTHONPATH=$PM3PATH/client/src" # try install dir elif [ -x "$PM3PATH/proxmark3" ]; then CLIENT="$PM3PATH/proxmark3" + EVALENV+=" PYTHONPATH=$PM3PATH/../share/proxmark3/pyscripts/" + # or /usr/[local/]lib/python3/dist-packages/pm3.py ? else -# hope it's installed somehow, still not sure where fw images are... +# hope it's installed somehow, still not sure where fw images and pm3.py are... CLIENT="proxmark3" fi -EVALENV="" # LeakSanitizer suppressions if [ -e .lsan_suppressions ]; then - EVALENV="export LSAN_OPTIONS=suppressions=.lsan_suppressions" + EVALENV+=" LSAN_OPTIONS=suppressions=.lsan_suppressions" +fi +if [ "$EVALENV" != "" ]; then + EVALENV="export $EVALENV" fi PM3LIST=() SHOWLIST=false From c9d60499e4c5ed082bb4500b1b1bec57b8e6b300 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 01:05:53 +0100 Subject: [PATCH 40/69] fix makefile --- client/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/Makefile b/client/Makefile index a71c09c32..3f0fac21c 100644 --- a/client/Makefile +++ b/client/Makefile @@ -600,11 +600,12 @@ SRCS += bucketsort.c \ # swig +SWIGSRCS = ifeq ($(SWIG_LUA_FOUND),1) - SRCS += pm3_luawrap.c + SWIGSRCS += pm3_luawrap.c endif ifeq ($(SWIG_PYTHON_FOUND),1) - SRCS += pm3_pywrap.c + SWIGSRCS += pm3_pywrap.c endif # gui @@ -620,6 +621,7 @@ ifeq ($(platform),Darwin) endif OBJS = $(SRCS:%.c=$(OBJDIR)/%.o) +OBJS += $(SWIGSRCS:%.c=$(OBJDIR)/%.o) OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o) OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o) @@ -803,6 +805,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(Q)$(POSTCOMPILE) DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \ + $(patsubst %wrap.c, $(OBJDIR)/%.d, $(SWIGSRCS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) From 0fc6f4d502f7e834ceee328b21ecb9ce3f1f250d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 01:13:07 +0100 Subject: [PATCH 41/69] iceman egg --- client/src/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 3cac51520..a51eaa204 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1225,10 +1225,10 @@ static int CmdHF14ACmdRaw(const char *Cmd) { arg_int0("b", NULL, "", "number of bits to send. Useful for send partial byte"), arg_lit0("c", NULL, "calculate and append CRC"), arg_lit0("k", NULL, "keep signal field ON after receive"), + arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), arg_lit0("r", NULL, "do not read response"), arg_lit0("s", NULL, "active signal field ON with select"), arg_int0("t", "timeout", "", "timeout in milliseconds"), - arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), arg_lit0(NULL, "topaz", "use Topaz protocol to send command"), arg_strx1(NULL, NULL, "", "raw bytes to send"), arg_param_end From d33e8708206f688cf729b6408ec3c436a1b913e9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 01:13:07 +0100 Subject: [PATCH 42/69] textual --- client/src/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 3cac51520..a51eaa204 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1225,10 +1225,10 @@ static int CmdHF14ACmdRaw(const char *Cmd) { arg_int0("b", NULL, "", "number of bits to send. Useful for send partial byte"), arg_lit0("c", NULL, "calculate and append CRC"), arg_lit0("k", NULL, "keep signal field ON after receive"), + arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), arg_lit0("r", NULL, "do not read response"), arg_lit0("s", NULL, "active signal field ON with select"), arg_int0("t", "timeout", "", "timeout in milliseconds"), - arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), arg_lit0(NULL, "topaz", "use Topaz protocol to send command"), arg_strx1(NULL, NULL, "", "raw bytes to send"), arg_param_end From da6fe8fa97e71732aecaec29dc71a58208d9d4c8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 11:59:48 +0100 Subject: [PATCH 43/69] cmake typo --- client/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 34ad38d26..92888a0fa 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -425,7 +425,7 @@ if (SKIPPYTHON EQUAL 1) else (SKIPPYTHON EQUAL 1) if (PYTHON3EMBED_FOUND) message(STATUS "Python3 library: Python3 embed found, enabled") - elseif (PYTHON_FOUND) + elseif (PYTHON3_FOUND) message(STATUS "Python3 library: Python3 found, enabled") else (PYTHON3EMBED_FOUND) message(STATUS "Python3 library: Python3 not found, disabled") From 81e4286409c035240c552c7d9fca004aa12a24a8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Nov 2020 12:36:47 +0100 Subject: [PATCH 44/69] makefile: fix condition --- client/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index 3f0fac21c..2f0899bc8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -292,7 +292,7 @@ endif ifneq ("$(wildcard src/pm3_luawrap.c)","") SWIG_LUA_FOUND = 1 endif -ifneq ($(SKIPPYTHON),1) +ifeq ($(PYTHON_FOUND),1) ifneq ("$(wildcard src/pm3_pywrap.c)","") SWIG_PYTHON_FOUND = 1 endif From 1ae89950eb074f60cdc2921fe04924041d78dea3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Nov 2020 12:40:59 +0100 Subject: [PATCH 45/69] dbg printing --- client/src/cmdhfmfdes.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 358f61493..3c5de933a 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -729,7 +729,6 @@ static int mfdes_get_info(mfdes_info_res_t *info) { return PM3_SUCCESS; } - static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload) { // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 4 different crypto arg1 DES, 3DES, 3K3DES, AES @@ -778,9 +777,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp if (payload->kdfAlgo == MFDES_KDF_ALGO_AN10922) { mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); - if (g_debugMode) { - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - } + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); } else if (payload->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { // We will overrite any provided KDF input since a gallagher specific KDF was requested. payload->kdfInputLen = 11; @@ -790,11 +787,9 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); + PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen)); + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - if (g_debugMode) { - PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen)); - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - } } uint8_t subcommand = MFDES_AUTHENTICATE; @@ -867,8 +862,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } if (g_debugMode > 1) { - PrintAndLogEx(INFO, "encRndB: %s", sprint_hex(encRndB, 8)); - PrintAndLogEx(INFO, "RndB: %s", sprint_hex(RndB, 8)); + PrintAndLogEx(DEBUG, "encRndB: %s", sprint_hex(encRndB, 8)); + PrintAndLogEx(DEBUG, "RndB: %s", sprint_hex(RndB, 8)); } // - Rotate RndB by 8 bits @@ -894,24 +889,24 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both: %s", sprint_hex(tmp, 16)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16)); } tdes_nxp_send(tmp, both, 16, key->data, IV, 2); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 16)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16)); } } else if (payload->algo == MFDES_ALGO_3K3DES) { uint8_t tmp[32] = {0x00}; memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); } tdes_nxp_send(tmp, both, 32, key->data, IV, 3); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); } } } else if (payload->mode == MFDES_AUTH_AES) { @@ -919,8 +914,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); } if (payload->algo == MFDES_ALGO_AES) { if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { @@ -928,7 +923,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); } } } @@ -997,8 +992,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp for (uint32_t x = 0; x < rndlen; x++) { if (RndA[x] != encRndA[x]) { if (g_debugMode > 1) { - PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); - PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); + PrintAndLogEx(DEBUG, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); + PrintAndLogEx(DEBUG, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); } return 11; } From 8a11bfee10bbc44a7ec15275e4d7be2b8791ea85 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Nov 2020 15:21:41 +0100 Subject: [PATCH 46/69] hf 14a raw - fix cli parse args --- client/src/cmdhf14a.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index a51eaa204..70821bc7f 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1240,10 +1240,10 @@ static int CmdHF14ACmdRaw(const char *Cmd) { uint16_t numbits = (uint16_t)arg_get_int_def(ctx, 2, 0); bool crc = arg_get_lit(ctx, 3); bool keep_field_on = arg_get_lit(ctx, 4); - bool reply = (arg_get_lit(ctx, 5) == false); - bool active_select = arg_get_lit(ctx, 6); - uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 7, 0); - bool no_rats = arg_get_lit(ctx, 8); + bool no_rats = arg_get_lit(ctx, 5); + bool reply = (arg_get_lit(ctx, 6) == false); + bool active_select = arg_get_lit(ctx, 7); + uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 8, 0); bool topazmode = arg_get_lit(ctx, 9); int datalen = 0; @@ -1344,13 +1344,15 @@ static int waitCmd(uint8_t iSelect, uint32_t timeout) { if (iSelect == 0 && len >= 3) { bool crc = check_crc(CRC_14443_A, data, len); + + char s[16]; + sprintf(s, + (crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"), + data[len - 2], + data[len - 1] + ); - PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s", - sprint_hex(data, len - 2), - data[len - 2], - data[len - 1], - (crc) ? _GREEN_("ok") : _RED_("fail") - ); + PrintAndLogEx(SUCCESS, "%s[ %s ]", sprint_hex(data, len - 2), s); } else { PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); } From 596a97a886a369bf839188e763273e1ea0202f26 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Nov 2020 15:25:27 +0100 Subject: [PATCH 47/69] hf 14a raw - adapt return codes --- client/src/cmdhf14a.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 70821bc7f..852aae3b8 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -33,7 +33,7 @@ bool APDUInFramingEnable = true; static int CmdHelp(const char *Cmd); -static int waitCmd(uint8_t iSelect, uint32_t timeout); +static int waitCmd(bool i_select, uint32_t timeout); static const manufactureName manufactureMapping[] = { // ID, "Vendor Country" @@ -1314,19 +1314,19 @@ static int CmdHF14ACmdRaw(const char *Cmd) { if (reply) { int res = 0; if (active_select) - res = waitCmd(1, timeout); - if (!res && datalen > 0) - waitCmd(0, timeout); + res = waitCmd(true, timeout); + if (res == PM3_SUCCESS && datalen > 0) + waitCmd(false, timeout); } return PM3_SUCCESS; } -static int waitCmd(uint8_t iSelect, uint32_t timeout) { +static int waitCmd(bool i_select, uint32_t timeout) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, timeout + 1500)) { uint16_t len = (resp.oldarg[0] & 0xFFFF); - if (iSelect) { + if (i_select) { len = (resp.oldarg[1] & 0xFFFF); if (len) { PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len); @@ -1338,11 +1338,11 @@ static int waitCmd(uint8_t iSelect, uint32_t timeout) { } if (!len) - return 1; + return PM3_ESOFT; uint8_t *data = resp.data.asBytes; - if (iSelect == 0 && len >= 3) { + if (i_select == false && len >= 3) { bool crc = check_crc(CRC_14443_A, data, len); char s[16]; @@ -1359,9 +1359,9 @@ static int waitCmd(uint8_t iSelect, uint32_t timeout) { } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 3; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } static int CmdHF14AAntiFuzz(const char *Cmd) { From 7c5e3a29deb656796fc5c5a231e32aad0180bda8 Mon Sep 17 00:00:00 2001 From: Ave Date: Sun, 15 Nov 2020 20:14:08 +0300 Subject: [PATCH 48/69] Fix old UID display on hf mf csetuid --- armsrc/mifarecmd.c | 3 ++- client/src/mifare/mifarehost.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 36fb7455c..7faa0c268 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2082,9 +2082,10 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); errormsg = MAGIC_UID; + mifare_classic_halt_ex(NULL); + break; } mifare_classic_halt_ex(NULL); - break; } // wipe tag, fill it with zeros diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index f48a696ed..3df2e295c 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -859,7 +859,7 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_ PrintAndLogEx(SUCCESS, "new block 0: %s", sprint_hex(block0, 16)); if (wipecard) params |= MAGIC_WIPE; - if (oldUID == NULL) params |= MAGIC_UID; + if (oldUID != NULL) params |= MAGIC_UID; return mfCSetBlock(0, block0, oldUID, params); } From 6341f751e523bd0c2f64f9e45f17c8767fd53e80 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Nov 2020 21:40:38 +0100 Subject: [PATCH 49/69] maur defaults --- client/dictionaries/mfc_default_keys.dic | 69 ++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 8c9611c56..2ee4bcd65 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1209,3 +1209,72 @@ FEE2A3FBC5B6 0602721E8F06 FC0B50AF8700 F7BA51A9434E +# +# eskart +# eskisehir transport card +E902395C1744 +4051A85E7F2D +7357EBD483CC +D8BA1AA9ABA0 +76939DDD9E97 +3BF391815A8D +# +# muzekart +# museum card for turkey +7C87013A648A +E8794FB14C63 +9F97C182585B +EC070A52E539 +C229CE5123D5 +E495D6E69D9C +26BF1A68B00F +B1D3BC5A7CCA +734EBE504CE8 +974A36E2B1BA +C197AE6D6990 +4D80A10649DF +037F64F470AD +C9CD8D7C65E5 +B70B1957FE71 +CE7712C5071D +C0AD1B72921A +45FEE09C1D06 +E592ED478E59 +F3C1F1DB1D83 +704A81DDACED +89E00BC444EF +AFAAFCC40DEC +ECC58C5D34CA +57D83754711D +D0DDDF2933EC +240F0BB84681 +9E7168064993 +2F8A867B06B4 +# +# bursakart +# bursa transport card +# +A0A1A2A3A4A5 +755D49191A78 +DAC7E0CBA8FD +68D3263A8CD6 +865B6472B1C0 +0860318A3A89 +1927A45A83D3 +B2FE3B2875A6 +# +# playland +# maltepe park +# +ABCC1276FCB0 +AABAFFCC7612 +# +# lunasan +# kocaeli fair +# +26107E7006A0 +# +# gamefactory +# ozdilek +# +17D071403C20 \ No newline at end of file From bfc5cd061ce9e331d6c4bf48e9da43b2d60a2036 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Nov 2020 21:42:17 +0100 Subject: [PATCH 50/69] remove dublicates --- client/dictionaries/mfc_default_keys.dic | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 2ee4bcd65..b3bf93312 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1132,8 +1132,6 @@ e2a9e88bfe16 aade86b1f9c1 5ea088c824c9 c67beb41ffbf -5ea088c824c9 -c67beb41ffbf b84d52971107 52b0d3f6116e # From 29b3477b0047ad535652b255728f5d8240c09b9d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Nov 2020 12:27:46 +0100 Subject: [PATCH 51/69] lto: textual --- client/src/cmdhflto.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index ab79423a4..69dab2108 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -28,6 +28,7 @@ If you have access to datasheet, le me know! LTO w Type info 00 01 has 101 blocks. + LTO w Type info 00 02 has 95 blocks. LTO w Type info 00 03 has 255 blocks. LTO w Type info 00 xx has NN blocks. */ @@ -242,18 +243,18 @@ static int CmdHfLTOList(const char *Cmd) { return CmdTraceList(args); } -static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_responce, bool verbose) { +static int lto_rdbl(uint8_t blk, uint8_t *block_response, uint8_t *block_cnt_response, bool verbose) { uint16_t resp_len = 18; uint8_t rdbl_cmd[] = {0x30, blk}; uint8_t rdbl_cnt_cmd[] = {0x80}; - int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_responce, &resp_len, true, false, verbose); + int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_response, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { return PM3_EWRONGANSWER; // READ BLOCK failed } - status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_responce, &resp_len, false, false, verbose); + status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_response, &resp_len, false, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { return PM3_EWRONGANSWER; // READ BLOCK CONTINUE failed } From f6aebe381b3573d806e96f7fdca28ede03afffd2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Nov 2020 20:06:33 +0100 Subject: [PATCH 52/69] lf hid demod - add raw back --- client/src/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 9bfbbaf3f..178a75449 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -138,9 +138,9 @@ int demodHID(bool verbose) { wiegand_message_t packed = initialize_message_object(hi2, hi, lo); if (HIDTryUnpack(&packed, false) == false) { - PrintAndLogEx(INFO, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo); printDemodBuff(0, false, false, true); } + PrintAndLogEx(INFO, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo); PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer: ", idx, size); if (g_debugMode) { From 4cafbcc25940b8c993ef0a1df5c6f98f63b387c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Nov 2020 23:47:54 +0100 Subject: [PATCH 53/69] hf mfdes - keeping track in the tag object of rf_field active status --- client/src/cmdhfmfdes.c | 11 ++++++++--- client/src/mifare/desfire_crypto.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 3c5de933a..b098e5837 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1558,9 +1558,14 @@ static int handler_desfire_select_application(uint8_t *aid) { sAPDU apdu = {0x90, MFDES_SELECT_APPLICATION, 0x00, 0x00, 0x03, aid}; //0x5a uint32_t recv_len = 0; uint16_t sw = 0; - int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, sizeof(dfname_t), true); + + int res = send_desfire_cmd(&apdu, !tag->rf_field_on, NULL, &recv_len, &sw, sizeof(dfname_t), true); if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, _RED_(" Can't select AID 0x%X -> %s"), (aid[2] << 16) + (aid[1] << 8) + aid[0], GetErrorString(res, &sw)); + PrintAndLogEx(WARNING, + _RED_(" Can't select AID 0x%X -> %s"), + (aid[2] << 16) + (aid[1] << 8) + aid[0], + GetErrorString(res, &sw) + ); DropField(); return res; } @@ -2238,9 +2243,9 @@ static int CmdHF14ADesSelectApp(const char *Cmd) { } int res = handler_desfire_select_application(aid); - DropField(); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error on selecting aid."); + DropField(); } else { PrintAndLogEx(SUCCESS, "Successfully selected aid."); } diff --git a/client/src/mifare/desfire_crypto.h b/client/src/mifare/desfire_crypto.h index a1d514507..e7219eaf0 100644 --- a/client/src/mifare/desfire_crypto.h +++ b/client/src/mifare/desfire_crypto.h @@ -93,6 +93,7 @@ struct desfire_tag { uint8_t *crypto_buffer; size_t crypto_buffer_size; uint32_t selected_application; + bool rf_field_on; }; typedef struct desfire_tag *desfiretag_t; From 4d28ffc014c4de61ea61d46bf26427c8bc6de996 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Nov 2020 23:58:50 +0100 Subject: [PATCH 54/69] hf mfdes deleteaid - shouldn't select before since it cancels the current session --- client/src/cmdhfmfdes.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index b098e5837..527515d89 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -2422,14 +2422,9 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { return PM3_ESOFT; } - uint8_t rootaid[3] = {0x00, 0x00, 0x00}; - int res = handler_desfire_select_application(rootaid); - if (res != PM3_SUCCESS) { - DropField(); - return res; - } - res = handler_desfire_deleteapp(aid); + int res = handler_desfire_deleteapp(aid); DropField(); + tag->rf_field_on = false; if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully deleted aid."); } From 57eef7c5a9e90a4ad1f98c634be7651ed781130b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Nov 2020 12:15:47 +0100 Subject: [PATCH 55/69] hf mfdes.. a session flag to keep track of rf field up/down. Now selectaid/createaid/deleteaid works. However, hf mfdes auth is needed before. the rest of the commands needs to be adapted to this new style. The reason is that a "select application" command aborts a current authenticated session. So we need to authenticate and keep that on until we done. --- client/src/cmdhfmfdes.c | 186 +++++++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 79 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 527515d89..4c4f713f7 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -42,6 +42,15 @@ #define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) +#ifndef DropFieldDesfire +#define DropFieldDesfire() { \ + clearCommandBuffer(); \ + SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ + tag->rf_field_on = false; \ + PrintAndLogEx(DEBUG, "field dropped"); \ + } +#endif + struct desfire_key default_key = {0}; uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official @@ -86,7 +95,7 @@ typedef struct mfdes_data { uint8_t *data; } PACKED mfdes_data_t; -typedef struct { +typedef struct mfdes_info_res { uint8_t isOK; uint8_t uid[7]; uint8_t uidlen; @@ -443,7 +452,7 @@ static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, int res = 0; if (activate_field) { - DropField(); + DropFieldDesfire(); msleep(50); } @@ -466,6 +475,11 @@ static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, return res; } + if (activate_field) { + PrintAndLogEx(DEBUG, "field up"); + tag->rf_field_on = true; + } + if (GetAPDULogging() || (g_debugMode > 1)) PrintAndLogEx(SUCCESS, "<<<< %s", sprint_hex(result, *result_len)); @@ -633,7 +647,7 @@ static int send_desfire_cmd(sAPDU *apdu, bool select, uint8_t *dest, uint32_t *r int res = DESFIRESendApdu(select, true, *apdu, data, sizeof(data), &resplen, sw); if (res != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "%s", GetErrorString(res, sw)); - DropField(); + DropFieldDesfire(); return res; } if (dest != NULL) { @@ -658,7 +672,7 @@ static int send_desfire_cmd(sAPDU *apdu, bool select, uint8_t *dest, uint32_t *r res = DESFIRESendApdu(false, true, *apdu, data, sizeof(data), &resplen, sw); if (res != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "%s", GetErrorString(res, sw)); - DropField(); + DropFieldDesfire(); return res; } @@ -704,7 +718,7 @@ static int mfdes_get_info(mfdes_info_res_t *info) { if (WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500) == false) { PrintAndLogEx(WARNING, "Command execute timeout"); - DropField(); + DropFieldDesfire(); return PM3_ETIMEOUT; } @@ -1058,7 +1072,7 @@ static int test_desfire_authenticate(void) { int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, 0, false); if (res == PM3_SUCCESS) if (sw == status(MFDES_ADDITIONAL_FRAME)) { - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1073,7 +1087,7 @@ static int test_desfire_authenticate_iso(void) { int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, 0, false); if (res == PM3_SUCCESS) if (sw == status(MFDES_ADDITIONAL_FRAME)) { - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1088,7 +1102,7 @@ static int test_desfire_authenticate_aes(void) { int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, 0, false); if (res == PM3_SUCCESS) if (sw == status(MFDES_ADDITIONAL_FRAME)) { - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1161,27 +1175,40 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n break; } } + /* + keyno 1b + key 8b + cpy 8b + crc 2b + padding + */ - // Variable length ciphered key data 26-42 bytes plus padding.. + // Variable length ciphered key data 24-42 bytes plus padding.. uint8_t data[64] = {key_no}; sAPDU apdu = {0x90, MFDES_CHANGE_KEY, 0x00, 0x00, 0x01, data}; // 0xC4 + size_t cmdcnt = 0; + uint8_t new_key_length = 16; switch (new_algo) { case MFDES_ALGO_DES: - new_key_length = 8; + // double + memcpy(data + cmdcnt + 1, new_key, new_key_length); + memcpy(data + cmdcnt + 1 + new_key_length, new_key, new_key_length); break; case MFDES_ALGO_3DES: case MFDES_ALGO_AES: new_key_length = 16; + memcpy(data + cmdcnt + 1, new_key, new_key_length); break; case MFDES_ALGO_3K3DES: new_key_length = 24; + memcpy(data + cmdcnt + 1, new_key, new_key_length); break; } - size_t cmdcnt = 0; - memcpy(data + cmdcnt + 1, new_key, new_key_length); + + if ((tag->authenticated_key_no & 0x0f) != (key_no & 0x0f)) { if (old_key) { @@ -1237,7 +1264,7 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't change key -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } @@ -1350,7 +1377,7 @@ static int handler_desfire_signature(uint8_t *signature, size_t *signature_len) *signature_len = recv_len; } } - DropField(); + DropFieldDesfire(); return res; } @@ -1566,7 +1593,7 @@ static int handler_desfire_select_application(uint8_t *aid) { (aid[2] << 16) + (aid[1] << 8) + aid[0], GetErrorString(res, &sw) ); - DropField(); + DropFieldDesfire(); return res; } memcpy(&tag->selected_application, aid, 3); @@ -1608,7 +1635,7 @@ static int handler_desfire_fileids(uint8_t *dest, uint32_t *file_ids_len) { int res = send_desfire_cmd(&apdu, false, dest, &recv_len, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't get file ids -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } *file_ids_len = recv_len; @@ -1627,7 +1654,7 @@ static int handler_desfire_filesettings(uint8_t file_id, uint8_t *dest, uint32_t int res = send_desfire_cmd(&apdu, false, dest, destlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't get file settings -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1667,7 +1694,7 @@ static int handler_desfire_createapp(aidhdr_t *aidhdr, bool usename, bool usefid } if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create aid -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); } return res; } @@ -1682,7 +1709,7 @@ static int handler_desfire_deleteapp(const uint8_t *aid) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't delete aid -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); } return res; } @@ -1700,7 +1727,7 @@ static int handler_desfire_credit(mfdes_value_t *value, uint8_t cs) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't credit value -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1719,7 +1746,7 @@ static int handler_desfire_limitedcredit(mfdes_value_t *value, uint8_t cs) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't credit limited value -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1738,7 +1765,7 @@ static int handler_desfire_debit(mfdes_value_t *value, uint8_t cs) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't debit value -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1760,7 +1787,7 @@ static int handler_desfire_readdata(mfdes_data_t *data, MFDES_FILE_TYPE_T type, int res = send_desfire_cmd(&apdu, false, data->data, &resplen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't read data -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } @@ -1790,7 +1817,7 @@ static int handler_desfire_getvalue(mfdes_value_t *value, uint32_t *resplen, uin int res = send_desfire_cmd(&apdu, false, value->value, resplen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't read data -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } size_t dlen = (size_t)resplen; @@ -1845,7 +1872,7 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type, res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't write data -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } offset += datasize; @@ -1855,7 +1882,7 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type, if (type == MFDES_RECORD_FILE) { if (handler_desfire_commit_transaction() != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't commit transaction -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } } @@ -1870,7 +1897,7 @@ static int handler_desfire_deletefile(uint8_t fileno) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't delete file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1884,13 +1911,13 @@ static int handler_desfire_clearrecordfile(uint8_t fileno) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't clear record file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } else { res = handler_desfire_commit_transaction(); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't commit transaction -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } } @@ -1907,7 +1934,7 @@ static int handler_desfire_create_value_file(mfdes_value_file_t *value) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create value -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1922,7 +1949,7 @@ static int handler_desfire_create_std_file(mfdes_file_t *file) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1938,7 +1965,7 @@ static int handler_desfire_create_linearrecordfile(mfdes_linear_t *file) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create linear record file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1954,7 +1981,7 @@ static int handler_desfire_create_cyclicrecordfile(mfdes_linear_t *file) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create cyclic record file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -1970,7 +1997,7 @@ static int handler_desfire_create_backup_file(mfdes_file_t *file) { int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't create backup file -> %s"), GetErrorString(res, &sw)); - DropField(); + DropFieldDesfire(); return res; } return res; @@ -2071,7 +2098,7 @@ static int getKeySettings(uint8_t *aid) { } } - DropField(); + DropFieldDesfire(); return PM3_SUCCESS; } @@ -2209,7 +2236,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) { uint8_t uid[16] = {0}; int res = handler_desfire_getuid(uid); if (res != PM3_SUCCESS) { - DropField(); + DropFieldDesfire(); PrintAndLogEx(ERR, "Error on getting uid."); return res; } @@ -2245,7 +2272,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) { int res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error on selecting aid."); - DropField(); + DropFieldDesfire(); } else { PrintAndLogEx(SUCCESS, "Successfully selected aid."); } @@ -2378,15 +2405,17 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { if (usename) PrintAndLogEx(INFO, "DF Name %s", aidhdr.name); +/* uint8_t rootaid[3] = {0x00, 0x00, 0x00}; int res = handler_desfire_select_application(rootaid); if (res != PM3_SUCCESS) { - DropField(); + DropFieldDesfire(); return res; } +*/ - res = handler_desfire_createapp(&aidhdr, usename, usefid); - DropField(); + int res = handler_desfire_createapp(&aidhdr, usename, usefid); + DropFieldDesfire(); if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully created aid."); } @@ -2397,7 +2426,6 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes deleteaid", "Delete Application ID", -// "Usage:\n\t-a aid (3 hex bytes, big endian)\n\n" "hf mfdes deleteaid -a 123456" ); @@ -2423,8 +2451,8 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { } int res = handler_desfire_deleteapp(aid); - DropField(); - tag->rf_field_on = false; + DropFieldDesfire(); + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully deleted aid."); } @@ -2514,7 +2542,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { } else { PrintAndLogEx(ERR, "Error on deleting file : %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -2574,7 +2602,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { } else { PrintAndLogEx(ERR, "Error on deleting file : %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -2664,12 +2692,12 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { if (aidlength != 3 && aidlength != 0) { PrintAndLogEx(ERR, _RED_(" The given aid must have 3 bytes (big endian).")); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } else if (aidlength == 0) { if (memcmp(&tag->selected_application, aid, 3) == 0) { PrintAndLogEx(ERR, _RED_(" You need to select an aid first.")); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } memcpy(aid, (uint8_t *)&tag->selected_application, 3); @@ -2678,7 +2706,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { int res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Couldn't select aid. Error %d", res); - DropField(); + DropFieldDesfire(); return res; } @@ -2692,7 +2720,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { else PrintAndLogEx(ERR, "Couldn't create standard/backup file. Error %d", res); - DropField(); + DropFieldDesfire(); return res; } @@ -2763,7 +2791,7 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { } else { PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -2879,12 +2907,12 @@ static int CmdHF14ADesReadData(const char *Cmd) { } } else { PrintAndLogEx(ERR, "Couldn't read data. Error %d", res); - DropField(); + DropFieldDesfire(); return res; } free(data); } - DropField(); + DropFieldDesfire(); return res; } @@ -2980,7 +3008,7 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { } else { PrintAndLogEx(ERR, "Couldn't change value in value file. Error %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -3074,7 +3102,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { uint8_t cs = 0; if (selectfile(aid, _fileno[0], &cs) != PM3_SUCCESS) { PrintAndLogEx(ERR, _RED_(" Error on selecting file.")); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } @@ -3086,7 +3114,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { } else { PrintAndLogEx(ERR, "Couldn't read data. Error %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -3222,7 +3250,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { } else { PrintAndLogEx(ERR, "Couldn't create linear/cyclic record file. Error %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -3354,7 +3382,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { } else { PrintAndLogEx(ERR, "Couldn't create value file. Error %d", res); } - DropField(); + DropFieldDesfire(); return res; } @@ -3380,13 +3408,13 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { } else { PrintAndLogEx(INFO, "Card successfully reset"); } - DropField(); + DropFieldDesfire(); return res; } static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far - DropField(); + DropFieldDesfire(); mfdes_info_res_t info; int res = mfdes_get_info(&info); @@ -3493,7 +3521,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { */ - DropField(); + DropFieldDesfire(); return PM3_SUCCESS; } @@ -3644,7 +3672,7 @@ static int CmdHF14ADesDump(const char *Cmd) { CLIParserFree(ctx); (void)Cmd; // Cmd is not used so far - DropField(); + DropFieldDesfire(); uint8_t aid[3] = {0}; uint8_t app_ids[78] = {0}; @@ -3660,7 +3688,7 @@ static int CmdHF14ADesDump(const char *Cmd) { if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Can't get list of applications on tag"); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } @@ -3724,7 +3752,7 @@ static int CmdHF14ADesDump(const char *Cmd) { uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t)); if (data == NULL) { - DropField(); + DropFieldDesfire(); return PM3_EMALLOC; } @@ -3771,7 +3799,7 @@ static int CmdHF14ADesDump(const char *Cmd) { memset(fdata.length, 0, 3); uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t)); if (data == NULL) { - DropField(); + DropFieldDesfire(); return PM3_EMALLOC; } @@ -3801,14 +3829,14 @@ static int CmdHF14ADesDump(const char *Cmd) { } PrintAndLogEx(INFO, "-------------------------------------------------------------"); - DropField(); + DropFieldDesfire(); return PM3_SUCCESS; } static int CmdHF14ADesEnumApplications(const char *Cmd) { (void)Cmd; // Cmd is not used so far - DropField(); + DropFieldDesfire(); uint8_t aid[3] = {0}; uint8_t app_ids[78] = {0}; @@ -3822,7 +3850,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Can't get list of applications on tag"); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } @@ -3892,12 +3920,12 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } PrintAndLogEx(INFO, "-------------------------------------------------------------"); - DropField(); + DropFieldDesfire(); return PM3_SUCCESS; } static int CmdHF14ADesChangeKey(const char *Cmd) { - //DropField(); + //DropFieldDesfire(); // NR DESC KEYLENGHT // ------------------------ // 1 = DES 8 @@ -3998,7 +4026,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) { // #define BUFSIZE 256 static int CmdHF14ADesAuth(const char *Cmd) { - //DropField(); + //DropFieldDesfire(); // NR DESC KEYLENGHT // ------------------------ // 1 = DES 8 @@ -4261,7 +4289,7 @@ static int AuthCheckDesfire(uint8_t *aid, break; } else if (error < 7) { badlen = true; - DropField(); + DropFieldDesfire(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { return res; @@ -4293,7 +4321,7 @@ static int AuthCheckDesfire(uint8_t *aid, break; } else if (error < 7) { badlen = true; - DropField(); + DropFieldDesfire(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { return res; @@ -4325,7 +4353,7 @@ static int AuthCheckDesfire(uint8_t *aid, break; } else if (error < 7) { badlen = true; - DropField(); + DropFieldDesfire(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { return res; @@ -4357,7 +4385,7 @@ static int AuthCheckDesfire(uint8_t *aid, break; } else if (error < 7) { badlen = true; - DropField(); + DropFieldDesfire(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { return res; @@ -4372,7 +4400,7 @@ static int AuthCheckDesfire(uint8_t *aid, } } } - DropField(); + DropFieldDesfire(); return PM3_SUCCESS; } @@ -4570,7 +4598,7 @@ static int CmdHF14aDesChk(const char *Cmd) { if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Can't get list of applications on tag"); - DropField(); + DropFieldDesfire(); return PM3_ESOFT; } @@ -4670,7 +4698,7 @@ static int CmdHF14ADesList(const char *Cmd) { /* static int CmdHF14aDesNDEF(const char *Cmd) { - DropField(); + DropFieldDesfire(); CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes ndef", @@ -4735,7 +4763,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) { uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t)); if (data == NULL) { - DropField(); + DropFieldDesfire(); return PM3_EMALLOC; } @@ -4774,7 +4802,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) { */ /* static int CmdHF14aDesMAD(const char *Cmd) { - DropField(); + DropFieldDesfire(); CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes mad", From 381a87c13823ee91774e04bd8e23143929e1fa2a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Nov 2020 20:44:44 +0100 Subject: [PATCH 56/69] msleep, hints, auto, now uses cliparser --- client/src/cmdmain.c | 133 +++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 68 deletions(-) diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 1cf3a6776..551f5ccf6 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -38,47 +38,10 @@ #include "util_posix.h" #include "commonutil.h" // ARRAYLEN #include "preferences.h" +#include "cliparser.h" static int CmdHelp(const char *Cmd); -static int usage_hints(void) { - PrintAndLogEx(NORMAL, "Turn on/off hints"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hints [h] <0|1>"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " <0|1> off or on"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" hints 1")); - return PM3_SUCCESS; -} - -static int usage_msleep(void) { - PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: msleep "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " time in milliseconds"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" msleep 100")); - return PM3_SUCCESS; -} - -static int usage_auto(void) { - PrintAndLogEx(NORMAL, "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE "); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: auto "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" auto")); - return PM3_SUCCESS; -} - static void AppendDate(char *s, size_t slen, const char *fmt) { struct tm *ct, tm_buf; time_t now = time(NULL); @@ -157,18 +120,31 @@ static int lf_search_plus(const char *Cmd) { return retval; } -static int CmdAuto(const char *Cmd) { - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_auto(); +static int CmdAuto(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "auto", + "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE", + "auto" + ); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + PrintAndLogEx(INFO, "lf search"); int ret = CmdLFfind(""); - if (ret == PM3_SUCCESS) + if (ret == PM3_SUCCESS) return ret; + PrintAndLogEx(INFO, "hf search"); ret = CmdHFSearch(""); if (ret == PM3_SUCCESS) return ret; + PrintAndLogEx(INFO, "lf search - unknown"); ret = lf_search_plus(""); if (ret == PM3_SUCCESS) return ret; @@ -193,26 +169,35 @@ int CmdRem(const char *Cmd) { } static int CmdHints(const char *Cmd) { - uint32_t ms = 0; - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hints(); - if (strlen(Cmd) > 1) { - str_lower((char *)Cmd); - if (str_startswith(Cmd, "of")) { - session.show_hints = false; - } else { - session.show_hints = true; - } - } else if (strlen(Cmd) == 1) { - if (param_getchar(Cmd, 0) != 0x00) { - ms = param_get32ex(Cmd, 0, 0, 10); - if (ms == 0) { - session.show_hints = false; - } else { - session.show_hints = true; - } - } + CLIParserContext *ctx; + CLIParserInit(&ctx, "hints", + "Turn on/off hints", + "hints --on\n" + "hints -1\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("1", "on", "turn on hints"), + arg_lit0("0", "off", "turn off hints"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool turn_on = arg_get_lit(ctx, 1); + bool turn_off = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if (turn_on && turn_off) { + PrintAndLogEx(ERR, "you can't turn off and on at the same time"); + return PM3_EINVARG; + } + + if (turn_off) { + session.show_hints = false; + } else if (turn_on) { + session.show_hints = true; } PrintAndLogEx(INFO, "Hints are %s", (session.show_hints) ? "ON" : "OFF"); @@ -220,14 +205,26 @@ static int CmdHints(const char *Cmd) { } static int CmdMsleep(const char *Cmd) { - uint32_t ms = 0; - char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_msleep(); - if (param_getchar(Cmd, 0) != 0x00) { - ms = param_get32ex(Cmd, 0, 0, 10); - if (ms == 0) - return usage_msleep(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "msleep", + "Sleep for given amount of milliseconds", + "msleep 100" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("t", "ms", "", "time in milliseconds"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + uint32_t ms = arg_get_u32_def(ctx, 1, 0); + CLIParserFree(ctx); + + if (ms == 0) { + PrintAndLogEx(ERR, "Specified invalid input. Can't be zero"); + return PM3_EINVARG; } + msleep(ms); return PM3_SUCCESS; } From 177fcbe4ca08639be8347a6661b4c52174e6ad1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Nov 2020 22:01:47 +0100 Subject: [PATCH 57/69] lf fdx clone - helptext --- client/src/cmdlffdxb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlffdxb.c b/client/src/cmdlffdxb.c index efd567128..92e466358 100644 --- a/client/src/cmdlffdxb.c +++ b/client/src/cmdlffdxb.c @@ -50,7 +50,7 @@ static int CmdHelp(const char *Cmd); static int usage_lf_fdxb_clone(void) { PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 or Q5/T5555 tag."); - PrintAndLogEx(NORMAL, "Usage: lf fdxb clone [h] [c ] [a ] [e ] "); + PrintAndLogEx(NORMAL, "Usage: lf fdxb clone [h] [c ] [n ] [e ] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " c : (dec) Country code"); From 3113cfabcbee34b6f56abb8df54ed33001ec7247 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Nov 2020 23:33:55 +0100 Subject: [PATCH 58/69] lf t55xx wipe - helptext (thanks @amal!) --- client/src/cmdlft55xx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index e34d14718..b2d3b56cd 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -315,11 +315,13 @@ static int usage_t55xx_wipe(void) { PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " c - set configuration from a block0"); + PrintAndLogEx(NORMAL, " p Date: Fri, 20 Nov 2020 15:45:14 +0100 Subject: [PATCH 59/69] more clear message (thanks @amal!) --- client/src/cmdlfem4x05.c | 6 +++--- client/src/cmdlft55xx.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index 93078178d..9abc2862c 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -429,7 +429,7 @@ int em4x05_clone_tag(uint32_t *blockdata, uint8_t numblocks, uint32_t pwd, bool } if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); + PrintAndLogEx(SUCCESS, "Data written and verified"); return PM3_SUCCESS; } @@ -824,7 +824,7 @@ int CmdEM4x05Write(const char *Cmd) { uint32_t dummy = 0; int status = em4x05_demod_resp(&dummy, true); if (status == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "Success writing to tag"); + PrintAndLogEx(SUCCESS, "Data written and verified"); else if (status == PM3_EFAILED) PrintAndLogEx(ERR, "Tag denied %s operation", protectOperation ? "Protect" : "Write"); else @@ -1431,7 +1431,7 @@ static int unlock_write_protect(bool use_pwd, uint32_t pwd, uint32_t data, bool uint32_t dummy = 0; int status = em4x05_demod_resp(&dummy, true); if (status == PM3_SUCCESS && verbose) - PrintAndLogEx(SUCCESS, "Success writing to tag"); + PrintAndLogEx(SUCCESS, "Data written and verified"); else if (status == PM3_EFAILED) PrintAndLogEx(ERR, "Tag denied PROTECT operation"); else diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index b2d3b56cd..a3ccf2052 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -489,7 +489,7 @@ int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) { } if (res == 0) - PrintAndLogEx(SUCCESS, "Success writing to tag"); + PrintAndLogEx(SUCCESS, "Data written and verified"); return PM3_SUCCESS; } From f75ba9bb3355756bff72bf1abaf5af6e38f67beb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Nov 2020 19:07:51 +0100 Subject: [PATCH 60/69] comment out iclass autopwn --- client/src/cmdhficlass.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 82bdbf5d0..2d61e0431 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3427,6 +3427,7 @@ static int CmdHFiClassPermuteKey(const char *Cmd) { return PM3_SUCCESS; } +/* static int CmdHFiClassAutopwn(const char *Cmd) { CLIParserContext *ctx; @@ -3448,6 +3449,7 @@ static int CmdHFiClassAutopwn(const char *Cmd) { PrintAndLogEx(INFO, "to be implemented"); return PM3_SUCCESS; } +*/ static command_t CommandTable[] = { {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, @@ -3463,7 +3465,7 @@ static command_t CommandTable[] = { {"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write Picopass / iCLASS block"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("recovery") " ---------------------"}, - {"autopwn", CmdHFiClassAutopwn, IfPm3Iclass, "[options..] Automatic key recovery tool for iCLASS"}, +// {"autopwn", CmdHFiClassAutopwn, IfPm3Iclass, "[options..] Automatic key recovery tool for iCLASS"}, {"chk", CmdHFiClassCheckKeys, IfPm3Iclass, "[options..] Check keys"}, {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce reader attack"}, {"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"}, From 1f8638c03bf67af6cd51850e0a807427ac0ce3a7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 20 Nov 2020 19:15:50 +0100 Subject: [PATCH 61/69] remove unused key --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 2d61e0431..eaf5b5406 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -43,11 +43,11 @@ static int CmdHelp(const char *Cmd); static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { { 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 }, { 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00 }, - { 0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xc1, 0x1b, 0x39 }, { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; From cef22ae84cc531c61e635bf8d69b62bdc1eb3c4f Mon Sep 17 00:00:00 2001 From: Gator96100 Date: Sun, 22 Nov 2020 22:46:58 +0100 Subject: [PATCH 62/69] Modified the tasks and launch configuration for ProxSpace --- .vscode/launch.json | 31 +++++++++++++++-- .vscode/tasks.json | 84 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d3d86ee80..f6a030c7c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,13 +18,21 @@ "text": "-enable-pretty-printing", "ignoreFailures": true } - ] + ], + "windows": { + "processId": "${input:ProcessIDWindows}", + "miDebuggerPath": "${workspaceFolder}/../../msys2/mingw64/bin/gdb.exe", + "externalConsole": true,//for ProxSpace externalConsole=true is required, because the internal cosole stops updating after a while + "environment": [{ + "name": "PATH","value": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin" + }] + } },{ "name": "(gdb) Build & Launch", "type": "cppdbg", "request": "launch", "program": "${cwd}/client/proxmark3", - "args": ["/dev/ttyACM0"], + "args": ["/dev/ttyACM0"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], @@ -38,7 +46,15 @@ } ], "preLaunchTask": "client: Debug: clean & make", - "miDebuggerPath": "/usr/bin/gdb" + "miDebuggerPath": "/usr/bin/gdb", + "windows": { + "args": ["COM5"], + "miDebuggerPath": "${workspaceFolder}/../../msys2/mingw64/bin/gdb.exe", + "externalConsole": true,//for ProxSpace externalConsole=true is required, because the internal cosole stops updating after a while + "environment": [{ + "name": "PATH","value": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin" + }] + } } ], "inputs": [ @@ -50,6 +66,15 @@ "args": { "command": "pgrep -n proxmark3", } + + },{ + "id": "ProcessIDWindows", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "${workspaceFolder}/../../runme64.bat -c \"cat /proc/$(pgrep -n proxmark3)/winpid\"", + } + } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 155aa80cd..7354a8a2d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,6 +7,18 @@ "label": "all: Make & run", "type": "shell", "command": "make -j && ./pm3", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [ "$gcc" ], @@ -19,6 +31,18 @@ "label": "choose: Make", "type": "shell", "command": "make ${input:componentType} -j", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [ "$gcc" ], @@ -28,6 +52,18 @@ "label": "client: Debug: make", "type": "shell", "command": "make client -j DEBUG=1", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [ "$gcc" ], @@ -37,6 +73,18 @@ "label": "client: Debug: clean & make", "type": "shell", "command": "make client/clean && make client -j DEBUG=1", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [ "$gcc" ], @@ -46,18 +94,54 @@ "label": "fullimage: Make & Flash", "type": "shell", "command": "make fullimage && ./pm3-flash-fullimage", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [] }, { "label": "BOOTROM: Make & Flash", "type": "shell", "command": "make bootrom && ./pm3-flash-bootrom", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [] }, { "label": "Run client", "type": "shell", "command": "./pm3", + "windows": { + "options": { + "cwd": "${workspaceFolder}/../..", + "shell": { + "executable": "${workspaceFolder}/../../runme64.bat", + "args": [ + "-c \"cd ${workspaceFolderBasename} &&" + ], + + } + } + }, "problemMatcher": [] } ], From a11e2ed4a6d73dc025ce17fd47b13b6777eb4c35 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Nov 2020 23:42:00 +0100 Subject: [PATCH 63/69] hf mfdes info - cmk textual ( #1062 ) --- client/src/cmdhfmf.c | 2 +- client/src/cmdhfmfdes.c | 206 +++++++++++++++++++++++----------------- 2 files changed, 118 insertions(+), 90 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 82fc8a1c4..481a5ce14 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5444,7 +5444,7 @@ static command_t CommandTable[] = { {"esave", CmdHF14AMfESave, IfPm3Iso14443a, "Save to file emul dump"}, {"eset", CmdHF14AMfESet, IfPm3Iso14443a, "Set simulator memory block"}, {"eview", CmdHF14AMfEView, IfPm3Iso14443a, "View emul memory"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " -----------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic gen1") " -----------------------"}, {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block"}, {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector"}, {"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump"}, diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 4c4f713f7..a69aa0d27 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -395,9 +395,9 @@ static char *getCardSizeStr(uint8_t fsize) { // is LSB set? if (fsize & 1) - snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d - %d bytes") ")", fsize, usize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X ( " _GREEN_("%d - %d bytes") " )", fsize, usize, lsize); else - snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d bytes") ")", fsize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X ( " _GREEN_("%d bytes") " )", fsize, lsize); return buf; } @@ -407,14 +407,14 @@ static char *getProtocolStr(uint8_t id, bool hw) { char *retStr = buf; if (id == 0x04) { - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-3 MIFARE, 14443-4") " )", id); } else if (id == 0x05) { if (hw) - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-2, 14443-3") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-2, 14443-3") " )", id); else - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") " )", id); } else { - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("Unknown") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Unknown") " )", id); } return buf; } @@ -425,19 +425,21 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; if (major == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire MF3ICD40") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor); else if (major == 0x01 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV1") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV1") " )", major, minor); else if (major == 0x12 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV2") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor); + else if (major == 0x42 && minor == 0x00) + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor); else if (major == 0x33 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV3") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV3") " )", major, minor); else if (major == 0x30 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire Light") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire Light") " )", major, minor); else if (major == 0x10 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("NTAG413DNA") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major, minor); else - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Unknown") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _YELLOW_("Unknown") " )", major, minor); return buf; //04 01 01 01 00 1A 05 @@ -1381,15 +1383,43 @@ static int handler_desfire_signature(uint8_t *signature, size_t *signature_len) return res; } -// --- KEY SETTING -static int desfire_print_keysetting(uint8_t key_settings, uint8_t num_keys, int algo) { +// --- KEY VERSION +static int desfire_print_keyversion(uint8_t key_idx, uint8_t key_version) { + PrintAndLogEx(SUCCESS, " Key [%u] Version : %d (0x%02x)", key_idx, key_version, key_version); + return PM3_SUCCESS; +} + +static int handler_desfire_keyversion(uint8_t curr_key, uint8_t *num_versions) { + if (num_versions == NULL) { + PrintAndLogEx(DEBUG, "NUM_VERSIONS=NULL"); + return PM3_EINVARG; + } + sAPDU apdu = {0x90, MFDES_GET_KEY_VERSION, 0x00, 0x00, 0x01, &curr_key}; //0x64 + uint32_t recv_len = 0; + uint16_t sw = 0; + int res = send_desfire_cmd(&apdu, false, num_versions, &recv_len, &sw, 0, true); + + if (res != PM3_SUCCESS) + return res; + + if (sw != status(MFDES_S_OPERATION_OK)) + return PM3_ESOFT; + + return res; +} + +// --- KEY SETTING Application Master Key +static int desfire_print_amk_keysetting(uint8_t key_settings, uint8_t num_keys, int algo) { PrintAndLogEx(SUCCESS, " AID Key settings : 0x%02x", key_settings); // 2 MSB denotes const char *str = " Max key number and type : %d, " _YELLOW_("%s"); - if (algo == MFDES_ALGO_DES) PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "(3)DES"); - else if (algo == MFDES_ALGO_AES) PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "AES"); - else if (algo == MFDES_ALGO_3K3DES) PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "3K3DES"); + if (algo == MFDES_ALGO_DES) + PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "(3)DES"); + else if (algo == MFDES_ALGO_AES) + PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "AES"); + else if (algo == MFDES_ALGO_3K3DES) + PrintAndLogEx(SUCCESS, str, num_keys & 0x3F, "3K3DES"); //PrintAndLogEx(SUCCESS, " Max number of keys in AID : %d", num_keys & 0x3F); PrintAndLogEx(INFO, "-------------------------------------------------------------"); @@ -1408,14 +1438,69 @@ static int desfire_print_keysetting(uint8_t key_settings, uint8_t num_keys, int PrintAndLogEx(SUCCESS, " -- All keys (except AMK,see Bit0) within this application are frozen"); break; default: - PrintAndLogEx(SUCCESS, " -- Authentication with the specified key is necessary to change any key.\nA change key and a PICC master key (CMK) can only be changed after authentication with the master key.\nFor keys other then the master or change key, an authentication with the same key is needed."); + PrintAndLogEx(SUCCESS, + " -- Authentication with the specified key is necessary to change any key.\n" + "A change key and a PICC master key (CMK) can only be changed after authentication with the master key.\n" + "For keys other then the master or change key, an authentication with the same key is needed." + ); break; } - PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", (key_settings & (1 << 3)) ? _GREEN_("YES") : "NO"); - PrintAndLogEx(SUCCESS, " [0x04] AMK required for create/delete : %s", (key_settings & (1 << 2)) ? "NO" : "YES"); - PrintAndLogEx(SUCCESS, " [0x02] Directory list access with AMK : %s", (key_settings & (1 << 1)) ? "NO" : "YES"); - PrintAndLogEx(SUCCESS, " [0x01] AMK is changeable : %s", (key_settings & (1 << 0)) ? _GREEN_("YES") : "NO"); + PrintAndLogEx(SUCCESS, " [1000] AMK Configuration changeable : %s", (key_settings & (1 << 3)) ? _GREEN_("YES") : "NO (frozen)"); + PrintAndLogEx(SUCCESS, " [0100] AMK required for create/delete : %s", (key_settings & (1 << 2)) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0010] Directory list access with AMK : %s", (key_settings & (1 << 1)) ? "NO" : "YES"); + PrintAndLogEx(SUCCESS, " [0001] AMK is changeable : %s", (key_settings & (1 << 0)) ? _GREEN_("YES") : "NO (frozen)"); + return PM3_SUCCESS; +} + +// --- KEY SETTING PICC Master Key (CMK) +static int desfire_print_piccmk_keysetting(uint8_t key_settings, uint8_t num_keys, int algo) { + //PrintAndLogEx(INFO, "--- " _CYAN_("PICC Master Key (CMK) settings")); + // number of Master keys (0x01) + PrintAndLogEx(SUCCESS, " Number of Masterkeys : " _YELLOW_("%u"), (num_keys & 0x3F)); + const char *str = " Operation of PICC master key : " _YELLOW_("%s"); + + if (algo == MFDES_ALGO_DES) + PrintAndLogEx(SUCCESS, str, "(3)DES"); + else if (algo == MFDES_ALGO_AES) + PrintAndLogEx(SUCCESS, str, "AES"); + else if (algo == MFDES_ALGO_3K3DES) + PrintAndLogEx(SUCCESS, str, "3K3DES"); + + uint8_t cmk_num_versions = 0; + if (handler_desfire_keyversion(0, &cmk_num_versions) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, " PICC Master key Version : " _YELLOW_("%d (0x%02x)"), cmk_num_versions, cmk_num_versions); + } + + PrintAndLogEx(INFO, " ----------------------------------------------------------"); + + // Authentication tests + int res = test_desfire_authenticate(); + if (res == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); + + res = test_desfire_authenticate_iso(); + if (res == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); + + res = test_desfire_authenticate_aes(); + if (res == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); + + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Key setting: 0x%02X [%c%c%c%c]", + key_settings, + (key_settings & (1 << 3)) ? '1' : '0', + (key_settings & (1 << 2)) ? '1' : '0', + (key_settings & (1 << 1)) ? '1' : '0', + (key_settings & (1 << 0)) ? '1' : '0' + ); + + PrintAndLogEx(SUCCESS, " [1...] CMK Configuration changeable : %s", (key_settings & (1 << 3)) ? _GREEN_("YES") : "NO (frozen)"); + PrintAndLogEx(SUCCESS, " [.1..] CMK required for create/delete : %s", (key_settings & (1 << 2)) ? _GREEN_("NO") : "YES"); + PrintAndLogEx(SUCCESS, " [..1.] Directory list access with CMK : %s", (key_settings & (1 << 1)) ? _GREEN_("NO") : "YES"); + PrintAndLogEx(SUCCESS, " [...1] CMK is changeable : %s", (key_settings & (1 << 0)) ? _GREEN_("YES") : "NO (frozen)"); + return PM3_SUCCESS; } @@ -1445,31 +1530,6 @@ static int handler_desfire_getkeysettings(uint8_t *key_settings, uint8_t *num_ke return res; } -// --- KEY VERSION -static int desfire_print_keyversion(uint8_t key_idx, uint8_t key_version) { - PrintAndLogEx(SUCCESS, " Key [%u] Version : %d (0x%02x)", key_idx, key_version, key_version); - return PM3_SUCCESS; -} - -static int handler_desfire_keyversion(uint8_t curr_key, uint8_t *num_versions) { - if (num_versions == NULL) { - PrintAndLogEx(DEBUG, "NUM_VERSIONS=NULL"); - return PM3_EINVARG; - } - sAPDU apdu = {0x90, MFDES_GET_KEY_VERSION, 0x00, 0x00, 0x01, &curr_key}; //0x64 - uint32_t recv_len = 0; - uint16_t sw = 0; - int res = send_desfire_cmd(&apdu, false, num_versions, &recv_len, &sw, 0, true); - - if (res != PM3_SUCCESS) - return res; - - if (sw != status(MFDES_S_OPERATION_OK)) - return PM3_ESOFT; - - return res; -} - static int handler_desfire_getuid(uint8_t *uid) { if (uid == NULL) { PrintAndLogEx(DEBUG, "UID=NULL"); @@ -2006,57 +2066,24 @@ static int handler_desfire_create_backup_file(mfdes_file_t *file) { static int getKeySettings(uint8_t *aid) { if (aid == NULL) return PM3_EINVARG; + uint8_t num_keys = 0; + uint8_t key_setting = 0; int res = 0; if (memcmp(aid, "\x00\x00\x00", 3) == 0) { - + // CARD MASTER KEY //PrintAndLogEx(INFO, "--- " _CYAN_("CMK - PICC, Card Master Key settings")); // KEY Settings - AMK - uint8_t num_keys = 0; - uint8_t key_setting = 0; mifare_des_authalgo_t algo = MFDES_ALGO_DES; res = key_setting_to_algo(aid, &key_setting, &algo, &num_keys); if (res == PM3_SUCCESS) { - // number of Master keys (0x01) - PrintAndLogEx(SUCCESS, " Number of Masterkeys : " _YELLOW_("%u"), (num_keys & 0x3F)); - - PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", (key_setting & (1 << 3)) ? _GREEN_("YES") : "NO"); - PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", (key_setting & (1 << 2)) ? _GREEN_("YES") : "NO"); - PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", (key_setting & (1 << 1)) ? _GREEN_("YES") : "NO"); - PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", (key_setting & (1 << 0)) ? _GREEN_("YES") : "NO"); + desfire_print_piccmk_keysetting(key_setting, num_keys, algo); } else { - PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); + PrintAndLogEx(WARNING, _RED_(" Can't read PICC Master key settings")); } - const char *str = " Operation of PICC master key : " _YELLOW_("%s"); - - if (algo == MFDES_ALGO_DES) PrintAndLogEx(SUCCESS, str, "(3)DES"); - else if (algo == MFDES_ALGO_AES) PrintAndLogEx(SUCCESS, str, "AES"); - else if (algo == MFDES_ALGO_3K3DES) PrintAndLogEx(SUCCESS, str, "3K3DES"); - - uint8_t cmk_num_versions = 0; - if (handler_desfire_keyversion(0, &cmk_num_versions) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, " PICC Master key Version : " _YELLOW_("%d (0x%02x)"), cmk_num_versions, cmk_num_versions); - PrintAndLogEx(INFO, " ----------------------------------------------------------"); - } - - // Authentication tests - res = test_desfire_authenticate(); - if (res == PM3_ETIMEOUT) return res; - PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); - - res = test_desfire_authenticate_iso(); - if (res == PM3_ETIMEOUT) return res; - PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); - - res = test_desfire_authenticate_aes(); - if (res == PM3_ETIMEOUT) return res; - PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); - - PrintAndLogEx(INFO, "-------------------------------------------------------------"); - } else { // AID - APPLICATION MASTER KEYS @@ -2065,12 +2092,10 @@ static int getKeySettings(uint8_t *aid) { if (res != PM3_SUCCESS) return res; // KEY Settings - AMK - uint8_t num_keys = 0; - uint8_t key_setting = 0; mifare_des_authalgo_t algo = MFDES_ALGO_DES; res = key_setting_to_algo(aid, &key_setting, &algo, &num_keys); if (res == PM3_SUCCESS) { - desfire_print_keysetting(key_setting, num_keys, algo); + desfire_print_amk_keysetting(key_setting, num_keys, algo); } else { PrintAndLogEx(WARNING, _RED_(" Can't read Application Master key settings")); } @@ -3436,6 +3461,8 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") " / " _GREEN_("20%02x"), info.details[12], info.details[13]); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information")); + PrintAndLogEx(INFO, " raw: %s", sprint_hex_inrow(info.versionHW, sizeof(info.versionHW))); + PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(info.versionHW[0])); PrintAndLogEx(INFO, " Type: " _YELLOW_("0x%02X"), info.versionHW[1]); PrintAndLogEx(INFO, " Subtype: " _YELLOW_("0x%02X"), info.versionHW[2]); @@ -3444,6 +3471,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(INFO, " Protocol: %s", getProtocolStr(info.versionHW[6], true)); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Software Information")); + PrintAndLogEx(INFO, " raw: %s", sprint_hex_inrow(info.versionSW, sizeof(info.versionSW))); PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(info.versionSW[0])); PrintAndLogEx(INFO, " Type: " _YELLOW_("0x%02X"), info.versionSW[1]); PrintAndLogEx(INFO, " Subtype: " _YELLOW_("0x%02X"), info.versionSW[2]); From 6c1bdd34570abb8e993a57a0be0a368d7e813d5b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Nov 2020 00:43:11 +0100 Subject: [PATCH 64/69] update ps version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9717c30c7..e61260b54 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). This repo compiles nicely on - Proxspace v3.x - - [latest release v3.7](https://github.com/Gator96100/ProxSpace/releases) + - [latest release v3.7.1](https://github.com/Gator96100/ProxSpace/releases) - Windows/mingw environment with Qt5.6.1 & GCC 4.9 - Ubuntu 16.04 -> 20.04 - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian From c80c7646da3bff1c064b71909537652718affd61 Mon Sep 17 00:00:00 2001 From: tcprst Date: Sun, 22 Nov 2020 19:33:11 -0500 Subject: [PATCH 65/69] iclass esave, eview - now use cliparser --- client/src/cmdhficlass.c | 149 ++++++++++++++------------------------- 1 file changed, 51 insertions(+), 98 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index eaf5b5406..c72db32b4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,35 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } - -static int usage_hf_iclass_esave(void) { - PrintAndLogEx(NORMAL, "Save emulator memory to file."); - PrintAndLogEx(NORMAL, "if not filename is supplied, CSN will be used."); - PrintAndLogEx(NORMAL, "Number of bytes to download defaults to 256. Other value is 2048\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass esave [h] [f ] [s ]\n"); - PrintAndLogEx(NORMAL, "Options"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " f : filename of dump"); - PrintAndLogEx(NORMAL, " s : (256|2048) number of bytes to save (default 256)"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass esave")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass esave f hf-iclass-dump.bin")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass esave s 2048 f hf-iclass-dump.bin")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} -static int usage_hf_iclass_eview(void) { - PrintAndLogEx(NORMAL, "It displays emulator memory"); - PrintAndLogEx(NORMAL, "Number of bytes to download defaults to 256. Other value is 2048\n"); - PrintAndLogEx(NORMAL, " Usage: hf iclass eview [s ] "); - PrintAndLogEx(NORMAL, " s : (256|2048) number of bytes to save (default 256)"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf iclass eview")); - PrintAndLogEx(NORMAL, _YELLOW_(" hf iclass eview s 2048 v")); - return PM3_SUCCESS; -} static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "3DES decrypt data\n"); PrintAndLogEx(NORMAL, "This is naive implementation, it tries to decrypt every block after block 6."); @@ -779,7 +750,7 @@ static int CmdHFiClassSim(const char *Cmd) { SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, numberOfCSNs, 1, CSN, 8); if (sim_type == ICLASS_SIM_MODE_FULL) - PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass esave h") "` to save the emulator memory to file"); + PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass esave -h") "` to save the emulator memory to file"); break; } } @@ -961,47 +932,36 @@ static int CmdHFiClassELoad(const char *Cmd) { PrintAndLogEx(SUCCESS, "sent %d bytes of data to device emulator memory", bytes_sent); return PM3_SUCCESS; } - static int CmdHFiClassESave(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass esave", + "Save emulator memory to file.\n" + "if filename is not supplied, CSN will be used.", + "hf iclass esave\n" + "hf iclass esave -f hf-iclass-dump\n" + "hf iclass esave -s 2048 -f hf-iclass-dump"); + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dumpfile"), + arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); char *fnameptr = filename; - int len = 0; - uint16_t bytes = 256; - bool errors = false; - uint8_t cmdp = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_esave(); - case 'f': - len = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); - if (len >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); - errors = true; - break; - } - cmdp += 2; - break; - case 's': - bytes = param_get32ex(Cmd, cmdp + 1, 256, 10); - if (bytes > 4096) { - PrintAndLogEx(WARNING, "Emulator memory is max 4096bytes. Truncating %u to 4096", bytes); - bytes = 4096; - } - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + + uint16_t bytes = arg_get_int_def(ctx, 2, 256); + + if (bytes > 4096) { + PrintAndLogEx(WARNING, "Emulator memory is max 4096bytes. Truncating %u to 4096", bytes); + bytes = 4096; } - //Validations - if (errors) { - return usage_hf_iclass_esave(); - } + CLIParserFree(ctx); uint8_t *dump = calloc(bytes, sizeof(uint8_t)); if (dump == NULL) { @@ -1017,7 +977,7 @@ static int CmdHFiClassESave(const char *Cmd) { } // user supplied filename? - if (len < 1) { + if (fnlen < 1) { fnameptr += snprintf(fnameptr, sizeof(filename), "hf-iclass-"); FillFileNameByUID(fnameptr, dump, "-dump", 8); } @@ -1032,44 +992,37 @@ static int CmdHFiClassESave(const char *Cmd) { } static int CmdHFiClassEView(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass eview", + "Display emulator memory.\n" + "Number of bytes to download defaults to 256. Other value is 2048.", + "hf iclass eview\n" + "hf iclass eview -s 2048\n" + "hf iclass eview -s 2048 -v"); - uint16_t blocks = 32, bytes = 256; - bool errors = false, verbose = false; - uint8_t cmdp = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_eview(); - case 's': - bytes = param_get32ex(Cmd, cmdp + 1, 256, 10); + void *argtable[] = { + arg_param_begin, + arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), + arg_lit0("v", "verbose" , "filename of dumpfile"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); - if (bytes > 4096) { - PrintAndLogEx(WARNING, "Emulator memory is max 4096bytes. Truncating %u to 4096", bytes); - bytes = 4096; - } + uint16_t blocks = 32; + uint16_t bytes = arg_get_int_def(ctx, 1, 256); + bool verbose = arg_get_lit(ctx, 2); + blocks = bytes / 8; - if (bytes % 8 != 0) { - bytes &= 0xFFF8; - PrintAndLogEx(WARNING, "Number not divided by 8, truncating to %u", bytes); - } + CLIParserFree(ctx); - blocks = bytes / 8; - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + if (bytes > 4096) { + PrintAndLogEx(WARNING, "Emulator memory is max 4096bytes. Truncating %u to 4096", bytes); + bytes = 4096; } - //Validations - if (errors || bytes == 0) { - return usage_hf_iclass_eview(); + if (bytes % 8 != 0) { + bytes &= 0xFFF8; + PrintAndLogEx(WARNING, "Number not divided by 8, truncating to %u", bytes); } uint8_t *dump = calloc(bytes, sizeof(uint8_t)); From 1afb335478ad34275fe9a6d566d5d9e70b68d240 Mon Sep 17 00:00:00 2001 From: tcprst Date: Sun, 22 Nov 2020 19:39:54 -0500 Subject: [PATCH 66/69] make style --- armsrc/iclass.c | 2 +- client/src/cmdhf14a.c | 24 ++++++------ client/src/cmdhficlass.c | 6 +-- client/src/cmdhfmfdes.c | 74 ++++++++++++++++++------------------ client/src/cmdlfem4x05.c | 2 +- client/src/cmdlft55xx.c | 18 ++++----- client/src/cmdmain.c | 6 +-- client/src/crypto/asn1dump.c | 4 +- client/src/emv/emv_tags.c | 26 ++++++------- client/src/fido/fidocore.c | 2 +- client/src/util.c | 14 +++---- 11 files changed, 89 insertions(+), 89 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 803972e05..86d8094b7 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1853,7 +1853,7 @@ void iClass_WriteBlock(uint8_t *msg) { // new block data memcpy(write + 2, payload->data, 8); - + uint8_t pagemap = get_pagemap(&hdr); if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { // Unsecured tags uses CRC16, but don't include the UPDATE operation code diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 852aae3b8..c8d0a57eb 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1178,11 +1178,11 @@ static int CmdHF14AAPDU(const char *Cmd) { } CLIParserFree(ctx); - PrintAndLogEx(SUCCESS, "( " _YELLOW_("%s%s%s")" )", - activateField ? "select" : "", - leaveSignalON ? ", keep" : "", - decodeTLV ? ", TLV" : "" - ); + PrintAndLogEx(SUCCESS, "( " _YELLOW_("%s%s%s")" )", + activateField ? "select" : "", + leaveSignalON ? ", keep" : "", + decodeTLV ? ", TLV" : "" + ); PrintAndLogEx(SUCCESS, ">>> %s", sprint_hex_inrow(data, datalen)); if (decodeAPDU) { @@ -1217,7 +1217,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) { "Sends an raw bytes over ISO14443a. With option to use TOPAZ 14a mode.", "hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n" "hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n" - ); + ); void *argtable[] = { arg_param_begin, @@ -1344,13 +1344,13 @@ static int waitCmd(bool i_select, uint32_t timeout) { if (i_select == false && len >= 3) { bool crc = check_crc(CRC_14443_A, data, len); - + char s[16]; - sprintf(s, - (crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"), - data[len - 2], - data[len - 1] - ); + sprintf(s, + (crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"), + data[len - 2], + data[len - 1] + ); PrintAndLogEx(SUCCESS, "%s[ %s ]", sprint_hex(data, len - 2), s); } else { diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index c72db32b4..2c90278a7 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1003,7 +1003,7 @@ static int CmdHFiClassEView(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), - arg_lit0("v", "verbose" , "filename of dumpfile"), + arg_lit0("v", "verbose", "filename of dumpfile"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -3546,8 +3546,8 @@ int info_iclass(void) { uint8_t cardtype = get_mem_config(hdr); PrintAndLogEx(SUCCESS, " Card type.... " _GREEN_("%s"), card_types[cardtype]); - - + + } DropField(); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index a69aa0d27..f2282dbfd 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1182,7 +1182,7 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n key 8b cpy 8b crc 2b - padding + padding */ // Variable length ciphered key data 24-42 bytes plus padding.. @@ -1190,11 +1190,11 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n sAPDU apdu = {0x90, MFDES_CHANGE_KEY, 0x00, 0x00, 0x01, data}; // 0xC4 size_t cmdcnt = 0; - + uint8_t new_key_length = 16; switch (new_algo) { case MFDES_ALGO_DES: - // double + // double memcpy(data + cmdcnt + 1, new_key, new_key_length); memcpy(data + cmdcnt + 1 + new_key_length, new_key, new_key_length); break; @@ -1438,11 +1438,11 @@ static int desfire_print_amk_keysetting(uint8_t key_settings, uint8_t num_keys, PrintAndLogEx(SUCCESS, " -- All keys (except AMK,see Bit0) within this application are frozen"); break; default: - PrintAndLogEx(SUCCESS, - " -- Authentication with the specified key is necessary to change any key.\n" - "A change key and a PICC master key (CMK) can only be changed after authentication with the master key.\n" - "For keys other then the master or change key, an authentication with the same key is needed." - ); + PrintAndLogEx(SUCCESS, + " -- Authentication with the specified key is necessary to change any key.\n" + "A change key and a PICC master key (CMK) can only be changed after authentication with the master key.\n" + "For keys other then the master or change key, an authentication with the same key is needed." + ); break; } @@ -1487,15 +1487,15 @@ static int desfire_print_piccmk_keysetting(uint8_t key_settings, uint8_t num_key if (res == PM3_SUCCESS) PrintAndLogEx(SUCCESS, " [0xAA] Authenticate AES : %s", (res == PM3_SUCCESS) ? _YELLOW_("YES") : "NO"); - PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PrintAndLogEx(INFO, " Key setting: 0x%02X [%c%c%c%c]", - key_settings, - (key_settings & (1 << 3)) ? '1' : '0', - (key_settings & (1 << 2)) ? '1' : '0', - (key_settings & (1 << 1)) ? '1' : '0', - (key_settings & (1 << 0)) ? '1' : '0' - ); - + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Key setting: 0x%02X [%c%c%c%c]", + key_settings, + (key_settings & (1 << 3)) ? '1' : '0', + (key_settings & (1 << 2)) ? '1' : '0', + (key_settings & (1 << 1)) ? '1' : '0', + (key_settings & (1 << 0)) ? '1' : '0' + ); + PrintAndLogEx(SUCCESS, " [1...] CMK Configuration changeable : %s", (key_settings & (1 << 3)) ? _GREEN_("YES") : "NO (frozen)"); PrintAndLogEx(SUCCESS, " [.1..] CMK required for create/delete : %s", (key_settings & (1 << 2)) ? _GREEN_("NO") : "YES"); PrintAndLogEx(SUCCESS, " [..1.] Directory list access with CMK : %s", (key_settings & (1 << 1)) ? _GREEN_("NO") : "YES"); @@ -1645,14 +1645,14 @@ static int handler_desfire_select_application(uint8_t *aid) { sAPDU apdu = {0x90, MFDES_SELECT_APPLICATION, 0x00, 0x00, 0x03, aid}; //0x5a uint32_t recv_len = 0; uint16_t sw = 0; - + int res = send_desfire_cmd(&apdu, !tag->rf_field_on, NULL, &recv_len, &sw, sizeof(dfname_t), true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, - _RED_(" Can't select AID 0x%X -> %s"), - (aid[2] << 16) + (aid[1] << 8) + aid[0], - GetErrorString(res, &sw) - ); + _RED_(" Can't select AID 0x%X -> %s"), + (aid[2] << 16) + (aid[1] << 8) + aid[0], + GetErrorString(res, &sw) + ); DropFieldDesfire(); return res; } @@ -1732,17 +1732,17 @@ static int handler_desfire_createapp(aidhdr_t *aidhdr, bool usename, bool usefid apdu.Lc = apdu.Lc - sizeof(aidhdr->fid); } uint8_t *data = NULL; - + // skip over FID if not used. if (usefid == false && usename) { data = calloc(apdu.Lc, sizeof(uint8_t)); apdu.data = data; - + memcpy(data, aidhdr->aid, sizeof(aidhdr->aid)); data[3] = aidhdr->keysetting1; data[4] = aidhdr->keysetting2; memcpy(data + 5, aidhdr->name, sizeof(aidhdr->name)); - + PrintAndLogEx(INFO, "new data: %s", sprint_hex_inrow(data, apdu.Lc)); } @@ -2070,7 +2070,7 @@ static int getKeySettings(uint8_t *aid) { uint8_t key_setting = 0; int res = 0; if (memcmp(aid, "\x00\x00\x00", 3) == 0) { - + // CARD MASTER KEY //PrintAndLogEx(INFO, "--- " _CYAN_("CMK - PICC, Card Master Key settings")); @@ -2418,7 +2418,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { if (usefid) memcpy(aidhdr.fid, fid, sizeof(aidhdr.fid)); - if (usename) + if (usename) memcpy(aidhdr.name, name, sizeof(aidhdr.name)); PrintAndLogEx(INFO, "Creating AID using:"); @@ -2430,14 +2430,14 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { if (usename) PrintAndLogEx(INFO, "DF Name %s", aidhdr.name); -/* - uint8_t rootaid[3] = {0x00, 0x00, 0x00}; - int res = handler_desfire_select_application(rootaid); - if (res != PM3_SUCCESS) { - DropFieldDesfire(); - return res; - } -*/ + /* + uint8_t rootaid[3] = {0x00, 0x00, 0x00}; + int res = handler_desfire_select_application(rootaid); + if (res != PM3_SUCCESS) { + DropFieldDesfire(); + return res; + } + */ int res = handler_desfire_createapp(&aidhdr, usename, usefid); DropFieldDesfire(); @@ -3462,7 +3462,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information")); PrintAndLogEx(INFO, " raw: %s", sprint_hex_inrow(info.versionHW, sizeof(info.versionHW))); - + PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(info.versionHW[0])); PrintAndLogEx(INFO, " Type: " _YELLOW_("0x%02X"), info.versionHW[1]); PrintAndLogEx(INFO, " Subtype: " _YELLOW_("0x%02X"), info.versionHW[2]); @@ -3698,7 +3698,7 @@ static int CmdHF14ADesDump(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - + (void)Cmd; // Cmd is not used so far DropFieldDesfire(); diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index 9abc2862c..3b260ed2e 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -1882,7 +1882,7 @@ uint32_t static em4x05_Sniff_GetBlock(char *bits, bool fwd) { if (parity != (bits[35] - '0')) parityerror = true; - if (parityerror) + if (parityerror) PrintAndLogEx(ERR, "parity error : "); if (!fwd) { diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index a3ccf2052..80c8eda4f 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1027,7 +1027,7 @@ static void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { } // Define prototype to call from within detect. -static int CmdT55xxWakeUp (const char *Cmd); +static int CmdT55xxWakeUp(const char *Cmd); static int CmdT55xxDetect(const char *Cmd) { @@ -1054,7 +1054,7 @@ static int CmdT55xxDetect(const char *Cmd) { return usage_t55xx_detect(); case 'p': password = param_get32ex(Cmd, cmdp + 1, 0, 16); - sprintf (wakecmd,"p %08x q",(uint32_t)(password & 0xFFFFFFFF)); + sprintf(wakecmd, "p %08x q", (uint32_t)(password & 0xFFFFFFFF)); usepwd = true; cmdp += 2; break; @@ -1077,7 +1077,7 @@ static int CmdT55xxDetect(const char *Cmd) { } if (errors) return usage_t55xx_detect(); - + // detect called so clear data blocks T55x7_ClearAllBlockData(); @@ -1096,11 +1096,11 @@ static int CmdT55xxDetect(const char *Cmd) { if (usewake) { // call wake if (try_with_pwd) - CmdT55xxWakeUp (wakecmd); + CmdT55xxWakeUp(wakecmd); else - CmdT55xxWakeUp ("q"); + CmdT55xxWakeUp("q"); // sleep 90 ms - nanosleep (&sleepperiod, &sleepperiod); + nanosleep(&sleepperiod, &sleepperiod); } if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, (try_with_pwd && usepwd), password, m) == false) @@ -1117,11 +1117,11 @@ static int CmdT55xxDetect(const char *Cmd) { if (usewake) { // call wake if (try_with_pwd) - CmdT55xxWakeUp (wakecmd); + CmdT55xxWakeUp(wakecmd); else - CmdT55xxWakeUp ("q"); + CmdT55xxWakeUp("q"); // sleep 90 ms - nanosleep (&sleepperiod, &sleepperiod); + nanosleep(&sleepperiod, &sleepperiod); } if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 551f5ccf6..c55c7792e 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -120,7 +120,7 @@ static int lf_search_plus(const char *Cmd) { return retval; } -static int CmdAuto(const char *Cmd) { +static int CmdAuto(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "auto", "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE", @@ -136,7 +136,7 @@ static int CmdAuto(const char *Cmd) { PrintAndLogEx(INFO, "lf search"); int ret = CmdLFfind(""); - if (ret == PM3_SUCCESS) + if (ret == PM3_SUCCESS) return ret; PrintAndLogEx(INFO, "hf search"); @@ -193,7 +193,7 @@ static int CmdHints(const char *Cmd) { PrintAndLogEx(ERR, "you can't turn off and on at the same time"); return PM3_EINVARG; } - + if (turn_off) { session.show_hints = false; } else if (turn_on) { diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index f1addb9e2..cae25c1b6 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -116,7 +116,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag if (longyear == false) PrintAndLogEx(NORMAL, "20" NOLF); - PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx) ); + PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx)); if (len < startindx + 2) break; @@ -276,7 +276,7 @@ static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag asn1_buf.p = (uint8_t *)tlv->value; char pstr[300]; mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf); - + PrintAndLogEx(INFO, "%*s %s" NOLF, (level * 4), " ", pstr); char *jsondesc = asn1_oid_description(pstr, true); diff --git a/client/src/emv/emv_tags.c b/client/src/emv/emv_tags.c index 661df0e5e..f86b88826 100644 --- a/client/src/emv/emv_tags.c +++ b/client/src/emv/emv_tags.c @@ -462,9 +462,9 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta if (val & 0x80) { PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); PrintAndLogEx(NORMAL, " %s - '%s'", - bitstrings[bit - 1], - (bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown" - ); + bitstrings[bit - 1], + (bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown" + ); } if (bits->bit == EMV_BIT(byte, bit)) bits ++; @@ -535,10 +535,10 @@ static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *ta static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, int level) { PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); PrintAndLogEx(NORMAL, " Date: 20%02lu.%lu.%lu", - emv_value_numeric(tlv, 0, 2), - emv_value_numeric(tlv, 2, 4), - emv_value_numeric(tlv, 4, 6) - ); + emv_value_numeric(tlv, 0, 2), + emv_value_numeric(tlv, 2, 4), + emv_value_numeric(tlv, 4, 6) + ); } static uint32_t emv_get_binary(const unsigned char *S) { @@ -749,12 +749,12 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); PrintAndLogEx(NORMAL, " %02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful", - tlv->value[i], - tlv->value[i + 1], - method, - condition, - (tlv->value[i] & 0x40) ? "continue" : "fail" - ); + tlv->value[i], + tlv->value[i + 1], + method, + condition, + (tlv->value[i] & 0x40) ? "continue" : "fail" + ); } } diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index abe3f28ce..fcebb2674 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -541,7 +541,7 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b res = CborGetArrayBinStringValue(&mapsmt, der, sizeof(der), &derLen); cbor_check(res); if (verbose2) { - PrintAndLogEx(INFO, "DER certificate[%zu]:", derLen); + PrintAndLogEx(INFO, "DER certificate[%zu]:", derLen); PrintAndLogEx(INFO, "------------------DER-------------------"); PrintAndLogEx(INFO, "%s", sprint_hex(der, derLen)); PrintAndLogEx(INFO, "----------------DER---------------------"); diff --git a/client/src/util.c b/client/src/util.c index 2e1cfb0bd..76a2d7885 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -212,23 +212,23 @@ void print_buffer(const uint8_t *data, const size_t len, int level) { // (16 * 3) + (16) + + 1 memset(buf, 0, sizeof(buf)); sprintf(buf, "%*s%02x: ", (level * 4), " ", i); - - hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, 16, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + + hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, 16, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, 16)); PrintAndLogEx(INFO, "%s", buf); } - + // the last odd bytes uint8_t mod = len % 16; - + if (mod) { memset(buf, 0, sizeof(buf)); sprintf(buf, "%*s%02x: ", (level * 4), " ", i); hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, mod, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); - + // add the spaces... - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((16 - mod) * 3) , " "); - + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((16 - mod) * 3), " "); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod)); PrintAndLogEx(INFO, "%s", buf); } From 4d616a1c09bf740abbfc97d02a3929d6462f8ad0 Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 14:46:07 -0500 Subject: [PATCH 67/69] hf iclass decrypt - now use cliparser --- client/src/cmdhficlass.c | 148 ++++++++++++++++++--------------------- doc/cheatsheet.md | 11 +-- 2 files changed, 73 insertions(+), 86 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 2c90278a7..8a2cbf2d7 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,28 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_decrypt(void) { - PrintAndLogEx(NORMAL, "3DES decrypt data\n"); - PrintAndLogEx(NORMAL, "This is naive implementation, it tries to decrypt every block after block 6."); - PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,"); - PrintAndLogEx(NORMAL, "which is defined by the configuration block."); - PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt d f k \n"); - PrintAndLogEx(NORMAL, "Options"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " d : 16 bytes hex"); - PrintAndLogEx(NORMAL, " f : filename of dump"); - PrintAndLogEx(NORMAL, " k : 16 bytes hex"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt f hf-iclass-AA162D30F8FF12F1-dump.bin")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt f hf-iclass-AA162D30F8FF12F1-dump.bin k 000102030405060708090a0b0c0d0e0f")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt d 1122334455667788 k 000102030405060708090a0b0c0d0e0f")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "3DES encrypt data\n"); PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file " _YELLOW_("'iclass_decryptionkey.bin'") " must reside"); @@ -1003,7 +981,7 @@ static int CmdHFiClassEView(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), - arg_lit0("v", "verbose", "filename of dumpfile"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1049,74 +1027,82 @@ static int CmdHFiClassEView(const char *Cmd) { free(dump); return PM3_SUCCESS; } - static int CmdHFiClassDecrypt(const char *Cmd) { + CLIParserContext *clictx; + CLIParserInit(&clictx, "hf iclass decrypt", + "3DES decrypt data\n" + "This is naive implementation, it tries to decrypt every block after block 6.\n" + "Correct behaviour would be to decrypt only the application areas where the key is valid,\n" + "which is defined by the configuration block.\n" + "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" + "in the resources directory. The file should be 16 bytes binary data", + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin --key 000102030405060708090a0b0c0d0e0f\n" + "hf iclass decrypt -d 1122334455667788 --key 000102030405060708090a0b0c0d0e0f"); - bool errors = false; - bool have_key = false; - bool have_data = false; - bool have_file = false; - bool verbose = false; - uint8_t cmdp = 0; + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dumpfile"), + arg_str0("d", "data", "", "3DES encrypted data"), + arg_str0(NULL, "key", "", "3DES transport key"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(clictx, Cmd, argtable, false); - uint8_t enc_data[8] = {0}; - uint8_t dec_data[8] = {0}; - - size_t keylen = 0; - uint8_t key[32] = {0}; - uint8_t *keyptr = NULL; + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(clictx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); size_t decryptedlen = 0; uint8_t *decrypted = NULL; - char filename[FILE_PATH_SIZE]; + bool have_file = false; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_decrypt(); - case 'd': - if (param_gethex(Cmd, cmdp + 1, enc_data, 16)) { - PrintAndLogEx(ERR, "Data must be 16 HEX symbols"); - errors = true; - break; - } - have_data = true; - cmdp += 2; - break; - case 'f': - if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { - PrintAndLogEx(WARNING, "No filename found after f"); - errors = true; - break; - } - - if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { - errors = true; - break; - } - have_file = true; - cmdp += 2; - break; - case 'k': - if (param_gethex(Cmd, cmdp + 1, key, 32)) { - PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); - errors = true; - } - have_key = true; - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; + if (fnlen > 0) { + if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { + CLIParserFree(clictx); + return PM3_EINVARG; } + have_file = true; } - if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); + int enc_data_len = 0; + uint8_t enc_data[8] = {0}; + bool have_data = false; + + CLIGetHexWithReturn(clictx, 2, enc_data, &enc_data_len); + + if (enc_data_len > 0) { + if (enc_data_len != 8) { + PrintAndLogEx(ERR, "Data must be 8 bytes (16 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_data = true; + } + + int key_len = 0; + uint8_t key[32] = {0}; + uint8_t *keyptr = NULL; + bool have_key = false; + + CLIGetHexWithReturn(clictx, 3, key, &key_len); + + if (key_len > 0) { + if (key_len != 16) { + PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_key = true; + } + + bool verbose = arg_get_lit(clictx, 4); + + CLIParserFree(clictx); + + size_t keylen = 0; + uint8_t dec_data[8] = {0}; bool use_sc = IsCryptoHelperPresent(verbose); diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index a3ea9c579..86dc4a29e 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -121,12 +121,13 @@ Decrypt iCLASS Block / file ``` Options --- -d : 16 bytes hex -f : filename of dump -k : 16 bytes hex +-f, --file filename of dumpfile +-d, --data 3DES encrypted data + --key 3DES transport key +-v, --verbose verbose output -pm3 --> hf iclass decrypt d 2AD4C8211F996871 -pm3 --> hf iclass decrypt f hf-iclass-db883702f8ff12e0.bin +pm3 --> hf iclass decrypt -d 2AD4C8211F996871 +pm3 --> hf iclass decrypt -f hf-iclass-db883702f8ff12e0.bin ``` Load iCLASS dump into memory for simulation From 9ef0e07d49947945911b996eb33d5f4adb767a0b Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 15:42:32 -0500 Subject: [PATCH 68/69] hf iclass encrypt - now use cliparser --- client/src/cmdhficlass.c | 99 ++++++++++++++++++---------------------- doc/cheatsheet.md | 7 +-- 2 files changed, 49 insertions(+), 57 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 8a2cbf2d7..7a26cbb0c 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,23 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_encrypt(void) { - PrintAndLogEx(NORMAL, "3DES encrypt data\n"); - PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file " _YELLOW_("'iclass_decryptionkey.bin'") " must reside"); - PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k \n"); - PrintAndLogEx(NORMAL, "Options"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " d : 16 bytes hex"); - PrintAndLogEx(NORMAL, " k : 16 bytes hex"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass encrypt d 0102030405060708")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass encrypt d 0102030405060708 k 00112233445566778899AABBCCDDEEFF")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, "Dump all memory from a iCLASS tag\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass dump f k c [e|r|v]\n"); @@ -1082,7 +1065,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } int key_len = 0; - uint8_t key[32] = {0}; + uint8_t key[16] = {0}; uint8_t *keyptr = NULL; bool have_key = false; @@ -1269,45 +1252,53 @@ static void iclass_encrypt_block_data(uint8_t *blk_data, uint8_t *key) { } static int CmdHFiClassEncryptBlk(const char *Cmd) { - bool errors = false; - bool have_key = false; - bool verbose = false; - uint8_t blk_data[8] = {0}; - uint8_t key[16] = {0}; - uint8_t *keyptr = NULL; - uint8_t cmdp = 0; + CLIParserContext *clictx; + CLIParserInit(&clictx, "hf iclass encrypt", + "3DES encrypt data\n" + "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" + "in the resources directory. The file should be 16 bytes binary data", + "hf iclass encrypt -d 0102030405060708\n" + "hf iclass encrypt -d 0102030405060708 --key 00112233445566778899AABBCCDDEEFF"); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_encrypt(); - case 'd': - if (param_gethex(Cmd, cmdp + 1, blk_data, 16)) { - PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); - errors = true; - } - cmdp += 2; - break; - case 'k': - if (param_gethex(Cmd, cmdp + 1, key, 32)) { - PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); - errors = true; - } - have_key = true; - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + void *argtable[] = { + arg_param_begin, + arg_str1("d", "data", "", "data to encrypt"), + arg_str0(NULL, "key", "", "3DES transport key"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(clictx, Cmd, argtable, false); + + int blk_data_len = 0; + uint8_t blk_data[8] = {0}; + + CLIGetHexWithReturn(clictx, 1, blk_data, &blk_data_len); + + if (blk_data_len != 8) { + PrintAndLogEx(ERR, "Block data must be 8 bytes (16 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; } - if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); + int key_len = 0; + uint8_t key[16] = {0}; + uint8_t *keyptr = NULL; + bool have_key = false; + + CLIGetHexWithReturn(clictx, 2, key, &key_len); + + if (key_len > 0) { + if (key_len != 16) { + PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_key = true; + } + + bool verbose = arg_get_lit(clictx, 3); + + CLIParserFree(clictx); bool use_sc = IsCryptoHelperPresent(verbose); diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 86dc4a29e..5de15e198 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -111,10 +111,11 @@ Encrypt iCLASS Block ``` Options --- -d : 16 bytes hex -k : 16 bytes hex +-d, --data data to encrypt + --key 3DES transport key +-v, --verbose verbose output -pm3 --> hf iclass encrypt d 0000000f2aa3dba8 +pm3 --> hf iclass encrypt -d 0000000f2aa3dba8 ``` Decrypt iCLASS Block / file From 0c0411c144685a0fbfbd8aea7b6afee86b8317fb Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 16:07:03 -0500 Subject: [PATCH 69/69] add short option and fix typo --- client/src/cmdhficlass.c | 12 ++++++------ doc/cheatsheet.md | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 7a26cbb0c..284317a47 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1014,20 +1014,20 @@ static int CmdHFiClassDecrypt(const char *Cmd) { CLIParserContext *clictx; CLIParserInit(&clictx, "hf iclass decrypt", "3DES decrypt data\n" - "This is naive implementation, it tries to decrypt every block after block 6.\n" + "This is a naive implementation, it tries to decrypt every block after block 6.\n" "Correct behaviour would be to decrypt only the application areas where the key is valid,\n" "which is defined by the configuration block.\n" "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" "in the resources directory. The file should be 16 bytes binary data", "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" - "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin --key 000102030405060708090a0b0c0d0e0f\n" - "hf iclass decrypt -d 1122334455667788 --key 000102030405060708090a0b0c0d0e0f"); + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin -k 000102030405060708090a0b0c0d0e0f\n" + "hf iclass decrypt -d 1122334455667788 -k 000102030405060708090a0b0c0d0e0f"); void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "filename of dumpfile"), arg_str0("d", "data", "", "3DES encrypted data"), - arg_str0(NULL, "key", "", "3DES transport key"), + arg_str0("k", "key", "", "3DES transport key"), arg_lit0("v", "verbose", "verbose output"), arg_param_end }; @@ -1258,12 +1258,12 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" "in the resources directory. The file should be 16 bytes binary data", "hf iclass encrypt -d 0102030405060708\n" - "hf iclass encrypt -d 0102030405060708 --key 00112233445566778899AABBCCDDEEFF"); + "hf iclass encrypt -d 0102030405060708 -k 00112233445566778899AABBCCDDEEFF"); void *argtable[] = { arg_param_begin, arg_str1("d", "data", "", "data to encrypt"), - arg_str0(NULL, "key", "", "3DES transport key"), + arg_str0("k", "key", "", "3DES transport key"), arg_lit0("v", "verbose", "verbose output"), arg_param_end }; diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 5de15e198..9699fabf0 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -112,7 +112,7 @@ Encrypt iCLASS Block Options --- -d, --data data to encrypt - --key 3DES transport key +-k, --key 3DES transport key -v, --verbose verbose output pm3 --> hf iclass encrypt -d 0000000f2aa3dba8 @@ -124,7 +124,7 @@ Options --- -f, --file filename of dumpfile -d, --data 3DES encrypted data - --key 3DES transport key +-k, --key 3DES transport key -v, --verbose verbose output pm3 --> hf iclass decrypt -d 2AD4C8211F996871