Updated Settings

- Added autosave settings with default values in A_config
- Moved strings from language in settings 
- Getter and setter only using the structs
- Json string is now generated manually to improve performance
This commit is contained in:
Stefan Kremser 2019-05-15 21:29:00 +02:00
parent d47bc85a14
commit b80cf4811d
13 changed files with 1034 additions and 874 deletions

View File

@ -36,6 +36,8 @@
#define DEFAULT_ESP8266
// Forces a reset of all settings at startup
// #define RESET_SETTINGS
// ========== CONFIGS ========== //
#if defined(D_DUINO_B_V5_LED_RING)
@ -228,6 +230,15 @@
// ========= FALLBACK ========= //
// ===== AUTOSAVE ===== //
#ifndef AUTOSAVE_ENABLED
#define AUTOSAVE_ENABLED true
#endif /* ifndef ATTACK_ALL_CH */
#ifndef AUTOSAVE_TIME
#define AUTOSAVE_TIME 60
#endif /* ifndef ATTACK_ALL_CH */
// ===== ATTACK ===== //
#ifndef ATTACK_ALL_CH
#define ATTACK_ALL_CH false

View File

@ -3,7 +3,7 @@
Attack::Attack() {
getRandomMac(mac);
if (settings.getBeaconInterval()) {
if (settings.getAttackSettings().beacon_interval == INTERVAL_1S) {
// 1s beacon interval
beaconPacket[32] = 0xe8;
beaconPacket[33] = 0x03;
@ -83,9 +83,9 @@ void Attack::updateCounter() {
// deauth packets per second
if (deauth.active) {
if (deauthAll) deauth.maxPkts = settings.getDeauthsPerTarget() *
if (deauthAll) deauth.maxPkts = settings.getAttackSettings().deauths_per_target *
(accesspoints.count() + stations.count() * 2 - names.selected());
else deauth.maxPkts = settings.getDeauthsPerTarget() *
else deauth.maxPkts = settings.getAttackSettings().deauths_per_target *
(accesspoints.selected() + stations.selected() * 2 + names.selected() + names.stations());
} else {
deauth.maxPkts = 0;
@ -95,17 +95,17 @@ void Attack::updateCounter() {
if (beacon.active) {
beacon.maxPkts = ssids.count();
if (!settings.getBeaconInterval()) beacon.maxPkts *= 10;
if (settings.getAttackSettings().beacon_interval == INTERVAL_100MS) beacon.maxPkts *= 10;
} else {
beacon.maxPkts = 0;
}
// probe packets per second
if (probe.active) probe.maxPkts = ssids.count() * settings.getProbesPerSSID();
if (probe.active) probe.maxPkts = ssids.count() * settings.getAttackSettings().probe_frames_per_ssid;
else probe.maxPkts = 0;
// random transmission power
if (settings.getRandomTX() && (beacon.active || probe.active)) setOutputPower(random(21));
if (settings.getAttackSettings().random_tx && (beacon.active || probe.active)) setOutputPower(random(21));
else setOutputPower(20.5f);
// reset counters
@ -240,7 +240,7 @@ void Attack::deauthAllUpdate() {
void Attack::probeUpdate() {
if (probe.active && (probe.maxPkts > 0) && (probe.packetCounter < probe.maxPkts)) {
if (probe.time <= currentTime - (1000 / probe.maxPkts)) {
if (settings.getBeaconChannel()) setWifiChannel(probe.tc % 11);
if (settings.getAttackSettings().attack_all_ch) setWifiChannel(probe.tc % 11);
probe.tc += sendProbe(probe.tc);
if (probe.tc >= ssids.count()) probe.tc = 0;
@ -259,18 +259,18 @@ void Attack::beaconUpdate() {
}
bool Attack::deauthStation(int num) {
return deauthDevice(stations.getAPMac(num), stations.getMac(num), settings.getDeauthReason(), stations.getCh(num));
return deauthDevice(stations.getAPMac(num), stations.getMac(num), settings.getAttackSettings().deauth_reason, stations.getCh(num));
}
bool Attack::deauthAP(int num) {
return deauthDevice(accesspoints.getMac(num), broadcast, settings.getDeauthReason(), accesspoints.getCh(num));
return deauthDevice(accesspoints.getMac(num), broadcast, settings.getAttackSettings().deauth_reason, accesspoints.getCh(num));
}
bool Attack::deauthName(int num) {
if (names.isStation(num)) {
return deauthDevice(names.getBssid(num), names.getMac(num), settings.getDeauthReason(), names.getCh(num));
return deauthDevice(names.getBssid(num), names.getMac(num), settings.getAttackSettings().deauth_reason, names.getCh(num));
} else {
return deauthDevice(names.getMac(num), broadcast, settings.getDeauthReason(), names.getCh(num));
return deauthDevice(names.getMac(num), broadcast, settings.getAttackSettings().deauth_reason, names.getCh(num));
}
}
@ -334,7 +334,7 @@ bool Attack::deauthDevice(uint8_t* apMac, uint8_t* stMac, uint8_t reason, uint8_
}
bool Attack::sendBeacon(uint8_t tc) {
if (settings.getBeaconChannel()) setWifiChannel(tc % 11);
if (settings.getAttackSettings().attack_all_ch) setWifiChannel(tc % 11);
mac[5] = tc;
return sendBeacon(mac, ssids.getName(tc).c_str(), wifi_channel, ssids.getWPA2(tc));
}
@ -379,7 +379,7 @@ bool Attack::sendBeacon(uint8_t* mac, const char* ssid, uint8_t ch, bool wpa2) {
}
bool Attack::sendProbe(uint8_t tc) {
if (settings.getBeaconChannel()) setWifiChannel(tc % 11);
if (settings.getAttackSettings().attack_all_ch) setWifiChannel(tc % 11);
mac[5] = tc;
return sendProbe(mac, ssids.getName(tc).c_str(), wifi_channel);
}

View File

@ -126,21 +126,21 @@ class Attack {
};
uint8_t probePacket[68] = {
/* 0 - 1 */ 0x40, 0x00, // Type: Probe Request
/* 2 - 3 */ 0x00, 0x00, // Duration: 0 microseconds
/* 4 - 9 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination: Broadcast
/* 10 - 15 */ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // Source: random MAC
/* 16 - 21 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // BSS Id: Broadcast
/* 22 - 23 */ 0x00, 0x00, // Sequence number (will be replaced by the SDK)
/* 24 - 25 */ 0x00, 0x20, // Tag: Set SSID length, Tag length: 32
/* 26 - 57 */ 0x20, 0x20, 0x20, 0x20, // SSID
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
/* 0 - 1 */ 0x40, 0x00, // Type: Probe Request
/* 2 - 3 */ 0x00, 0x00, // Duration: 0 microseconds
/* 4 - 9 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination: Broadcast
/* 10 - 15 */ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // Source: random MAC
/* 16 - 21 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // BSS Id: Broadcast
/* 22 - 23 */ 0x00, 0x00, // Sequence number (will be replaced by the SDK)
/* 24 - 25 */ 0x00, 0x20, // Tag: Set SSID length, Tag length: 32
/* 26 - 57 */ 0x20, 0x20, 0x20, 0x20, // SSID
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
/* 58 - 59 */ 0x01, 0x08, // Tag Number: Supported Rates (1), Tag length: 8
/* 60 */ 0x82, // 1(B)
/* 61 */ 0x84, // 2(B)
@ -153,53 +153,53 @@ class Attack {
};
uint8_t beaconPacket[109] = {
/* 0 - 3 */ 0x80, 0x00, 0x00, 0x00, // Type/Subtype: managment beacon frame
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Destination: broadcast
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
/* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
/* 0 - 3 */ 0x80, 0x00, 0x00, 0x00, // Type/Subtype: managment beacon frame
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Destination: broadcast
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
/* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
// Fixed parameters
/* 22 - 23 */ 0x00, 0x00, // Fragment & sequence number (will be done by the SDK)
/* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, // Timestamp
/* 32 - 33 */ 0xe8, 0x03, // Interval: 0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
/* 34 - 35 */ 0x31, 0x00, // capabilities Tnformation
/* 22 - 23 */ 0x00, 0x00, // Fragment & sequence number (will be done by the SDK)
/* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, // Timestamp
/* 32 - 33 */ 0xe8, 0x03, // Interval: 0x64, 0x00 => every 100ms - 0xe8, 0x03 => every 1s
/* 34 - 35 */ 0x31, 0x00, // capabilities Tnformation
// Tagged parameters
// SSID parameters
/* 36 - 37 */ 0x00, 0x20, // Tag: Set SSID length, Tag length: 32
/* 38 - 69 */ 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, // SSID
/* 38 - 69 */ 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, // SSID
// Supported Rates
/* 70 - 71 */ 0x01, 0x08, // Tag: Supported Rates, Tag length: 8
/* 72 */ 0x82, // 1(B)
/* 73 */ 0x84, // 2(B)
/* 74 */ 0x8b, // 5.5(B)
/* 75 */ 0x96, // 11(B)
/* 76 */ 0x24, // 18
/* 77 */ 0x30, // 24
/* 78 */ 0x48, // 36
/* 79 */ 0x6c, // 54
/* 70 - 71 */ 0x01, 0x08, // Tag: Supported Rates, Tag length: 8
/* 72 */ 0x82, // 1(B)
/* 73 */ 0x84, // 2(B)
/* 74 */ 0x8b, // 5.5(B)
/* 75 */ 0x96, // 11(B)
/* 76 */ 0x24, // 18
/* 77 */ 0x30, // 24
/* 78 */ 0x48, // 36
/* 79 */ 0x6c, // 54
// Current Channel
/* 80 - 81 */ 0x03, 0x01, // Channel set, length
/* 82 */ 0x01, // Current Channel
/* 80 - 81 */ 0x03, 0x01, // Channel set, length
/* 82 */ 0x01, // Current Channel
// RSN information
/* 83 - 84 */ 0x30, 0x18,
/* 85 - 86 */ 0x01, 0x00,
/* 87 - 90 */ 0x00, 0x0f, 0xac, 0x02,
/* 87 - 90 */ 0x00, 0x0f, 0xac, 0x02,
/* 91 - 92 */ 0x02, 0x00,
/* 93 - 100 */ 0x00, 0x0f, 0xac, 0x04, 0x00, 0x0f, 0xac, 0x04, /*Fix: changed 0x02(TKIP) to 0x04(CCMP) is default. WPA2 with TKIP not supported by many devices*/
/* 93 - 100 */ 0x00, 0x0f, 0xac, 0x04, 0x00, 0x0f, 0xac, 0x04, /*Fix: changed 0x02(TKIP) to 0x04(CCMP) is default. WPA2 with TKIP not supported by many devices*/
/* 101 - 102 */ 0x01, 0x00,
/* 103 - 106 */ 0x00, 0x0f, 0xac, 0x02,
/* 103 - 106 */ 0x00, 0x0f, 0xac, 0x02,
/* 107 - 108 */ 0x00, 0x00
};
};

View File

@ -224,7 +224,7 @@ void CLI::runCommand(String input) {
return;
}
if (settings.getSerialEcho()) {
if (settings.getCLISettings().serial_echo) {
// print command
prnt(CLI_INPUT_PREFIX);
prntln(input);
@ -653,7 +653,7 @@ void CLI::runCommand(String input) {
bool deauthAll = false;
bool probe = false;
bool output = true;
uint32_t timeout = settings.getAttackTimeout() * 1000;
uint32_t timeout = settings.getAttackSettings().timeout * 1000;
for (int i = 1; i < list->size(); i++) {
if (eqlsCMD(i, CLI_BEACON)) beacon = true;
@ -674,12 +674,13 @@ void CLI::runCommand(String input) {
// ===== GET/SET ===== //
// get <setting>
else if (eqlsCMD(0, CLI_GET) && (list->size() == 2)) {
prntln(settings.get(list->get(1).c_str()));
settings.print();
// prntln(settings.get(list->get(1).c_str()));
}
// set <setting> <value>
else if (eqlsCMD(0, CLI_SET) && (list->size() == 3)) {
settings.set(list->get(1).c_str(), list->get(2));
// settings.set(list->get(1).c_str(), list->get(2));
}
// ====== CHICKEN ===== //
@ -717,7 +718,7 @@ void CLI::runCommand(String input) {
prntln(String(s));
prnt(CLI_SYSTEM_CHANNEL);
prntln(settings.getChannel());
prntln(settings.getWifiSettings().channel);
uint8_t mac[6];
@ -892,7 +893,7 @@ void CLI::runCommand(String input) {
else if (eqlsCMD(0, CLI_INFO)) {
prntln(CLI_INFO_HEADER);
prnt(CLI_INFO_SOFTWARE);
prntln(settings.getVersion());
prntln(DEAUTHER_VERSION);
prntln(CLI_INFO_COPYRIGHT);
prntln(CLI_INFO_LICENSE);
prntln(CLI_INFO_ADDON);
@ -977,7 +978,7 @@ void CLI::runCommand(String input) {
led.update(); // update LED color
// auto-save
if (settings.getAutosave() && (currentTime - autosaveTime > settings.getAutosaveTime())) {
if (settings.getAutosaveSettings().enabled && (currentTime - autosaveTime > settings.getAutosaveSettings().time)) {
autosaveTime = currentTime;
names.save(false);
ssids.save(false);
@ -1066,11 +1067,11 @@ void CLI::runCommand(String input) {
// startap [-p <path][-s <ssid>] [-pswd <password>] [-ch <channel>] [-h] [-cp]
else if (eqlsCMD(0, CLI_STARTAP)) {
String path = String(F("/web"));
String ssid = settings.getSSID();
String password = settings.getPassword();
String ssid = settings.getAccessPointSettings().ssid;
String password = settings.getAccessPointSettings().password;
int ch = wifi_channel;
bool hidden = settings.getHidden();
bool captivePortal = settings.getCaptivePortal();
bool hidden = settings.getAccessPointSettings().hidden;
bool captivePortal = settings.getWebSettings().captive_portal;
for (int i = 1; i < list->size(); i++) {
if (eqlsCMD(i, CLI_PATH)) {

View File

@ -395,7 +395,7 @@ void DisplayUI::setup() {
if (attack.isRunning()) {
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
settings.getAttackTimeout() * 1000);
settings.getAttackSettings().timeout * 1000);
}
});
addMenuNode(&attackMenu, [this]() { // *BEACON 0/0
@ -408,7 +408,7 @@ void DisplayUI::setup() {
if (attack.isRunning()) {
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
settings.getAttackTimeout() * 1000);
settings.getAttackSettings().timeout * 1000);
}
});
addMenuNode(&attackMenu, [this]() { // *PROBE 0/0
@ -421,7 +421,7 @@ void DisplayUI::setup() {
if (attack.isRunning()) {
attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
settings.getAttackTimeout() * 1000);
settings.getAttackSettings().timeout * 1000);
}
});
addMenuNode(&attackMenu, [this]() { // START
@ -430,7 +430,7 @@ void DisplayUI::setup() {
}, [this]() {
if (attack.isRunning()) attack.stop();
else attack.start(beaconSelected, deauthSelected, false, probeSelected, true,
settings.getAttackTimeout() * 1000);
settings.getAttackSettings().timeout * 1000);
});
});
@ -461,7 +461,7 @@ void DisplayUI::update() {
draw();
uint32_t timeout = settings.getDisplayTimeout() * 1000;
uint32_t timeout = settings.getAttackSettings().timeout * 1000;
if (currentTime > timeout) {
if (!tempOff) {
@ -775,7 +775,7 @@ void DisplayUI::drawIntro() {
drawString(1, center(str(D_INTRO_1), maxLen));
drawString(2, center(str(D_INTRO_2), maxLen));
drawString(3, center(str(D_INTRO_3), maxLen));
drawString(4, center(settings.getVersion(), maxLen));
drawString(4, center(DEAUTHER_VERSION, maxLen));
}
void DisplayUI::drawClock() {

View File

@ -83,11 +83,11 @@ void LED::setup() {
}
void LED::update() {
if (!settings.getLedEnabled()) {
if (!settings.getLEDSettings().enabled) {
setMode(OFF);
} else if (scan.isScanning() && (scan.deauths < settings.getMinDeauths())) {
} else if (scan.isScanning() && (scan.deauths < settings.getSnifferSettings().min_deauth_frames)) {
setMode(SCAN);
} else if (attack.isRunning() || (scan.deauths >= settings.getMinDeauths())) {
} else if (attack.isRunning()) {
setMode(ATTACK);
} else {
setMode(IDLE);

View File

@ -126,7 +126,7 @@ void Scan::start(uint8_t mode, uint32_t time, uint8_t nextmode, uint32_t continu
else if (mode == SCAN_MODE_OFF) {
wifi_promiscuous_enable(false);
if (settings.getWebInterface()) resumeAP();
if (settings.getWebSettings().enabled) resumeAP();
prntln(SC_STOPPED);
save(true);
@ -181,7 +181,7 @@ void Scan::update() {
}
// channel hopping
if (channelHop && (currentTime - snifferChannelTime > settings.getChTime())) {
if (channelHop && (currentTime - snifferChannelTime > settings.getSnifferSettings().channel_time)) {
snifferChannelTime = currentTime;
if (scanMode == SCAN_MODE_STATIONS) nextChannel(); // go to next channel an AP is on
@ -410,23 +410,23 @@ uint32_t Scan::getPackets(int i) {
String Scan::getMode() {
switch (scanMode) {
case SCAN_MODE_OFF:
return str(SC_MODE_OFF);
case SCAN_MODE_OFF:
return str(SC_MODE_OFF);
case SCAN_MODE_APS:
return str(SC_MODE_AP);
case SCAN_MODE_APS:
return str(SC_MODE_AP);
case SCAN_MODE_STATIONS:
return str(SC_MODE_ST);
case SCAN_MODE_STATIONS:
return str(SC_MODE_ST);
case SCAN_MODE_ALL:
return str(SC_MODE_ALL);
case SCAN_MODE_ALL:
return str(SC_MODE_ALL);
case SCAN_MODE_SNIFFER:
return str(SC_MODE_SNIFFER);
case SCAN_MODE_SNIFFER:
return str(SC_MODE_SNIFFER);
default:
return String();
default:
return String();
}
}

View File

@ -3,6 +3,7 @@
#include <Hash.h> // sha1() used in calcHash()
#include "EEPROMHelper.h" // To load and save settings_t
// ===== INTERNAL ===== //
bool operator==(settings_hash_t a, settings_hash_t b) {
for (int i = 0; i<20; i++)
if (a.hash[i] != b.hash[i]) return false;
@ -13,6 +14,64 @@ bool operator==(version_t a, version_t b) {
return a.major == b.major && a.minor == b.minor && a.revision == b.revision;
}
void jsonStr(String& str, const char* name, const char* value) {
str += '"';
str += String(name);
str += '"';
str += ':';
str += '"';
str += String(value);
str += '"';
str += ',';
}
void jsonFlag(String& str, const char* name, bool value) {
str += '"';
str += String(name);
str += '"';
str += ':';
str += String(value ? S_JSON_TRUE : S_JSON_FALSE);
str += ',';
}
void jsonValue(String& str, const char* name, int value) {
str += '"';
str += String(name);
str += '"';
str += ':';
str += String(value);
str += ',';
}
void jsonHex(String& str, const char* name, uint8_t* byteArr, int len) {
str += '"';
str += String(name);
str += '"';
str += ':';
for (int i = 0; i<len; i++) {
if (i > 0) str += ':';
if (byteArr[i] < 0x10) str += '0';
str += String(byteArr[i], HEX);
}
str += ',';
}
void jsonDec(String& str, const char* name, uint8_t* byteArr, int len) {
str += '"';
str += String(name);
str += '"';
str += ':';
for (int i = 0; i<len; i++) {
if (i > 0) str += '.';
str += String(byteArr[i]);
}
str += ',';
}
// ========== PRIVATE ========== //
settings_hash_t Settings::calcHash(settings_t data) {
settings_hash_t hash;
@ -22,50 +81,63 @@ settings_hash_t Settings::calcHash(settings_t data) {
}
String Settings::getJsonStr() {
DynamicJsonBuffer jsonBuffer(4000);
JsonObject& data = jsonBuffer.createObject();
String str((char*)0);
str.reserve(600);
str += '{';
// Version
data.set("version", DEAUTHER_VERSION);
jsonStr(str, S_JSON_VERSION, DEAUTHER_VERSION);
// AP
data.set(keyword(S_SSID), getSSID());
data.set(keyword(S_PASSWORD), getPassword());
data.set(keyword(S_CHANNEL), getChannel());
data.set(keyword(S_HIDDEN), getHidden());
data.set(keyword(S_CAPTIVEPORTAL), getCaptivePortal());
// Autosave
jsonFlag(str, S_JSON_AUTOSAVE, data.autosave.enabled);
jsonValue(str, S_JSON_AUTOSAVETIME, data.autosave.time);
// GENERAL
data.set(keyword(S_LANG), getLang());
data.set(keyword(S_AUTOSAVE), getAutosave());
data.set(keyword(S_AUTOSAVETIME), getAutosaveTime());
data.set(keyword(S_DISPLAYINTERFACE), getDisplayInterface());
data.set(keyword(S_DISPLAY_TIMEOUT), getDisplayTimeout());
data.set(keyword(S_SERIALINTERFACE), getCLI());
data.set(keyword(S_SERIAL_ECHO), getSerialEcho());
data.set(keyword(S_WEBINTERFACE), getWebInterface());
data.set(keyword(S_WEB_SPIFFS), getWebSpiffs());
data.set(keyword(S_LEDENABLED), getLedEnabled());
data.set(keyword(S_MACAP), macToStr(getMacAP()));
data.set(keyword(S_MACST), macToStr(getMacSt()));
// Attack
jsonFlag(str, S_JSON_BEACONCHANNEL, data.attack.attack_all_ch);
jsonFlag(str, S_JSON_RANDOMTX, data.attack.random_tx);
jsonValue(str, S_JSON_ATTACKTIMEOUT, data.attack.timeout);
jsonValue(str, S_JSON_DEAUTHSPERTARGET, data.attack.deauths_per_target);
jsonValue(str, S_JSON_DEAUTHREASON, data.attack.deauth_reason);
jsonFlag(str, S_JSON_BEACONINTERVAL, data.attack.beacon_interval == INTERVAL_1S);
jsonValue(str, S_JSON_PROBESPERSSID, data.attack.probe_frames_per_ssid);
// SCAN
data.set(keyword(S_CHTIME), getChTime());
data.set(keyword(S_MIN_DEAUTHS), getMinDeauths());
// WiFi
jsonValue(str, S_JSON_CHANNEL, data.wifi.channel);
jsonHex(str, S_JSON_MACST, data.wifi.mac_st, 6);
jsonHex(str, S_JSON_MACAP, data.wifi.mac_ap, 6);
// ATTACK
data.set(keyword(S_ATTACKTIMEOUT), getAttackTimeout());
data.set(keyword(S_DEAUTHSPERTARGET), getDeauthsPerTarget());
data.set(keyword(S_DEAUTHREASON), getDeauthReason());
data.set(keyword(S_BEACONCHANNEL), getBeaconChannel());
data.set(keyword(S_BEACONINTERVAL), getBeaconInterval());
data.set(keyword(S_RANDOMTX), getRandomTX());
data.set(keyword(S_PROBESPERSSID), getProbesPerSSID());
// Sniffer
jsonValue(str, S_JSON_CHTIME, data.sniffer.channel_time);
jsonValue(str, S_JSON_MIN_DEAUTHS, data.sniffer.min_deauth_frames);
String buf;
data.printTo(buf);
// Access Point
jsonStr(str, S_JSON_SSID, data.ap.ssid);
jsonStr(str, S_JSON_PASSWORD, data.ap.password);
jsonFlag(str, S_JSON_HIDDEN, data.ap.hidden);
jsonDec(str, S_JSON_IP, data.ap.ip, 4);
return buf;
// Web Interface
jsonFlag(str, S_JSON_WEBINTERFACE, data.web.enabled);
jsonFlag(str, S_JSON_CAPTIVEPORTAL, data.web.captive_portal);
jsonFlag(str, S_JSON_WEB_SPIFFS, data.web.use_spiffs);
jsonStr(str, S_JSON_LANG, data.web.lang);
// CLI
jsonFlag(str, S_JSON_SERIALINTERFACE, data.cli.enabled);
jsonFlag(str, S_JSON_SERIAL_ECHO, data.cli.serial_echo);
// LED
jsonFlag(str, S_JSON_LEDENABLED, data.led.enabled);
// Display
jsonFlag(str, S_JSON_DISPLAYINTERFACE, data.display.enabled);
jsonValue(str, S_JSON_DISPLAY_TIMEOUT, data.display.timeout);
str[str.length()-1] = '}';
return str;
}
// ========== PUBLIC ========== //
@ -90,8 +162,8 @@ void Settings::load() {
}
// check and fix mac
if (!macValid(getMacSt())) getRandomMac(data.wifi.mac_st);
if (!macValid(getMacAP())) getRandomMac(data.wifi.mac_ap);
if (!macValid(data.wifi.mac_st)) getRandomMac(data.wifi.mac_st);
if (!macValid(data.wifi.mac_ap)) getRandomMac(data.wifi.mac_ap);
changed = true;
}
@ -125,15 +197,19 @@ void Settings::save(bool force) {
void Settings::print() {
String settingsJson = getJsonStr();
settingsJson.replace("{", "{\r\n");
settingsJson.replace("}", "\r\n}");
settingsJson.replace("\":", " = ");
settingsJson.replace("\"", "");
settingsJson.replace("{", "");
settingsJson.replace("}", "");
settingsJson.replace(",", "\r\n");
prntln(S_SETTINGS_HEADER);
prntln(settingsJson);
Serial.println(settingsJson);
// printf("%s\r\n", settingsJson.c_str());
}
void Settings::set(const char* str, String value) {
/*
void Settings::set(const char* str, String value) {
// booleans
if (eqls(str, S_BEACONCHANNEL)) setBeaconChannel(s2b(value));
else if (eqls(str, S_AUTOSAVE)) setAutosave(s2b(value));
@ -180,9 +256,9 @@ void Settings::set(const char* str, String value) {
prnt(S_CHANGED_SETTING);
prntln(str);
}
}
String Settings::get(const char* str) {
String Settings::get(const char* str) {
if (eqls(str, S_SETTINGS)) print();
// booleans
else if (eqls(str, S_BEACONCHANNEL)) return b2s(getBeaconChannel());
@ -222,294 +298,382 @@ String Settings::get(const char* str) {
}
return "";
}
}
*/
// ===== GETTERS ===== //
String Settings::getVersion() {
return DEAUTHER_VERSION;
const version_t& Settings::getVersion() {
return data.version;
}
uint16_t Settings::getDeauthsPerTarget() {
return data.attack.deauths_per_target;
}
uint8_t Settings::getDeauthReason() {
return data.attack.deauth_reason;
}
bool Settings::getBeaconChannel() {
return data.attack.attack_all_ch;
}
bool Settings::getAutosave() {
const autosave_settings_t& Settings::getAutosaveSettings() {
return data.autosave;
}
uint32_t Settings::getAutosaveTime() {
return data.autosave_time;
const attack_settings_t& Settings::getAttackSettings() {
return data.attack;
}
bool Settings::getBeaconInterval() {
const wifi_settings_t& Settings::getWifiSettings() {
return data.wifi;
}
const sniffer_settings_t& Settings::getSnifferSettings() {
return data.sniffer;
}
const access_point_settings_t& Settings::getAccessPointSettings() {
return data.ap;
}
const web_settings_t& Settings::getWebSettings() {
return data.web;
}
const cli_settings_t& Settings::getCLISettings() {
return data.cli;
}
const led_settings_t& Settings::getLEDSettings() {
return data.led;
}
const display_settings_t& Settings::getDisplaySettings() {
return data.display;
}
/*
String Settings::getVersion() {
return DEAUTHER_VERSION;
}
uint16_t Settings::getDeauthsPerTarget() {
return data.attack.deauths_per_target;
}
uint8_t Settings::getDeauthReason() {
return data.attack.deauth_reason;
}
bool Settings::getBeaconChannel() {
return data.attack.attack_all_ch;
}
bool Settings::getAutosave() {
return data.autosave.enabled;
}
uint32_t Settings::getAutosaveTime() {
return data.autosave.time;
}
bool Settings::getBeaconInterval() {
return (int)data.attack.beacon_interval;
}
}
uint8_t Settings::getChannel() {
uint8_t Settings::getChannel() {
return data.wifi.channel;
}
}
String Settings::getSSID() {
String Settings::getSSID() {
return String(data.ap.ssid);
}
}
String Settings::getPassword() {
String Settings::getPassword() {
return String(data.ap.password);
}
}
bool Settings::getCLI() {
bool Settings::getCLI() {
return data.cli.enabled;
}
}
bool Settings::getDisplayInterface() {
bool Settings::getDisplayInterface() {
return data.display.enabled;
}
}
bool Settings::getWebInterface() {
bool Settings::getWebInterface() {
return data.web.enabled;
}
}
uint16_t Settings::getChTime() {
uint16_t Settings::getChTime() {
return data.sniffer.channel_time;
}
}
uint8_t* Settings::getMacSt() {
uint8_t* Settings::getMacSt() {
return data.wifi.mac_st;
}
}
uint8_t* Settings::getMacAP() {
uint8_t* Settings::getMacAP() {
return data.wifi.mac_ap;
}
}
bool Settings::getRandomTX() {
bool Settings::getRandomTX() {
return data.attack.random_tx;
}
}
uint32_t Settings::getAttackTimeout() {
uint32_t Settings::getAttackTimeout() {
return data.attack.timeout;
}
}
bool Settings::getLedEnabled() {
bool Settings::getLedEnabled() {
return data.led.enabled;
}
}
uint8_t Settings::getProbesPerSSID() {
uint8_t Settings::getProbesPerSSID() {
return data.attack.probe_frames_per_ssid;
}
}
bool Settings::getHidden() {
bool Settings::getHidden() {
return data.ap.hidden;
}
}
bool Settings::getCaptivePortal() {
bool Settings::getCaptivePortal() {
return data.web.captive_portal;
}
}
uint16_t Settings::getMinDeauths() {
uint16_t Settings::getMinDeauths() {
return data.sniffer.min_deauth_frames;
}
}
uint32_t Settings::getDisplayTimeout() {
uint32_t Settings::getDisplayTimeout() {
return data.display.timeout;
}
}
String Settings::getLang() {
String Settings::getLang() {
return data.web.lang;
}
}
bool Settings::getSerialEcho() {
bool Settings::getSerialEcho() {
return data.cli.serial_echo;
}
}
bool Settings::getWebSpiffs() {
bool Settings::getWebSpiffs() {
return data.web.use_spiffs;
}
}
*/
// ===== SETTERS ===== //
void Settings::setDeauthsPerTarget(uint8_t deauthsPerTarget) {
void Settings::setAutosaveSettings(const autosave_settings_t& autosave) {
data.autosave = autosave;
changed = true;
}
void Settings::setAttackSettings(const attack_settings_t& attack) {
data.attack = attack;
changed = true;
}
void Settings::setWifiSettings(const wifi_settings_t& wifi) {
data.wifi = wifi;
changed = true;
}
void Settings::setSnifferSettings(const sniffer_settings_t& sniffer) {
data.sniffer = sniffer;
changed = true;
}
void Settings::setAccessPointSettings(const access_point_settings_t& ap) {
data.ap = ap;
changed = true;
}
void Settings::setWebSettings(const web_settings_t& web) {
data.web = web;
changed = true;
}
void Settings::setCLISettings(const cli_settings_t& cli) {
data.cli = cli;
changed = true;
}
void Settings::setLEDSettings(const led_settings_t& led) {
data.led = led;
changed = true;
}
void Settings::setDisplaySettings(const display_settings_t& display) {
data.display = display;
changed = true;
}
/*
void Settings::setDeauthsPerTarget(uint8_t deauthsPerTarget) {
data.attack.deauths_per_target = deauthsPerTarget;
changed = true;
}
}
void Settings::setDeauthReason(uint8_t deauthReason) {
void Settings::setDeauthReason(uint8_t deauthReason) {
data.attack.deauth_reason = deauthReason;
changed = true;
}
}
void Settings::setBeaconChannel(bool beaconChannel) {
void Settings::setBeaconChannel(bool beaconChannel) {
data.attack.attack_all_ch = beaconChannel;
changed = true;
}
}
void Settings::setAutosave(bool autosave) {
data.autosave = autosave;
}
void Settings::setAutosave(bool autosave) {
data.autosave.enabled = autosave;
}
void Settings::setAutosaveTime(uint32_t autosaveTime) {
data.autosave_time = autosaveTime;
}
void Settings::setAutosaveTime(uint32_t autosaveTime) {
data.autosave.time = autosaveTime;
}
void Settings::setBeaconInterval(bool beaconInterval) {
void Settings::setBeaconInterval(bool beaconInterval) {
data.attack.beacon_interval = (beacon_interval_t)(int)beaconInterval;
changed = true;
}
}
void Settings::setChannel(uint8_t channel) {
void Settings::setChannel(uint8_t channel) {
if ((channel >= 1) && (channel <= 14)) {
data.wifi.channel = channel;
changed = true;
data.wifi.channel = channel;
changed = true;
setWifiChannel(channel);
setWifiChannel(channel);
prnt(S_CHANNEL_CHANGE);
prntln(channel);
prnt(S_CHANNEL_CHANGE);
prntln(channel);
} else {
prntln(S_CHANNEL_ERROR);
prntln(S_CHANNEL_ERROR);
}
}
}
void Settings::setSSID(String ssid) {
void Settings::setSSID(String ssid) {
if ((ssid.length() > 0) && (ssid.length() <= 32)) {
ssid = fixUtf8(ssid);
ssid = fixUtf8(ssid);
strncpy(data.ap.ssid, ssid.c_str(), 32);
strncpy(data.ap.ssid, ssid.c_str(), 32);
changed = true;
changed = true;
} else {
prntln(S_ERROR_SSID_LEN);
prntln(S_ERROR_SSID_LEN);
}
}
}
void Settings::setPassword(String password) {
void Settings::setPassword(String password) {
if ((password.length() >= 8) && (password.length() <= 32)) {
password = fixUtf8(password);
password = fixUtf8(password);
strncpy(data.ap.password, password.c_str(), 64);
strncpy(data.ap.password, password.c_str(), 64);
changed = true;
changed = true;
} else {
prntln(S_ERROR_PASSWORD_LEN);
prntln(S_ERROR_PASSWORD_LEN);
}
}
}
void Settings::setCLI(bool cli) {
void Settings::setCLI(bool cli) {
data.cli.enabled = cli;
changed = true;
}
}
void Settings::setDisplayInterface(bool displayInterface) {
void Settings::setDisplayInterface(bool displayInterface) {
data.display.enabled = displayInterface;
changed = true;
}
}
void Settings::setWebInterface(bool webInterface) {
void Settings::setWebInterface(bool webInterface) {
data.web.enabled = webInterface;
changed = true;
}
}
void Settings::setChTime(uint16_t chTime) {
void Settings::setChTime(uint16_t chTime) {
data.sniffer.channel_time = chTime;
changed = true;
}
}
void Settings::setMacSt(String macStr) {
void Settings::setMacSt(String macStr) {
uint8_t mac[6];
if (eqls(macStr, S_RANDOM)) getRandomMac(mac);
else strToMac(macStr, mac);
setMacSt(mac);
}
}
bool Settings::setMacSt(uint8_t* macSt) {
bool Settings::setMacSt(uint8_t* macSt) {
if (macSt[0] % 2 == 0) {
memcpy(data.wifi.mac_st, macSt, 6);
changed = true;
return true;
memcpy(data.wifi.mac_st, macSt, 6);
changed = true;
return true;
}
return false;
}
}
void Settings::setMacAP(String macStr) {
void Settings::setMacAP(String macStr) {
uint8_t mac[6];
if (eqls(macStr, S_RANDOM)) getRandomMac(mac);
else strToMac(macStr, mac);
setMacAP(mac);
}
}
bool Settings::setMacAP(uint8_t* macAP) {
bool Settings::setMacAP(uint8_t* macAP) {
if (macAP[0] % 2 == 0) {
memcpy(data.wifi.mac_ap, macAP, 6);
changed = true;
return true;
memcpy(data.wifi.mac_ap, macAP, 6);
changed = true;
return true;
}
return false;
}
}
void Settings::setRandomTX(bool randomTX) {
void Settings::setRandomTX(bool randomTX) {
data.attack.random_tx = randomTX;
changed = true;
}
}
void Settings::setAttackTimeout(uint32_t attackTimeout) {
void Settings::setAttackTimeout(uint32_t attackTimeout) {
data.attack.timeout = attackTimeout;
changed = true;
}
}
void Settings::setLedEnabled(bool ledEnabled) {
void Settings::setLedEnabled(bool ledEnabled) {
data.led.enabled = ledEnabled;
changed = true;
}
}
void Settings::setProbesPerSSID(uint8_t probesPerSSID) {
void Settings::setProbesPerSSID(uint8_t probesPerSSID) {
if (probesPerSSID > 0) {
data.attack.probe_frames_per_ssid = probesPerSSID;
changed = true;
data.attack.probe_frames_per_ssid = probesPerSSID;
changed = true;
}
}
}
void Settings::setHidden(bool hidden) {
void Settings::setHidden(bool hidden) {
data.ap.hidden = hidden;
changed = true;
}
}
void Settings::setCaptivePortal(bool captivePortal) {
void Settings::setCaptivePortal(bool captivePortal) {
data.web.captive_portal = captivePortal;
changed = true;
}
}
void Settings::setMinDeauths(uint16_t minDeauths) {
void Settings::setMinDeauths(uint16_t minDeauths) {
data.sniffer.min_deauth_frames = minDeauths;
changed = true;
}
}
void Settings::setDisplayTimeout(uint32_t displayTimeout) {
void Settings::setDisplayTimeout(uint32_t displayTimeout) {
data.display.timeout = displayTimeout;
changed = true;
}
}
void Settings::setLang(String lang) {
void Settings::setLang(String lang) {
strncpy(data.web.lang, lang.c_str(), 2);
changed = true;
}
}
void Settings::setSerialEcho(bool serialEcho) {
void Settings::setSerialEcho(bool serialEcho) {
data.cli.serial_echo = serialEcho;
changed = true;
}
}
void Settings::setWebSpiffs(bool webSpiffs) {
void Settings::setWebSpiffs(bool webSpiffs) {
data.web.use_spiffs = webSpiffs;
changed = true;
}
}*/

View File

@ -25,6 +25,68 @@ extern void copyWebFiles(bool force);
extern bool macValid(uint8_t* mac);
extern String bytesToStr(uint8_t* b, uint32_t size);
const char S_JSON_TRUE[] PROGMEM = "true";
const char S_JSON_FALSE[] PROGMEM = "true";
const char S_JSON_VERSION[] PROGMEM = "version";
const char S_JSON_AUTOSAVE[] PROGMEM = "autosave";
const char S_JSON_AUTOSAVETIME[] PROGMEM = "autosavetime";
const char S_JSON_BEACONCHANNEL[] PROGMEM = "beaconchannel";
const char S_JSON_RANDOMTX[] PROGMEM = "randomTX";
const char S_JSON_ATTACKTIMEOUT[] PROGMEM = "attacktimeout";
const char S_JSON_DEAUTHSPERTARGET[] PROGMEM = "deauthspertarget";
const char S_JSON_DEAUTHREASON[] PROGMEM = "deauthReason";
const char S_JSON_BEACONINTERVAL[] PROGMEM = "beaconInterval";
const char S_JSON_PROBESPERSSID[] PROGMEM = "probesPerSSID";
const char S_JSON_CHANNEL[] PROGMEM = "channel";
const char S_JSON_MACST[] PROGMEM = "macSt";
const char S_JSON_MACAP[] PROGMEM = "macAP";
const char S_JSON_CHTIME[] PROGMEM = "chtime";
const char S_JSON_MIN_DEAUTHS[] PROGMEM = "minDeauths";
const char S_JSON_SSID[] PROGMEM = "ssid";
const char S_JSON_PASSWORD[] PROGMEM = "password";
const char S_JSON_HIDDEN[] PROGMEM = "hidden";
const char S_JSON_IP[] PROGMEM = "ip";
const char S_JSON_WEBINTERFACE[] PROGMEM = "webinterface";
const char S_JSON_CAPTIVEPORTAL[] PROGMEM = "captivePortal";
const char S_JSON_WEB_SPIFFS[] PROGMEM = "webSpiffs";
const char S_JSON_LANG[] PROGMEM = "lang";
const char S_JSON_SERIALINTERFACE[] PROGMEM = "serial";
const char S_JSON_SERIAL_ECHO[] PROGMEM = "serialEcho";
const char S_JSON_LEDENABLED[] PROGMEM = "led";
const char S_JSON_DISPLAYINTERFACE[] PROGMEM = "display";
const char S_JSON_DISPLAY_TIMEOUT[] PROGMEM = "displayTimeout";
// ============
const char S_OK[] PROGMEM = "OK";
const char S_INVALID_HASH[] PROGMEM = "Invalid Hash - reseted to default";
const char S_SETTINGS[] PROGMEM = "settings";
const char S_FORCEPACKETS[] PROGMEM = "forcepackets";
const char S_AUTOSAVETIME[] PROGMEM = "autosavetime";
const char S_VERSION[] PROGMEM = "version";
const char S_MAC[] PROGMEM = "mac";
const char S_SETTINGS_LOADED[] PROGMEM = "Loading settings...";
const char S_SETTINGS_RESETED[] PROGMEM = "Settings reseted";
const char S_SETTINGS_SAVED[] PROGMEM = "Settings saved in ";
const char S_SETTINGS_HEADER[] PROGMEM = "[========== Settings ==========]";
const char S_ERROR_VERSION[] PROGMEM = "Sorry, you can't change the version number";
const char S_ERROR_NOT_FOUND[] PROGMEM = "ERROR: No setting found for ";
const char S_CHANGED_SETTING[] PROGMEM = "Changed setting ";
const char S_CHANNEL_CHANGE[] PROGMEM = "Switched to Channel ";
const char S_CHANNEL_ERROR[] PROGMEM = "ERROR: Channel must be between 1 and 14";
const char S_ERROR_SSID_LEN[] PROGMEM = "ERROR: SSID must be between 1 and 32 characters";
const char S_ERROR_PASSWORD_LEN[] PROGMEM = "ERROR: Password must be between 8 and 32 characters";
const char S_RANDOM[] PROGMEM = "random";
// ===== VERSION ===== //
typedef struct version_t {
uint8_t major = DEAUTHER_VERSION_MAJOR;
@ -32,6 +94,12 @@ typedef struct version_t {
uint8_t revision = DEAUTHER_VERSION_REVISION;
} version_t;
// ===== AUTOSAVE ===== //
typedef struct autosave_settings_t {
bool enabled = AUTOSAVE_ENABLED;
uint32_t time = AUTOSAVE_TIME;
} autosave_t;
// ===== ATTACK ===== //
typedef enum beacon_interval_t {
INTERVAL_1S = 0,
@ -104,6 +172,7 @@ typedef struct display_settings_t {
// ===== SETTINGS ===== //
typedef struct settings_t {
version_t version;
autosave_settings_t autosave;
attack_settings_t attack;
wifi_settings_t wifi;
sniffer_settings_t sniffer;
@ -112,9 +181,6 @@ typedef struct settings_t {
cli_settings_t cli;
led_settings_t led;
display_settings_t display;
bool autosave;
uint32_t autosave_time;
} settings_t;
// ===== CHECK SUM / HASH ====== //
@ -139,65 +205,29 @@ class Settings {
void reset();
void print();
void set(const char* str, String value);
String get(const char* str);
// void set(const char* str, String value);
// String get(const char* str);
String getVersion();
uint16_t getDeauthsPerTarget();
uint8_t getDeauthReason();
bool getBeaconChannel();
bool getAutosave();
uint32_t getAutosaveTime();
bool getBeaconInterval();
uint8_t getChannel();
String getSSID();
String getPassword();
bool getCLI();
bool getDisplayInterface();
bool getWebInterface();
uint16_t getChTime();
uint8_t* getMacSt();
uint8_t* getMacAP();
bool getRandomTX();
uint32_t getAttackTimeout();
bool getLedEnabled();
uint8_t getProbesPerSSID();
bool getHidden();
bool getCaptivePortal();
uint16_t getMinDeauths();
uint32_t getDisplayTimeout();
String getLang();
bool getSerialEcho();
bool getWebSpiffs();
const version_t& getVersion();
const autosave_settings_t& getAutosaveSettings();
const attack_settings_t & getAttackSettings();
const wifi_settings_t & getWifiSettings();
const sniffer_settings_t & getSnifferSettings();
const access_point_settings_t& getAccessPointSettings();
const web_settings_t& getWebSettings();
const cli_settings_t& getCLISettings();
const led_settings_t& getLEDSettings();
const display_settings_t& getDisplaySettings();
void setDeauthsPerTarget(uint8_t deauthsPerTarget);
void setDeauthReason(uint8_t deauthReason);
void setBeaconChannel(bool beaconChannel);
void setAutosave(bool autosave);
void setAutosaveTime(uint32_t autosaveTime);
void setBeaconInterval(bool beaconInterval);
void setChannel(uint8_t channel);
void setSSID(String ssid);
void setPassword(String password);
void setCLI(bool cli);
void setDisplayInterface(bool displayInterface);
void setWebInterface(bool webInterface);
void setChTime(uint16_t chTime);
void setMacSt(String macStr);
bool setMacSt(uint8_t* macSt);
void setMacAP(String macStr);
bool setMacAP(uint8_t* macAP);
void setRandomTX(bool randomTX);
void setAttackTimeout(uint32_t attackTimeout);
void setLedEnabled(bool ledEnabled);
void setProbesPerSSID(uint8_t probesPerSSID);
void setHidden(bool hidden);
void setCaptivePortal(bool captivePortal);
void setMinDeauths(uint16_t minDeauths);
void setDisplayTimeout(uint32_t displayTimeout);
void setLang(String lang);
void setSerialEcho(bool serialEcho);
void setWebSpiffs(bool webSpiffs);
void setAutosaveSettings(const autosave_settings_t& autosave);
void setAttackSettings(const attack_settings_t& attack);
void setWifiSettings(const wifi_settings_t& wifi);
void setSnifferSettings(const sniffer_settings_t& sniffer);
void setAccessPointSettings(const access_point_settings_t& ap);
void setWebSettings(const web_settings_t& web);
void setCLISettings(const cli_settings_t& cli);
void setLEDSettings(const led_settings_t& led);
void setDisplaySettings(const display_settings_t& display);
};
#endif // ifndef Settings_h

View File

@ -84,10 +84,16 @@ void setup() {
currentTime = millis();
// load settings
#ifndef RESET_SETTINGS
settings.load();
#else // ifndef RESET_SETTINGS
settings.reset();
settings.save();
#endif // ifndef RESET_SETTINGS
// set mac for access point
wifi_set_macaddr(SOFTAP_IF, settings.getMacAP());
// set mac address
wifi_set_macaddr(STATION_IF, (uint8_t*)settings.getWifiSettings().mac_st);
wifi_set_macaddr(SOFTAP_IF, (uint8_t*)settings.getWifiSettings().mac_ap);
// start WiFi
WiFi.mode(WIFI_OFF);
@ -96,11 +102,8 @@ void setup() {
scan.sniffer(buf, len);
});
// set mac for station
wifi_set_macaddr(STATION_IF, settings.getMacSt());
// start display
if (settings.getDisplayInterface()) {
if (settings.getDisplaySettings().enabled) {
displayUI.setup();
displayUI.mode = displayUI.DISPLAY_MODE::INTRO;
}
@ -117,16 +120,13 @@ void setup() {
scan.setup();
// set channel
setWifiChannel(settings.getChannel());
setWifiChannel(settings.getWifiSettings().channel);
// load Wifi settings: SSID, password,...
#ifdef DEFAULT_SSID
if (settings.getSSID() == "pwned") settings.setSSID(DEFAULT_SSID);
#endif // ifdef DEFAULT_SSID
loadWifiConfigDefaults();
// dis/enable serial command interface
if (settings.getCLI()) {
if (settings.getCLISettings().enabled) {
cli.enable();
} else {
prntln(SETUP_SERIAL_WARNING);
@ -135,13 +135,13 @@ void setup() {
}
// start access point/web interface
if (settings.getWebInterface()) startAP();
if (settings.getWebSettings().enabled) startAP();
// STARTED
prntln(SETUP_STARTED);
// version
prntln(settings.getVersion());
prntln(DEAUTHER_VERSION);
// setup LED
led.setup();
@ -159,7 +159,8 @@ void loop() {
ssids.update(); // run random mode, if enabled
// auto-save
if (settings.getAutosave() && (currentTime - autosaveTime > settings.getAutosaveTime())) {
if (settings.getAutosaveSettings().enabled
&& (currentTime - autosaveTime > settings.getAutosaveSettings().time)) {
autosaveTime = currentTime;
names.save(false);
ssids.save(false);

View File

@ -410,53 +410,6 @@ const char ST_ERROR_ID[] PROGMEM = "ERROR: No station found with ID ";
const char ST_SELECTED_ALL[] PROGMEM = "Selected all stations";
const char ST_DESELECTED_ALL[] PROGMEM = "Deselected all stations";
// ===== SETTINGS ===== //
const char S_OK[] PROGMEM = "OK";
const char S_INVALID_HASH[] PROGMEM = "Invalid Hash - reseted to default";
const char S_SETTINGS[] PROGMEM = "settings";
const char S_BEACONCHANNEL[] PROGMEM = "beaconchannel";
const char S_FORCEPACKETS[] PROGMEM = "forcepackets";
const char S_AUTOSAVE[] PROGMEM = "autosave";
const char S_LANG[] PROGMEM = "lang";
const char S_SERIALINTERFACE[] PROGMEM = "serial";
const char S_DISPLAYINTERFACE[] PROGMEM = "display";
const char S_WEBINTERFACE[] PROGMEM = "web/interface";
const char S_AUTOSAVETIME[] PROGMEM = "autosavetime";
const char S_DEAUTHSPERTARGET[] PROGMEM = "deauthspertarget";
const char S_CHTIME[] PROGMEM = "chtime";
const char S_DEAUTHREASON[] PROGMEM = "deauthReason";
const char S_MACST[] PROGMEM = "macSt";
const char S_MACAP[] PROGMEM = "macAP";
const char S_RANDOMTX[] PROGMEM = "randomTX";
const char S_ATTACKTIMEOUT[] PROGMEM = "attacktimeout";
const char S_LEDENABLED[] PROGMEM = "led/Enabled";
const char S_PROBESPERSSID[] PROGMEM = "probesPerSSID";
const char S_BEACONINTERVAL[] PROGMEM = "beaconInterval";
const char S_VERSION[] PROGMEM = "version";
const char S_CHANNEL[] PROGMEM = "channel";
const char S_CAPTIVEPORTAL[] PROGMEM = "captivePortal";
const char S_HIDDEN[] PROGMEM = "hidden";
const char S_PASSWORD[] PROGMEM = "password";
const char S_SSID[] PROGMEM = "ssid";
const char S_MAC[] PROGMEM = "mac";
const char S_MIN_DEAUTHS[] PROGMEM = "minDeauths";
const char S_DISPLAY_TIMEOUT[] PROGMEM = "displayTimeout";
const char S_SERIAL_ECHO[] PROGMEM = "serialEcho";
const char S_WEB_SPIFFS[] PROGMEM = "webSpiffs";
const char S_SETTINGS_LOADED[] PROGMEM = "Loading settings...";
const char S_SETTINGS_RESETED[] PROGMEM = "Settings reseted";
const char S_SETTINGS_SAVED[] PROGMEM = "Settings saved in ";
const char S_SETTINGS_HEADER[] PROGMEM = "[========== Settings ==========]";
const char S_ERROR_VERSION[] PROGMEM = "Sorry, you can't change the version number";
const char S_ERROR_NOT_FOUND[] PROGMEM = "ERROR: No setting found for ";
const char S_CHANGED_SETTING[] PROGMEM = "Changed setting ";
const char S_CHANNEL_CHANGE[] PROGMEM = "Switched to Channel ";
const char S_CHANNEL_ERROR[] PROGMEM = "ERROR: Channel must be between 1 and 14";
const char S_ERROR_SSID_LEN[] PROGMEM = "ERROR: SSID must be between 1 and 32 characters";
const char S_ERROR_PASSWORD_LEN[] PROGMEM = "ERROR: Password must be between 8 and 32 characters";
const char S_RANDOM[] PROGMEM = "random";
// ===== ACCESS POINTS ===== //
const char AP_HEADER[] PROGMEM = "[===== Access Points =====]";
const char AP_LIST_EMPTY[] PROGMEM = "AP list is empty :(";

File diff suppressed because one or more lines are too long

View File

@ -1,410 +1,410 @@
#ifndef WifiManager_h
#define WifiManager_h
#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>
extern "C" {
#include "user_interface.h"
}
#define WIFI_MODE_OFF 0
#define WIFI_MODE_AP 1
#define WIFI_MODE_STATION 2
/*
This file contains all necessary functions for hosting and connecting to an access point.
For compatibility and simplicity, all those functions are global.
*/
// Important strings
const char W_DEAUTHER[] PROGMEM = "deauth.me"; // captive portal domain (alternative to 192.168.4.1)
const char W_WEBINTERFACE[] PROGMEM = "/web"; // default folder containing the web files
const char W_ERROR_PASSWORD[] PROGMEM = "ERROR: Password must have at least 8 characters!";
const char W_DEFAULT_LANG[] PROGMEM = "/lang/default.lang";
const char W_HTML[] PROGMEM = "text/html";
const char W_CSS[] PROGMEM = "text/css";
const char W_JS[] PROGMEM = "application/javascript";
const char W_PNG[] PROGMEM = "image/png";
const char W_GIF[] PROGMEM = "image/gif";
const char W_JPG[] PROGMEM = "image/jpeg";
const char W_ICON[] PROGMEM = "image/x-icon";
const char W_XML[] PROGMEM = "text/xml";
const char W_XPDF[] PROGMEM = "application/x-pdf";
const char W_XZIP[] PROGMEM = "application/x-zip";
const char W_GZIP[] PROGMEM = "application/x-gzip";
const char W_JSON[] PROGMEM = "application/json";
const char W_TXT[] PROGMEM = "text/plain";
const char W_DOT_HTM[] PROGMEM = ".htm";
const char W_DOT_HTML[] PROGMEM = ".html";
const char W_DOT_CSS[] PROGMEM = ".css";
const char W_DOT_JS[] PROGMEM = ".js";
const char W_DOT_PNG[] PROGMEM = ".png";
const char W_DOT_GIF[] PROGMEM = ".gif";
const char W_DOT_JPG[] PROGMEM = ".jpg";
const char W_DOT_ICON[] PROGMEM = ".ico";
const char W_DOT_XML[] PROGMEM = ".xml";
const char W_DOT_PDF[] PROGMEM = ".pdf";
const char W_DOT_ZIP[] PROGMEM = ".zip";
const char W_DOT_GZIP[] PROGMEM = ".gz";
const char W_DOT_JSON[] PROGMEM = ".json";
// Server and other global objects
ESP8266WebServer server(80);
DNSServer dnsServer;
IPAddress apIP(192, 168, 4, 1);
IPAddress netMsk(255, 255, 255, 0);
File fsUploadFile;
// current WiFi mode and config
uint8_t wifiMode = WIFI_MODE_OFF;
bool wifi_config_hidden = false;
bool wifi_config_captivePortal = false;
String wifi_config_ssid;
String wifi_config_password;
String wifi_config_path;
void stopAP() {
if (wifiMode == WIFI_MODE_AP) {
wifi_promiscuous_enable(0);
WiFi.persistent(false);
WiFi.disconnect(true);
wifi_set_opmode(STATION_MODE);
prntln(W_STOPPED_AP);
wifiMode = WIFI_MODE_STATION;
}
}
void wifiUpdate() {
if ((wifiMode != WIFI_MODE_OFF) && !scan.isScanning()) {
server.handleClient();
dnsServer.processNextRequest();
}
}
String getWifiMode() {
switch (wifiMode) {
case WIFI_MODE_OFF:
return W_MODE_OFF;
break;
case WIFI_MODE_AP:
return W_MODE_AP;
break;
case WIFI_MODE_STATION:
return W_MODE_ST;
break;
default:
return String();
}
}
String getContentType(String filename) {
if (server.hasArg("download")) return String(F("application/octet-stream"));
else if (filename.endsWith(str(W_DOT_GZIP))) filename = filename.substring(0, filename.length() - 3);
else if (filename.endsWith(str(W_DOT_HTM))) return str(W_HTML);
else if (filename.endsWith(str(W_DOT_HTML))) return str(W_HTML);
else if (filename.endsWith(str(W_DOT_CSS))) return str(W_CSS);
else if (filename.endsWith(str(W_DOT_JS))) return str(W_JS);
else if (filename.endsWith(str(W_DOT_PNG))) return str(W_PNG);
else if (filename.endsWith(str(W_DOT_GIF))) return str(W_GIF);
else if (filename.endsWith(str(W_DOT_JPG))) return str(W_JPG);
else if (filename.endsWith(str(W_DOT_ICON))) return str(W_ICON);
else if (filename.endsWith(str(W_DOT_XML))) return str(W_XML);
else if (filename.endsWith(str(W_DOT_PDF))) return str(W_XPDF);
else if (filename.endsWith(str(W_DOT_ZIP))) return str(W_XZIP);
else if (filename.endsWith(str(W_DOT_JSON))) return str(W_JSON);
else return str(W_TXT);
}
bool handleFileRead(String path) {
//prnt(W_AP_REQUEST);
//prnt(path);
if (!path.charAt(0) == SLASH) path = String(SLASH) + path;
if (path.charAt(path.length() - 1) == SLASH) path += String(F("index.html"));
String contentType = getContentType(path);
if (!SPIFFS.exists(path)) {
if (SPIFFS.exists(path + str(W_DOT_GZIP))) path += str(W_DOT_GZIP);
else if (SPIFFS.exists(wifi_config_path + path)) path = wifi_config_path + path;
else if (SPIFFS.exists(wifi_config_path + path + str(W_DOT_GZIP))) path = wifi_config_path + path + str(
W_DOT_GZIP);
else {
// prntln(W_NOT_FOUND);
return false;
}
}
File file = SPIFFS.open(path, "r");
server.streamFile(file, contentType);
file.close();
//prnt(SPACE);
//prntln(W_OK);
return true;
}
void handleFileList() {
if (!server.hasArg("dir")) {
server.send(500, str(W_TXT), str(W_BAD_ARGS));
return;
}
String path = server.arg("dir");
// Serial.println("handleFileList: " + path);
Dir dir = SPIFFS.openDir(path);
String output = String(OPEN_BRACKET); // {
File entry;
bool first = true;
while (dir.next()) {
entry = dir.openFile("r");
if (first) first = false;
else output += COMMA; // ,
output += OPEN_BRACKET; // [
output += String(DOUBLEQUOTES) + entry.name() + String(DOUBLEQUOTES); // "filename"
output += CLOSE_BRACKET; // ]
entry.close();
}
output += CLOSE_BRACKET;
server.send(200, str(W_JSON).c_str(), output);
}
void sendProgmem(const char* ptr, size_t size, const char* type) {
server.sendHeader("Content-Encoding", "gzip");
server.sendHeader("Cache-Control", "max-age=86400");
server.send_P(200, str(type).c_str(), ptr, size);
}
// path = folder of web files, ssid = name of network, password = password ("0" => no password), hidden = if the network
// is visible, captivePortal = enable a captive portal
void startAP(String path, String ssid, String password, uint8_t ch, bool hidden, bool captivePortal) {
if (password.length() < 8) {
prntln(W_ERROR_PASSWORD);
return;
}
if (!path.charAt(0) == SLASH) path = String(SLASH) + path;
if (password == String(ZERO)) password = String(NEWLINE);
wifi_config_path = path;
wifi_config_ssid = ssid;
wifi_config_password = password;
setWifiChannel(ch);
wifi_config_hidden = hidden;
wifi_config_captivePortal = captivePortal;
WiFi.softAPConfig(apIP, apIP, netMsk);
WiFi.softAP(ssid.c_str(), password.c_str(), wifi_channel, hidden);
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(53, String(ASTERIX), apIP);
MDNS.begin(str(W_DEAUTHER).c_str());
server.on(String(F("/list")).c_str(), HTTP_GET, handleFileList); // list directory
// ================================================================
// post here the output of the webConverter.py
#ifdef USE_PROGMEM_WEB_FILES
if (!settings.getWebSpiffs()) {
server.on(String(SLASH).c_str(), HTTP_GET, []() {
sendProgmem(indexhtml, sizeof(indexhtml), W_HTML);
});
server.on(String(F("/attack.html")).c_str(), HTTP_GET, []() {
sendProgmem(attackhtml, sizeof(attackhtml), W_HTML);
});
server.on(String(F("/index.html")).c_str(), HTTP_GET, []() {
sendProgmem(indexhtml, sizeof(indexhtml), W_HTML);
});
server.on(String(F("/info.html")).c_str(), HTTP_GET, []() {
sendProgmem(infohtml, sizeof(infohtml), W_HTML);
});
server.on(String(F("/scan.html")).c_str(), HTTP_GET, []() {
sendProgmem(scanhtml, sizeof(scanhtml), W_HTML);
});
server.on(String(F("/settings.html")).c_str(), HTTP_GET, []() {
sendProgmem(settingshtml, sizeof(settingshtml), W_HTML);
});
server.on(String(F("/ssids.html")).c_str(), HTTP_GET, []() {
sendProgmem(ssidshtml, sizeof(ssidshtml), W_HTML);
});
server.on(String(F("/style.css")).c_str(), HTTP_GET, []() {
sendProgmem(stylecss, sizeof(stylecss), W_CSS);
});
server.on(String(F("/js/attack.js")).c_str(), HTTP_GET, []() {
sendProgmem(attackjs, sizeof(attackjs), W_JS);
});
server.on(String(F("/js/scan.js")).c_str(), HTTP_GET, []() {
sendProgmem(scanjs, sizeof(scanjs), W_JS);
});
server.on(String(F("/js/settings.js")).c_str(), HTTP_GET, []() {
sendProgmem(settingsjs, sizeof(settingsjs), W_JS);
});
server.on(String(F("/js/site.js")).c_str(), HTTP_GET, []() {
sendProgmem(sitejs, sizeof(sitejs), W_JS);
});
server.on(String(F("/js/ssids.js")).c_str(), HTTP_GET, []() {
sendProgmem(ssidsjs, sizeof(ssidsjs), W_JS);
});
server.on(String(F("/lang/cn.lang")).c_str(), HTTP_GET, []() {
sendProgmem(cnlang, sizeof(cnlang), W_JSON);
});
server.on(String(F("/lang/cs.lang")).c_str(), HTTP_GET, []() {
sendProgmem(cslang, sizeof(cslang), W_JSON);
});
server.on(String(F("/lang/de.lang")).c_str(), HTTP_GET, []() {
sendProgmem(delang, sizeof(delang), W_JSON);
});
server.on(String(F("/lang/en.lang")).c_str(), HTTP_GET, []() {
sendProgmem(enlang, sizeof(enlang), W_JSON);
});
server.on(String(F("/lang/es.lang")).c_str(), HTTP_GET, []() {
sendProgmem(eslang, sizeof(eslang), W_JSON);
});
server.on(String(F("/lang/fi.lang")).c_str(), HTTP_GET, []() {
sendProgmem(filang, sizeof(filang), W_JSON);
});
server.on(String(F("/lang/fr.lang")).c_str(), HTTP_GET, []() {
sendProgmem(frlang, sizeof(frlang), W_JSON);
});
server.on(String(F("/lang/it.lang")).c_str(), HTTP_GET, []() {
sendProgmem(itlang, sizeof(itlang), W_JSON);
});
server.on(String(F("/lang/ru.lang")).c_str(), HTTP_GET, []() {
sendProgmem(rulang, sizeof(rulang), W_JSON);
});
server.on(String(F("/lang/tlh.lang")).c_str(), HTTP_GET, []() {
sendProgmem(tlhlang, sizeof(tlhlang), W_JSON);
});
}
server.on(str(W_DEFAULT_LANG).c_str(), HTTP_GET, []() {
if (!settings.getWebSpiffs()) {
if (settings.getLang() == String(F("cn"))) sendProgmem(cnlang, sizeof(cnlang), W_JSON);
else if (settings.getLang() == String(F("cs"))) sendProgmem(cslang, sizeof(cslang), W_JSON);
else if (settings.getLang() == String(F("de"))) sendProgmem(delang, sizeof(delang), W_JSON);
else if (settings.getLang() == String(F("en"))) sendProgmem(enlang, sizeof(enlang), W_JSON);
else if (settings.getLang() == String(F("es"))) sendProgmem(eslang, sizeof(eslang), W_JSON);
else if (settings.getLang() == String(F("fi"))) sendProgmem(filang, sizeof(filang), W_JSON);
else if (settings.getLang() == String(F("fr"))) sendProgmem(frlang, sizeof(frlang), W_JSON);
else if (settings.getLang() == String(F("it"))) sendProgmem(itlang, sizeof(itlang), W_JSON);
else if (settings.getLang() == String(F("ru"))) sendProgmem(rulang, sizeof(rulang), W_JSON);
else if (settings.getLang() == String(F("tlh"))) sendProgmem(tlhlang, sizeof(tlhlang), W_JSON);
else handleFileRead(String(F("/web/lang/")) + settings.getLang() + String(F(".lang")));
} else {
handleFileRead(String(F("/web/lang/")) + settings.getLang() + String(F(".lang")));
}
});
#endif
// ================================================================
server.on(String(F("/run")).c_str(), HTTP_GET, []() {
server.send(200, str(W_TXT), str(W_OK).c_str());
String input = server.arg("cmd");
cli.exec(input);
});
server.on(String(F("/attack.json")).c_str(), HTTP_GET, []() {
server.send(200, str(W_JSON), attack.getStatusJSON());
});
// aggressively caching static assets
server.serveStatic("/js", SPIFFS, String(wifi_config_path + "/js").c_str(), "max-age=86400");
// called when the url is not defined here
// use it to load content from SPIFFS
server.onNotFound([]() {
if (!handleFileRead(server.uri())) {
server.send(404, str(W_TXT), str(W_FILE_NOT_FOUND));
}
});
server.begin();
wifiMode = WIFI_MODE_AP;
prntln(W_STARTED_AP);
printWifiStatus();
}
void printWifiStatus() {
prnt(String(F("[WiFi] Path: '")));
prnt(wifi_config_path);
prnt(String(F("', Mode: '")));
switch (wifiMode) {
case WIFI_MODE_OFF:
prnt(W_MODE_OFF);
break;
case WIFI_MODE_AP:
prnt(W_AP);
break;
case WIFI_MODE_STATION:
prnt(W_STATION);
break;
}
prnt(String(F("', SSID: '")));
prnt(wifi_config_ssid);
prnt(String(F("', password: '")));
prnt(wifi_config_password);
prnt(String(F("', channel: '")));
prnt(wifi_channel);
prnt(String(F("', hidden: ")));
prnt(b2s(wifi_config_hidden));
prnt(String(F(", captive-portal: ")));
prntln(b2s(wifi_config_captivePortal));
}
void startAP() {
startAP(wifi_config_path.c_str(), wifi_config_ssid.c_str(),
wifi_config_password.c_str(), wifi_channel, wifi_config_hidden, wifi_config_captivePortal);
}
void startAP(String path) {
wifi_config_path = path;
startAP();
}
void loadWifiConfigDefaults() {
wifi_config_hidden = settings.getHidden();
wifi_config_ssid = settings.getSSID();
wifi_config_password = settings.getPassword();
wifi_config_captivePortal = settings.getCaptivePortal();
wifi_config_path = str(W_WEBINTERFACE);
}
void resumeAP() {
if (wifiMode != WIFI_MODE_AP) {
wifiMode = WIFI_MODE_AP;
wifi_promiscuous_enable(0);
WiFi.softAPConfig(apIP, apIP, netMsk);
WiFi.softAP(wifi_config_ssid.c_str(), wifi_config_password.c_str(), wifi_channel, wifi_config_hidden);
prntln(W_STARTED_AP);
}
}
#endif // ifndef WifiManager_h
#ifndef WifiManager_h
#define WifiManager_h
#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>
extern "C" {
#include "user_interface.h"
}
#define WIFI_MODE_OFF 0
#define WIFI_MODE_AP 1
#define WIFI_MODE_STATION 2
/*
This file contains all necessary functions for hosting and connecting to an access point.
For compatibility and simplicity, all those functions are global.
*/
// Important strings
const char W_DEAUTHER[] PROGMEM = "deauth.me"; // captive portal domain (alternative to 192.168.4.1)
const char W_WEBINTERFACE[] PROGMEM = "/web"; // default folder containing the web files
const char W_ERROR_PASSWORD[] PROGMEM = "ERROR: Password must have at least 8 characters!";
const char W_DEFAULT_LANG[] PROGMEM = "/lang/default.lang";
const char W_HTML[] PROGMEM = "text/html";
const char W_CSS[] PROGMEM = "text/css";
const char W_JS[] PROGMEM = "application/javascript";
const char W_PNG[] PROGMEM = "image/png";
const char W_GIF[] PROGMEM = "image/gif";
const char W_JPG[] PROGMEM = "image/jpeg";
const char W_ICON[] PROGMEM = "image/x-icon";
const char W_XML[] PROGMEM = "text/xml";
const char W_XPDF[] PROGMEM = "application/x-pdf";
const char W_XZIP[] PROGMEM = "application/x-zip";
const char W_GZIP[] PROGMEM = "application/x-gzip";
const char W_JSON[] PROGMEM = "application/json";
const char W_TXT[] PROGMEM = "text/plain";
const char W_DOT_HTM[] PROGMEM = ".htm";
const char W_DOT_HTML[] PROGMEM = ".html";
const char W_DOT_CSS[] PROGMEM = ".css";
const char W_DOT_JS[] PROGMEM = ".js";
const char W_DOT_PNG[] PROGMEM = ".png";
const char W_DOT_GIF[] PROGMEM = ".gif";
const char W_DOT_JPG[] PROGMEM = ".jpg";
const char W_DOT_ICON[] PROGMEM = ".ico";
const char W_DOT_XML[] PROGMEM = ".xml";
const char W_DOT_PDF[] PROGMEM = ".pdf";
const char W_DOT_ZIP[] PROGMEM = ".zip";
const char W_DOT_GZIP[] PROGMEM = ".gz";
const char W_DOT_JSON[] PROGMEM = ".json";
// Server and other global objects
ESP8266WebServer server(80);
DNSServer dnsServer;
IPAddress apIP(192, 168, 4, 1);
IPAddress netMsk(255, 255, 255, 0);
File fsUploadFile;
// current WiFi mode and config
uint8_t wifiMode = WIFI_MODE_OFF;
bool wifi_config_hidden = false;
bool wifi_config_captivePortal = false;
String wifi_config_ssid;
String wifi_config_password;
String wifi_config_path;
void stopAP() {
if (wifiMode == WIFI_MODE_AP) {
wifi_promiscuous_enable(0);
WiFi.persistent(false);
WiFi.disconnect(true);
wifi_set_opmode(STATION_MODE);
prntln(W_STOPPED_AP);
wifiMode = WIFI_MODE_STATION;
}
}
void wifiUpdate() {
if ((wifiMode != WIFI_MODE_OFF) && !scan.isScanning()) {
server.handleClient();
dnsServer.processNextRequest();
}
}
String getWifiMode() {
switch (wifiMode) {
case WIFI_MODE_OFF:
return W_MODE_OFF;
break;
case WIFI_MODE_AP:
return W_MODE_AP;
break;
case WIFI_MODE_STATION:
return W_MODE_ST;
break;
default:
return String();
}
}
String getContentType(String filename) {
if (server.hasArg("download")) return String(F("application/octet-stream"));
else if (filename.endsWith(str(W_DOT_GZIP))) filename = filename.substring(0, filename.length() - 3);
else if (filename.endsWith(str(W_DOT_HTM))) return str(W_HTML);
else if (filename.endsWith(str(W_DOT_HTML))) return str(W_HTML);
else if (filename.endsWith(str(W_DOT_CSS))) return str(W_CSS);
else if (filename.endsWith(str(W_DOT_JS))) return str(W_JS);
else if (filename.endsWith(str(W_DOT_PNG))) return str(W_PNG);
else if (filename.endsWith(str(W_DOT_GIF))) return str(W_GIF);
else if (filename.endsWith(str(W_DOT_JPG))) return str(W_JPG);
else if (filename.endsWith(str(W_DOT_ICON))) return str(W_ICON);
else if (filename.endsWith(str(W_DOT_XML))) return str(W_XML);
else if (filename.endsWith(str(W_DOT_PDF))) return str(W_XPDF);
else if (filename.endsWith(str(W_DOT_ZIP))) return str(W_XZIP);
else if (filename.endsWith(str(W_DOT_JSON))) return str(W_JSON);
else return str(W_TXT);
}
bool handleFileRead(String path) {
// prnt(W_AP_REQUEST);
// prnt(path);
if (!path.charAt(0) == SLASH) path = String(SLASH) + path;
if (path.charAt(path.length() - 1) == SLASH) path += String(F("index.html"));
String contentType = getContentType(path);
if (!SPIFFS.exists(path)) {
if (SPIFFS.exists(path + str(W_DOT_GZIP))) path += str(W_DOT_GZIP);
else if (SPIFFS.exists(wifi_config_path + path)) path = wifi_config_path + path;
else if (SPIFFS.exists(wifi_config_path + path + str(W_DOT_GZIP))) path = wifi_config_path + path + str(
W_DOT_GZIP);
else {
// prntln(W_NOT_FOUND);
return false;
}
}
File file = SPIFFS.open(path, "r");
server.streamFile(file, contentType);
file.close();
// prnt(SPACE);
// prntln(W_OK);
return true;
}
void handleFileList() {
if (!server.hasArg("dir")) {
server.send(500, str(W_TXT), str(W_BAD_ARGS));
return;
}
String path = server.arg("dir");
// Serial.println("handleFileList: " + path);
Dir dir = SPIFFS.openDir(path);
String output = String(OPEN_BRACKET); // {
File entry;
bool first = true;
while (dir.next()) {
entry = dir.openFile("r");
if (first) first = false;
else output += COMMA; // ,
output += OPEN_BRACKET; // [
output += String(DOUBLEQUOTES) + entry.name() + String(DOUBLEQUOTES); // "filename"
output += CLOSE_BRACKET; // ]
entry.close();
}
output += CLOSE_BRACKET;
server.send(200, str(W_JSON).c_str(), output);
}
void sendProgmem(const char* ptr, size_t size, const char* type) {
server.sendHeader("Content-Encoding", "gzip");
server.sendHeader("Cache-Control", "max-age=86400");
server.send_P(200, str(type).c_str(), ptr, size);
}
// path = folder of web files, ssid = name of network, password = password ("0" => no password), hidden = if the network
// is visible, captivePortal = enable a captive portal
void startAP(String path, String ssid, String password, uint8_t ch, bool hidden, bool captivePortal) {
if (password.length() < 8) {
prntln(W_ERROR_PASSWORD);
return;
}
if (!path.charAt(0) == SLASH) path = String(SLASH) + path;
if (password == String(ZERO)) password = String(NEWLINE);
wifi_config_path = path;
wifi_config_ssid = ssid;
wifi_config_password = password;
setWifiChannel(ch);
wifi_config_hidden = hidden;
wifi_config_captivePortal = captivePortal;
WiFi.softAPConfig(apIP, apIP, netMsk);
WiFi.softAP(ssid.c_str(), password.c_str(), wifi_channel, hidden);
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(53, String(ASTERIX), apIP);
MDNS.begin(str(W_DEAUTHER).c_str());
server.on(String(F("/list")).c_str(), HTTP_GET, handleFileList); // list directory
// ================================================================
// post here the output of the webConverter.py
#ifdef USE_PROGMEM_WEB_FILES
if (!settings.getWebSettings().use_spiffs) {
server.on(String(SLASH).c_str(), HTTP_GET, [] () {
sendProgmem(indexhtml, sizeof(indexhtml), W_HTML);
});
server.on(String(F("/attack.html")).c_str(), HTTP_GET, [] () {
sendProgmem(attackhtml, sizeof(attackhtml), W_HTML);
});
server.on(String(F("/index.html")).c_str(), HTTP_GET, [] () {
sendProgmem(indexhtml, sizeof(indexhtml), W_HTML);
});
server.on(String(F("/info.html")).c_str(), HTTP_GET, [] () {
sendProgmem(infohtml, sizeof(infohtml), W_HTML);
});
server.on(String(F("/scan.html")).c_str(), HTTP_GET, [] () {
sendProgmem(scanhtml, sizeof(scanhtml), W_HTML);
});
server.on(String(F("/settings.html")).c_str(), HTTP_GET, [] () {
sendProgmem(settingshtml, sizeof(settingshtml), W_HTML);
});
server.on(String(F("/ssids.html")).c_str(), HTTP_GET, [] () {
sendProgmem(ssidshtml, sizeof(ssidshtml), W_HTML);
});
server.on(String(F("/style.css")).c_str(), HTTP_GET, [] () {
sendProgmem(stylecss, sizeof(stylecss), W_CSS);
});
server.on(String(F("/js/attack.js")).c_str(), HTTP_GET, [] () {
sendProgmem(attackjs, sizeof(attackjs), W_JS);
});
server.on(String(F("/js/scan.js")).c_str(), HTTP_GET, [] () {
sendProgmem(scanjs, sizeof(scanjs), W_JS);
});
server.on(String(F("/js/settings.js")).c_str(), HTTP_GET, [] () {
sendProgmem(settingsjs, sizeof(settingsjs), W_JS);
});
server.on(String(F("/js/site.js")).c_str(), HTTP_GET, [] () {
sendProgmem(sitejs, sizeof(sitejs), W_JS);
});
server.on(String(F("/js/ssids.js")).c_str(), HTTP_GET, [] () {
sendProgmem(ssidsjs, sizeof(ssidsjs), W_JS);
});
server.on(String(F("/lang/cn.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(cnlang, sizeof(cnlang), W_JSON);
});
server.on(String(F("/lang/cs.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(cslang, sizeof(cslang), W_JSON);
});
server.on(String(F("/lang/de.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(delang, sizeof(delang), W_JSON);
});
server.on(String(F("/lang/en.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(enlang, sizeof(enlang), W_JSON);
});
server.on(String(F("/lang/es.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(eslang, sizeof(eslang), W_JSON);
});
server.on(String(F("/lang/fi.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(filang, sizeof(filang), W_JSON);
});
server.on(String(F("/lang/fr.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(frlang, sizeof(frlang), W_JSON);
});
server.on(String(F("/lang/it.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(itlang, sizeof(itlang), W_JSON);
});
server.on(String(F("/lang/ru.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(rulang, sizeof(rulang), W_JSON);
});
server.on(String(F("/lang/tlh.lang")).c_str(), HTTP_GET, [] () {
sendProgmem(tlhlang, sizeof(tlhlang), W_JSON);
});
}
server.on(str(W_DEFAULT_LANG).c_str(), HTTP_GET, [] () {
if (!settings.getWebSettings().use_spiffs) {
if (String(settings.getWebSettings().lang) == String(F("cn"))) sendProgmem(cnlang, sizeof(cnlang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("cs"))) sendProgmem(cslang, sizeof(cslang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("de"))) sendProgmem(delang, sizeof(delang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("en"))) sendProgmem(enlang, sizeof(enlang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("es"))) sendProgmem(eslang, sizeof(eslang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("fi"))) sendProgmem(filang, sizeof(filang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("fr"))) sendProgmem(frlang, sizeof(frlang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("it"))) sendProgmem(itlang, sizeof(itlang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("ru"))) sendProgmem(rulang, sizeof(rulang), W_JSON);
else if (String(settings.getWebSettings().lang) == String(F("tlh"))) sendProgmem(tlhlang, sizeof(tlhlang), W_JSON);
else handleFileRead(String(F("/web/lang/")) + String(settings.getWebSettings().lang) + String(F(".lang")));
} else {
handleFileRead(String(F("/web/lang/")) + String(settings.getWebSettings().lang) + String(F(".lang")));
}
});
#endif /* ifdef USE_PROGMEM_WEB_FILES */
// ================================================================
server.on(String(F("/run")).c_str(), HTTP_GET, [] () {
server.send(200, str(W_TXT), str(W_OK).c_str());
String input = server.arg("cmd");
cli.exec(input);
});
server.on(String(F("/attack.json")).c_str(), HTTP_GET, [] () {
server.send(200, str(W_JSON), attack.getStatusJSON());
});
// aggressively caching static assets
server.serveStatic("/js", SPIFFS, String(wifi_config_path + "/js").c_str(), "max-age=86400");
// called when the url is not defined here
// use it to load content from SPIFFS
server.onNotFound([] () {
if (!handleFileRead(server.uri())) {
server.send(404, str(W_TXT), str(W_FILE_NOT_FOUND));
}
});
server.begin();
wifiMode = WIFI_MODE_AP;
prntln(W_STARTED_AP);
printWifiStatus();
}
void printWifiStatus() {
prnt(String(F("[WiFi] Path: '")));
prnt(wifi_config_path);
prnt(String(F("', Mode: '")));
switch (wifiMode) {
case WIFI_MODE_OFF:
prnt(W_MODE_OFF);
break;
case WIFI_MODE_AP:
prnt(W_AP);
break;
case WIFI_MODE_STATION:
prnt(W_STATION);
break;
}
prnt(String(F("', SSID: '")));
prnt(wifi_config_ssid);
prnt(String(F("', password: '")));
prnt(wifi_config_password);
prnt(String(F("', channel: '")));
prnt(wifi_channel);
prnt(String(F("', hidden: ")));
prnt(b2s(wifi_config_hidden));
prnt(String(F(", captive-portal: ")));
prntln(b2s(wifi_config_captivePortal));
}
void startAP() {
startAP(wifi_config_path.c_str(), wifi_config_ssid.c_str(),
wifi_config_password.c_str(), wifi_channel, wifi_config_hidden, wifi_config_captivePortal);
}
void startAP(String path) {
wifi_config_path = path;
startAP();
}
void loadWifiConfigDefaults() {
wifi_config_hidden = settings.getAccessPointSettings().hidden;
wifi_config_ssid = settings.getAccessPointSettings().ssid;
wifi_config_password = settings.getAccessPointSettings().password;
wifi_config_captivePortal = settings.getWebSettings().captive_portal;
wifi_config_path = str(W_WEBINTERFACE);
}
void resumeAP() {
if (wifiMode != WIFI_MODE_AP) {
wifiMode = WIFI_MODE_AP;
wifi_promiscuous_enable(0);
WiFi.softAPConfig(apIP, apIP, netMsk);
WiFi.softAP(wifi_config_ssid.c_str(), wifi_config_password.c_str(), wifi_channel, wifi_config_hidden);
prntln(W_STARTED_AP);
}
}
#endif // ifndef WifiManager_h