diff --git a/TagTinker b/TagTinker new file mode 160000 index 0000000000..12b0c04860 --- /dev/null +++ b/TagTinker @@ -0,0 +1 @@ +Subproject commit 12b0c0486031367725fb9c53d948801fc6f00f0a diff --git a/sd_files/portals/media/gorilla.jpg b/sd_files/portals/media/gorilla.jpg new file mode 100644 index 0000000000..4e018713ad Binary files /dev/null and b/sd_files/portals/media/gorilla.jpg differ diff --git a/sd_files/portals/media/rickroll.gif b/sd_files/portals/media/rickroll.gif new file mode 100644 index 0000000000..4df6611e52 Binary files /dev/null and b/sd_files/portals/media/rickroll.gif differ diff --git a/src/modules/wifi/evil_portal.cpp b/src/modules/wifi/evil_portal.cpp index 46a84b7d9a..efbc232145 100644 --- a/src/modules/wifi/evil_portal.cpp +++ b/src/modules/wifi/evil_portal.cpp @@ -14,10 +14,10 @@ EvilPortal::EvilPortal( ) : apName(tssid), _channel(channel), _deauth(deauth), _verifyPwd(verifyPwd), _autoMode(autoMode), _backgroundMode(backgroundMode), webServer(80), _launchTime(millis()) { - + _originalWifiMode = WiFi.getMode(); _wifiWasConnected = (WiFi.status() == WL_CONNECTED); - + if (!setup()) return; cleanlyStopWebUiForWiFiFeature(); beginAP(); @@ -67,7 +67,8 @@ bool EvilPortal::setup() { } options = { - {"Custom Html", [this]() { loadCustomHtml(); }} + {"Custom Html", [this]() { loadCustomHtml(); }}, + {"Meme Portal", [this]() { loadMemeHtml(); }} }; addOptionToMainMenu(); @@ -200,6 +201,18 @@ void EvilPortal::setupRoutes() { request->send(response); }); + webServer.on("/media", HTTP_GET, [this](AsyncWebServerRequest *request) { + if (fsMedia == nullptr || _memeFilePath == "") { + request->send(404, "text/plain", "Not found"); + return; + } + String contentType = "image/jpeg"; + if (_memeFilePath.endsWith(".gif")) contentType = "image/gif"; + else if (_memeFilePath.endsWith(".png")) contentType = "image/png"; + else if (_memeFilePath.endsWith(".mp4")) contentType = "video/mp4"; + request->send(*fsMedia, _memeFilePath, contentType); + }); + webServer.on("/", [this](AsyncWebServerRequest *request) { portalController(request); }); webServer.on("/post", [this](AsyncWebServerRequest *request) { credsController(request); }); @@ -246,17 +259,17 @@ void EvilPortal::restartWiFi(bool reset) { webServer.end(); dnsServer.stop(); vTaskDelay(100 / portTICK_PERIOD_MS); - + _captiveHandler = nullptr; - + wifiDisconnect(); WiFi.softAP(apName, emptyString, _channel); vTaskDelay(100 / portTICK_PERIOD_MS); - + setupRoutes(); dnsServer.start(53, "*", WiFi.softAPIP()); webServer.begin(); - + if (reset) resetCapturedCredentials(); } @@ -309,24 +322,24 @@ void EvilPortal::loop() { }}, {"Resume", [&shouldRedraw]() { shouldRedraw = true; }} }; - + loopOptions(options); if (exitPortal) { displayTextLine("Shutting down..."); vTaskDelay(100 / portTICK_PERIOD_MS); - + webServer.end(); vTaskDelay(200 / portTICK_PERIOD_MS); - + dnsServer.stop(); vTaskDelay(100 / portTICK_PERIOD_MS); - + WiFi.mode(_originalWifiMode); vTaskDelay(100 / portTICK_PERIOD_MS); - + wifiDisconnect(); vTaskDelay(100 / portTICK_PERIOD_MS); - + return; } shouldRedraw = true; @@ -380,7 +393,7 @@ void EvilPortal::recordPageView() { bool EvilPortal::shouldTerminate() { unsigned long currentTime = millis(); unsigned long elapsed = currentTime - _launchTime; - + if (_durationExtended) { return elapsed > (_extendedDurationSec * 1000); } else { @@ -390,7 +403,7 @@ bool EvilPortal::shouldTerminate() { void EvilPortal::checkAndExtendDuration() { if (_durationExtended) return; - + if (hasRecentActivity()) { _durationExtended = true; Serial.println("[PORTAL] Activity detected, extending duration"); @@ -488,6 +501,41 @@ void EvilPortal::loadCustomHtml() { } } +void EvilPortal::loadMemeHtml() { + fsMedia = nullptr; + + options = {}; + if (sdcardMounted) + options.push_back({"SD Card", [this]() { fsMedia = &SD; }}); + if (checkLittleFsSizeNM()) + options.push_back({"LittleFS", [this]() { fsMedia = &LittleFS; }}); + + if (options.empty()) { loadDefaultHtml(); return; } + loopOptions(options); + if (returnToMenu || fsMedia == nullptr) return; + + String startPath = fsMedia->exists("/portals/media") ? "/portals/media" : "/"; + + apName = ""; + apName_from_keyboard(); + if (returnToMenu) return; + + String pickedFile = loopSD(*fsMedia, true, "JPG|JPEG|PNG|GIF|MP4", startPath); + if (pickedFile == "" || returnToMenu) return; + + _memeFilePath = pickedFile; + String tag; + if (pickedFile.endsWith(".mp4")) + tag = ""; + else + tag = ""; + + htmlPage = "" + tag + ""; + outputFile = "meme_creds.csv"; + isDefaultHtml = true; +} + + String EvilPortal::wifiLoadPage() { return String( "