📄 default.c
字号:
{
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 + -