📄 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 + -