#include "lwip/opt.h" #include "lwip/arch.h" #include "lwip/api.h" #include "lwip/tcp.h" #include "http_server.h" #include "web_params_api.h" #include "parameters.h" #include "urlcode.h" #include "trap_params.h" #include "fsdata.c" #include "settings_api.h" #include "netconf.h" #include "common_config.h" #include "testing.h" #include "rtc.h" #include "rng.h" #include "megatec.h" #include "log.h" #include "hal.h" #include "radius_user.h" #include "sntp_api.h" #ifdef PRINTF_STDLIB #include #endif #ifdef PRINTF_CUSTOM #include "tinystdio.h" #endif #include #include #include "FreeRTOS.h" #include "task.h" #include "fr_timers.h" static int fs_open(char *name, struct fs_file *file); static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len); static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len); static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len); static void http_sent_log_err(void * arg, err_t err); static void send_data(struct tcp_pcb *pcb, struct http_state *hs); static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len); static uint32_t Parse_Content_Length(char *data, uint32_t len); static void HTTP_SetUserCookie(char *str, uint8_t user_id); static void HTTP_UpdateUserLoginTime(uint8_t user_id); static void HTTP_ForceUserLogout(uint8_t user_id); void LogoutTimerCallback(TimerHandle_t pxTimer); void LoginTimerCallback(TimerHandle_t pxTimer); int HTTP_ChangeUserPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut); SET_PAGE_t SET_PAGE = SET_PAGE_IDLE; #define SEND_BUF_MAX_LEN 2000 #define RECIVE_BUF_MAX_LEN 1500 char sendBuf[SEND_BUF_MAX_LEN]; uint16_t sendBufLoadLen = 0; uint16_t printLen = 0; //char printBuf[1000]; char receiveBuf[RECIVE_BUF_MAX_LEN]; uint16_t receivedBufLen = 0; #define MAX_POST_REQ_LEN 256 char post_req_data[MAX_POST_REQ_LEN]; uint32_t post_data_count; uint32_t log_post_reqn; /* Logout timeout, 30 minutes */ #define WEB_LOGOUT_TIME configTICK_RATE_HZ*60*30 /* Max user active sessions count */ #define WEB_USER_MAX_SESSION_COUNT 5 struct { //auth_session_t session[WEB_USER_MAX_SESSION_COUNT]; char cookie[MAX_WEB_COOKIE_LEN]; TimerHandle_t LogoutTimer; } users[MAX_WEB_USERS]; TimerHandle_t RepeatLoginTimer; /* Repeat Login timeout, 1 minutes */ #define REPEAT_LOGIN_TIME configTICK_RATE_HZ*60*1 uint8_t cnt_err_psw = 0; bool Authenticated = false; /* Level of currently logged-in user */ uint8_t seclevel = 0xFF; static volatile uint32_t DataFlag2=0; static volatile uint32_t DataFlag=0; static volatile uint32_t size =0; static uint32_t TotalReceived=0; static volatile uint32_t TotalData=0; static uint32_t ContentLengthOffset =0, BrowserFlag=0; static const char Content_Length[17] = /* Content Length */ {0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67,0x74, 0x68, 0x3a, 0x20, }; const char HTTP_200_OK[] = "HTTP/1.1 200 OK\r\n\r\n"; /* utf-8 marker to support MS Excel */ const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF, 0x00}; unsigned long log_ptr = 0; unsigned long log_size = 0; bool fLogTransInprog = false; static bool fl_raddius_net_err = false; /** * @brief Общая структура настроек */ extern SETTINGS_t sSettings; /** * @brief closes tcp connection * @param pcb: pointer to a tcp_pcb struct * @param hs: pointer to a http_state struct * @retval */ static void close_conn(struct tcp_pcb *pcb, struct http_state *hs) { tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); mem_free(hs); tcp_close(pcb); } /** * @brief callback function for handling TCP HTTP traffic * @param arg: pointer to an argument structure to be passed to callback function * @param pcb: pointer to a tcp_pcb structure * @param p: pointer to a packet buffer * @param err: LwIP error code * @retval err */ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { char *data; struct http_state *hs; struct fs_file file = {0, 0}; hs = arg; if (err == ERR_OK && p != NULL) { tcp_recved(pcb, p->tot_len); if (hs->file == NULL) { data = p->payload; /* printLen = p->tot_len; memcpy(printBuf, p->payload , printLen); printf(printBuf); */ receivedBufLen = p->tot_len; memcpy(receiveBuf, p->payload , receivedBufLen); // На производстве if (strncmp(data, "GET /setProdate.cgi", 19) == 0) { HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); hs->file = sendBuf; hs->left = sendBufLoadLen; send_data(pcb, hs); tcp_sent(pcb, http_sent); } } pbuf_free(p); close_conn(pcb,hs); } if (err == ERR_OK && p == NULL) { close_conn(pcb, hs); } return ERR_OK; } /** * @brief Error callback for log file transfer */ static void http_sent_log_err(void * arg, err_t err) { (void)err; (void)arg; /* Clear file transfer in progress flag */ fLogTransInprog = false; } /** * @brief Sent callback for log file transfer (messages as is, not ordered) */ static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len) { struct http_state *hs; uint32_t nbytes = 0; static bool start = true; (void)len; hs = arg; if (hs->left > 0) { send_data(pcb, hs); } else { memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start); } else if (log_ptr < log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { /* File transfer finished. */ start = true; close_conn(pcb, hs); /* Clear file transfer in progress flag */ fLogTransInprog = false; return ERR_OK; } hs->file = logFileBuf; hs->left = nbytes; send_data(pcb, hs); tcp_sent(pcb, http_sent_log); } return ERR_OK; } /** * @brief Sent callback for log file transfer (messages as is, not ordered) */ static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len) { struct http_state *hs; uint32_t nbytes = 0; static bool start = true; (void)len; hs = arg; if (hs->left > 0) { send_data(pcb, hs); } else { memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN <= log_size) { nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start); } else if (log_ptr < log_size) { nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { /* File transfer finished. */ start = true; close_conn(pcb, hs); /* Clear file transfer in progress flag */ fLogTransInprog = false; return ERR_OK; } hs->file = logFileBuf; hs->left = nbytes; send_data(pcb, hs); tcp_sent(pcb, http_sent_history); } return ERR_OK; } /** * @brief callback function for handling connection errors * @param arg: pointer to an argument to be passed to callback function * @param err: LwIP error code * @retval none */ static void conn_err(void *arg, err_t err) { struct http_state *hs; hs = arg; mem_free(hs); } /** * @brief callback function called after a successfull TCP data packet transmission * @param arg: pointer to an argument to be passed to callback function * @param pcb: pointer on tcp_pcb structure * @param len * @retval err : LwIP error code */ static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { struct http_state *hs; hs = arg; if (hs->left > 0) { send_data(pcb, hs); } else { close_conn(pcb, hs); } return ERR_OK; } /** * @brief sends data found in member "file" of a http_state struct * @param pcb: pointer to a tcp_pcb struct * @param hs: pointer to a http_state struct * @retval none */ static void send_data(struct tcp_pcb *pcb, struct http_state *hs) { err_t err; u16_t len; /* We cannot send more data than space available in the send buffer */ if (tcp_sndbuf(pcb) < hs->left) { len = tcp_sndbuf(pcb); } else { len = hs->left; } err = tcp_write(pcb, hs->file, len, 0); if (err == ERR_OK) { hs->file += len; hs->left -= len; } } /** * @brief tcp poll callback function * @param arg: pointer to an argument to be passed to callback function * @param pcb: pointer on tcp_pcb structure * @retval err_t */ static err_t http_poll(void *arg, struct tcp_pcb *pcb) { if (arg == NULL) { tcp_close(pcb); } else { send_data(pcb, (struct http_state *)arg); } return ERR_OK; } /** * @brief callback function on TCP connection setup ( on port 80) * @param arg: pointer to an argument structure to be passed to callback function * @param pcb: pointer to a tcp_pcb structure * ¶m err: Lwip stack error code * @retval err */ static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; /* Allocate memory for the structure that holds the state of the connection */ hs = mem_malloc(sizeof(struct http_state)); if (hs == NULL) { return ERR_MEM; } /* Initialize the structure. */ hs->file = NULL; hs->left = 0; /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */ tcp_recv(pcb, http_recv); tcp_err(pcb, conn_err); tcp_poll(pcb, http_poll, 10); return ERR_OK; } /** * @brief Opens a file defined in fsdata.c ROM filesystem * @param name : pointer to a file name * @param file : pointer to a fs_file structure * @retval 1 if success, 0 if fail */ static int fs_open(char *name, struct fs_file *file) { struct fsdata_file_noconst *f; for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next) { if (!strcmp(name, f->name)) { file->data = f->data; file->len = f->len; return 1; } } return 0; } /** * @brief Initialize the HTTP server (start its thread) * @param none * @retval None */ void HTTP_Init() { char buf[MAX_WEB_COOKIE_LEN]; uint8_t user_id; //sys_thread_new("HTTP", http_server_netconn_thread, NULL, 3000, 2); struct tcp_pcb *pcb; /*create new pcb*/ pcb = tcp_new(); /* bind HTTP traffic to pcb */ tcp_bind(pcb, IP_ADDR_ANY, 80); /* start listening on port 80 */ pcb = tcp_listen(pcb); /* define callback function for TCP connection setup */ tcp_accept(pcb, http_accept); /* for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { //Flush user cookie by random value sprintf(buf, "%X", (unsigned int)GetRandomNumber()); HTTP_SetUserCookie(buf, user_id); // Create user logout timers users[user_id].LogoutTimer = xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback); } */ } /** * @brief * @retval None */ int HTTP_SettingsPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char tempStr[30]; strncpy(tempStr, bufIn, 30); /* В запросе нет параметров, нужно формировать JSON ответ */ if (strpbrk(tempStr,"?") == 0) { memset(bufOut, 0, SEND_BUF_MAX_LEN); HTTP_GetSettings(bufOut); //printf(bufOut); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } /* В запросе есть параметры, нужно парсить и сохранять настройки */ else { //HTTP_SetSettings(bufIn, lenBufIn); return SEND_REQUIRED_NO; } } /** * @brief * @retval None */ int HTTP_InfoPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char tempStr[30]; strncpy(tempStr, bufIn, 30); /* В запросе нет параметров, нужно формировать JSON ответ */ if (strpbrk(tempStr,"?") == 0) { memset(bufOut, 0, SEND_BUF_MAX_LEN); HTTP_GetInfo(bufOut); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } /* В запросе есть параметры, нужно парсить и сохранять настройки */ else { //HTTP_SetInfo(bufIn, lenBufIn); return SEND_REQUIRED_NO; /* HTTP_SetSettings(bufIn, lenBufIn); return SEND_REQUIRED_NO; */ } } int HTTP_HistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t i, valueLen = 0; char value[20]; uint32_t nbytes = 0; (void)lenBufIn; memset(bufOut, 0, FILE_BUF_MAX_LEN); ClearParamString(bufIn); memset(value, 0, 20); GetParamValue(bufIn, "page=", value, &valueLen); if (strcmp(value, "all") == 0) { if (!LOG_IsInit()) { return SEND_REQUIRED_NO; } if (fLogTransInprog == false) { // Send log as raw data log_ptr = 0; log_size = History_GetTotalSTRCount() * STRING_SIZE_HISTORY + sizeof(UTF8_BOM)-1; sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM); *lenBufOut = strlen(bufOut); // Set file transfer in progress flag fLogTransInprog = true; return SEND_REQUIRED_FILE; } else { // We send nothing if file transfer already in progress return SEND_REQUIRED_NO; } } else { if (!LOG_IsInit()) { return SEND_REQUIRED_NO; } else { HTTP_GetHistoryPage(bufOut, atoi(value)); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } } } int HTTP_UpsHistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t i, valueLen = 0; char value[20]; uint32_t nbytes = 0; (void)lenBufIn; memset(bufOut, 0, FILE_BUF_MAX_LEN); ClearParamString(bufIn); memset(value, 0, 20); GetParamValue(bufIn, "page=", value, &valueLen); if (strcmp(value, "all") == 0) { if (!LOG_IsInit()) { return SEND_REQUIRED_NO; } if (fLogTransInprog == false) { // Send log as raw data log_ptr = 0; log_size = LOG_GetTotalSTRCount() * STRING_SIZE + sizeof(UTF8_BOM)-1; sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM); *lenBufOut = strlen(bufOut); // Set file transfer in progress flag fLogTransInprog = true; return SEND_REQUIRED_FILE; } else { // We send nothing if file transfer already in progress return SEND_REQUIRED_NO; } } else { if (!LOG_IsInit()) { return SEND_REQUIRED_NO; } else { HTTP_GetUpsHistoryPage(bufOut, atoi(value)); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } } } /** * @brief Установка даты производства */ // TODO Убрать заглушку! void HTTP_Prodate(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t valueLen = 0; char value[20]; memset(bufOut, 0, SEND_BUF_MAX_LEN); ClearParamString(bufIn); memset(value, 0, 20); GetParamValue(bufIn, "prodate=", value, &valueLen); /* printf("Prodate: "); printf(value); printf("\r\n"); */ /* Устанавливаем дату производства */ SETTINGS_SetProDate(value, valueLen); /* Пока отправляем true */ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\nTrue"); *lenBufOut = strlen(bufOut); TEST_SetServerFlag(); } /** * @brief * @retval None */ void HTTP_SetSettings(char *buf, uint16_t lenBuf) { uint8_t valueLen = 0; const uint8_t len = MAX_WEB_PARAM_LEN; char value[MAX_WEB_PARAM_LEN]; char str[MAX_WEB_PARAM_LEN]; //printf(buf); //ClearParamString(buf); memset(value, 0, len); memset(str, 0, MAX_WEB_PARAM_LEN); /* SNMP */ GetParamValue(buf, "read_community=", value, &valueLen); SetReadCommunity(value); memset(value, 0, len); GetParamValue(buf, "write_community=", value, &valueLen); SetWriteCommunity(value); memset(value, 0, len); GetParamValue(buf, "managerIP=", value, &valueLen); SetManagerIp(value); memset(value, 0, len); GetParamValue(buf, "managerIP2=", value, &valueLen); SetManagerIp2(value); memset(value, 0, len); GetParamValue(buf, "managerIP3=", value, &valueLen); SetManagerIp3(value); memset(value, 0, len); GetParamValue(buf, "managerIP4=", value, &valueLen); SetManagerIp4(value); memset(value, 0, len); GetParamValue(buf, "managerIP5=", value, &valueLen); SetManagerIp5(value); memset(value, 0, len); /* Сетевые параметры */ GetParamValue(buf, "dhcp=", value, &valueLen); SetDhcpStateStr(value); if (strncmp(value, "on", 2) != 0) // Если dhcp off устанавливаем параметры { memset(value, 0, len); GetParamValue(buf, "ipaddr=", value, &valueLen); SetIPStr(value); memset(value, 0, len); GetParamValue(buf, "gw=", value, &valueLen); SetGatewayStr(value); memset(value, 0, len); GetParamValue(buf, "mask=", value, &valueLen); SetMaskStr(value); memset(value, 0, len); } memset(value, 0, len); GetParamValue(buf, "swauth=", value, &valueLen); SetAuthEnableStateStr(value); if (strncmp(value, "on", 2) == 0){ /* параметры RADIUS*/ memset(value, 0, len); GetParamValue(buf, "rs_enabled=", value, &valueLen); SetRDSEnableStateStr(value); if (strncmp(value, "on", 2) == 0) // Если raddius off устанавливаем параметры { memset(value, 0, len); GetParamValue(buf, "rs_server=", value, &valueLen); SetRDSIpStr(value); memset(value, 0, len); GetParamValue(buf, "rs_port=", value, &valueLen); SetRDSPortStr(value); memset(value, 0, len); GetParamValue(buf, "rs_pwd=", value, &valueLen); SetRDSPasswordkStr(value); memset(value, 0, len); GetParamValue(buf, "rs_key=", value, &valueLen); SetRDSKeyAccesstStr(value); memset(value, 0, len); } } memset(value, 0, len); // Параметры реле и сухих контактов GetParamValue(buf, "di1=", value, &valueLen); SetDINTypeActStr(value, 0); memset(value, 0, len); GetParamValue(buf, "ro1=", value, &valueLen); SetROTypeActStr(value, 0); memset(value, 0, len); GetParamValue(buf, "ro2=", value, &valueLen); SetROTypeActStr(value, 1); memset(value, 0, len); GetParamValue(buf, "utc=", value, &valueLen); SetSntpTimeZoneStr(value); memset(value, 0, len); // Параметры даты и времени GetParamValue(buf, "ntp=", value, &valueLen); if (strncmp(value, "1", 1) == 0) // Если ntp on устанавливаем параметры { bool old_sntp = false; bool enable_old_sntp = sSettings.sSNTP.sntpEnable; memset(str, 0, len); GetParamValue(buf, "ntpservip=", str, &valueLen); if(strncmp(str, sSettings.sSNTP.ip, valueLen)) old_sntp = true; SetSntpServerIpStr(str); SetSntpStateStr(value); if(sSettings.sSNTP.sntpEnable != enable_old_sntp) old_sntp = true; if(old_sntp){ SNTP_Init(); //vTaskDelay(7000); SNTP_Poll(); } memset(value, 0, len); memset(str, 0, len); } else if (strncmp(value, "0", 1) == 0){ SetSntpStateStr(value); memset(value, 0, len); GetParamValue(buf, "date=", value, &valueLen); SetDateStr(value); memset(value, 0, len); GetParamValue(buf, "time=", value, &valueLen); memset(str, 0, len); url_decode(str, sizeof(str), value); SetTimeStr(str); memset(value, 0, len); memset(str, 0, len); } /* Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся */ if (GetStateWebReinit() == true) { SetWebReinitFlag(true); HTTP_SaveSettings(); /* Блокируем управление ключем на тау секунд*/ //IO_KeyBlockOn(); vTaskDelay(1010); Reboot(); } HTTP_SaveSettings(); } /** * @brief * @retval None */ void HTTP_SetInfo(char *buf, uint16_t lenBuf) { uint8_t valueLen = 0; const uint8_t len = 110; char value[110]; char str[110]; // ClearParamString(buf); memset(value, 0, len); /* Владелец */ GetParamValue(buf, "owner=", value, &valueLen); url_decode(str, sizeof(str), value); SetOwner(str); memset(value, 0, len); /* Владелец */ GetParamValue(buf, "sysLocation=", value, &valueLen); url_decode(str, sizeof(str), value); SetLocation(str); memset(value, 0, len); /* Комментарий */ GetParamValue(buf, "comment=", value, &valueLen); url_decode(str, sizeof(str), value); SetComment(str); memset(value, 0, len); HTTP_SaveSettings(); } /** * @brief Запуск/останов теста UPS */ void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t valueLen = 0; char tempValue[20]; char tempValue2[20]; int8_t res = 0; char log_string[50]; memset(tempValue, 0, 20); memset(tempValue2, 0, 20); memset(log_string, 0,50); strcpy(bufOut, HTTP_200_OK); GetParamValue(bufIn, "func=", tempValue, &valueLen); if (strcmp(tempValue, "stop") == 0){ res = ups_metac_service_pdu(ups_cancel_test); if(res == 1 || res == 0){ strcat(bufOut, "Тест остановлен!"); strcpy(log_string, name_login); strcat(log_string, " (Останов)"); log_event_data(LOG_TEST_UPS, log_string); } if(res == -1) strcat(bufOut, "Тест не удалось остановить!"); *lenBufOut = strlen(bufOut); } else if (strcmp(tempValue, "discharge") == 0){ res = ups_metac_service_pdu(ups_test_low_bat); if(res == 1 || res == 0){ strcat(bufOut, "Тест запущен!"); strcpy(log_string, name_login); strcat(log_string, " (Запущен)"); log_event_data(LOG_TEST_UPS, log_string); } if(res == -1) strcat(bufOut, "Тест не удалось запустить!"); *lenBufOut = strlen(bufOut); } else if (strncmp(tempValue, "time", 6) == 0){ GetParamValue(bufIn, "=", tempValue2, &valueLen); TimeParam = atoi(tempValue2); res = ups_metac_service_pdu(ups_test_time); if(res == 1 || res == 0){ strcat(bufOut, "Тест запущен!"); strcpy(log_string, name_login); strcat(log_string, " (Запущен)"); log_event_data(LOG_TEST_UPS, log_string); } if(res == -1) strcat(bufOut, "Тест не удалось запустить!"); *lenBufOut = strlen(bufOut); } } /** * @brief Выклюение UPS */ void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t valueLen = 0; char *valueLenEnd = 0; char tempValue[50]; char tempValue2[50]; int8_t res = 0; char log_string[50]; memset(tempValue, 0, 50); memset(log_string, 0,50); strcpy(bufOut, HTTP_200_OK); GetParamValue(bufIn, "func=", tempValue, &valueLen); if (strcmp(tempValue, "reboot") == 0){ res = ups_metac_service_pdu(ups_cancel_shut_down); if(res == 1){ strcpy(log_string, name_login); strcat(log_string, " (Останов)"); log_event_data(LOG_SHUTDOWN_UPS, log_string); strcat(bufOut, "Выключение нагрузки ИБП отменено!"); } else strcat(bufOut, "Выключение нагрузки ИБП не удалось отменить!"); *lenBufOut = strlen(bufOut); } else if (strncmp(tempValue, "off", 5) == 0){ memset(tempValue2, 0, 50); GetParamValue(bufIn, "after=", tempValue2, &valueLen); TimeParamFloat = atof(tempValue2); res = ups_metac_service_pdu(ups_shutdown); if(res == 1){ strcat(bufOut, "Отключение нагрузки ИБП!"); log_event_data(LOG_SHUTDOWN_UPS, name_login); }else strcat(bufOut, "Отключение нагрузки ИБП не удалось!"); *lenBufOut = strlen(bufOut); } } /** * @brief Проверка пароля для перехода в режим bootloader * @retval None */ void HTTP_ConfirmBootPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char tempStr[50]; strncpy(tempStr, bufIn, 50); char value[20]; uint8_t valueLen; memset(value, 0, 20); //if (GetParamValue(tempStr, "password=", value, &valueLen)) { //if (strcmp(BOOTLOADER_PASWORD, value) == 0) { // *bufOut = '1'; /* Запускаем задачу отложенной перезагрузки. Контроллер должен успеть отправить ответ серверу о статусе пароля */ HTTP_StartResetTask(true); } /* else *bufOut = '0';*/ //*lenBufOut = 1; } } void LoginTimerCallback(TimerHandle_t pxTimer) { cnt_err_psw = 0; DBG printf("cnt_err_psw %d", cnt_err_psw); xTimerStop(RepeatLoginTimer, 0); } /** * @brief Проверка пароля для входа в Web * @retval None */ int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char tempStr[50]; char login[20]; char password[20]; 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(tempStr, 0, 50); memset(name_login, 0, 50); /* Get first 50 bytes of string */ strncpy(tempStr, bufIn, 49); /* Add " " to the string in order GetParamValue() can be able to parse the param */ strcat(tempStr, " "); GetParamValue(tempStr, "login=", login, &valueLen); GetParamValue(tempStr, "password=", password, &valueLen); if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){ 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,"

Ошибка соединения с RADIUS сервером

"); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_NO; break; case RC_ACC_DENIED: Authenticated = false; break; default: break; } } else{ for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { GetUserLogin(user_id, WebLogin, &valueLen); GetUserPassword(user_id, WebPassword, &valueLen); /* Check login and password */ if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) && (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) { /* Login and pass are valid */ /* TODO replace global flag with user-pass-cookie */ if(cnt_err_psw < 4){ cnt_err_psw = 0; Authenticated = true; } else{ Authenticated = false; } break; } else{ Authenticated = false; } } } if(Authenticated){ /* Generate cookie */ sprintf(tempStr, "%X", (unsigned int)GetRandomNumber()); /* Set users cookie */ HTTP_SetUserCookie(tempStr, user_id); HTTP_UpdateUserLoginTime(user_id); /* Send login and cookie back */ 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); strcat(bufOut, "\r\nSet-Cookie: role="); strcat(bufOut, tempStr); if(sSettings.sRADIUS.Auth_enable) strcat(bufOut, "\r\nSet-Cookie: auth=1"); else strcat(bufOut, "\r\nSet-Cookie: auth=0"); strcat(bufOut, "\r\n\r\n"); strcat(bufOut,"\r\n\r\n"); *lenBufOut = strlen(bufOut); if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){ snprintf(name_login, (strlen(login)+1), login); } else{ fl_raddius_net_err = false; switch (user_id) { case 0: snprintf(name_login, sizeof(name_login), "Администратор"); break; case 1: snprintf(name_login, sizeof(name_login), "Пользователь"); break; default: snprintf(name_login, (strlen(login)+1), login); break; } } log_event_data(LOG_LOGIN, name_login); /* Запускаем задачу-таймер логаута. */ /* TODO отправить ответ серверу о статусе пароля */ 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((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){ if(cnt_err_psw < 4) strcat(bufOut,"

Не правильный логин или пароль

"); else strcat(bufOut,"

Вход заблокирован!

Повторите попытку через 1 минуту

"); } else{ if(cnt_err_psw < 4) strcat(bufOut,"

Не правильный логин или пароль

"); else strcat(bufOut,"

Вход заблокирован!

Повторите попытку через 1 минуту

"); } *lenBufOut = strlen(bufOut); return SEND_REQUIRED_NO; } } void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut) { char tempStr[50]; uint8_t valueLen; char WebLogin[MAX_WEB_LOGIN_LEN]; GetUserLogin(ADMIN, WebLogin, &valueLen); memset(tempStr, 0, 50); memset(name_login, 0, 50); /* TODO replace global flag with user-pass-cookie */ Authenticated = true; /* Generate cookie */ sprintf(tempStr, "%X", (unsigned int)GetRandomNumber()); /* Set users cookie */ HTTP_SetUserCookie(tempStr, ADMIN); HTTP_UpdateUserLoginTime(ADMIN); /* Send login and cookie back */ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname="); strcat(bufOut, WebLogin); strcat(bufOut, "\r\nSet-Cookie: id="); strcat(bufOut, tempStr); strcat(bufOut, "\r\nSet-Cookie: role=0"); if(sSettings.sRADIUS.Auth_enable) strcat(bufOut, "\r\nSet-Cookie: auth=1"); else strcat(bufOut, "\r\nSet-Cookie: auth=0"); strcat(bufOut, "\r\n\r\n"); strcat(bufOut,"\r\n\r\n"); *lenBufOut = strlen(bufOut); snprintf(name_login, sizeof(name_login), "Администратор"); } /** * @brief * @retval None */ uint8_t GetParamValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen) { char *beginValue = 0; char *endValue = 0; int len = 0; char *strPtr = 0; strPtr = strstr(inStr, paramName); if (strPtr != 0) { beginValue = strpbrk(strPtr,"="); endValue = strpbrk(strPtr,"&"); if (endValue == 0) endValue = strpbrk(strPtr," "); len = endValue - beginValue - 1; strncpy(paramValue, beginValue + 1, len); *endValue = '0'; *beginValue = '0'; *paramLen = len; return 1; } else { *paramLen = 0; return 0; } } /** * @brief * @retval None */ uint8_t GetCookieValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen) { char *beginValue = 0; char *endValue = 0; int len = 0; char *strPtr = 0; strPtr = strstr(inStr, paramName); if (strPtr != 0) { beginValue = strpbrk(strPtr,"="); endValue = strpbrk(strPtr,";"); if (endValue == 0) endValue = strpbrk(strPtr,"\n"); len = endValue - beginValue - 1; strncpy(paramValue, beginValue + 1, len); *endValue = '0'; *beginValue = '0'; *paramLen = len; return 1; } else { *paramLen = 0; return 0; } } char* Parce_Boundary(const char* data, uint32_t len, char* dst, uint8_t dstlen) { char *ptr = NULL; char *boundary = NULL; uint8_t i = 0; for (uint32_t j = 0; j < len; j++) { if (strncmp ((char*)(data + j), "boundary=", 9) == 0) { boundary = (char*)data + j + 9; break; } } if (!boundary) return NULL; *dst++ = '-'; *dst++ = '-'; ptr = boundary; while ((*ptr != 0x0d) && (i < dstlen - 4)) { *dst++ = *ptr++; i++; } //*dst++ = '-'; //*dst++ = '-'; *dst = '\0'; if (i > 0) return boundary; else return NULL; } /** * @brief * @retval None */ /* uint8_t GetParamValueInEnd(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen) { char *beginValue = 0; char *endValue = 0; int len = 0; char *strPtr = 0; strPtr = strstr(inStr, paramName); if (strPtr != 0) { beginValue = strpbrk(strPtr,"="); endValue = strpbrk(strPtr," "); len = endValue - beginValue - 1; strncpy(paramValue, beginValue + 1, len); *endValue = '0'; *beginValue = '0'; *paramLen = len; return 1; } else { *paramLen = 0; return 0; } } */ void ClearParamString(char *inBuf) { uint16_t len; char *str; str = strstr(inBuf, "HTTP"); if (str != 0) { len = str - inBuf; memset(str, 0, RECIVE_BUF_MAX_LEN - len - 1); } } /** * @brief Чтение Cookie пользователя */ static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len) { sprintf(str, "%s", users[user_id].cookie); *len = strlen(str); } /** * @brief Установка Cookie пользователя */ static void HTTP_SetUserCookie(char *str, uint8_t user_id) { strcpy(users[user_id].cookie, str); } /** * @brief Обновление времени последней активности пользователя */ static void HTTP_UpdateUserLoginTime(uint8_t user_id) { xTimerStart(users[user_id].LogoutTimer, 0); } /** * @brief Extract the Content_Length data from HTML data * @param data : pointer on receive packet buffer * @param len : buffer length * @retval size : Content_length in numeric format */ static uint32_t Parse_Content_Length(char *data, uint32_t len) { uint32_t i=0,size=0, S=1; int32_t j=0; char sizestring[6], *ptr; ContentLengthOffset =0; /* find Content-Length data in packet buffer */ for (i=0;i0) { /* transform string data into numeric format */ for(j=i-1;j>=0;j--) { size += (sizestring[j]-0x30)*S; S=S*10; } } } return size; } /** * @brief Принудительный логаут пользователя */ static void HTTP_ForceUserLogout(uint8_t user_id) { char cookie[MAX_WEB_COOKIE_LEN]; /* Flush user cookie by random value */ sprintf(cookie, "%X", (unsigned int)GetRandomNumber()); HTTP_SetUserCookie(cookie, user_id); } /** * @brief >Callback таймера логаута пользователя */ void LogoutTimerCallback(TimerHandle_t pxTimer) { uint8_t user_id = (uint8_t)pvTimerGetTimerID( pxTimer ); if( sSettings.sRADIUS.Auth_enable ) HTTP_ForceUserLogout(user_id); } /** * @brief Смена пароля пользователя * @retval None */ int HTTP_ChangeUserPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char tempStr[110]; char value[20]; char login[20]; char password[20]; uint8_t valueLen, valueLen2, user_id; char WebLogin[MAX_WEB_LOGIN_LEN]; (void)lenBufIn; memset(login, 0, 20); memset(password, 0, 20); memset(tempStr, 0, 50); memset(value, 0, 20); ClearParamString(bufIn); strncpy(tempStr, bufIn, 110); strcpy(bufOut, HTTP_200_OK); if (GetParamValue(tempStr, "username=", login, &valueLen) && GetParamValue(tempStr, "oldpass=", password, &valueLen)) { for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { memset(value, 0, 20); memset(WebLogin, 0, MAX_WEB_LOGIN_LEN); GetUserLogin(user_id, WebLogin, &valueLen); GetUserPassword(user_id, value, &valueLen2); /* Check login and password */ if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) && (memcmp(password, value, 11) == 0)) { memset(password, 0, 20); if (GetParamValue(tempStr, "newpass=", password, &valueLen)) { memcpy(sSettings.sAuth[user_id].password, password, 11); HTTP_SaveSettings(); log_event_data(LOG_PSW_CHANGE, name_login); strcat(bufOut, "Пароль успешно изменён"); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } else { strcat(bufOut, "Введены некорректные данные!"); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } } } strcat(bufOut, "Введён неверный пароль!"); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } else { strcat(bufOut, "Введены некорректные данные!"); *lenBufOut = strlen(bufOut); return SEND_REQUIRED_YES; } } // ----------------------------------------------------------------------------- // // // SSL тесты // // // ----------------------------------------------------------------------------- #if 0 //#include "stm32f4xx.h" #include "rtc.h" /* PolarSSL includes */ #include "polarssl/net.h" #include "polarssl/ssl.h" #include "polarssl/havege.h" #include "polarssl/certs.h" #include "polarssl/x509.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define DEBUG_LEVEL 1 /* Set DEBUG_LEVEL if you want to enable SSL debug option, this should be set to 2, 3, 4 or 5 */ #define HTTP_RESPONSE "

Successful connection using: %s\r\n" /* Format of dynamic web page */ #define PAGE_START \ "\ \ \ \ STM32F407xx : SSL Server Demo not using HW Crypto :<)\

\r\nPage Hits = "

#define PAGE_END \
" \r\n



\ All rights reserved ©2017 ROTEK\ \r\n\ " /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* SSL structures */ rng_state rngs; ssl_context ssl; ssl_session ssn; x509_cert srvcert; rsa_context rsa; uint32_t nPageHits = 0; /* Private functions ---------------------------------------------------------*/ /* * Computing a "safe" DH-1024 prime can take a very * long time, so a precomputed value is provided below. * You may run dh_genprime to generate a new value. */ char *my_dhm_P = "E4004C1F94182000103D883A448B3F80" \ "2CE4B44A83301270002C20D0321CFD00" \ "11CCEF784C26A400F43DFB901BCA7538" \ "F2C6B176001CF5A0FD16D2C48B1D0C1C" \ "F6AC8E1DA6BCC3B4E1F96B0564965300" \ "FFA1D0B601EB2800F489AA512C4B248C" \ "01F76949A60BB7F00A40B1EAB64BDD48" \ "E8A700D60B7F1200FA8E77B0A979DABF"; char *my_dhm_G = "4"; /* * Sorted by order of preference */ int my_ciphersuites[] = { SSL_EDH_RSA_AES_256_SHA, SSL_EDH_RSA_CAMELLIA_256_SHA, SSL_EDH_RSA_AES_128_SHA, SSL_EDH_RSA_CAMELLIA_128_SHA, SSL_EDH_RSA_DES_168_SHA, SSL_RSA_AES_256_SHA, SSL_RSA_CAMELLIA_256_SHA, SSL_RSA_AES_128_SHA, SSL_RSA_CAMELLIA_128_SHA, SSL_RSA_DES_168_SHA, SSL_RSA_RC4_128_SHA, SSL_RSA_RC4_128_MD5, 0 }; void my_debug(void *ctx, int level, const char *str) { if(level < DEBUG_LEVEL) { printf("\r%s", str); } } /* * These session callbacks use a simple chained list * to store and retrieve the session information. */ ssl_session *s_list_1st = NULL; ssl_session *cur, *prv; static int my_get_session(ssl_context *ssl) { time_t t = RTC_GetUnixTime(); //time(NULL); if(ssl->resume == 0) return(1); cur = s_list_1st; prv = NULL; while(cur != NULL) { prv = cur; cur = cur->next; if(ssl->timeout != 0 && t - prv->start > ssl->timeout) continue; if( ssl->session->ciphersuite != prv->ciphersuite || ssl->session->length != prv->length) continue; if(memcmp( ssl->session->id, prv->id, prv->length ) != 0) continue; memcpy(ssl->session->master, prv->master, 48); return(0); } return(1); } static int my_set_session(ssl_context *ssl) { time_t t = RTC_GetUnixTime(); //time(NULL); cur = s_list_1st; prv = NULL; while(cur != NULL) { if(ssl->timeout != 0 && t - cur->start > ssl->timeout) break; /* expired, reuse this slot */ if(memcmp( ssl->session->id, cur->id, cur->length ) == 0) break; /* client reconnected */ prv = cur; cur = cur->next; } if(cur == NULL) { cur = (ssl_session *) malloc(sizeof(ssl_session)); if(cur == NULL) return(1); if(prv == NULL) s_list_1st = cur; else prv->next = cur; } memcpy(cur, ssl->session, sizeof(ssl_session)); return(0); } int ssl_server_read(void) { int ret; do { receivedBufLen = RECIVE_BUF_MAX_LEN - 1; memset(receiveBuf, 0, RECIVE_BUF_MAX_LEN); // Read decrypted application data ret = ssl_read(&ssl, (unsigned char*)receiveBuf, receivedBufLen); // printf("receive %s \r\n", receiveBuf); if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE) continue; if(ret <= 0) { switch(ret) { case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: printf("\n\r connection was closed \n"); break; case POLARSSL_ERR_NET_CONN_RESET: printf("\n\r connection was reset by peer\n"); break; default: // printf("\n\r ssl_read returned %d\n", ret); break; } return ret; //break; } receivedBufLen = ret; // Display the length of read data // printf("\n\r Successfully read %d bytes from client \n\r",receivedBufLen); }while(0); } /** * @brief SSL Server task. * @param pvParameters not used * @retval None */ void ssl_server(void *pvParameters) { int ret, len; int listen_fd; int client_fd; char buf[1024]; char *ptr; char CookieBuf[50]; char *CookiePtr = NULL; char name[MAX_WEB_COOKIE_LEN]; char id[MAX_WEB_COOKIE_LEN]; uint8_t nameLen = 0, idLen = 0; char *DataOffset; struct fs_file file = {0, 0}; uint32_t i; memset(&srvcert, 0, sizeof(x509_cert)); // 1. Load the certificates and private RSA key //printf("\n\r Loading the server certificates and key..."); // This demonstration program uses embedded test certificates. // Instead, you may want to use x509parse_crtfile() to read the // server and CA certificates, as well as x509parse_keyfile(). ret = x509parse_crt(&srvcert, sSettings.our_srv_crt, strlen(sSettings.our_srv_crt));//(unsigned char *) test_srv_crt if(ret != 0) { //printf(" failed\n ! x509parse_crt returned %d\n\r", ret); goto exit; } /* ret = x509parse_crt(&srvcert, (unsigned char *) test_ca_crt, strlen(test_ca_crt)); if(ret != 0) { //printf(" failed\n ! x509parse_crt returned %d\n\r", ret); goto exit; }*/ rsa_init( &rsa, RSA_PKCS_V15, 0 ); ret = x509parse_key(&rsa, (unsigned char *) test_srv_key, strlen(test_srv_key), NULL, 0);// if( ret != 0 ) { //printf(" failed\n ! x509parse_key returned %d\n\r", ret); goto exit; } // 2. Setup the listening TCP socket //printf("\n\r Bind to https port ..."); // Bind the connection to https port : 443 ret = net_bind(&listen_fd, NULL, 443); if(ret != 0) { //printf(" failed\n ! net_bind returned %d\n\r", ret); goto exit; } //printf(" ok\n\r"); // 3. Wait until a client connects for(;;) { //printf("\n\r Waiting for a remote connection ..."); ret = net_accept(listen_fd, &client_fd, NULL); if(ret != 0) { //printf(" failed\n ! net_accept returned %d\n\n", ret); //goto exit; goto accept; } //printf(" ok\n"); // 4. Initialize the session data //printf("\n\r Setting up the RNG and SSL data...."); // Initialize the SSL context ret = ssl_init(&ssl); if(ret != 0) { //printf(" failed\n ! ssl_init returned %d\n\n", ret); goto accept; } //printf(" ok\n"); // Set the current session as SSL server ssl_set_endpoint(&ssl, SSL_IS_SERVER); // No certificate verification ssl_set_authmode(&ssl, SSL_VERIFY_NONE); // Set the random number generator callback function ssl_set_rng(&ssl, RandVal, &rngs); // Set the debug callback function //ssl_set_dbg(&ssl, my_debug, stdout); // Set read and write callback functions ssl_set_bio(&ssl, net_recv, &client_fd, net_send, &client_fd); // Set the session callback functions ssl_set_scb(&ssl, my_get_session, my_set_session); // The list of ciphersuites to be used in this session ssl_set_ciphersuites(&ssl, my_ciphersuites); // Set the session resuming flag, timeout and session context ssl_set_session(&ssl, 1, 0, &ssn); memset(&ssn, 0, sizeof(ssl_session)); // Set the data required to verify peer certificate ssl_set_ca_chain(&ssl, srvcert.next, NULL, NULL); // Set own certificate and private key ssl_set_own_cert(&ssl, &srvcert, &rsa); // Set the Diffie-Hellman public P and G values ssl_set_dh_param(&ssl, my_dhm_P, my_dhm_G); // 5. Handshake protocol //printf("\n\r Performing the SSL/TLS handshake..."); // Perform the SSL handshake protocol while((ret = ssl_handshake(&ssl)) != 0) { if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { //printf(" failed\n ! ssl_handshake returned %d\n\n", ret); goto accept; } } //printf(" ok\n"); // 6. Read the HTTP Request //printf("\n\r <= Read from client :"); if(ssl_server_read() <= 0) goto accept; //ssl_server_read(); // ------------------------------------------------------------------------- //receivedBufLen = p->tot_len; //memcpy(receiveBuf, p->payload , receivedBufLen); receiveBuf[receivedBufLen] = '\0'; // printf("receive %s \r\n", receiveBuf); // Get cookie "uname" value CookiePtr = strstr(receiveBuf, "uname="); strncpy(CookieBuf, CookiePtr, 50); //printf("********CookieBuf1= %s\r\n", CookieBuf); memset(name, 0, MAX_WEB_COOKIE_LEN); GetCookieValue(CookieBuf, "uname=", name, &nameLen); //printf("********CookieBuf2= %s\r\n", CookieBuf); //printf("********uname= %s\r\n", name); // Get cookie "id" value CookiePtr = strstr(receiveBuf, "id="); strncpy(CookieBuf, CookiePtr, 50); //printf("********CookieBuf1= %s\r\n", CookieBuf); memset(id, 0, MAX_WEB_COOKIE_LEN); GetCookieValue(CookieBuf, "id=", id, &idLen); //printf("********CookieBuf2= %s\r\n", CookieBuf); //printf("********id= %s\r\n", id); // Id of currently logged-in user uint8_t user_id; // if(sSettings.sRADIUS.Auth_enable == true){ // Level of currently logged-in user seclevel = 0xFF; for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { HTTP_GetUserCookie(user_id, CookieBuf, &idLen); if (strncmp(id, CookieBuf, idLen) == 0 ) { GetUserLevelInt(user_id, &seclevel); Authenticated = true; break; } Authenticated = false; seclevel = 0xFF; } // } if ( Authenticated == false && sSettings.sRADIUS.Auth_enable == false) { //user_id = 0; // seclevel = 0; HTTP_LOGIN(sendBuf, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } else if ( Authenticated == false )//&& sSettings.sRADIUS.Auth_enable == true { if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // + { fs_open("/main.css", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // + { fs_open("/rotek.png", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ? { fs_open("/favicon.ico", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /role.js", 12) == 0) { fs_open("/role.js", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "POST /login.cgi", 15) == 0) { uint32_t req_data_received = 0; char *offset; offset = 0; post_data_count = Parse_Content_Length(receiveBuf, receivedBufLen); if (post_data_count < MAX_POST_REQ_LEN) { memset(post_req_data, 0, MAX_POST_REQ_LEN); offset = (strstr(receiveBuf, "\r\n\r\n")) + 4; req_data_received = receivedBufLen - (offset - &receiveBuf[0]); if (offset != 0) { if (req_data_received < post_data_count) { snprintf(post_req_data, req_data_received, "%s", receiveBuf); post_data_count -= req_data_received; ssl_server_read(); offset = receiveBuf; } if(strlen(receiveBuf) != 0) { strncat(post_req_data, offset, post_data_count); if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } else { /*if(sSettings.sRADIUS.RDSEnable == true) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len);*/ ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } post_data_count = 0; } else{ /* Redirect to login page */ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len); /* End reqest */ post_data_count = 0; } } /* request was fragmented before "\r\n\r\n" */ else { /* Redirect to login page */ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len); /* End reqest */ post_data_count = 0; } } else { //printf("Too long POST request!\r\n"); /* Ignore request */ post_data_count = 0; /* Redirect to login page */ if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len); } } else if (post_data_count > 0) { strncat(post_req_data, receiveBuf, post_data_count); if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } else { /*if(sSettings.sRADIUS.RDSEnable == true) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len);*/ ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } post_data_count = 0; log_post_reqn = 0; } else { if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len); } } else if ( Authenticated == true ) { if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // + { fs_open("/main.css", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // + { fs_open("/rotek.png", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ? { fs_open("/favicon.ico", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /main.js", 12) == 0) // + { fs_open("/main.js", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /role.js", 12) == 0) { fs_open("/role.js", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /settings.html", 18) == 0) // + { HTTP_UpdateUserLoginTime(user_id); if (seclevel == 0) { fs_open("/settings.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else { fs_open("/index.html", &file); ssl_sendframes(&ssl, file.data, file.len); } } else if (strncmp(receiveBuf, "GET /info.html", 14) == 0) // + { HTTP_UpdateUserLoginTime(user_id); fs_open("/info.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /history.html", 17) == 0) { HTTP_UpdateUserLoginTime(user_id); fs_open("/history.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /ups_history.html", 21) == 0) { HTTP_UpdateUserLoginTime(user_id); fs_open("/ups_history.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(receiveBuf, "GET /getJson.cgi", 16) == 0) // + { HTTP_GetParamsPage1(sendBuf); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else if (strncmp(receiveBuf, "GET /settings.cgi", 17) == 0) // + { if (seclevel == 0) { SET_PAGE = SET_PAGE_PAGE2; if (HTTP_SettingsPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } } } else if (strncmp(receiveBuf, "POST /settings.cgi", 18) == 0) { if (seclevel == 0) { DataOffset = 0; // POST Packet received TotalReceived = 0; TotalData = 0; memset(sendBuf, 0, strlen(sendBuf)); // parse packet for Content-length field size = Parse_Content_Length(receiveBuf, receivedBufLen); DataOffset = strstr(receiveBuf, "managerIP"); /* case of MSIE8 : we do not receive data in the POST packet*/ if (DataOffset == 0) { ssl_server_read(); DataOffset = strstr(receiveBuf, "managerIP"); } TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); for(i = TotalData; i < size; i ++) { ssl_server_read(); strncat(sendBuf, receiveBuf, receivedBufLen); TotalData += receivedBufLen; } // check if last data packet if (TotalData == size) { DBG printf("State: Received %d bytes\r\n", (int)TotalData); // printf("receive %s \r\n", sendBuf); strncat(sendBuf, " ", 1); HTTP_SetSettings(sendBuf, strlen(sendBuf)); memset(sendBuf, 0, size); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n"); strcat(sendBuf, "\r\n\r\n"); strcat(sendBuf,"\r\n\r\n"); sendBufLoadLen = strlen(sendBuf); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } } } else if (strncmp(receiveBuf, "POST /srv_crt_upload.cgi", 24) == 0) { static char boundary[70]; static char boundary_buf[70]; static char *pbound = NULL; char* ContentOffset = 0; DataOffset = 0; TotalData = 0; memset(sendBuf, 0, sizeof(sendBuf)); //printf("receive %s \r\n", receiveBuf); /* parse packet for Content-length field */ size = Parse_Content_Length(receiveBuf, receivedBufLen); pbound = Parce_Boundary(receiveBuf, receivedBufLen, boundary, sizeof(boundary)); if (pbound != NULL) { ContentOffset = strstr(receiveBuf, boundary); //ContentOffset += 4; DataOffset = strstr(ContentOffset, "\r\n\r\n"); if( DataOffset != NULL ) DataOffset += 4; } /* case of MSIE8 : we do not receive data in the POST packet*/ if (DataOffset == NULL) { ssl_server_read(); receiveBuf[receivedBufLen] = '\0'; // printf("receive2 %s \r\n", receiveBuf); if (pbound != NULL) { ContentOffset = strstr(receiveBuf, boundary); // ContentOffset += 4; DataOffset = strstr(ContentOffset, "\r\n\r\n"); if( DataOffset != NULL ) DataOffset += 4; } } TotalReceived = receivedBufLen - (uint32_t)(ContentOffset - receiveBuf); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); //for(i = TotalData; i < size; i ++) while(TotalData < size) { ssl_server_read(); receiveBuf[receivedBufLen] = '\0'; //printf("receive3 %s \r\n", receiveBuf); strncat(sendBuf, receiveBuf, receivedBufLen); TotalData += receivedBufLen; //printf("TotalData %d \r\n", TotalData); /*printf("receivedBufLen %d \r\n", receivedBufLen); printf("TotalData %d \r\n", TotalData); printf("size %d \r\n", size); printf("receive3 %s \r\n", (receiveBuf+receivedBufLen - 30));*/ } // printf("TotalData %d \r\n", TotalData); // check if last data packet if (TotalData == size) { printf("receive %s \r\n", sendBuf); if(strstr(sendBuf, "BEGIN CERTIFICATE") != NULL){ DataOffset = strstr(sendBuf, "-----END CERTIFICATE"); uint32_t len_crt = (uint32_t)(DataOffset - sendBuf) + 25; memset(sSettings.our_srv_crt, 0, sizeof(sSettings.our_srv_crt)); memcpy(sSettings.our_srv_crt, sendBuf, len_crt); strcat(sendBuf, "\r\n"); HTTP_SaveSettings(); memset(sendBuf, 0, sizeof(sendBuf)); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n"); strcat(sendBuf,"1"); } else{ memset(sendBuf, 0, sizeof(sendBuf)); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n"); strcat(sendBuf,"Некорректный сертефикат"); } ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } } else if (strncmp(receiveBuf, "GET /info.cgi", 13) == 0) // + { if (HTTP_InfoPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } } else if (strncmp(receiveBuf, "POST /info.cgi", 14) == 0) { if (seclevel == 0) { DataOffset = 0; // POST Packet received TotalReceived = 0; TotalData = 0; memset(sendBuf, 0, strlen(sendBuf)); // parse packet for Content-length field size = Parse_Content_Length(receiveBuf, receivedBufLen); DataOffset = strstr(receiveBuf, "owner"); /* case of MSIE8 : we do not receive data in the POST packet*/ if (DataOffset == 0) { ssl_server_read(); DataOffset = strstr(receiveBuf, "owner"); } TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); // check if last data packet if (TotalReceived == size) { strncat(sendBuf, " ", 1); HTTP_SetInfo(sendBuf, strlen(sendBuf)); DataFlag = 0; BrowserFlag = 0; memset(sendBuf, 0, size); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n"); strcat(sendBuf, "\r\n\r\n"); strcat(sendBuf,"\r\n\r\n"); sendBufLoadLen = strlen(sendBuf); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } // not last data packet else { // write data in flash if(receivedBufLen) { strncat(sendBuf, ptr, receivedBufLen); //memcpy(receiveBufTemp, ptr, receivedBufLen); } } } } else if (strncmp(receiveBuf, "GET /history.cgi", 16) == 0) { int res; res = HTTP_HistoryPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); if (res == SEND_REQUIRED_FILE) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); //send_data(pcb, hs); //tcp_sent(pcb, http_sent_history); HTTP_SendHistory(); //tcp_err(pcb, http_sent_log_err); } else if (res == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } } else if (strncmp(receiveBuf, "GET /ups_history.cgi", 19) == 0) { int res; res = HTTP_UpsHistoryPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); if (res == SEND_REQUIRED_FILE) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); //send_data(pcb, hs); //tcp_sent(pcb, http_sent_log); HTTP_SendLog(); //tcp_err(pcb, http_sent_log_err); } else if (res == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } } /* Тест АКБ ИБП */ else if (strncmp(receiveBuf, "GET /bat_test.cgi", 17) == 0) { HTTP_UPSTest(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } /* Выключение ИБП */ else if (strncmp(receiveBuf, "GET /ups_power.cgi", 18) == 0) { HTTP_UPSshutdown(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } /* Сброс настроек и сохранине */ else if (strncmp(receiveBuf, "GET /reset.cgi", 14) == 0) { HTTP_ResetSettings(); HTTP_SaveSettings(); fs_open("/settings.html", &file); ssl_sendframes(&ssl, file.data, file.len); } /* Перезагрузка контроллера */ else if (strncmp(receiveBuf, "GET /reboot.cgi", 15) == 0) { HTTP_Reboot(); } /* Подтверждение новых сетевых настроек */ else if (strncmp(receiveBuf, "GET /confirm.cgi", 16) == 0) { SetWebReinitFlag(false); SetConfirmWebParamsFlag(); fs_open("/index.html", &file); ssl_sendframes(&ssl, file.data, file.len); } /* Проверка пароля, переход в bootloader */ else if (strncmp(receiveBuf, "GET /fw_update.cgi", 18) == 0) { HTTP_ConfirmBootPwd(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } /* Смена пароля пользователя */ else if (strncmp(receiveBuf, "GET /changepwd.cgi", 18) == 0) { HTTP_ChangeUserPwd(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } // На производстве else if (strncmp(receiveBuf, "GET /setProdate.cgi", 19) == 0) { HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); } else { HTTP_UpdateUserLoginTime(user_id); fs_open("/index.html", &file); // + ssl_sendframes(&ssl, file.data, file.len); } } //} /* if (strncmp(buf, "GET /main.css", 13) == 0) // + { fs_open("/main.css", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /rotek.png", 14) == 0) // + { fs_open("/rotek.png", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /favicon.ico", 16) == 0) // ? { fs_open("/favicon.ico", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /main.js", 12) == 0) // + { fs_open("/main.js", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /getJson.cgi", 16) == 0) // + { HTTP_GetParamsPage1(sendBuf); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else if (strncmp(buf, "GET /settings.html", 18) == 0) // + { fs_open("/settings.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /info.html", 14) == 0) // + { fs_open("/info.html", &file); ssl_sendframes(&ssl, file.data, file.len); } else if (strncmp(buf, "GET /getJson.cgi", 16) == 0) // + { HTTP_GetParamsPage1(sendBuf); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else if (strncmp(buf, "GET /settings.cgi", 17) == 0) // + { SET_PAGE = SET_PAGE_PAGE2; if (HTTP_SettingsPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else { fs_open("/settings.html", &file); ssl_sendframes(&ssl, file.data, file.len); } } else if (strncmp(buf, "GET /info.cgi", 13) == 0) // + { if (HTTP_InfoPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES) { ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else { fs_open("/info.html", &file); ssl_sendframes(&ssl, file.data, file.len); } } // Сброс настроек и сохранине else if (strncmp(buf, "GET /reset.cgi", 14) == 0) { HTTP_ResetSettings(); HTTP_SaveSettings(); fs_open("/settings.html", &file); ssl_sendframes(&ssl, file.data, file.len); } // Перезагрузка контроллера else if (strncmp(buf, "GET /reboot.cgi", 15) == 0) { HTTP_Reboot(); } // Подтверждение новых сетевых настроек else if (strncmp(buf, "GET /confirm.cgi", 16) == 0) { SetWebReinitFlag(false); SetConfirmWebParamsFlag(); fs_open("/index.html", &file); ssl_sendframes(&ssl, file.data, file.len); } // Проверка пароля, переход в bootloader else if (strncmp(buf, "POST /checkpwd.cgi", 18) == 0) { HTTP_ConfirmBootPwd(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } // На производстве else if (strncmp(buf, "GET /setProdate.cgi", 19) == 0) { HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } // На производстве else if (strncmp(buf, "GET /progon.cgi", 15) == 0) { HTTP_Progon(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen); ssl_sendframes(&ssl, sendBuf, strlen(sendBuf)); } else { fs_open("/index.html", &file); ssl_sendframes(&ssl, file.data, file.len); } // ------------------------------------------------------------------------- */ // Для теста // 7. Write the Response //printf("\n\r => Write to client :\n\r"); // Send the dynamic html page //ssl_DynPage(&ssl); // Close the connection ssl_close_notify(&ssl); goto accept; exit: // Close and delete the current session data: certificate, RSA key and SSL session x509_free(&srvcert); rsa_free(&rsa); cur = s_list_1st; while(cur != NULL) { prv = cur; cur = cur->next; memset(prv, 0, sizeof(ssl_session)); free(prv); } memset(&ssl, 0, sizeof(ssl_context)); accept: // Wait 200s until next retry //vTaskDelay(200); // Close and free the SSL context net_close(client_fd); ssl_free(&ssl); } } /** * @brief Create and send a dynamic Web Page. This page contains the list of * running tasks and the number of page hits. * @param ssl the SSL context * @retval None */ void ssl_DynPage(ssl_context *ssl) { portCHAR buf[2024]; portCHAR pagehits[10]; portCHAR getcipher[100]; uint32_t len = 0; memset(buf, 0, 2024); // Update the hit count nPageHits++; sprintf( pagehits, "%d", nPageHits ); sprintf( (char *) getcipher, HTTP_RESPONSE, ssl_get_ciphersuite(ssl)); // Generate the dynamic page strcpy(buf, PAGE_START); // Page header strcat(buf, pagehits); strcat((char *) buf, "
** The list of tasks and their status **");
  strcat((char *) buf, "
---------------------------------------------"); 
  strcat((char *) buf, "
Name State Priority Stack Num" ); //strcat((char *) buf, "
---------------------------------------------"); strcat((char *) buf, "
---------------------------------------------
"); // The list of tasks and their status vTaskList((signed char *)buf + strlen(buf)); strcat((char *) buf, "
---------------------------------------------"); strcat((char *) buf, "
B : Blocked, R : Ready, D : Deleted, S : Suspended"); // The current cipher used strcat(buf, getcipher); // Page footer strcat(buf, PAGE_END); // Send the dynamically generated page len = ssl_write(ssl, (unsigned char *)buf, strlen(buf)); // Display the length of application data //printf( "\n Successfully write %d bytes to client\n\r", len); } /** * @brief This function is used to send messages with size upper 16k bytes. * @param ssl SSL context * @param data buffer holding the data * @param len how many bytes must be written * @retval None */ #define FRAME_SIZE (1000) void ssl_sendframes( ssl_context *ssl, char *data, int datalen ) { int index = 0; int k = 0; int lastframe, nbrframes; // Calculate the number of frames nbrframes = datalen / FRAME_SIZE; // Send nbrframes frames while(nbrframes > 0) { index = k * FRAME_SIZE; ssl_write( ssl, (unsigned char *)(data + index), FRAME_SIZE ); nbrframes--; k++; } // Send the last frame index = k * FRAME_SIZE; lastframe = datalen % FRAME_SIZE ; ssl_write( ssl, (unsigned char *)(data + index), lastframe ); } /** * @brief Returns a 32-bit random number. * @param arg not used * @retval 32-bit random number */ int RandVal(void* arg) { return (int)GetRandomNumber(); } /** * @brief Send callback for log file transfer (messages as is, not ordered) */ void HTTP_SendHistory(void) { uint32_t nbytes = 0; static bool start = true; memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN <= log_size) { nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start); } else if (log_ptr < log_size) { nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { // File transfer finished. start = true; // Clear file transfer in progress flag fLogTransInprog = false; return; } ssl_sendframes(&ssl, logFileBuf, nbytes); HTTP_SendHistory(); } /** * @brief Sent callback for log file transfer (messages as is, not ordered) */ void HTTP_SendLog(void) { uint32_t nbytes = 0; static bool start = true; memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start); } else if (log_ptr < log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { // File transfer finished. start = true; // Clear file transfer in progress flag fLogTransInprog = false; return; } ssl_sendframes(&ssl, logFileBuf, nbytes); HTTP_SendLog(); return; } /** * @brief Initialize the HTTPS server (start its thread) */ void HTTPS_Init() { char buf[MAX_WEB_COOKIE_LEN]; uint8_t user_id; for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { // Flush user cookie by random value sprintf(buf, "%X", (unsigned int)GetRandomNumber()); HTTP_SetUserCookie(buf, user_id); // Create user logout timers users[user_id].LogoutTimer = xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback); } RepeatLoginTimer = xTimerCreate("LoginTmr", REPEAT_LOGIN_TIME, pdFALSE, ( void * ) 0, LoginTimerCallback); } #endif // ----------------------------------------------------------------------------- #include "mbedtls/platform.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/certs.h" #include "mbedtls/x509.h" //#include "mbedtls/ssl.h" #include "mbedtls/net_sockets.h" #include "mbedtls/error.h" #include "mbedtls/debug.h" #include "mbedtls/memory_buffer_alloc.h" #include "mbedtls_time.h" #include "mbedtls_debug.h" #include "FreeRTOS.h" #include "task.h" #include #include char HTTP_RESPONSE[] = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n \

mbed TLS Test Server

\r\n \

Successful connection using: %s

\r\n"; static mbedtls_net_context listen_fd, client_fd; static const uint8_t *pers = (uint8_t *)("ssl_server"); mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt srvcert; mbedtls_pk_context pkey; char CookieBuf[50]; char *CookiePtr = NULL; char name[MAX_WEB_COOKIE_LEN]; char id[MAX_WEB_COOKIE_LEN]; uint8_t nameLen = 0, idLen = 0; uint8_t user_id; // Id of currently logged-in user struct fs_file file = {0, 0}; #define HEAP_SIZE (1u << 14) // 16k unsigned char malloc_buf[HEAP_SIZE]; // void Cockie(void) { receiveBuf[receivedBufLen] = '\0'; // printf("receive %s \r\n", receiveBuf); // Get cookie "uname" value CookiePtr = strstr(receiveBuf, "uname="); strncpy(CookieBuf, CookiePtr, 50); //printf("********CookieBuf1= %s\r\n", CookieBuf); memset(name, 0, MAX_WEB_COOKIE_LEN); GetCookieValue(CookieBuf, "uname=", name, &nameLen); //printf("********CookieBuf2= %s\r\n", CookieBuf); //printf("********uname= %s\r\n", name); // Get cookie "id" value CookiePtr = strstr(receiveBuf, "id="); strncpy(CookieBuf, CookiePtr, 50); //printf("********CookieBuf1= %s\r\n", CookieBuf); memset(id, 0, MAX_WEB_COOKIE_LEN); GetCookieValue(CookieBuf, "id=", id, &idLen); } // void getAuthenticatedState(void) { seclevel = 0xFF; for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { HTTP_GetUserCookie(user_id, CookieBuf, &idLen); if (strncmp(id, CookieBuf, idLen) == 0 ) { GetUserLevelInt(user_id, &seclevel); Authenticated = true; break; } Authenticated = false; seclevel = 0xFF; } } // void ssl_server(void *pvParameters) { SSL_SERVER_STATE ssl_state = SSL_ACCEPT; char* sendPtr; int ret; #ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C mbedtls_memory_buffer_alloc_init(malloc_buf, sizeof(malloc_buf)); #endif mbedtls_net_init( &listen_fd ); mbedtls_net_init( &client_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); mbedtls_x509_crt_init( &srvcert ); mbedtls_pk_init( &pkey ); mbedtls_entropy_init( &entropy ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_platform_set_time(&MBEDTLS_GetTime); #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold(DEBUG_LEVEL); mbedtls_ssl_conf_dbg(&conf, MBEDTLS_Debug, NULL); #endif // 1. Load the certificates and private RSA key mbedtls_printf( "\r\n . Loading the server cert. and key..." ); ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt, mbedtls_test_srv_crt_len ); if( ret != 0 ) { mbedtls_printf( " failed\r\n ! mbedtls_x509_crt_parse returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0 ); if( ret != 0 ) { mbedtls_printf( " failed\r\n ! mbedtls_pk_parse_key returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } mbedtls_printf( " ok\r\n" ); // 2. Setup the listening TCP socket mbedtls_printf( " . Bind on https://localhost:443/ ..." ); if((ret = mbedtls_net_bind(&listen_fd, NULL, "443", MBEDTLS_NET_PROTO_TCP )) != 0) { mbedtls_printf( " failed\n ! mbedtls_net_bind returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } mbedtls_printf( " ok\r\n" ); // 3. Seed the RNG mbedtls_printf( " . Seeding the random number generator..." ); if((ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( (char *)pers))) != 0) { mbedtls_printf( " failed\r\n ! mbedtls_ctr_drbg_seed returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } mbedtls_printf( " ok\r\n" ); // 4. Setup stuff mbedtls_printf( " . Setting up the SSL data...." ); if( ( ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_config_defaults returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL); if( ( ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey ) ) != 0) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_conf_own_cert returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_setup returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } mbedtls_printf( " ok\r\n" ); for (;;) { switch (ssl_state) { case SSL_ACCEPT : mbedtls_net_free( &client_fd ); mbedtls_ssl_session_reset( &ssl ); mbedtls_printf( " . Waiting for a remote connection ...\r\n" ); if((ret = mbedtls_net_accept(&listen_fd, &client_fd, NULL, 0, NULL)) != 0) { mbedtls_printf( " failed\r\n ! mbedtls_net_accept returned %d\r\n", ret ); ssl_state = SSL_CRITICAL_ERROR; } else { mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL ); mbedtls_printf( " ok\r\n" ); ssl_state = SSL_HANDSHAKE; } break; case SSL_HANDSHAKE : mbedtls_printf( " . Performing the SSL/TLS handshake..." ); while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) { if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_handshake returned %d\r\n", ret ); ssl_state = SSL_ACCEPT; break; } } mbedtls_printf( " ok\r\n" ); ssl_state = SSL_READ; break; case SSL_READ : SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); ssl_state = SSL_PROCESSING; break; case SSL_PROCESSING : sendPtr = SSL_ProcessingRoutine(&sendBufLoadLen); if (sendPtr) ssl_state = SSL_WRITE; else ssl_state = SSL_ACCEPT; break; case SSL_WRITE : ssl_state = SSL_WriteRoutine(&ssl, sendPtr, sendBufLoadLen); break; case SSL_ERROR : break; case SSL_CRITICAL_ERROR: mbedtls_x509_crt_free( &srvcert ); mbedtls_pk_free( &pkey ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); vTaskDelete(NULL); break; } } } /** * @brief Initialize the HTTPS server (start its thread) */ void HTTPS_Init() { char buf[MAX_WEB_COOKIE_LEN]; uint8_t user_id; for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { // Flush user cookie by random value sprintf(buf, "%X", (unsigned int)GetRandomNumber()); HTTP_SetUserCookie(buf, user_id); // Create user logout timers users[user_id].LogoutTimer = xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback); } RepeatLoginTimer = xTimerCreate("LoginTmr", REPEAT_LOGIN_TIME, pdFALSE, ( void * ) 0, LoginTimerCallback); } // void SSL_ReadRoutine(mbedtls_ssl_context *ssl, unsigned char* recvBuf) { int ret; mbedtls_printf( " < Read from client:" ); do { receivedBufLen = RECIVE_BUF_MAX_LEN - 1; memset(recvBuf, 0, RECIVE_BUF_MAX_LEN); ret = mbedtls_ssl_read(ssl, recvBuf, (size_t)receiveBuf); //memset(receiveBuf, 0, RECIVE_BUF_MAX_LEN); //ret = mbedtls_ssl_read(ssl, receiveBuf, receivedBufLen); if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) { continue; } if( ret <= 0 ) { switch( ret ) { case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: mbedtls_printf( " connection was closed gracefully\r\n" ); break; case MBEDTLS_ERR_NET_CONN_RESET: mbedtls_printf( " connection was reset by peer\r\n" ); break; default: mbedtls_printf( " mbedtls_ssl_read returned -0x%x\r\n", -ret ); break; } break; } receivedBufLen = ret; //mbedtls_printf( " %d bytes read\r\n%s", len, (char *) receiveBuf ); mbedtls_printf( " %d bytes read\r\n", receivedBufLen); printf(receiveBuf); printf("\r\n"); if( ret > 0 ) break; } while(1); } // SSL_SERVER_STATE SSL_WriteRoutine(mbedtls_ssl_context *ssl, char *data, int datalen) { return SSL_SendFrames(ssl, data, datalen); } // char* SSL_ProcessingRoutine(uint16_t* sendLen) { Cockie(); getAuthenticatedState(); if ( Authenticated == false && sSettings.sRADIUS.Auth_enable == false) { HTTP_LOGIN(sendBuf, sendLen); return sendBuf; } else if (!Authenticated)//&& sSettings.sRADIUS.Auth_enable == true { return AuthenticatedFalseRoutine(sendLen); } else { return AuthenticatedTrueRoutine(sendLen); } } // char* AuthenticatedFalseRoutine(uint16_t* sendLen) { if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // + { fs_open("/main.css", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // + { fs_open("/rotek.png", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ? { fs_open("/favicon.ico", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /role.js", 12) == 0) { fs_open("/role.js", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "POST /login.cgi", 15) == 0) { uint32_t req_data_received = 0; char *offset = 0; post_data_count = Parse_Content_Length(receiveBuf, receivedBufLen); if (post_data_count < MAX_POST_REQ_LEN) { memset(post_req_data, 0, MAX_POST_REQ_LEN); offset = (strstr(receiveBuf, "\r\n\r\n")) + 4; req_data_received = receivedBufLen - (offset - &receiveBuf[0]); if (offset != 0) { if (req_data_received < post_data_count) { snprintf(post_req_data, req_data_received, "%s", receiveBuf); post_data_count -= req_data_received; //ssl_server_read(); SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); offset = receiveBuf; } if(strlen(receiveBuf) != 0) { strncat(post_req_data, offset, post_data_count); if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), sendLen) == SEND_REQUIRED_YES) { return sendBuf; } else { /*if(sSettings.sRADIUS.RDSEnable == true) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); ssl_sendframes(&ssl, file.data, file.len);*/ //ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); return sendBuf; } post_data_count = 0; } else { // Redirect to login page if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); post_data_count = 0; *sendLen = file.len; return file.data; } } // request was fragmented before "\r\n\r\n" else { // Redirect to login page if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); post_data_count = 0; *sendLen = file.len; return file.data; } } else { //printf("Too long POST request!\r\n"); // Ignore request post_data_count = 0; // Redirect to login page if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); *sendLen = file.len; return file.data; } } else if (post_data_count > 0) { strncat(post_req_data, receiveBuf, post_data_count); post_data_count = 0; log_post_reqn = 0; if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), sendLen) == SEND_REQUIRED_YES) { //ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); return sendBuf; } else { //ssl_sendframes(&ssl, sendBuf, sendBufLoadLen); return sendBuf; } } else { if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) fs_open("/rslogin.html", &file); else fs_open("/login.html", &file); *sendLen = file.len; return file.data; } } // char* AuthenticatedTrueRoutine(uint16_t* sendLen) { char *DataOffset; char *ptr; if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // + { fs_open("/main.css", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // + { fs_open("/rotek.png", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ? { fs_open("/favicon.ico", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /main.js", 12) == 0) // + { fs_open("/main.js", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /role.js", 12) == 0) { fs_open("/role.js", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /settings.html", 18) == 0) // + { HTTP_UpdateUserLoginTime(user_id); if (seclevel == 0) fs_open("/settings.html", &file); else fs_open("/index.html", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /info.html", 14) == 0) // + { HTTP_UpdateUserLoginTime(user_id); fs_open("/info.html", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /history.html", 17) == 0) { HTTP_UpdateUserLoginTime(user_id); fs_open("/history.html", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /ups_history.html", 21) == 0) { HTTP_UpdateUserLoginTime(user_id); fs_open("/ups_history.html", &file); *sendLen = file.len; return file.data; } else if (strncmp(receiveBuf, "GET /getJson.cgi", 16) == 0) // + { HTTP_GetParamsPage1(sendBuf); *sendLen = strlen(sendBuf); return sendBuf; } else if (strncmp(receiveBuf, "GET /settings.cgi", 17) == 0) // + { if (seclevel == 0) { SET_PAGE = SET_PAGE_PAGE2; if (HTTP_SettingsPage(receiveBuf, sendBuf, receivedBufLen, sendLen) == SEND_REQUIRED_YES) { *sendLen = strlen(sendBuf); return sendBuf; } } return 0; } else if (strncmp(receiveBuf, "POST /settings.cgi", 18) == 0) { if (seclevel == 0) { DataOffset = 0; // POST Packet received TotalReceived = 0; TotalData = 0; memset(sendBuf, 0, strlen(sendBuf)); // parse packet for Content-length field size = Parse_Content_Length(receiveBuf, receivedBufLen); DataOffset = strstr(receiveBuf, "managerIP"); /* case of MSIE8 : we do not receive data in the POST packet*/ if (DataOffset == 0) { //ssl_server_read(); SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); DataOffset = strstr(receiveBuf, "managerIP"); } TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); for (int i = TotalData; i < size; i ++) { //ssl_server_read(); SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); strncat(sendBuf, receiveBuf, receivedBufLen); TotalData += receivedBufLen; } // check if last data packet if (TotalData == size) { DBG printf("State: Received %d bytes\r\n", (int)TotalData); // printf("receive %s \r\n", sendBuf); strncat(sendBuf, " ", 1); HTTP_SetSettings(sendBuf, strlen(sendBuf)); memset(sendBuf, 0, size); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n"); strcat(sendBuf, "\r\n\r\n"); strcat(sendBuf,"\r\n\r\n"); sendBufLoadLen = strlen(sendBuf); *sendLen = sendBufLoadLen; return sendBuf; } } return 0; } else if (strncmp(receiveBuf, "POST /srv_crt_upload.cgi", 24) == 0) { static char boundary[70]; static char *pbound = NULL; char* ContentOffset = 0; DataOffset = 0; TotalData = 0; memset(sendBuf, 0, sizeof(sendBuf)); //printf("receive %s \r\n", receiveBuf); // parse packet for Content-length field size = Parse_Content_Length(receiveBuf, receivedBufLen); pbound = Parce_Boundary(receiveBuf, receivedBufLen, boundary, sizeof(boundary)); if (pbound != NULL) { ContentOffset = strstr(receiveBuf, boundary); //ContentOffset += 4; DataOffset = strstr(ContentOffset, "\r\n\r\n"); if( DataOffset != NULL ) DataOffset += 4; } // case of MSIE8 : we do not receive data in the POST packet if (DataOffset == NULL) { SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); receiveBuf[receivedBufLen] = '\0'; printf("receive2 %s \r\n", receiveBuf); if (pbound != NULL) { ContentOffset = strstr(receiveBuf, boundary); // ContentOffset += 4; DataOffset = strstr(ContentOffset, "\r\n\r\n"); if( DataOffset != NULL ) DataOffset += 4; } } TotalReceived = receivedBufLen - (uint32_t)(ContentOffset - receiveBuf); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); while(TotalData < size) { SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); receiveBuf[receivedBufLen] = '\0'; //printf("receive3 %s \r\n", receiveBuf); strncat(sendBuf, receiveBuf, receivedBufLen); TotalData += receivedBufLen; //printf("TotalData %d \r\n", TotalData); /*printf("receivedBufLen %d \r\n", receivedBufLen); printf("TotalData %d \r\n", TotalData); printf("size %d \r\n", size); printf("receive3 %s \r\n", (receiveBuf+receivedBufLen - 30));*/ } printf("TotalData %d \r\n", TotalData); // check if last data packet if (TotalData == size) { printf("receive %s \r\n", sendBuf); if(strstr(sendBuf, "BEGIN CERTIFICATE") != NULL) { DataOffset = strstr(sendBuf, "-----END CERTIFICATE"); uint32_t len_crt = (uint32_t)(DataOffset - sendBuf) + 25; memset(sSettings.our_srv_crt, 0, sizeof(sSettings.our_srv_crt)); memcpy(sSettings.our_srv_crt, sendBuf, len_crt); strcat(sendBuf, "\r\n"); HTTP_SaveSettings(); memset(sendBuf, 0, sizeof(sendBuf)); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n"); strcat(sendBuf,"1"); } else { memset(sendBuf, 0, sizeof(sendBuf)); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n"); strcat(sendBuf,"Некорректный сертефикат"); } *sendLen = strlen(sendBuf); return sendBuf; } } else if (strncmp(receiveBuf, "GET /info.cgi", 13) == 0) // + { if (HTTP_InfoPage(receiveBuf, sendBuf, receivedBufLen, sendLen) == SEND_REQUIRED_YES) { return sendBuf; } } else if (strncmp(receiveBuf, "POST /info.cgi", 14) == 0) { if (seclevel == 0) { DataOffset = 0; // POST Packet received TotalReceived = 0; TotalData = 0; memset(sendBuf, 0, strlen(sendBuf)); // parse packet for Content-length field size = Parse_Content_Length(receiveBuf, receivedBufLen); DataOffset = strstr(receiveBuf, "owner"); // case of MSIE8 : we do not receive data in the POST packet if (DataOffset == 0) { SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf); DataOffset = strstr(receiveBuf, "owner"); } TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]); TotalData += TotalReceived; strncat(sendBuf, DataOffset, TotalReceived); // check if last data packet if (TotalReceived == size) { strncat(sendBuf, " ", 1); HTTP_SetInfo(sendBuf, strlen(sendBuf)); DataFlag = 0; BrowserFlag = 0; memset(sendBuf, 0, size); strcpy(sendBuf, "HTTP/1.1 200 OK\r\n"); strcat(sendBuf, "\r\n\r\n"); strcat(sendBuf,"\r\n\r\n"); *sendLen = strlen(sendBuf); return sendBuf; } // not last data packet else { // write data in flash if(receivedBufLen) { strncat(sendBuf, ptr, receivedBufLen); //memcpy(receiveBufTemp, ptr, receivedBufLen); } } } } else if (strncmp(receiveBuf, "GET /history.cgi", 16) == 0) { int res; res = HTTP_HistoryPage(receiveBuf, sendBuf, receivedBufLen, sendLen); if (res == SEND_REQUIRED_FILE) { if (SSL_SendFrames(&ssl, sendBuf, sendBufLoadLen) == SSL_ERROR) return 0; HTTP_SendHistory(); return 0; } else if (res == SEND_REQUIRED_YES) { return sendBuf; } } else if (strncmp(receiveBuf, "GET /ups_history.cgi", 19) == 0) { int res; res = HTTP_UpsHistoryPage(receiveBuf, sendBuf, receivedBufLen, sendLen); if (res == SEND_REQUIRED_FILE) { if (SSL_SendFrames(&ssl, sendBuf, sendBufLoadLen) == SSL_ERROR) return 0; HTTP_SendLog(); return 0; } else if (res == SEND_REQUIRED_YES) { return sendBuf; } } /* Тест АКБ ИБП */ else if (strncmp(receiveBuf, "GET /bat_test.cgi", 17) == 0) { HTTP_UPSTest(receiveBuf, sendBuf, receivedBufLen, sendLen); return sendBuf; } /* Выключение ИБП */ else if (strncmp(receiveBuf, "GET /ups_power.cgi", 18) == 0) { HTTP_UPSshutdown(receiveBuf, sendBuf, receivedBufLen, sendLen); return sendBuf; } /* Сброс настроек и сохранине */ else if (strncmp(receiveBuf, "GET /reset.cgi", 14) == 0) { HTTP_ResetSettings(); HTTP_SaveSettings(); fs_open("/settings.html", &file); *sendLen = file.len; return file.data; } /* Перезагрузка контроллера */ else if (strncmp(receiveBuf, "GET /reboot.cgi", 15) == 0) { HTTP_Reboot(); } /* Подтверждение новых сетевых настроек */ else if (strncmp(receiveBuf, "GET /confirm.cgi", 16) == 0) { SetWebReinitFlag(false); SetConfirmWebParamsFlag(); fs_open("/index.html", &file); *sendLen = file.len; return file.data; } /* Проверка пароля, переход в bootloader */ else if (strncmp(receiveBuf, "GET /fw_update.cgi", 18) == 0) { HTTP_ConfirmBootPwd(receiveBuf, sendBuf, receivedBufLen, sendLen); return sendBuf; } /* Смена пароля пользователя */ else if (strncmp(receiveBuf, "GET /changepwd.cgi", 18) == 0) { HTTP_ChangeUserPwd(receiveBuf, sendBuf, receivedBufLen, sendLen); return sendBuf; } // На производстве else if (strncmp(receiveBuf, "GET /setProdate.cgi", 19) == 0) { HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, sendLen); return sendBuf; } else { HTTP_UpdateUserLoginTime(user_id); fs_open("/index.html", &file); // + *sendLen = file.len; return file.data; } return 0; } #define FRAME_SIZE (1000) SSL_SERVER_STATE SSL_SendFrames(mbedtls_ssl_context *ssl, char *data, int datalen) { SSL_SERVER_STATE ret; int retClose; int index = 0; int k = 0; int lastframe, nbrframes; nbrframes = datalen / FRAME_SIZE; while(nbrframes > 0) { index = k * FRAME_SIZE; if (SSL_Write(ssl, (data + index), FRAME_SIZE ) == SSL_CRITICAL_ERROR) return SSL_CRITICAL_ERROR; nbrframes--; k++; } index = k * FRAME_SIZE; lastframe = datalen % FRAME_SIZE ; if (SSL_Write(ssl, (data + index), lastframe ) == SSL_CRITICAL_ERROR) return SSL_CRITICAL_ERROR; mbedtls_printf( " . Closing the connection..." ); while( ( retClose = mbedtls_ssl_close_notify( ssl ) ) < 0 ) { if( retClose != MBEDTLS_ERR_SSL_WANT_READ && retClose != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_close_notify returned %d\r\n", ret ); return SSL_ERROR; } } mbedtls_printf( " ok\r\n" ); return SSL_ACCEPT; } SSL_SERVER_STATE SSL_Write(mbedtls_ssl_context *ssl, char *data, int datalen) { int ret; mbedtls_printf( " > Write to client:" ); while( ( ret = mbedtls_ssl_write(ssl, data, datalen) ) <= 0 ) { if( ret == MBEDTLS_ERR_NET_CONN_RESET ) { mbedtls_printf( " failed\r\n ! peer closed the connection\r\n" ); return SSL_ACCEPT; } if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_write returned %d\r\n", ret ); //return SSL_CRITICAL_ERROR; // TODO заменить на особоый дит ошибки return SSL_ACCEPT; } } mbedtls_printf( " %d bytes written\r\n", ret); /* mbedtls_printf( " . Closing the connection..." ); while( ( ret = mbedtls_ssl_close_notify( ssl ) ) < 0 ) { if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\r\n ! mbedtls_ssl_close_notify returned %d\r\n", ret ); return SSL_ACCEPT; } } mbedtls_printf( " ok\r\n" ); */ ret = 0; return SSL_ACCEPT; } /** * @brief Send callback for log file transfer (messages as is, not ordered) */ void HTTP_SendHistory(void) { uint32_t nbytes = 0; static bool start = true; memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN <= log_size) { nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start); } else if (log_ptr < log_size) { nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { // File transfer finished. start = true; // Clear file transfer in progress flag fLogTransInprog = false; return; } SSL_SendFrames(&ssl, logFileBuf, nbytes); HTTP_SendHistory(); } /** * @brief Sent callback for log file transfer (messages as is, not ordered) */ void HTTP_SendLog(void) { uint32_t nbytes = 0; static bool start = true; memset(logFileBuf, 0, FILE_BUF_MAX_LEN); if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start); } else if (log_ptr < log_size) { nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start); } else { nbytes = 0; } log_ptr += nbytes; start = false; if (nbytes == 0) { // File transfer finished. start = true; // Clear file transfer in progress flag fLogTransInprog = false; return; } SSL_SendFrames(&ssl, logFileBuf, nbytes); HTTP_SendLog(); return; }