|
@@ -48,6 +48,10 @@ 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);
|
|
|
+void send_file(char *filename, char *pnonmatch, struct fs_file *file);
|
|
|
+static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value);
|
|
|
+bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen);
|
|
|
+
|
|
|
|
|
|
SET_PAGE_t SET_PAGE = SET_PAGE_IDLE;
|
|
|
|
|
@@ -91,6 +95,13 @@ bool Authenticated = false;
|
|
|
/* Level of currently logged-in user */
|
|
|
uint8_t seclevel = 0xFF;
|
|
|
|
|
|
+/* Max HTTP file name length including "/" */
|
|
|
+#define MAX_FILENAME_LEN 32
|
|
|
+/* Max HTTP Etag field length */
|
|
|
+#define MAX_ETAG_LEN 48
|
|
|
+static const char If_None_Match[] = "If-None-Match: ";
|
|
|
+static const char Etag[] = "ETag: ";
|
|
|
+
|
|
|
static volatile uint32_t DataFlag2=0;
|
|
|
static volatile uint32_t DataFlag=0;
|
|
|
static volatile uint32_t size =0;
|
|
@@ -103,6 +114,7 @@ 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_304_NOT_MODIFIED[] = "HTTP/1.1 304 Not Modified\r\n\r\n";
|
|
|
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};
|
|
@@ -2830,6 +2842,8 @@ void HTTPS_Init()
|
|
|
#include "FreeRTOS.h"
|
|
|
#include "task.h"
|
|
|
|
|
|
+#include "cert_req.h"
|
|
|
+
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
|
|
@@ -2857,6 +2871,8 @@ struct fs_file file = {0, 0};
|
|
|
#define HEAP_SIZE (1u << 14) // 16k
|
|
|
unsigned char malloc_buf[HEAP_SIZE];
|
|
|
|
|
|
+extern unsigned char req_cert[];
|
|
|
+
|
|
|
//
|
|
|
void Cockie(void)
|
|
|
{
|
|
@@ -2901,6 +2917,7 @@ void ssl_server(void *pvParameters)
|
|
|
SSL_SERVER_STATE ssl_state = SSL_ACCEPT;
|
|
|
char* sendPtr;
|
|
|
int ret;
|
|
|
+ TickType_t handshakeTime = 0;
|
|
|
|
|
|
#ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
|
|
mbedtls_memory_buffer_alloc_init(malloc_buf, sizeof(malloc_buf));
|
|
@@ -3008,6 +3025,7 @@ void ssl_server(void *pvParameters)
|
|
|
case SSL_HANDSHAKE :
|
|
|
|
|
|
mbedtls_printf( " . Performing the SSL/TLS handshake..." );
|
|
|
+ handshakeTime = xTaskGetTickCount();
|
|
|
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
|
|
{
|
|
|
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
@@ -3022,6 +3040,7 @@ void ssl_server(void *pvParameters)
|
|
|
ssl_state = SSL_ERROR;
|
|
|
else {
|
|
|
mbedtls_printf( " ok\r\n" );
|
|
|
+ printf("HANDSHAKE_TIME: %d ms\r\n", xTaskGetTickCount() - handshakeTime);
|
|
|
ssl_state = SSL_READ;
|
|
|
}
|
|
|
|
|
@@ -3060,6 +3079,7 @@ void ssl_server(void *pvParameters)
|
|
|
case SSL_ERROR :
|
|
|
//mbedtls_net_free(&client_fd);
|
|
|
//mbedtls_ssl_free( &ssl );
|
|
|
+ mbedtls_ssl_close_notify(&ssl);
|
|
|
mbedtls_net_free(&client_fd);
|
|
|
ssl_state = SSL_ACCEPT;
|
|
|
break;
|
|
@@ -3175,6 +3195,30 @@ char* SSL_ProcessingRoutine(uint16_t* sendLen)
|
|
|
//
|
|
|
char* AuthenticatedFalseRoutine(uint16_t* sendLen)
|
|
|
{
|
|
|
+ if (strncmp(receiveBuf, "GET", 3) == 0) {
|
|
|
+ char filename[MAX_FILENAME_LEN];
|
|
|
+ char nonmatch[MAX_ETAG_LEN];
|
|
|
+ char *pnonmatch = NULL;
|
|
|
+ uint8_t len;
|
|
|
+
|
|
|
+ if (GetFileName(receiveBuf, filename, &len)) {
|
|
|
+ HTTP_UpdateUserLoginTime(user_id);
|
|
|
+
|
|
|
+ /* Parce If-Non_Match value */
|
|
|
+ uint8_t nonmatch_len = Parse_Header(receiveBuf, receivedBufLen, If_None_Match, 15, nonmatch);
|
|
|
+ if (nonmatch_len < MAX_ETAG_LEN && nonmatch_len > 0) {
|
|
|
+ DBG printf("If_None_Match: %s\r\n", nonmatch);
|
|
|
+ pnonmatch = nonmatch;
|
|
|
+ }
|
|
|
+ memset(sendBuf, 0, sizeof(sendBuf));
|
|
|
+ send_file(filename, pnonmatch, &file);
|
|
|
+
|
|
|
+ if (strlen(sendBuf)) {
|
|
|
+ *sendLen = strlen(sendBuf);
|
|
|
+ return sendBuf;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // +
|
|
|
{
|
|
|
fs_open("/main.css", &file);
|
|
@@ -3318,6 +3362,31 @@ char* AuthenticatedTrueRoutine(uint16_t* sendLen)
|
|
|
char *DataOffset;
|
|
|
char *ptr;
|
|
|
|
|
|
+ if (strncmp(receiveBuf, "GET", 3) == 0) {
|
|
|
+ char filename[MAX_FILENAME_LEN];
|
|
|
+ char nonmatch[MAX_ETAG_LEN];
|
|
|
+ char *pnonmatch = NULL;
|
|
|
+ uint8_t len;
|
|
|
+
|
|
|
+ if (GetFileName(receiveBuf, filename, &len)) {
|
|
|
+ HTTP_UpdateUserLoginTime(user_id);
|
|
|
+
|
|
|
+ /* Parce If-Non_Match value */
|
|
|
+ uint8_t nonmatch_len = Parse_Header(receiveBuf, receivedBufLen, If_None_Match, 15, nonmatch);
|
|
|
+ if (nonmatch_len < MAX_ETAG_LEN && nonmatch_len > 0) {
|
|
|
+ DBG printf("If_None_Match: %s\r\n", nonmatch);
|
|
|
+ pnonmatch = nonmatch;
|
|
|
+ }
|
|
|
+ memset(sendBuf, 0, sizeof(sendBuf));
|
|
|
+ send_file(filename, pnonmatch, &file);
|
|
|
+
|
|
|
+ if (strlen(sendBuf)) {
|
|
|
+ *sendLen = strlen(sendBuf);
|
|
|
+ return sendBuf;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // +
|
|
|
{
|
|
|
fs_open("/main.css", &file);
|
|
@@ -3449,6 +3518,19 @@ char* AuthenticatedTrueRoutine(uint16_t* sendLen)
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
+ else if (strncmp(receiveBuf, "GET /getcert.cgi", 16) == 0)
|
|
|
+ {
|
|
|
+ /* Send HTTP header first (Safari needs it) */
|
|
|
+
|
|
|
+ strcpy(sendBuf, HTTP_200_OK);
|
|
|
+ *sendLen = strlen(sendBuf);
|
|
|
+ SSL_WriteRoutine(&ssl, sendBuf, *sendLen);
|
|
|
+
|
|
|
+ // SSL_Test();
|
|
|
+
|
|
|
+ *sendLen = strlen(req_cert);
|
|
|
+ return req_cert;
|
|
|
+ }
|
|
|
else if (strncmp(receiveBuf, "POST /srv_crt_upload.cgi", 24) == 0)
|
|
|
{
|
|
|
static char boundary[70];
|
|
@@ -3830,3 +3912,127 @@ void HTTP_SendLog(void)
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief sends file from flash FS
|
|
|
+ * @param filename: pointer to the file name to send
|
|
|
+ * @param pnonmatch: pointer to the If-Non_Match value
|
|
|
+ * @param pcb: pointer to a tcp_pcb struct
|
|
|
+ * @param hs: pointer to a http_state struct
|
|
|
+ * @param file: pointer to a fs_file struct
|
|
|
+ * @retval
|
|
|
+ */
|
|
|
+void send_file(char *filename, char *pnonmatch, struct fs_file *file)
|
|
|
+{
|
|
|
+ int res = 0;
|
|
|
+ char etag[MAX_ETAG_LEN];
|
|
|
+ char *petag = NULL;
|
|
|
+
|
|
|
+ res = fs_open(filename, file);
|
|
|
+
|
|
|
+ if (res == 0) {
|
|
|
+ printf("Not found: %s\r\n", filename);
|
|
|
+ sprintf(filename, "/index.html");
|
|
|
+ fs_open(filename, file);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Find Etag value */
|
|
|
+ uint8_t etag_len = Parse_Header(file->data, file->len, Etag, 6, etag);
|
|
|
+ if (etag_len < MAX_ETAG_LEN && etag_len > 0) {
|
|
|
+ DBG printf("Etag: %s\r\n", etag);
|
|
|
+ petag = etag;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Compare Etag and If-Non-Match fields */
|
|
|
+ if (pnonmatch && petag && (strcmp(pnonmatch, petag) == 0)) {
|
|
|
+ /* Send 304 code */
|
|
|
+ sprintf(sendBuf, HTTP_304_NOT_MODIFIED);
|
|
|
+ DBG printf(sendBuf);
|
|
|
+ //hs->file = sendBuf;
|
|
|
+ //hs->left = strlen(sendBuf);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* Send file */
|
|
|
+ //DBG printf("%s\r\n\r\n", filename);
|
|
|
+ //hs->file = file->data;
|
|
|
+ //hs->left = file->len;
|
|
|
+ }
|
|
|
+
|
|
|
+ //send_data(pcb, hs);
|
|
|
+ //tcp_sent(pcb, http_sent);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Extract the custom field data from HTML data
|
|
|
+ * @param data : pointer on receive packet buffer
|
|
|
+ * @param len : buffer length
|
|
|
+ * @param field : field name
|
|
|
+ * @param flen : field name length
|
|
|
+ * @retval value : pointer for field data
|
|
|
+ */
|
|
|
+static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value)
|
|
|
+{
|
|
|
+ uint32_t i = 0, size = 0;
|
|
|
+ char *ptr;
|
|
|
+ uint32_t Offset = 0;
|
|
|
+
|
|
|
+ /* Find field name in data buffer */
|
|
|
+ for (i = 0; i < len; i++) {
|
|
|
+ if (strncmp ((char*)(data + i), field, flen) == 0) {
|
|
|
+ Offset = i + flen;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* Copy Field value */
|
|
|
+ if (Offset) {
|
|
|
+ i = 0;
|
|
|
+ ptr = (char*)(data + Offset);
|
|
|
+ while (*(ptr + i) != 0x0d) {
|
|
|
+ value[i] = *(ptr + i);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ value[i] = '\0';
|
|
|
+ size = i;
|
|
|
+ }
|
|
|
+ return size;
|
|
|
+}
|
|
|
+/**
|
|
|
+ * @brief
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen)
|
|
|
+{
|
|
|
+ char *beginValue = NULL;
|
|
|
+ char *endValue = NULL;
|
|
|
+ int len = 0;
|
|
|
+ char *strPtr = NULL;
|
|
|
+
|
|
|
+ strPtr = strstr(inStr, "GET");
|
|
|
+ if (strPtr == NULL) {
|
|
|
+ strPtr = strstr(inStr, "POST");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strPtr == NULL) {
|
|
|
+ *fileNameLen = 0;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ beginValue = strpbrk(strPtr, "/");
|
|
|
+
|
|
|
+ endValue = strpbrk(beginValue, " ");
|
|
|
+ if (endValue == NULL) {
|
|
|
+ *fileNameLen = 0;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ len = endValue - beginValue;
|
|
|
+ if (len < MAX_FILENAME_LEN) {
|
|
|
+ strncpy(fileName, beginValue, len);
|
|
|
+ *fileNameLen = len;
|
|
|
+ fileName[len] = '\0';
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|