⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 default.c

📁 GOAHEAD WEBSERVER嵌入式的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   {
      if (VER_PLATFORM_WIN32_NT != version.dwPlatformId)
      {
         /*
          * we are currently running on 95/98/ME.
          */
         for (i = 0; i < partCount; ++i)
         {
            /*
             * check against the prohibited names. If any of our requested 
             * subdirectories match any of these, return '1' immediately.
             */

            if ( 
             (badPath(parts[i], T("con"), 3)) ||
             (badPath(parts[i], T("nul"), 3)) ||
             (badPath(parts[i], T("aux"), 3)) ||
             (badPath(parts[i], T("clock$"), 6)) ||
             (badPath(parts[i], T("config$"), 7)) )
            {
               return 1;
            }
         }
      }
   }
   /*
    * either we're not on one of the bad OS versions, or the request has 
    * no problems.
    */
   return 0;
}
#endif


/******************************************************************************/
/*
 *	Validate the URL path and process ".." path segments. Return -1 if the URL
 *	is bad.
 */

int websValidateUrl(webs_t wp, char_t *path)
{
   /*
     Thanks to Dhanwa T (dhanwa@polyserve.com) for this fix -- previously,
     if an URL was requested having more than (the hardcoded) 64 parts,
     the webServer would experience a hard crash as it attempted to
     write past the end of the array 'parts'.
    */

#define kMaxUrlParts 64
	char_t	*parts[kMaxUrlParts];	/* Array of ptr's to URL parts */
	char_t	*token, *dir, *lpath; 
   int	      i, len, npart;

	a_assert(websValid(wp));
	a_assert(path);

	dir = websGetRequestDir(wp);
	if (dir == NULL || *dir == '\0') {
		return -1;
	}

/*
 *	Copy the string so we don't destroy the original
 */
	path = bstrdup(B_L, path);
	websDecodeUrl(path, path, gstrlen(path));

	len = npart = 0;
	parts[0] = NULL;

   /*
    * 22 Jul 02 -- there were reports that a directory traversal exploit was
    * possible in the WebServer running under Windows if directory paths
    * outside the server's specified root web were given by URL-encoding the
    * backslash character, like:
    *
    *  GoAhead is vulnerable to a directory traversal bug. A request such as
    *  
    *  GoAhead-server/../../../../../../../ results in an error message
    *  'Cannot open URL'.

    *  However, by encoding the '/' character, it is possible to break out of
    *  the
    *  web root and read arbitrary files from the server.
    *  Hence a request like:
    * 
    *  GoAhead-server/..%5C..%5C..%5C..%5C..%5C..%5C/winnt/win.ini returns the
    *  contents of the win.ini file.
    * (Note that the description uses forward slashes (0x2F), but the example
    * uses backslashes (0x5C). In my tests, forward slashes are correctly
    * trapped, but backslashes are not. The code below substitutes forward
    * slashes for backslashes before attempting to validate that there are no
    * unauthorized paths being accessed.
    */
   token = gstrchr(path, '\\');
   while (token != NULL)
   {
      *token = '/';
      token = gstrchr(token, '\\');
   }
   
	token = gstrtok(path, T("/"));

/*
 *	Look at each directory segment and process "." and ".." segments
 *	Don't allow the browser to pop outside the root web. 
 */
	while (token != NULL) 
   {
      if (npart >= kMaxUrlParts)
      {
         /*
          * malformed URL -- too many parts for us to process.
          */
         bfree(B_L, path);
         return -1;
      }
		if (gstrcmp(token, T("..")) == 0) 
      {
			if (npart > 0) 
         {
				npart--;
			}

		} 
      else if (gstrcmp(token, T(".")) != 0) 
      {
			parts[npart] = token;
			len += gstrlen(token) + 1;
			npart++;
		}
		token = gstrtok(NULL, T("/"));
	}

#ifdef WIN32
   if (isBadWindowsPath(parts, npart))
   {
      bfree(B_L, path);
      return -1;
   }

#endif

/*
 *	Create local path for document. Need extra space all "/" and null.
 */
	if (npart || (gstrcmp(path, T("/")) == 0) || (path[0] == '\0')) 
   {
		lpath = balloc(B_L, (gstrlen(dir) + 1 + len + 1) * sizeof(char_t));
		gstrcpy(lpath, dir);

		for (i = 0; i < npart; i++) 
      {
			gstrcat(lpath, T("/"));
			gstrcat(lpath, parts[i]);
		}
		websSetRequestLpath(wp, lpath);
		bfree(B_L, path);
		bfree(B_L, lpath);

	} 
   else 
   {
		bfree(B_L, path);
		return -1;
	}
	return 0;
}

/******************************************************************************/
/*
 *	Do output back to the browser in the background. This is a socket
 *	write handler.
 */

static void websDefaultWriteEvent(webs_t wp)
{
	int		len, wrote, flags, bytes, written;
	char	*buf;

	a_assert(websValid(wp));

	flags = websGetRequestFlags(wp);

	websSetTimeMark(wp);

	wrote = bytes = 0;
	written = websGetRequestWritten(wp);

/*
 *	We only do this for non-ASP documents
 */
	if ( !(flags & WEBS_ASP)) {
		bytes = websGetRequestBytes(wp);
/*
 *		Note: websWriteDataNonBlock may return less than we wanted. It will
 *		return -1 on a socket error
 */
		if ((buf = balloc(B_L, PAGE_READ_BUFSIZE)) == NULL) {
			websError(wp, 200, T("Can't get memory"));
		} else {
			while ((len = websPageReadData(wp, buf, PAGE_READ_BUFSIZE)) > 0) {
				if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) {
					break;
				}
				written += wrote;
				if (wrote != len) {
					websPageSeek(wp, - (len - wrote));
					break;
				}
			}
/*
 *			Safety. If we are at EOF, we must be done
 */
			if (len == 0) {
				a_assert(written >= bytes);
				written = bytes;
			}
			bfree(B_L, buf);
		}
	}

/*
 *	We're done if an error, or all bytes output
 */
	websSetRequestWritten(wp, written);
	if (wrote < 0 || written >= bytes) {
		websDone(wp, 200);
	}
}

/******************************************************************************/
/* 
 *	Closing down. Free resources.
 */

void websDefaultClose()
{
	if (websDefaultPage) {
		bfree(B_L, websDefaultPage);
		websDefaultPage = NULL;
	}
	if (websDefaultDir) {
		bfree(B_L, websDefaultDir);
		websDefaultDir = NULL;
	}
}

/******************************************************************************/
/*
 *	Get the default page for URL requests ending in "/"
 */

char_t *websGetDefaultPage()
{
	return websDefaultPage;
}

/******************************************************************************/
/*
 *	Get the default web directory
 */

char_t *websGetDefaultDir()
{
	return websDefaultDir;
}

/******************************************************************************/
/*
 *	Set the default page for URL requests ending in "/"
 */

void websSetDefaultPage(char_t *page)
{
	a_assert(page && *page);

	if (websDefaultPage) {
		bfree(B_L, websDefaultPage);
	}
	websDefaultPage = bstrdup(B_L, page);
}

/******************************************************************************/
/*
 *	Set the default web directory
 */

void websSetDefaultDir(char_t *dir)
{
	a_assert(dir && *dir);
	if (websDefaultDir) {
		bfree(B_L, websDefaultDir);
	}
	websDefaultDir = bstrdup(B_L, dir);
}

/******************************************************************************/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -