|
@@ -33,7 +33,9 @@
|
|
|
#include "log.h"
|
|
|
#include "hal.h"
|
|
|
#include "sntp_api.h"
|
|
|
-
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+#include "radius_user.h"
|
|
|
+#endif
|
|
|
#ifdef PRINTF_STDLIB
|
|
|
#include <stdio.h>
|
|
|
#endif
|
|
@@ -148,10 +150,25 @@ const char HTTP_200_OK[] = "HTTP/1.1 200 OK\r\n\r\n";
|
|
|
|
|
|
const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF, 0x00};
|
|
|
|
|
|
+const char REFRESH_LOGIN_PAGE[] = "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/login.html\"/></head></html>\r\n";
|
|
|
+const char REFRESH_RS_LOGIN_PAGE[] = "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/rslogin.html\"/></head></html>\r\n";
|
|
|
+
|
|
|
unsigned long log_ptr = 0;
|
|
|
unsigned long log_size = 0;
|
|
|
bool fLogTransInprog = false;
|
|
|
-
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+void auth_task(void *pvParameters);
|
|
|
+static bool fl_raddius_net_err = false;
|
|
|
+typedef enum
|
|
|
+{
|
|
|
+ RS_AUTH_READY = 0,
|
|
|
+ RS_AUTH_PROCESS,
|
|
|
+ RS_AUTH_FINISH,
|
|
|
+ MAX_RS_AUTH_STATE
|
|
|
+} rs_auth_state_t;
|
|
|
+static uint8_t auth_flag = RS_AUTH_READY;
|
|
|
+static char sendAuthBuf[300];
|
|
|
+#endif
|
|
|
|
|
|
* @brief Общая структура настроек
|
|
|
*/
|
|
@@ -364,8 +381,12 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t er
|
|
|
#ifdef HTTP_AUTH_ENABLE
|
|
|
if (h->accsess == TIME_ACCESS && !Authenticated) {
|
|
|
strcpy(sendBuf, HTTP_401_NO_AUTH);
|
|
|
- strcat(sendBuf,
|
|
|
- "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/login.html\"/></head></html>\r\n");
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ strcat(sendBuf, REFRESH_RS_LOGIN_PAGE);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ strcat(sendBuf, REFRESH_LOGIN_PAGE);
|
|
|
sendBufLoadLen = strlen(sendBuf);
|
|
|
hs->file = sendBuf;
|
|
|
hs->left = sendBufLoadLen;
|
|
@@ -711,7 +732,9 @@ void HTTP_Init()
|
|
|
{
|
|
|
err_t err;
|
|
|
struct tcp_pcb *pcb;
|
|
|
-
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ xTaskCreate(auth_task, "auth_task", 4 * configMINIMAL_STACK_SIZE, NULL, ( configMAX_PRIORITIES - 3), NULL);
|
|
|
+#endif
|
|
|
|
|
|
pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
|
|
|
LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL);
|
|
@@ -1216,8 +1239,26 @@ char *HTTP_GetRequest(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBu
|
|
|
if (strcmp(filename, html_page_name[i]) == 0) {
|
|
|
break;
|
|
|
}
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if (strcmp(filename, "/check_auth.html") == 0 && auth_flag != RS_AUTH_READY ) {
|
|
|
+ if (auth_flag == RS_AUTH_FINISH){
|
|
|
+ auth_flag = RS_AUTH_READY;
|
|
|
+ } else {
|
|
|
+ strcpy(sendAuthBuf, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
|
|
|
+ strcat(sendAuthBuf,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>Ожидание соединения с RADIUS сервером</h2></center></html>");
|
|
|
+ }
|
|
|
+ sendBufLoadLen = strlen(sendAuthBuf);
|
|
|
+ return sendAuthBuf;
|
|
|
+ }
|
|
|
+#endif
|
|
|
if (i == 3) {
|
|
|
- strcpy(filename, "/login.html");
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ strcpy(filename, "/rslogin.html");
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ strcpy(filename, "/login.html");
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
@@ -1248,8 +1289,12 @@ char *HTTP_NoFound(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn
|
|
|
return file.data;
|
|
|
} else {
|
|
|
strcpy(bufOut, HTTP_401_NO_AUTH);
|
|
|
- strcat(bufOut,
|
|
|
- "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/login.html\"/></head></html>\r\n");
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ strcat(bufOut, REFRESH_RS_LOGIN_PAGE);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ strcat(bufOut, REFRESH_LOGIN_PAGE);
|
|
|
*lenBufOut = strlen(bufOut);
|
|
|
return bufOut;
|
|
|
}
|
|
@@ -1461,11 +1506,139 @@ void LoginTimerCallback(TimerHandle_t pxTimer)
|
|
|
xTimerStop(RepeatLoginTimer, 0);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+void auth_task(void *pvParameters)
|
|
|
+{
|
|
|
+ for(;;){
|
|
|
+ if(auth_flag == RS_AUTH_PROCESS) {
|
|
|
+ HTTP_RADIUSAuthConfirmWebPwd(post_req_data, sendAuthBuf, strlen(post_req_data), &sendBufLoadLen);
|
|
|
+ auth_flag = RS_AUTH_FINISH;
|
|
|
+ }
|
|
|
+ vTaskDelay(40);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * @brief Проверка пароля для входа в Web
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+int HTTP_RADIUSAuthConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
|
|
|
+{
|
|
|
+ char tempStr[52];
|
|
|
+ char login[20];
|
|
|
+ char password[20];
|
|
|
+ char tmp_password[33];
|
|
|
+ uint8_t valueLen, user_id;
|
|
|
+ char *strPtr = 0;
|
|
|
+ char WebPassword[MAX_WEB_PASSWD_LEN];
|
|
|
+ char WebLogin[MAX_WEB_LOGIN_LEN];
|
|
|
+
|
|
|
+ memset(login, 0, 20);
|
|
|
+ memset(password, 0, 20);
|
|
|
+ memset(tmp_password, 0, 33);
|
|
|
+ memset(tempStr, 0, 52);
|
|
|
+
|
|
|
+ memset(name_login, 0, 50);
|
|
|
+
|
|
|
+ tempStr[0] = '0';
|
|
|
+
|
|
|
+ strncat(tempStr, bufIn, 49);
|
|
|
+
|
|
|
+
|
|
|
+ strcat(tempStr, " ");
|
|
|
+ GetParamValue(tempStr, "login", login, &valueLen);
|
|
|
+ GetParamValue(tempStr, "password", tmp_password, &valueLen);
|
|
|
+ url_decode(password, sizeof(password), tmp_password);
|
|
|
+ valueLen = strlen(password);
|
|
|
+
|
|
|
+ switch (RC_Login(login, password)) {
|
|
|
+ case RC_ERROR:
|
|
|
+ Authenticated = false;
|
|
|
+ break;
|
|
|
+ case RC_LOGIN_ADMIN_OK:
|
|
|
+ Authenticated = true;
|
|
|
+ user_id = 0;
|
|
|
+ break;
|
|
|
+ case RC_LOGIN_USER_OK:
|
|
|
+ Authenticated = true;
|
|
|
+ user_id = 1;
|
|
|
+ break;
|
|
|
+ case RC_NET_ERR:
|
|
|
+ Authenticated = false;
|
|
|
+ fl_raddius_net_err = true;
|
|
|
+ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Ошибка соединения с RADIUS сервером</h2></center></html>");
|
|
|
+ *lenBufOut = strlen(bufOut);
|
|
|
+ return SEND_REQUIRED_NO;
|
|
|
+ break;
|
|
|
+ case RC_ACC_DENIED:
|
|
|
+ Authenticated = false;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ snprintf(name_login, (strlen(login) + 1), login);
|
|
|
+
|
|
|
+ if (Authenticated) {
|
|
|
+
|
|
|
+ sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
|
|
|
+
|
|
|
+
|
|
|
+ HTTP_SetUserCookie(tempStr, user_id);
|
|
|
+
|
|
|
+ HTTP_UpdateUserLoginTime(user_id);
|
|
|
+
|
|
|
+
|
|
|
+ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
|
|
|
+ strcat(bufOut, login);
|
|
|
+ strcat(bufOut, "\r\nSet-Cookie: id=");
|
|
|
+ strcat(bufOut, tempStr);
|
|
|
+ sprintf(tempStr, "%d", (user_id + 1));
|
|
|
+ strcat(bufOut, "\r\nSet-Cookie: role=");
|
|
|
+ strcat(bufOut, tempStr);
|
|
|
+ strcat(bufOut, "\r\nSet-Cookie: auth=1");
|
|
|
+ strcat(bufOut, "\r\n\r\n");
|
|
|
+
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
|
|
|
+
|
|
|
+ *lenBufOut = strlen(bufOut);
|
|
|
+ fl_raddius_net_err = false;
|
|
|
+
|
|
|
+ log_event_data(LOG_LOGIN, name_login);
|
|
|
+
|
|
|
+
|
|
|
+ return SEND_REQUIRED_YES;
|
|
|
+ } else {
|
|
|
+ if (cnt_err_psw <= 4) {
|
|
|
+ cnt_err_psw ++;
|
|
|
+ }
|
|
|
+ DBG printf("cnt_err_psw %d", cnt_err_psw);
|
|
|
+ if (cnt_err_psw == 4) {
|
|
|
+ xTimerStart(RepeatLoginTimer, 0);
|
|
|
+ }
|
|
|
+ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
|
|
|
+
|
|
|
+ if (cnt_err_psw < 4) {
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
|
|
|
+ } else {
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Вход заблокирован!</h2></center></head><center><h2>Повторите попытку через 1 минуту</h2></center></html>");
|
|
|
+ }
|
|
|
+
|
|
|
+ *lenBufOut = strlen(bufOut);
|
|
|
+ return SEND_REQUIRED_NO;
|
|
|
+ }
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
* @brief Проверка пароля для входа в Web
|
|
|
* @retval None
|
|
|
*/
|
|
|
-int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
|
|
|
+int HTTP_LocalAuthConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
|
|
|
{
|
|
|
char tempStr[52];
|
|
|
char login[20];
|
|
@@ -1509,6 +1682,16 @@ int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *l
|
|
|
if (cnt_err_psw < 4) {
|
|
|
cnt_err_psw = 0;
|
|
|
Authenticated = true;
|
|
|
+ switch (user_id) {
|
|
|
+ case 0:
|
|
|
+ snprintf(name_login, sizeof(name_login), "Администратор");
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ snprintf(name_login, sizeof(name_login), "Пользователь");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
} else {
|
|
|
Authenticated = false;
|
|
|
}
|
|
@@ -1542,17 +1725,9 @@ int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *l
|
|
|
"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
|
|
|
|
|
|
*lenBufOut = strlen(bufOut);
|
|
|
- switch (user_id) {
|
|
|
- case 0:
|
|
|
- snprintf(name_login, sizeof(name_login), "Администратор");
|
|
|
- break;
|
|
|
- case 1:
|
|
|
- snprintf(name_login, sizeof(name_login), "Пользователь");
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ fl_raddius_net_err = false;
|
|
|
+#endif
|
|
|
log_event_data(LOG_LOGIN, name_login);
|
|
|
|
|
|
|
|
@@ -1741,6 +1916,44 @@ static void getAuthenticatedState(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, char *postBuf, uint16_t lenBufIn, uint16_t *lenBufOut)
|
|
|
+{
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ static char rs_id[16];
|
|
|
+ if (auth_flag != RS_AUTH_READY) {
|
|
|
+ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
|
|
|
+ char CookieBuf[51];
|
|
|
+ char *CookiePtr = NULL;
|
|
|
+ char rs_id_check[MAX_WEB_COOKIE_LEN];
|
|
|
+ uint8_t rs_idLen = 0;
|
|
|
+ CookiePtr = strstr(bufIn, "rs_id=");
|
|
|
+ strncpy(CookieBuf, CookiePtr, 50);
|
|
|
+ GetCookieValue(CookieBuf, "rs_id=", rs_id_check, &rs_idLen);
|
|
|
+ if (strncmp(rs_id, rs_id_check, strlen(rs_id)) == 0 && rs_idLen != 0) {
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>RADIUS сервер занят. Повторите попытку позже</h2></center></html>");
|
|
|
+ } else {
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>RADIUS сервер занят. Повторите попытку позже</h2></center></html>");
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) {
|
|
|
+ auth_flag = RS_AUTH_PROCESS;
|
|
|
+
|
|
|
+ sprintf(rs_id, "%X", (unsigned int)GetRandomNumber());
|
|
|
+ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: rs_id=");
|
|
|
+ strcat(bufOut, rs_id);
|
|
|
+ strcat(bufOut, "\r\n\r\n");
|
|
|
+ strcat(bufOut,
|
|
|
+ "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>Ожидание соединения с RADIUS сервером</h2></center></html>");
|
|
|
+ } else
|
|
|
+#endif
|
|
|
+ {
|
|
|
+ HTTP_LocalAuthConfirmWebPwd(postBuf, bufOut, strlen(postBuf), lenBufOut);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
|
|
|
{
|
|
|
(void)reqNum;
|
|
@@ -1782,7 +1995,7 @@ char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBuf
|
|
|
|
|
|
post_data_count = 0;
|
|
|
log_post_reqn = 0;
|
|
|
- HTTP_ConfirmWebPwd(post_req_data, bufOut, strlen(post_req_data), lenBufOut);
|
|
|
+ HTTP_ConfirmWebPwd(bufIn, bufOut, post_req_data, lenBufIn, lenBufOut);
|
|
|
*lenBufOut = strlen(bufOut);
|
|
|
return bufOut;
|
|
|
}
|
|
@@ -1796,7 +2009,12 @@ char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBuf
|
|
|
post_data_count = 0;
|
|
|
log_post_reqn = 0;
|
|
|
|
|
|
- fs_open("/login.html", &file);
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ fs_open("/rslogin.html", &file);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ fs_open("/login.html", &file);
|
|
|
*lenBufOut = file.len;
|
|
|
return file.data;
|
|
|
}
|
|
@@ -1808,7 +2026,13 @@ char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBuf
|
|
|
log_post_reqn = 0;
|
|
|
|
|
|
|
|
|
- fs_open("/login.html", &file);
|
|
|
+
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ fs_open("/rslogin.html", &file);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ fs_open("/login.html", &file);
|
|
|
*lenBufOut = file.len;
|
|
|
return file.data;
|
|
|
}
|
|
@@ -1816,13 +2040,17 @@ char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBuf
|
|
|
strncat(post_req_data, receiveBuf, post_data_count);
|
|
|
post_data_count = 0;
|
|
|
log_post_reqn = 0;
|
|
|
-
|
|
|
- HTTP_ConfirmWebPwd(post_req_data, bufOut, strlen(post_req_data), lenBufOut);
|
|
|
+ HTTP_ConfirmWebPwd(bufIn, bufOut, post_req_data, lenBufIn, lenBufOut);
|
|
|
*lenBufOut = strlen(bufOut);
|
|
|
return bufOut;
|
|
|
} else {
|
|
|
|
|
|
- fs_open("/login.html", &file);
|
|
|
+#ifdef RADIUS_SERVER_ENABLE
|
|
|
+ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
|
|
|
+ fs_open("/rslogin.html", &file);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ fs_open("/login.html", &file);
|
|
|
*lenBufOut = file.len;
|
|
|
return file.data;
|
|
|
}
|