diff --git a/src/core/mykeyboard.cpp b/src/core/mykeyboard.cpp index 25f5fe31..4e4ad417 100644 --- a/src/core/mykeyboard.cpp +++ b/src/core/mykeyboard.cpp @@ -78,7 +78,7 @@ bool menuPress(int bot) { bool checkNextPress(){ #if defined (CARDPUTER) Keyboard.update(); - if(Keyboard.isKeyPressed('/') || Keyboard.isKeyPressed('.')) + if(Keyboard.isKeyPressed('.')) #elif defined(CORE2) || defined(CORE) M5.update(); if(M5.BtnC.isPressed()) @@ -108,7 +108,7 @@ bool checkPrevPress() { if(axp192.GetBtnPress()) #elif defined(CARDPUTER) Keyboard.update(); - if(Keyboard.isKeyPressed(',') || Keyboard.isKeyPressed(';')) + if(Keyboard.isKeyPressed(';')) #elif defined(CORE2) || defined(CORE) M5.update(); if(M5.BtnA.isPressed()) @@ -215,6 +215,33 @@ bool checkAnyKeyPress() { } #ifdef CARDPUTER + +bool checkNextPagePress(){ + Keyboard.update(); + if(Keyboard.isKeyPressed('/')) // right arrow + { + if(wakeUpScreen()){ + delay(200); + return false; + } + return true; + } + return false; +} + +bool checkPrevPagePress() { + Keyboard.update(); + if(Keyboard.isKeyPressed(',')) // left arrow + { + if(wakeUpScreen()){ + delay(200); + return false; + } + return true; + } + return false; +} + void checkShortcutPress(){ // shortctus to quickly starts apps Keyboard.update(); diff --git a/src/core/mykeyboard.h b/src/core/mykeyboard.h index 909bc61d..dc8fb8d0 100644 --- a/src/core/mykeyboard.h +++ b/src/core/mykeyboard.h @@ -16,6 +16,8 @@ bool checkEscPress(); void checkShortcutPress(); int checkNumberShortcutPress(); char checkLetterShortcutPress(); +bool checkNextPagePress(); +bool checkPrevPagePress(); #endif bool checkAnyKeyPress(); diff --git a/src/core/passwords.cpp b/src/core/passwords.cpp index fecb237b..7c948ee3 100644 --- a/src/core/passwords.cpp +++ b/src/core/passwords.cpp @@ -1,149 +1,31 @@ -#include "mbedtls/aes.h" -#include "mbedtls/md.h" -#include "mbedtls/pkcs5.h" -#include - -#include -#include -#include -#include -#include // error code to string conversion - -#include // entropy gathering -#include // CSPRNG -#include // error code to string conversion -#include // hash algorithms -#include // pbkdf2 KDF - -const size_t iterations = 1000; -const size_t keyLength = 32; - - -String generateRandom(int len) { +#include +#include + + +String xorEncryptDecrypt(const String &input, const String &password) { + uint8_t md5Hash[16]; + + MD5Builder md5; + md5.begin(); + md5.add(password); + md5.calculate(); + md5.getBytes(md5Hash); // Store MD5 hash in the output array + + String output = input; // Copy input to output for modification + for (size_t i = 0; i < input.length(); i++) { + output[i] = input[i] ^ md5Hash[i % 16]; // XOR each byte with the MD5 hash + } + + return output; } -String aes_encrypt(String& plaintext, const String& password_str) { - // buggy? https://github.com/espressif/arduino-esp32/issues/3719 - - /* - unsigned char* salt = generateRandom(16).c_str(); // salt size = 16 - unsigned char* iv = generateRandom(12).c_str(); // iv size = 12 - unsigned char* tag = generateRandom(16).c_str(); // tag size = 16 - - - - mbedtls_gcm_context ctx; - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 256); - mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, plaintext_len, iv, 12, ad, 16, plaintext.c_str(), ciphertext, tag); - int ret = mbedtls_gcm_crypt_and_tag(&aes, MBEDTLS_GCM_ENCRYPT, strlen(text), (const unsigned char*) iv, strlen(iv), NULL, NULL, (const unsigned char*) text, (unsigned char*) encrypted, strlen(tag), (unsigned char*) tag); - - mbedtls_gcm_free(&ctx); - - */ - // WIP - return plaintext; +String encryptString(String& plaintext, const String& password_str) { + return xorEncryptDecrypt(plaintext, password_str); } - -String aes_decrypt(String& encryptedBase64, const String& password_str) { - - const char* password = password_str.c_str(); - //char mbed_err[MBED_ERR_BUF]; - int ret; - - // decode base64 - size_t decodedLen; - mbedtls_base64_decode(NULL, 0, &decodedLen, (const unsigned char *)encryptedBase64.c_str(), encryptedBase64.length()); - unsigned char* decodedData = (unsigned char*)malloc(decodedLen); - memset(decodedData, 0, decodedLen); - mbedtls_base64_decode(decodedData, decodedLen, &decodedLen, (const unsigned char *)encryptedBase64.c_str(), encryptedBase64.length()); - if(decodedLen<=44) { - Serial.println("base64 decode error or incomplete file"); - return ""; - } - - unsigned char* salt = decodedData; - unsigned char* iv = decodedData + 16; // salt size = 16 - unsigned char* tag = decodedData + 28; // salt+iv size = 16+12 - unsigned char* encryptedContent = decodedData + 44; // salt+iv+tag size = 16+12+16 - size_t encryptedContentLen = decodedLen - 44; - - // Derive key using PBKDF2 - unsigned char key[keyLength]; - mbedtls_md_context_t md_ctx; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); - - mbedtls_md_init(&md_ctx); - ret = mbedtls_md_setup(&md_ctx, - md_info, - 1); // non-zero implies HMAC is going to be used (0 saves memory, but is less secure) - if (md_info == NULL || ret != 0) { - Serial.println("Hash algorithm setup failed"); - Serial.println(ret); - free(decodedData); - //mbedtls_strerror(ret, mbed_err, MBED_ERR_BUF); - //mbedtls_printf( "mbedTLS ERROR: %s\n", mbed_err); - return ""; - } - - ret = mbedtls_pkcs5_pbkdf2_hmac( - &md_ctx, - (const unsigned char*)password, - strlen(password), - salt, - 16, // salt_bytes - iterations, - keyLength, - key - ); - - mbedtls_md_free(&md_ctx); - - if (ret != 0) { - Serial.println("Key derivation failed"); - Serial.println(ret); - free(decodedData); - //mbedtls_strerror(ret, mbed_err, MBED_ERR_BUF); - //mbedtls_printf( "mbedTLS ERROR: %s\n", mbed_err); - return ""; - } - - // Decrypt using AES-GCM - unsigned char decryptedContent[encryptedContentLen] = {0}; - mbedtls_gcm_context gcm; - mbedtls_gcm_init(&gcm); - - ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, keyLength * 8); - - if (ret != 0) { - Serial.println("Set Key failed"); - free(decodedData); - Serial.println(ret); - //mbedtls_strerror(ret, mbed_err, MBED_ERR_BUF); - //mbedtls_printf( "mbedTLS ERROR: %s\n", mbed_err); - return ""; - } - - ret = mbedtls_gcm_auth_decrypt(&gcm, encryptedContentLen, iv, 12, NULL, 0, tag, 16, encryptedContent, decryptedContent); - String r = String((char*)decryptedContent); - - mbedtls_gcm_free(&gcm); - free(decodedData); - //free(decryptedContent); - - if (ret == 0) { - // Successfully decrypted - return(r); - } else { - // Decryption failed - Serial.println("Decryption failed"); - Serial.println(ret); - //mbedtls_strerror(ret, mbed_err, MBED_ERR_BUF); - //mbedtls_printf( "mbedTLS ERROR: %s\n", mbed_err); - return(""); - } +String decryptString(String& cypertext, const String& password_str) { + return xorEncryptDecrypt(cypertext, password_str); } diff --git a/src/core/passwords.h b/src/core/passwords.h index b4dd1acd..5e060d7d 100644 --- a/src/core/passwords.h +++ b/src/core/passwords.h @@ -2,6 +2,6 @@ #include -String aes_encrypt(String& plaintext, const String& password_str); +String encryptString(String& plaintext, const String& password_str); -String aes_decrypt(String& encryptedBase64, const String& password_str); +String decryptString(String& cypertext, const String& password_str); diff --git a/src/core/sd_functions.cpp b/src/core/sd_functions.cpp index 9cc989ab..b125d8f3 100644 --- a/src/core/sd_functions.cpp +++ b/src/core/sd_functions.cpp @@ -375,28 +375,30 @@ String crc32File(FS &fs, String filepath) { return(String(s)); } -String readDecryptedAesFile(FS &fs, String filepath) { - String base64enc = readSmallFile(fs, filepath); - //Serial.println(base64enc); - if(base64enc.length() == 0) return ""; +String readDecryptedFile(FS &fs, String filepath) { + String cyphertext = readSmallFile(fs, filepath); + if(cyphertext.length() == 0) return ""; if(cachedPassword.length()==0) { cachedPassword = keyboard("", 32, "password"); if(cachedPassword.length()==0) return ""; // cancelled } + //Serial.println(cyphertext); + //Serial.println(cachedPassword); + // else try to decrypt - String plaintext = aes_decrypt(base64enc, cachedPassword); + String plaintext = decryptString(cyphertext, cachedPassword); - /* // check if really plaintext if(!isValidAscii(plaintext)) { // invalidate cached password -> will ask again on the next try cachedPassword = ""; Serial.println("invalid password"); - Serial.println(plaintext); + //Serial.println(plaintext); return ""; - }*/ + } + // else return plaintext; } @@ -654,7 +656,7 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) { delay(200); txSubFile(&fs, filepath); }}); - if(filepath.endsWith(".bjs") || filepath.endsWith(".js")) options.insert(options.begin(), {"Run JS Script", [&]() { + if(filepath.endsWith(".bjs") || filepath.endsWith(".js")) options.insert(options.begin(), {"JS Script Run", [&]() { delay(200); run_bjs_script_headless(fs, filepath); }}); @@ -662,37 +664,36 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) { if(filepath.endsWith(".txt")) { options.push_back({"BadUSB Run", [&]() { Kb.begin(); USB.begin(); - // TODO: set default keyboard layout key_input(fs, filepath); + Kb.end(); }}); - /* options.push_back({"USB HID Type", [&]() { - Kb.begin(); USB.begin(); - Kb.print(readSmallFile(fs, filepath).c_str()); // buggy? - //String t = readSmallFile(fs, filepath).c_str(); - //Kb.write((const uint8_t*) t.c_str(), t.length()); - }});*/ + String t = readSmallFile(fs, filepath); + displayInfo("Typing"); + key_input_from_string(t); + }}); } - if(filepath.endsWith(".aes")) { // aes encrypted files + if(filepath.endsWith(".enc")) { // aes encrypted files options.insert(options.begin(), {"Decrypt+Type", [&]() { - String plaintext = readDecryptedAesFile(fs, filepath); - if(plaintext.length()==0) return displayError("invalid password"); // file is too big or cannot read, or cancelled + String plaintext = readDecryptedFile(fs, filepath); + if(plaintext.length()==0) // file is too big or cannot read, or cancelled // else - Kb.begin(); USB.begin(); - Kb.print(plaintext.c_str()); + key_input_from_string(plaintext); }}); } #endif - if(filepath.endsWith(".aes")) { // aes encrypted files + if(filepath.endsWith(".enc")) { // aes encrypted files options.insert(options.begin(), {"Decrypt+Show", [&]() { - String plaintext = readDecryptedAesFile(fs, filepath); - if(plaintext.length()==0) return; // file is too big or cannot read, or cancelled - // else + String plaintext = readDecryptedFile(fs, filepath); + delay(200); + if(plaintext.length()==0) return displayError("Decryption failed"); + //if(plaintext.length()<..) displaySuccess(plaintext); while(!checkAnyKeyPress()) delay(100); // else // TODO: show in the text viewer + }}); } #if defined(HAS_NS4168_SPKR) @@ -743,6 +744,8 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) { } #ifdef CARDPUTER + if(checkEscPress()) break; // quit + /* TODO: go back 1 level instead of quitting if(Keyboard.isKeyPressed(KEY_BACKSPACE)) { // go back 1 level @@ -752,7 +755,23 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) { redraw=true; continue; }*/ - if(checkEscPress()) break; + + const short PAGE_JUMP_SIZE = 5; + if(checkNextPagePress()) { + index += PAGE_JUMP_SIZE; + if(index>maxFiles) index=maxFiles-1; // check bounds + redraw = true; + continue; + } + if(checkPrevPagePress()) { + index -= PAGE_JUMP_SIZE; + if(index<0) index = 0; // check bounds + redraw = true; + continue; + } + + // check letter shortcuts + char pressed_letter = checkLetterShortcutPress(); if(pressed_letter>0) { //Serial.println(pressed_letter); diff --git a/src/core/sd_functions.h b/src/core/sd_functions.h index 369cf35e..0393aca6 100644 --- a/src/core/sd_functions.h +++ b/src/core/sd_functions.h @@ -33,7 +33,7 @@ String md5File(FS &fs, String filepath); String crc32File(FS &fs, String filepath); -String readDecryptedAesFile(FS &fs, String filepath); +String readDecryptedFile(FS &fs, String filepath); void readFs(FS fs, String folder, String result[][3], String allowed_ext = "*"); diff --git a/src/core/serialcmds.cpp b/src/core/serialcmds.cpp index 9cc45cb2..de374811 100644 --- a/src/core/serialcmds.cpp +++ b/src/core/serialcmds.cpp @@ -14,6 +14,7 @@ #include "display.h" #include "powerSave.h" #include "wifi_common.h" +#include "passwords.h" #include "modules/rf/rf.h" //#include "modules/rf/rtl433.h" //#include "modules/rf/radiolib_test.h" @@ -51,7 +52,6 @@ bool setupPsramFs() { return true; } - String readSmallFileFromSerial() { String buf = ""; String curr_line = ""; @@ -601,7 +601,7 @@ bool processSerialCommand(String cmd_str) { } return true; } - + if(cmd_str == "power sleep_and_wakeup_from_uart" ) { #ifdef HAS_SCREEN turnOffDisplay(); @@ -617,15 +617,14 @@ bool processSerialCommand(String cmd_str) { //uart_set_pin(UART_NUM_0, TX, RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); gpio_sleep_set_direction((gpio_num_t)RX, GPIO_MODE_INPUT); gpio_sleep_set_pull_mode((gpio_num_t)RX, GPIO_PULLUP_ONLY); + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); uart_set_wakeup_threshold(UART_NUM_0, 3); // 3 edges on U0RXD to wakeup - uart_set_wakeup_threshold(UART_NUM_1, 3); // 3 edges on U0RXD to wakeup - uart_set_wakeup_threshold(UART_NUM_2, 3); // 3 edges on U0RXD to wakeup + delay(100); esp_sleep_enable_uart_wakeup(UART_NUM_0); - esp_sleep_enable_uart_wakeup(UART_NUM_1); - esp_sleep_enable_uart_wakeup(UART_NUM_2); + //uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); delay(100); esp_light_sleep_start(); - //Serial.begin(115200); // needs reinit + Serial.begin(115200); // needs reinit? Serial.println("woken"); return true; } @@ -828,18 +827,15 @@ bool processSerialCommand(String cmd_str) { if(!fs) return false; // else if(cmd_str.startsWith("storage read ")) { - String txt = readSmallFile(*fs, filepath); - Serial.println(txt); + Serial.println( readSmallFile(*fs, filepath) ); return true; } else if(cmd_str.startsWith("storage md5 ")) { - String txt = md5File(*fs, filepath); - Serial.println(txt); + Serial.println( md5File(*fs, filepath) ); return true; } else if(cmd_str.startsWith("storage crc32 ")) { - String txt = crc32File(*fs, filepath); - Serial.println(txt); + Serial.println( crc32File(*fs, filepath) ); return true; } } @@ -1025,10 +1021,15 @@ bool processSerialCommand(String cmd_str) { // else return true; } - - if(cmd_str.startsWith("crypto decrypt_from_file")) { - // crypto decrypt_from_file passwords/vmoptions.txt.enc 123 - String args = cmd_str.substring(strlen("crypto decrypt_from_file ")); + + if(cmd_str.startsWith("crypto ")) { + // crypto decrypt_from_file passwords/test.txt.enc 123 + // crypto encrypt_to_file passwords/test.txt.enc 123 + String args = ""; + if(cmd_str.startsWith("crypto decrypt_from_file ")) + args = cmd_str.substring(strlen("crypto decrypt_from_file ")); + else if(cmd_str.startsWith("crypto encrypt_to_file ")) + args = cmd_str.substring(strlen("crypto encrypt_to_file ")); String filepath = args.substring(0, args.indexOf(" ")); filepath.trim(); if(filepath.length()==0) return false; // missing arg @@ -1036,17 +1037,34 @@ bool processSerialCommand(String cmd_str) { String password = args.substring(args.indexOf(" ")+1, args.length()); password.trim(); if(password.length()==0) return false; // missing arg + cachedPassword = password; // avoid interactive prompt //Serial.println(filepath); //Serial.println(password); - FS* fs = NULL; - if(SD.exists(filepath)) fs = &SD; - if(LittleFS.exists(filepath)) fs = &LittleFS; - if(!fs) return false; // file not found - cachedPassword = password; // avoid interactive prompt - String plaintext = readDecryptedAesFile(*fs, filepath); - if(plaintext=="") return false; - Serial.println(plaintext); - return true; + + if(cmd_str.startsWith("crypto decrypt_from_file")) { + FS* fs = NULL; + if(SD.exists(filepath)) fs = &SD; + if(LittleFS.exists(filepath)) fs = &LittleFS; + if(!fs) return false; // file not found + String plaintext = readDecryptedFile(*fs, filepath); + if(plaintext=="") return false; + Serial.println(plaintext); + return true; + } + else if(cmd_str.startsWith("crypto encrypt_to_file")) { + String txt = readSmallFileFromSerial(); + if(txt.length()==0) return false; + FS* fs = &SD; + if(LittleFS.exists(filepath)) fs = &LittleFS; + File f = fs->open(filepath, FILE_WRITE); + if(!f) return false; + String cyphertxt = encryptString(txt, cachedPassword); + if(cyphertxt=="") return false; + f.write((const uint8_t*) cyphertxt.c_str(), cyphertxt.length()); + f.close(); + Serial.println("file written: " + filepath); + return true; + } } if(cmd_str == "uptime") { diff --git a/src/modules/bjs_interpreter/interpreter.cpp b/src/modules/bjs_interpreter/interpreter.cpp index ae2ace22..5872adc2 100644 --- a/src/modules/bjs_interpreter/interpreter.cpp +++ b/src/modules/bjs_interpreter/interpreter.cpp @@ -203,6 +203,13 @@ static duk_ret_t native_drawFillRect(duk_context *ctx) { return 0; } +/* +static duk_ret_t native_drawLine(duk_context *ctx) { + // drawLine(int16_t x, int16_t y, int16_t x2, int16_t y2, uint16_t color) + //tft.fillRect(duk_to_int(ctx, 0),duk_to_int(ctx, 1),duk_to_int(ctx, 2),duk_to_int(ctx, 3),duk_to_int(ctx, 4)); + return 0; +}*/ + static duk_ret_t native_drawString(duk_context *ctx) { tft.drawString(duk_to_string(ctx, 0),duk_to_int(ctx, 1),duk_to_int(ctx, 2)); return 0; @@ -472,35 +479,33 @@ static duk_ret_t native_subghzSetFrequency(duk_context *ctx) { static duk_ret_t native_dialogMessage(duk_context *ctx) { // usage: dialogMessage(msg : string) - if(duk_is_string(ctx, 0)) { - displayInfo(String(duk_to_string(ctx, 0))); - while(!checkAnyKeyPress()) delay(100); - } + displayInfo(String(duk_to_string(ctx, 0))); + while(!checkAnyKeyPress()) delay(100); return 0; } static duk_ret_t native_dialogError(duk_context *ctx) { // usage: dialogError(msg : string) - if(duk_is_string(ctx, 0)) { - displayError(String(duk_to_string(ctx, 0))); - while(!checkAnyKeyPress()) delay(100); - } + displayError(String(duk_to_string(ctx, 0))); + while(!checkAnyKeyPress()) delay(100); return 0; } static duk_ret_t native_dialogPickFile(duk_context *ctx) { + // usage: dialogPickFile() : string // usage: dialogPickFile(path : string) : string // returns: selected file , empty string if cancelled String r = ""; + String filepath = "/"; if(duk_is_string(ctx, 0)) { - String filepath = String(duk_to_string(ctx, 0)); + filepath = String(duk_to_string(ctx, 0)); if(!filepath.startsWith("/")) filepath = "/" + filepath; // add "/" if missing - FS* fs = NULL; - if(SD.exists(filepath)) fs = &SD; - if(LittleFS.exists(filepath)) fs = &LittleFS; - if(fs) { - r = loopSD(*fs, true); - } + } + FS* fs = NULL; + if(SD.exists(filepath)) fs = &SD; + if(LittleFS.exists(filepath)) fs = &LittleFS; + if(fs) { + r = loopSD(*fs, true); } duk_push_string(ctx, r.c_str()); return 1; @@ -663,6 +668,10 @@ void interpreter() { duk_push_c_function(ctx, native_drawString, 3); duk_put_global_string(ctx, "drawString"); duk_push_c_function(ctx, native_width, 0); + // TODO: drawLine(x1, y1, x2, y2, color) + // TODO: drawPixel(x, y, color) + // TODO: drawBitmap(filename:string, x, y) + // TODO: clearScreen() duk_put_global_string(ctx, "width"); duk_push_c_function(ctx, native_height, 0); duk_put_global_string(ctx, "height"); @@ -725,7 +734,7 @@ void interpreter() { duk_put_global_string(ctx, "dialogError"); duk_push_c_function(ctx, native_dialogPickFile, 1); duk_put_global_string(ctx, "dialogPickFile"); - // TODO: dialogChoice + // TODO: dialogChoice(array) duk_push_c_function(ctx, native_dialogViewFile, 1); duk_put_global_string(ctx, "dialogViewFile"); duk_push_c_function(ctx, native_keyboard, 3); @@ -792,5 +801,5 @@ bool run_bjs_script_headless(String code) { bool run_bjs_script_headless(FS fs, String filename) { String code = readScriptFile(fs, filename); - run_bjs_script_headless(code); + return run_bjs_script_headless(code); } \ No newline at end of file diff --git a/src/modules/others/bad_usb.cpp b/src/modules/others/bad_usb.cpp index 477b485f..a6f83080 100644 --- a/src/modules/others/bad_usb.cpp +++ b/src/modules/others/bad_usb.cpp @@ -270,7 +270,23 @@ void usb_setup() { } +//#include // https://github.com/chegewara/EspTinyUSB 1.3.4 +void key_input_from_string(String text) { + + Kb.begin(); + USB.begin(); + + Kb.print(text.c_str()); // buggy with some special chars + + //Kb.end(); + + /* + HIDcomposite KeyboardMouse; + KeyboardMouse.begin(); + KeyboardMouse.sendString(text+"\n"); + * */ +} #if defined(CARDPUTER) //Now cardputer works as a USB Keyboard! diff --git a/src/modules/others/bad_usb.h b/src/modules/others/bad_usb.h index 038e4a71..755fe5d8 100644 --- a/src/modules/others/bad_usb.h +++ b/src/modules/others/bad_usb.h @@ -11,6 +11,7 @@ extern USBHIDKeyboard Kb; void key_input(FS fs, String bad_script = "/badpayload.txt"); +void key_input_from_string(String text); void usb_setup(); diff --git a/src/modules/others/webInterface.cpp b/src/modules/others/webInterface.cpp index c90345f8..dcdf56dc 100644 --- a/src/modules/others/webInterface.cpp +++ b/src/modules/others/webInterface.cpp @@ -4,6 +4,7 @@ #include "core/mykeyboard.h" // using keyboard when calling rename #include "core/display.h" // using displayRedStripe as error msg #include "core/serialcmds.h" +#include "core/passwords.h" #include "webInterface.h" @@ -133,8 +134,9 @@ String listFiles(FS fs, bool ishtml, String folder, bool isLittleFS) { //if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("bin")) returnText+= "  \n"; if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("sub")) returnText+= "  \n"; if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("ir")) returnText+= "  \n"; + if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("bjs")) returnText+= "  \n"; #if defined(USB_as_HID) - if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("txt")) returnText+= "  \n"; + if (String(foundfile.name()).substring(String(foundfile.name()).lastIndexOf('.') + 1).equalsIgnoreCase("txt")) returnText+= "  \n"; #endif returnText += "  \n"; returnText += "\n\n"; @@ -197,21 +199,40 @@ bool checkUserWebAuth() { void handleFileUpload(FS fs) { HTTPUpload& upload = server->upload(); String filename = upload.filename; + if (server->hasArg("password")) filename = filename + ".enc"; if (upload.status == UPLOAD_FILE_START) { if (!filename.startsWith("/")) filename = "/" + filename; if (uploadFolder != "/") filename = uploadFolder + filename; fs.remove(filename); uploadFile = fs.open(filename, "w"); Serial.println("Upload Start: " + filename); - } else if (upload.status == UPLOAD_FILE_WRITE) { - if (uploadFile) uploadFile.write(upload.buf, upload.currentSize); - } else if (upload.status == UPLOAD_FILE_END) { - if (uploadFile) { + } else if (upload.status == UPLOAD_FILE_WRITE && uploadFile) { + if (server->hasArg("password")) { + // encryption requested + static int chunck_no = 0; + if(chunck_no != 0) { + // TODO: handle multiple chunks + server->send(404, "text/html", "file is too big"); + return; + } else chunck_no += 1; + String enc_password = server->arg("password"); + // upload to ram, encrypt, then write cypertext + //Serial.println(enc_password); + String plaintext = String((char*)upload.buf).substring(0, upload.currentSize); + //Serial.println(plaintext); + //Serial.println(upload.currentSize); + String cyphertxt = encryptString(plaintext, enc_password); + if(cyphertxt=="") return; + uploadFile.write((const uint8_t*) cyphertxt.c_str(), cyphertxt.length()); + } else { + // write directly + uploadFile.write(upload.buf, upload.currentSize); + } + } else if (upload.status == UPLOAD_FILE_END && uploadFile) { uploadFile.close(); Serial.println("Upload End: " + filename); server->sendHeader("Location", "/"); // Redireciona para a raiz server->send(303); - } } } diff --git a/src/modules/others/webInterface.h b/src/modules/others/webInterface.h index 8c668b18..557ba072 100644 --- a/src/modules/others/webInterface.h +++ b/src/modules/others/webInterface.h @@ -491,7 +491,21 @@ function sendSubFile(filePath) { listFilesButton(actualFolder, fs, true); } -function sendBadusbFile(filePath) { +function runJsFile(filePath) { + if(!confirm("Confirm executing the selected JS script?")) return; + var actualFolder = document.getElementById("actualFolder").value; + var fs = document.getElementById("actualFS").value; + const ajax5 = new XMLHttpRequest(); + const formdata5 = new FormData(); + formdata5.append("cmnd", "js " + filePath); + ajax5.open("POST", "/cm", false); + ajax5.send(formdata5); + document.getElementById("status").innerHTML = ajax5.responseText; + var fs = document.getElementById("actualFS").value; + listFilesButton(actualFolder, fs, true); +} + +function runBadusbFile(filePath) { if(!confirm("Confirm executing the selected DuckyScript on the machine connected via USB?")) return; var actualFolder = document.getElementById("actualFolder").value; var fs = document.getElementById("actualFS").value; @@ -556,6 +570,7 @@ function showUploadButtonFancy(folders) { "

Send file to " + folders + "

"+ "
" + "" + + " Encrypted
" + "
" + "" + "

" + @@ -568,14 +583,21 @@ function _(el) { return document.getElementById(el); } - +var cachedPassword=""; function uploadFile(folder) { var fs = document.getElementById("actualFS").value; var folder = _("folder").value; var files = _("file1").files; // Extract files from input element - + var formdata = new FormData(); + + var encrypted = _("encryptCheckbox").checked; + if(encrypted) { + cachedPassword = prompt("Enter encryption password (do not lose it): ", cachedPassword); + formdata.append("password", cachedPassword); + } + for (var i = 0; i < files.length; i++) { formdata.append("files[]", files[i]); // Append each file to form data }