[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/goahead/server/goahead.c b/ap/app/goahead/server/goahead.c
new file mode 100755
index 0000000..b0007fd
--- /dev/null
+++ b/ap/app/goahead/server/goahead.c
@@ -0,0 +1,339 @@
+#include	"uemf.h"
+#include	"wsIntrn.h"
+#include	<signal.h>
+#include	<unistd.h> 
+#include	<sys/types.h>
+#include	<sys/wait.h>
+#include    <sched.h>
+#ifdef WEBS_SSL_SUPPORT
+#include	"websSSL.h"
+#endif
+#include "../interface5.0/zte_web_interface.h"
+
+static char_t		*rootWeb = T("etc_ro/web");			/* Root web directory */
+static int			port = 80;						/* Server port */
+static int			retries = 5;					/* Server port retries */
+static int			finished;						/* Finished flag */
+
+/****************************** Forward Declarations **************************/
+
+static int 	initWebs();
+static int  websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+				int arg, char_t *url, char_t *path, char_t *query);
+extern void defaultErrorHandler(int etype, char_t *msg);
+extern void defaultTraceHandler(int level, char_t *buf);
+
+//added by liuyingnan for PC Client begin, 20120829
+extern int websXMLPostHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query);
+//added by liuyingnan for PC Client end, 20120829
+
+int main(int argc, char** argv)
+{
+    int rs;
+    struct sched_param param;
+
+    loglevel_init();
+	slog(MISC_PRINT, SLOG_DEBUG, "goahead main\n");
+	bopen(NULL, (60 * 1024), B_USE_MALLOC);
+	signal(SIGPIPE, SIG_IGN);
+	if (initWebs() < 0) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed.");
+		return -1;
+	}
+
+#ifdef WEBS_SSL_SUPPORT
+	websSSLOpen();
+#endif
+	web_init_pwd();
+	web_aes_init();
+
+	slog(MISC_PRINT, SLOG_NORMAL,"[goahead] enter working\n");
+	while (!finished) {
+		if (socketReady(-1) || socketSelect(-1, 1000)) {         
+			socketProcess(-1);
+		}
+		websCgiCleanup();
+		emfSchedProcess();
+	}
+
+#ifdef WEBS_SSL_SUPPORT
+	websSSLClose();
+#endif
+
+	websCloseServer();
+	socketClose();
+	bclose();
+	return 0;
+}
+
+static int initWebs()
+{
+	struct in_addr	intaddr;
+	const char			lan_ip[128] = {0};
+	char			host[128], dir[128], webdir[128];
+	char			*cp;
+	char_t			wbuf[128];
+	socketOpen();
+
+	sc_cfg_get("lan_ipaddr", lan_ip, sizeof(lan_ip));
+	if (0 == strcmp(lan_ip, "")) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed: lan_ip is NULL!");
+		return -1;
+	}
+	intaddr.s_addr = inet_addr(lan_ip);
+	if (intaddr.s_addr == INADDR_NONE) {
+		slog(MISC_PRINT, SLOG_ERR, "goahead initWebs failed: lan_ip is %s, INADDR_NONE!", lan_ip);
+		return -1;
+	}
+	getcwd(dir, sizeof(dir)); 
+	if ((cp = strrchr(dir, '/'))) {
+		*cp = '\0';
+	}
+    snprintf(webdir, sizeof(webdir), "%s/%s", dir, rootWeb);
+    slog(MISC_PRINT,SLOG_DEBUG, "goahead initWebs info: webdir is %s!",webdir);
+	websSetDefaultDir(webdir);
+	cp = inet_ntoa(intaddr);
+	ascToUni(wbuf, cp, min(strlen(cp) + 1, sizeof(wbuf)));
+	websSetIpaddr(wbuf);
+	websSetHost(wbuf);
+	websSetDefaultPage(T(ZTE_WEB_PAGE_LOGIN_NAME));
+	websOpenServer(port, retries);
+	//websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, WEBS_HANDLER_FIRST);
+	websUrlHandlerDefine(T("/reqproc"), NULL, 0, websFormHandler, 0);
+#ifndef WEBS_SECURITY
+	websUrlHandlerDefine(T("/cgi-bin"), NULL, 0, websCgiHandler, 0);
+    //websUrlHandlerDefine(T("/api/xmlclient/post"), NULL, 0, websXMLPostHandler, 0);
+	websUrlHandlerDefine(T("/mmc2"), NULL, 0, websCgiDownLoadHandler, 0);//http share
+#endif	
+	websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, WEBS_HANDLER_LAST); 
+	zte_web_init();
+	zte_httpshare_init();//httpshare
+	websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); 
+
+	system("rm -rf /firmware_tmp_file");
+	return 0;
+}
+
+static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
+                               int arg, char_t *url, char_t *path, char_t *query)
+{
+    if (*url == '\0' || gstrcmp(url, T("/")) == 0) 
+    {
+        websRedirect(wp, zte_web_get_login_page(wp)); /*×ÔÊÊÓ¦ÖÕ¶Ëä¯ÀÀÆ÷*/
+        return 1;
+    }
+    return 0;
+}
+
+void defaultErrorHandler(int etype, char_t *msg)
+{
+	printf("[goahead]e %s\n",msg);
+}
+
+void defaultTraceHandler(int level, char_t *buf)
+{
+	if (buf) {
+		printf("[goahead]t %s\n",buf);
+	}
+}
+
+char_t *websGetCgiCommName(webs_t wp)
+{
+	char_t	*pname1, *pname2;
+
+	pname1 = (char_t *)tempnam(T("/var"), T("cgi"));
+	pname2 = bstrdup(B_L, pname1);
+	free(pname1);
+	return pname2;
+}
+
+int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp,
+					  char_t *stdIn, char_t *stdOut)
+{
+	int	pid, fdin, fdout, hstdin, hstdout, rc;
+
+	fdin = fdout = hstdin = hstdout = rc = -1; 
+	if ((fdin = open(stdIn, O_RDWR | O_CREAT, 0666)) < 0 ||
+		(fdout = open(stdOut, O_RDWR | O_CREAT, 0666)) < 0 ||
+		(hstdin = dup(0)) == -1 ||
+		(hstdout = dup(1)) == -1 ||
+		dup2(fdin, 0) == -1 ||
+		dup2(fdout, 1) == -1) {
+		goto DONE;
+	}
+		
+ 	rc = pid = fork();
+ 	if (pid == 0) {
+        int result = execve(cgiPath, argp, envp);
+        slog(MISC_PRINT,SLOG_DEBUG, "content-type: text/html Execution of cgi process :%d", result);
+		exit (0);
+	} 
+
+DONE:
+	if (hstdout >= 0) {
+		dup2(hstdout, 1);
+      close(hstdout);
+	}
+	if (hstdin >= 0) {
+		dup2(hstdin, 0);
+      close(hstdin);
+	}
+	if (fdout >= 0) {
+		close(fdout);
+	}
+	if (fdin >= 0) {
+		close(fdin);
+	}
+	return rc;
+}
+
+int websCheckCgiProc(int handle, int *status)
+{
+	if (waitpid(handle, status, WNOHANG) == handle) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+static int i64c(int i)
+{
+	i &= 0x3f;
+	if (i == 0)
+		return '.';
+	if (i == 1)
+		return '/';
+	if (i < 12)
+		return ('0' - 2 + i);
+	if (i < 38)
+		return ('A' - 12 + i);
+	return ('a' - 38 + i);
+}
+
+static int web_make_salt(char *p, int cnt /*, int x */)
+{
+	/* was: x += ... */
+	int x = getpid() + (int)time(0);
+	do {
+		/* x = (x*1664525 + 1013904223) % 2^32 generator is lame
+		 * (low-order bit is not "random", etc...),
+		 * but for our purposes it is good enough */
+		x = x*1664525 + 1013904223;
+		/* BTW, Park and Miller's "minimal standard generator" is
+		 * x = x*16807 % ((2^31)-1)
+		 * It has no problem with visibly alternating lowest bit
+		 * but is also weak in cryptographic sense + needs div,
+		 * which needs more code (and slower) on many CPUs */
+		*p++ = i64c(x >> 16);
+		*p++ = i64c(x >> 22);
+	} while (--cnt);
+	*p = '\0';
+	return x;
+}
+
+int web_set_pwd(char *buf)
+{
+	if(buf == NULL)
+		return -1;
+	int bufLen = strlen(buf);
+	if(bufLen <= 0 || bufLen > LOGIN_PSW_MAX_LEN)
+		return -1;
+#ifdef WEBS_SSL_SUPPORT
+	char salt[LOGIN_PSW_MAX_LEN+1]={0};
+	web_make_salt(salt,(sizeof(salt)-1)/2);
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]salt %s\n",salt);
+	unsigned char md[LOGIN_PSW_MAX_LEN] = {0};
+	{
+		unsigned char src[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		memcpy(src,salt,LOGIN_PSW_MAX_LEN);
+		memcpy(src+LOGIN_PSW_MAX_LEN,buf,bufLen);
+		SHA256((const unsigned char *)src, bufLen+LOGIN_PSW_MAX_LEN, md);
+	}
+	{
+		char i = 0; 
+		char str_md[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		for(i = 0; i < LOGIN_PSW_MAX_LEN; i++)
+		{
+			sprintf(str_md+i+i,"%02x", md[i]);
+		}
+		char psw_buf[100] = {0};
+		snprintf(psw_buf,sizeof(psw_buf),"%s%s",salt,str_md);
+		slog(MISC_PRINT,SLOG_DEBUG, "goahead]set_pw %s\n",psw_buf);
+		return sc_cfg_set("admin_Password", psw_buf);
+	}
+#else
+	return sc_cfg_set("admin_Password", buf);
+#endif
+}
+
+void web_init_pwd(void)
+{
+#ifdef WEBS_SSL_SUPPORT
+	char psw_buf[LOGIN_PSW_MAX_LEN*3+1] = {0};
+	sc_cfg_get("admin_Password", psw_buf, sizeof(psw_buf));
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]init_pw %s\n",psw_buf);
+	if(strlen(psw_buf) <= LOGIN_PSW_MAX_LEN)
+	{
+		web_set_pwd(psw_buf);
+	}
+#endif	
+}
+
+int web_check_pwd(char* buf)
+{
+	char psw_buf[LOGIN_PSW_MAX_LEN*3+1] = {0};
+	if(buf == NULL)
+		return -1;
+	int bufLen = strlen(buf);
+	if(bufLen <= 0 || bufLen > LOGIN_PSW_MAX_LEN)
+		return -1;
+	sc_cfg_get("admin_Password", psw_buf, sizeof(psw_buf));
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]check_pw in %s\n",buf);
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]check_pw src %s\n",psw_buf);
+#ifdef WEBS_SSL_SUPPORT
+	unsigned char md[LOGIN_PSW_MAX_LEN] = {0};
+	{
+		unsigned char src[LOGIN_PSW_MAX_LEN*2+1] = {0};
+		memcpy(src,psw_buf,LOGIN_PSW_MAX_LEN);
+		memcpy(src+LOGIN_PSW_MAX_LEN,buf,bufLen);
+		SHA256((const unsigned char *)src, bufLen+LOGIN_PSW_MAX_LEN, md);
+	}
+	{
+		char i = 0;	
+		char str_md[65] = {0};
+		for(i = 0; i < LOGIN_PSW_MAX_LEN; i++)
+		{
+			sprintf(str_md+i+i,"%02x", md[i]);
+		}
+		return strncmp(str_md,psw_buf+LOGIN_PSW_MAX_LEN,sizeof(str_md)-1);
+	}
+#else
+	if(bufLen != strlen(psw_buf))
+		return -1;
+
+	return strncmp(buf,psw_buf,bufLen);;
+#endif
+}
+
+int web_make_salt_base64(char *buf, int len)
+{
+	int salt_len;
+	char *salt;
+	if(buf == NULL || len < 5)
+	{
+		return 0;
+	}
+	salt_len = (len - 1)/4*3;
+	salt = balloc(B_L, salt_len+1);
+	if(salt == NULL)
+	{
+		return 0;
+	}
+	web_make_salt(salt,salt_len/2);
+	websEncode64(buf, salt, len);
+	bfree(B_L, salt);
+	*(buf + len -1) = '\0';
+	slog(MISC_PRINT,SLOG_DEBUG, "[goahead]salt_base64=%s\n",buf);
+	return strlen(buf);
+}
+