mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #291 from DrDoof/fix/webui-login-cookies
httpd: fix browser login (cookie parsed by name, Connection: close, self-contained login page)
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
<h1 data-i18n="login_heading"> RTL Switch Login</h1>
|
<h1 data-i18n="login_heading"> RTL Switch Login</h1>
|
||||||
<form method="post" action="login">
|
<form method="post" action="login">
|
||||||
<div class="txt_field">
|
<div class="txt_field">
|
||||||
<input name="pwd" type="password" onclick="removeNote()" required />
|
<input name="pwd" type="password" autocomplete="current-password" onclick="removeNote()" required />
|
||||||
<span></span>
|
<span></span>
|
||||||
<label data-i18n="login_password">Password</label>
|
<label data-i18n="login_password">Password</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+30
-11
@@ -174,7 +174,8 @@ bool is_word_x(__xdata uint8_t *lhs_str_p, __xdata uint8_t *rhs_str_p)
|
|||||||
c = *rhs_str_p++;
|
c = *rhs_str_p++;
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
/* ';' separates cookies in a Cookie header, so it ends a value too. */
|
||||||
|
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r' && u != ';')
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -204,28 +205,28 @@ uint8_t parse_short(__xdata uint8_t *p)
|
|||||||
|
|
||||||
void send_not_found(void)
|
void send_not_found(void)
|
||||||
{
|
{
|
||||||
slen = strtox(outbuf, "HTTP/1.1 404 Not found\r\nContent-Type: text/html\r\n\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 404 Not found\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n" \
|
||||||
"<!DOCTYPE HTML PUBLIC>\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n");
|
"<!DOCTYPE HTML PUBLIC>\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_bad_request(void)
|
void send_bad_request(void)
|
||||||
{
|
{
|
||||||
slen = strtox(outbuf, "HTTP/1.1 400 Bad Request\r\nContent-Type: text/html\r\n\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n" \
|
||||||
"<!DOCTYPE HTML PUBLIC>\n<title>400 Bad Request</title>\n<h1>Bad Request</h1>\n");
|
"<!DOCTYPE HTML PUBLIC>\n<title>400 Bad Request</title>\n<h1>Bad Request</h1>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_to_login(void)
|
void send_to_login(void)
|
||||||
{
|
{
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\n" \
|
||||||
"Location: login.html\r\n\r\n");
|
"Location: login.html\r\n\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_unauthorized(void)
|
void send_unauthorized(void)
|
||||||
{
|
{
|
||||||
slen = strtox(outbuf, "HTTP/1.1 401 Unauthorized\r\n\r\n");
|
slen = strtox(outbuf, "HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -252,8 +253,20 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p)
|
|||||||
break;
|
break;
|
||||||
if (is_word(p, "\nContent-Type:"))
|
if (is_word(p, "\nContent-Type:"))
|
||||||
content_type = p + 15;
|
content_type = p + 15;
|
||||||
else if (is_word(p, "\nCookie:"))
|
else if (is_word(p, "\nCookie:")) {
|
||||||
session = p + 17;
|
/* Scan for the "session" key: the header may hold several
|
||||||
|
* cookies in any order. Match "session" not "session=" -
|
||||||
|
* is_word() requires a separator after the match and '=' is
|
||||||
|
* one, so this also rejects a longer key like "sessionx". */
|
||||||
|
__xdata uint8_t *c = p + 8; /* past "\nCookie:" */
|
||||||
|
while (*c && *c != '\r' && *c != '\n') {
|
||||||
|
if (is_word(c, "session")) {
|
||||||
|
session = c + 8; /* past "session=" */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
||||||
dbg_string("\nFound multipart\n");
|
dbg_string("\nFound multipart\n");
|
||||||
@@ -469,14 +482,14 @@ void handle_post(void)
|
|||||||
read_reg_timer(&last_session_use);
|
read_reg_timer(&last_session_use);
|
||||||
gen_random_bytes(session_id, SESSION_ID_LENGTH);
|
gen_random_bytes(session_id, SESSION_ID_LENGTH);
|
||||||
session_id[SESSION_ID_LENGTH] = '\0';
|
session_id[SESSION_ID_LENGTH] = '\0';
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: index.html\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
|
||||||
"Set-Cookie: session=");
|
"Set-Cookie: session=");
|
||||||
for (register uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
|
for (register uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
|
||||||
outbuf[slen++] = session_id[i];
|
outbuf[slen++] = session_id[i];
|
||||||
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
dbg_string("Password invalid!\n");
|
dbg_string("Password invalid!\n");
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: login.html\r\n\r\n");
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: login.html\r\n\r\n");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
|
} else if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
|
||||||
@@ -521,7 +534,7 @@ void handle_post(void)
|
|||||||
send_not_found();
|
send_not_found();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\n\r\n");
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n");
|
||||||
return;
|
return;
|
||||||
bad_request:
|
bad_request:
|
||||||
send_bad_request();
|
send_bad_request();
|
||||||
@@ -699,7 +712,13 @@ void httpd_appcall(void)
|
|||||||
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
||||||
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
||||||
slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\nContent-Security-Policy: style-src 'self' 'unsafe-inline'\r\n\r\n");
|
/* 'unsafe-inline' is needed for the inline onclick handlers
|
||||||
|
* and the inline <script> on login.html. Connection: close is
|
||||||
|
* required because this httpd closes the connection after every
|
||||||
|
* response; without advertising it a browser reuses the socket
|
||||||
|
* from its keep-alive pool and the next request hits the already
|
||||||
|
* closed connection (a POST is then dropped without a retry). */
|
||||||
|
slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nConnection: close\r\nAccess-Control-Allow-Origin: *\r\nContent-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; form-action 'self'\r\n\r\n");
|
||||||
|
|
||||||
len_left = f_data[entry].len;
|
len_left = f_data[entry].len;
|
||||||
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ extern __xdata char sfp_module_model[2][17];
|
|||||||
extern __xdata char sfp_module_serial[2][17];
|
extern __xdata char sfp_module_serial[2][17];
|
||||||
extern __xdata uint8_t sfp_options[2];
|
extern __xdata uint8_t sfp_options[2];
|
||||||
|
|
||||||
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
|
||||||
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
||||||
|
|
||||||
// Convert uint8_t to ascii HEX char push on html-buffer.
|
// Convert uint8_t to ascii HEX char push on html-buffer.
|
||||||
|
|||||||
Reference in New Issue
Block a user