ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/libs/libcgi/patches/001-add_check_session.patch b/package/libs/libcgi/patches/001-add_check_session.patch
new file mode 100644
index 0000000..d4c8b7e
--- /dev/null
+++ b/package/libs/libcgi/patches/001-add_check_session.patch
@@ -0,0 +1,230 @@
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cgi.c libcgi-1.0/src/cgi.c
+--- libcgi-back-1.0/libcgi-1.0/src/cgi.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cgi.c 2015-05-11 16:19:55.980570364 +0800
+@@ -143,16 +143,18 @@
+ char *method;
+
+ method = getenv("REQUEST_METHOD");
+-
++ system("echo \"cgi_process_form!\" > /tmp/my_debug");
+ // When METHOD has no contents, the default action is to process it as GET method
+- if (method == NULL || !strcasecmp("GET", method)) {
++ if (method == NULL || !strcasecmp("GET", method) || !strcasecmp("POST", method)) {
+ char *dados;
+ dados = getenv("QUERY_STRING");
+-
++
+ // Sometimes, GET comes with not any data
+- if (dados == NULL || strlen(dados) < 1)
+- return NULL;
+-
++ if (dados == NULL || strlen(dados) < 1) {
++ system("echo \"query string is null!\" > /tmp/my_debug");
++ return NULL;
++ }
++ system("echo \"query string is not null!\" > /tmp/my_debug");
+ return process_data(dados, &formvars_start, &formvars_last, '=', '&');
+ }
+ else if (!strcasecmp("POST", method)) {
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cgi.h libcgi-1.0/src/cgi.h
+--- libcgi-back-1.0/libcgi-1.0/src/cgi.h 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cgi.h 2015-05-08 16:56:51.865844100 +0800
+@@ -25,6 +25,14 @@
+ extern "C" {
+ #endif
+
++#define LAST_ACCESS_TIME "last_time"
++#define LOG_STATUS "log_status"
++#define USER_ID "user_name"
++#define USER_PSWD "user_pswd"
++//second
++#define MAX_SESSION_TIMEOUT 600
++//tmp buffer size
++#define TMP_BUF_MAX 256
+
+ // general purpose linked list. Actualy isn't very portable
+ // because uses only 'name' and 'value' variables to store data.
+@@ -36,6 +44,15 @@
+ struct formvarsA *next;
+ } formvars;
+
++enum {
++ SESS_VALID,
++ SESS_NO_COOKIE,
++ SESS_NO_ACCESS_TIME,
++ SESS_NOT_FOUND,
++ SESS_INVALID,
++ SESS_TIMEOUT
++};
++
+ extern formvars *formvars_start;
+ extern formvars *formvars_last;
+ extern formvars *cookies_start;
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cookie.c libcgi-1.0/src/cookie.c
+--- libcgi-back-1.0/libcgi-1.0/src/cookie.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cookie.c 2015-05-12 10:27:11.335231627 +0800
+@@ -92,14 +92,30 @@
+ aux = cookies;
+
+ while (cookies) {
+- position = 0;
++start: position = 0;
++
+ data = (formvars *)malloc(sizeof(formvars));
+ if (!data)
+ libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
+
+- while (*aux++ != '=')
+- position++;
+
++ if ((strchr(cookies, '=')) == NULL) {
++ aux = NULL;
++ free(data);
++ cookies = aux;
++ goto end;
++ }
++
++ while (*aux++ != '=') {
++ if (*(aux-1) != ';') {
++ position++;
++ } else {
++ position = 0;
++ free(data);
++ cookies = aux;
++ goto start;
++ }
++ }
+ data->name = (char *)malloc(position+1);
+ if (!data->name) {
+ libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
+@@ -120,7 +136,8 @@
+ while (*aux++ != ';')
+ position++;
+ // Eliminate the blank space after ';'
+- aux++;
++ while(*aux == ' ')
++ aux++;
+ }
+
+ data->value = (char *)malloc(position + 1);
+@@ -134,7 +151,7 @@
+ slist_add(data, &cookies_start, &cookies_last);
+ cookies = aux;
+ }
+-
++end:
+ return cookies_start;
+ }
+
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/session.c libcgi-1.0/src/session.c
+--- libcgi-back-1.0/libcgi-1.0/src/session.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/session.c 2015-05-12 14:23:44.854940353 +0800
+@@ -124,6 +124,7 @@
+ SESS_OPEN_FILE
+ } sess_error;
+
++
+ // This variables are used to control the linked list of all
+ // session objects. Most of time you don't need to use them
+ // directly
+@@ -214,8 +215,6 @@
+ {
+ formvars *data;
+
+- cgi_init_headers();
+-
+ // Rewrites all data to session file
+ sess_file = fopen(sess_fname, "w");
+
+@@ -547,10 +546,90 @@
+ fclose(fp);
+ sess_initialized = 1;
+ free(buf);
+-
+ return 1;
+ }
+
++/**
++* check the request validation.
++* This function is responsible for reading a exist session file and
++* validate the request. It no session file found will return session_invalid
++* if file found but session timeout will return session_timeout, meanwhile
++* destroy the session file anyway
++* if seesion is valid will return session_valid and refresh the session access time
++* @see session_destroy()
++*/
++int cgi_session_check()
++{
++ char *buf = NULL, *sid = NULL, *value = NULL;;
++ struct stat st;
++ FILE *fp;
++ struct timeval cur_tv;
++ time_t last_time;
++ char tmp[TMP_BUF_MAX] = { 0 };
++
++ // Get the session ID
++ sid = cgi_cookie_value(SESSION_COOKIE_NAME);
++
++ // If there isn't a session ID
++ if (sid == NULL) {
++ return SESS_NO_COOKIE;
++ }
++
++ save_path_len = strlen(SESSION_SAVE_PATH) + strlen(SESSION_FILE_PREFIX);
++
++ sess_fname = (char *)malloc(save_path_len + SESS_ID_LEN + 1);
++ if (!sess_fname)
++ libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
++
++ snprintf(sess_fname, (SESS_ID_LEN + save_path_len + 1), "%s%s%s", SESSION_SAVE_PATH, SESSION_FILE_PREFIX, sid);
++ sess_fname[SESS_ID_LEN + save_path_len] = '\0';
++
++ errno = 0;
++ fp = fopen(sess_fname, "r");
++ if (errno == ENOENT) {
++ // The file doesn't exists
++ return SESS_NOT_FOUND;
++ }
++
++ strncpy(sess_id, sid, SESS_ID_LEN);
++ sess_id[SESS_ID_LEN] = '\0';
++
++ stat(sess_fname, &st);
++ buf = (char *)malloc(st.st_size + 2);
++ if (!buf)
++ libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
++
++ fgets(buf, st.st_size+1, fp);
++ if (buf != NULL && strlen(buf) > 1)
++ process_data(buf, &sess_list_start, &sess_list_last, '=', ';');
++
++ fclose(fp);
++ sess_initialized = 1;
++ free(buf);
++
++ gettimeofday(&cur_tv, NULL);
++ value = cgi_session_var(LAST_ACCESS_TIME);
++ if (!value) {
++ return SESS_NO_ACCESS_TIME;
++ }
++
++ last_time = (time_t)atol(value);
++
++ if (cur_tv.tv_sec - last_time > MAX_SESSION_TIMEOUT) {
++ cgi_session_destroy();
++ return SESS_TIMEOUT;
++ }
++
++ //refresh last access time
++ memset(tmp, 0, TMP_BUF_MAX);
++ snprintf(tmp, TMP_BUF_MAX - 1, "%u", cur_tv.tv_sec );
++ if ( cgi_session_alter_var(LAST_ACCESS_TIME, tmp)) {
++ return SESS_VALID;
++ }
++ else {
++ return SESS_INVALID;
++ }
++}
+ /**
+ * @}
+ */
diff --git a/package/libs/libcgi/patches/002-fix_md5_bug.patch b/package/libs/libcgi/patches/002-fix_md5_bug.patch
new file mode 100644
index 0000000..94e0466
--- /dev/null
+++ b/package/libs/libcgi/patches/002-fix_md5_bug.patch
@@ -0,0 +1,38 @@
+--- ../libcgi-1.0-last/libcgi-1.0/src/md5.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/md5.c 2015-05-20 15:36:47.000000000 +0800
+@@ -65,17 +65,18 @@
+ **/
+ char *md5(const char *str)
+ {
+- char *tmp, buf[32];
++ char *tmp, buf[32] = { 0 };
+ int i, str_size;
+ unsigned char md[16];
+ MD5_CTX context;
+
+ // allocating a pointer to the string
+ str_size = strlen(str) + 1;
+- tmp = (char *)malloc(str_size);
++ tmp = (char *)malloc(32 + 1);
+ if (tmp == NULL)
+ libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
+
++ memset(tmp, 0, 32 + 1);
+ // initializing a context that will content the encrypted string
+ MD5Init(&context);
+ MD5Update(&context, str, strlen(str));
+@@ -85,12 +86,12 @@
+
+ // here, the loop is less than 32 because a md5 string can content
+ // just 32 bytes
+- for(i = 0; i < 32; i++) {
++ for(i = 0; i <16; i++) {
+ snprintf(buf, sizeof(float), "%02x", md[i]);
+ strncat(tmp, buf, sizeof(float));
+ }
+
+- tmp[i] = '\0';
++ tmp[32] = '\0';
+
+ // returning a encrypted string
+ return tmp;
diff --git a/package/libs/libcgi/patches/003-fix_y2038.patch b/package/libs/libcgi/patches/003-fix_y2038.patch
new file mode 100644
index 0000000..496401c
--- /dev/null
+++ b/package/libs/libcgi/patches/003-fix_y2038.patch
@@ -0,0 +1,21 @@
+diff -r -u libcgi-1.0_back/src/session.c libcgi-1.0/src/session.c
+--- libcgi-1.0_back/src/session.c 2024-10-24 13:02:58.302808361 +0800
++++ libcgi-1.0/src/session.c 2024-10-24 13:04:34.088241739 +0800
+@@ -613,7 +613,7 @@
+ return SESS_NO_ACCESS_TIME;
+ }
+
+- last_time = (time_t)atol(value);
++ last_time = (time_t)atoll(value);
+
+ if (cur_tv.tv_sec - last_time > MAX_SESSION_TIMEOUT) {
+ cgi_session_destroy();
+@@ -622,7 +622,7 @@
+
+ //refresh last access time
+ memset(tmp, 0, TMP_BUF_MAX);
+- snprintf(tmp, TMP_BUF_MAX - 1, "%u", cur_tv.tv_sec );
++ snprintf(tmp, TMP_BUF_MAX - 1, "%lld", cur_tv.tv_sec );
+ if ( cgi_session_alter_var(LAST_ACCESS_TIME, tmp)) {
+ return SESS_VALID;
+ }