char_t *websUrlType(char_t *url, char_t *buf, int charCnt) { sym_t *sp; char_t *ext, *parsebuf; a_assert(url && *url); a_assert(buf && charCnt > 0); if (url == NULL || *url == '\0') { gstrcpy(buf, T("text/plain")); return buf; } if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL, NULL, &ext) < 0) { gstrcpy(buf, T("text/plain")); return buf; } strlower(ext); /* * Lookup the mime type symbol table to find the relevant content type */ if ((sp = symLookup(websMime, ext)) != NULL) { gstrncpy(buf, sp->content.value.string, charCnt); } else { gstrcpy(buf, T("text/plain")); } bfree(B_L, parsebuf); return buf; }
//---------------------------------------------------------------------------- // MQTT client callback, topic=<client-id>/... msg=... //---------------------------------------------------------------------------- void ICACHE_FLASH_ATTR mqttOnPublish(String strTopic, String strMsg) { tUint32 cbTopic = strTopic.length(), cbMsg = strMsg.length(); do { // make sure topic starts with <client-id> Debug.logTxt(CLSLVL_MQTT | 0x0000, "mqttOnPublish,topic=%s,msg=%s", strTopic.c_str(), strMsg.c_str()); if (strTopic.startsWith(AppSettings.mqttClientId + "/") == 0) { Debug.logTxt(CLSLVL_MQTT | 0x0010, "mqttOnPublish,not for us,dropping"); g_mqttPktRxDropped++; return; } // if g_mqttPktRx++; // copy topic/msg to modifiable buffer on stack tChar szTopic[cbTopic + 1], szMsg[cbMsg + 1]; tChar *pTopic = szTopic; gstrcpy(szTopic, strTopic.c_str()); gstrcpy(szMsg, strMsg.c_str()); // pass topic=<pfx>/<obj>... on to GPIOD pTopic += (AppSettings.mqttClientId.length() + 1); gpiodOnMqttPublish(pTopic, szMsg); } while (FALSE); } // mqttOnPublish
int gmstrcpy(char **dest, const char *source, ...){ int length = 0; char *other_source = NULL; char *temp = NULL; va_list args; if (dest == NULL) return -1; if (source == NULL) return -1; length += strlen(source); va_start(args, source); while ((other_source = va_arg(args, char *)) != NULL) length += strlen(other_source); va_end(args); temp = gstralloc(length); strcat(temp, source); va_start(args, source); while ((other_source = va_arg(args, char *)) != NULL) strcat(temp, other_source); va_end(args); gstrcpy(dest, temp); gstrdel(temp); return 0; };
int gmstrcat(char **main, const char *sufix, ...){ int length = 0; char *other_sufix = NULL; char *temp = NULL; va_list args; if (main == NULL) return -1; if (sufix == NULL) return -1; if ((*main) != NULL) length = strlen((*main)); length += strlen(sufix); va_start(args, sufix); while ((other_sufix = va_arg(args, char *)) != NULL) length += strlen(other_sufix); va_end(args); temp = gstralloc(length); if ((*main) != NULL) strcpy(temp, (*main)); strcat(temp, sufix); va_start(args, sufix); while ((other_sufix = va_arg(args, char *)) != NULL) strcat(temp, other_sufix); va_end(args); gstrdel((*main)); gstrcpy(main, temp); gstrdel(temp); return 0; };
int create_tmp_file(stats_t *stats, node_t *node){ #define create_tmp_file_error { \ gstrdel(tmp_template); \ if (desc != -1) \ close(desc); \ return -1; \ } char *tmp_template = NULL; int desc = -1; debug(3, "Received file %s;\n", stats->path); if (gmstrcpy(&tmp_template, data_dir, "/", stats->name, "XXXXXX", 0) != 0) create_tmp_file_error; desc = mkstemp(tmp_template); if (desc == -1) create_tmp_file_error; close(desc); if (gstrcpy(&node->tmp_path, tmp_template) != 0) create_tmp_file_error; gstrdel(tmp_template); return 0; };
void parse_mount(char *arg){ if (mount != NULL) fail(ERR_PARAMETRES); if (gstrcpy(&mount, arg) != 0) fail(-1); };
node_t * add_file(list_t *list, char *path, int rev){ if (list->head == NULL){ list->head = list->tail = single(node_t); gstrcpy(&list->head->path, path); return list->head; } node_t *node = get_open_file(path); if (node) return node; node = single(node_t); list->tail->next = node; node->prev = list->tail; list->tail = node; gstrcpy(&node->path, path); node->rev = rev; return node; };
void copy_stats(stats_t *source, stats_t **dest){ debug(3, "copying stats for: path %s, internal: %s, name: %s, rev: %d\n", source->path, source->internal, source->name, source->rev); *dest = single(stats_t); memcpy((*dest), source, sizeof(stats_t)); if (source->path){ (*dest)->path = 0; gstrcpy(&(*dest)->path, source->path); } if (source->internal) (*dest)->internal = (*dest)->path + (source->internal - source->path); if (source->name) (*dest)->name = (*dest)->path + (source->name - source->path); if (source->link) { (*dest)->link = 0; gstrcpy(&(*dest)->link, source->link); } debug(4, "done copying stats: path %s, internal %s, name %s, rev: %d\n", (*dest)->path, (*dest)->internal, (*dest)->name, (*dest)->rev); };
// service *main == sufix int gstrcat(char **main, const char *sufix){ if (sufix == NULL) return -1; if (main == NULL) return -1; if ((*main) == NULL) return gstrcpy(main, sufix); return __gstrcat(main, sufix); };
int sent_xmsg_stats(User *usr, XMsg *x, char *name) { switch(x->type) { case XMSG_X: usr->xsent++; user_dirty(usr, "xsent"); update_stats(usr); inc_stats(STATS_XSENT); break; case XMSG_EMOTE: usr->esent++; user_dirty(usr, "esent"); update_stats(usr); inc_stats(STATS_ESENT); break; case XMSG_FEELING: usr->fsent++; user_dirty(usr, "fsent"); update_stats(usr); inc_stats(STATS_FSENT); break; case XMSG_QUESTION: usr->qsent++; user_dirty(usr, "qsent"); update_stats(usr); inc_stats(STATS_QSENT); break; case XMSG_ANSWER: usr->qansw++; user_dirty(usr, "qansw"); update_stats(usr); inc_stats(STATS_QANSW); break; default: ; } if (name != NULL) { /* add to talked_to list */ if (usr->talked_to.len <= 0) gstrcpy(&(usr->talked_to), name); else { if (!cstrfind(usr->talked_to.str, name, ',')) { gstrcat(&(usr->talked_to), ","); gstrcat(&(usr->talked_to), name); } } } return 0; }
//---------------------------------------------------------------------------- // duplicate string //---------------------------------------------------------------------------- tChar* xstrdup(tCChar* pStr) { tChar *pstr; tInt32 nLen; if (pStr == NULL) pStr = ""; nLen = gstrlen(pStr) + 1; if ((pstr = (tChar*) malloc(nLen))) gstrcpy(pstr, pStr); return pstr; } // xstrdup
char_t *bstrdup(B_ARGS_DEC, char_t *s) { char_t *cp; int len; if (s == NULL) { s = T(""); } len = gstrlen(s) + 1; if ((cp = balloc(B_ARGS, len * sizeof(char_t))) != NULL) { gstrcpy(cp, s); } return cp; }
void parse_repo(struct file_system_info *fsinfo, int argc, char** argv, int *index){ int i = 0; if (fsinfo->repo_count != 0) fail(ERR_PARAMETRES); for (i = *index; (i < argc) && (!isOption(argv[i])); i++){ }; fsinfo->repo_count = i - *index; fsinfo->repos = calloc(fsinfo->repo_count, sizeof(char *)); for (i = *index; (i < argc) && (!isOption(argv[i])); i++) gstrcpy(&fsinfo->repos[i - *index], argv[i]); *index += fsinfo->repo_count - 1; };
// dest != NULL, (*dest) != NULL, sufix != NULL int __gstrcat(char **dest, const char *sufix){ int dest_length = strlen((*dest)); int sufix_length = strlen(sufix); int i = 0; char temp[dest_length + sufix_length + 1]; for (i = 0; i < dest_length; i++) temp[i] = (*dest)[i]; for (i = 0; i < sufix_length; i++) temp[i + dest_length] = sufix[i]; temp[dest_length + sufix_length] = 0; free((*dest)); (*dest) = gstralloc(dest_length + sufix_length); if ((*dest) == NULL) return -1; gstrcpy(dest, temp); return 0; };
int set_directory(int argc, char **argv, int *index){ #define set_directory_finish(value) { \ if (temp != NULL) \ free(temp); \ return value; \ } struct stat *temp = NULL; if ((*index + 1 >= argc) || (isOption(argv[*index + 1]) == 1)) set_directory_finish(-1); temp = single(struct stat); if ((stat(argv[*index + 1], temp) != 0) || ((temp->st_mode & S_IFDIR) == 0)) set_directory_finish(-1); *index += 1; if (gstrcpy(&tmp_dir, argv[*index]) != 0) set_directory_finish(-1); set_directory_finish(0); };
int gstrline(char **line, size_t *length, FILE *file){ int filled = 0; char next = 0; char *temp = NULL; if (line == NULL) return -1; if ((*line == NULL) || (*length <= 0)){ *line = gstralloc(128); *length = 129; } else memset(*line, 0, *length); while (1){ next = (char) getc(file); if (next == EOF){ if (filled == 0) return -1; else return filled; }; if (filled == *length){ gstrcpy(&temp, *line); gstrdel(*line); *length = (*length - 1) * 2 + 1; *line = gstralloc(*length); strcpy(*line, temp); }; (*line)[filled] = next; filled++; if (next == '\n') return filled; }; gstrdel(temp); return filled; };
int websValidateUrl(webs_t wp, char_t *path) { char_t *parts[64]; /* 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 (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("/")); } /* * 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; }
int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath, char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag, char_t **pext) { char_t *tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext; char_t *last_delim, *hostbuf, *portbuf, *buf; int c, len, ulen; a_assert(url); a_assert(pbuf); ulen = gstrlen(url); /* * We allocate enough to store separate hostname and port number fields. * As there are 3 strings in the one buffer, we need room for 3 null chars. * We allocate MAX_PORT_LEN char_t's for the port number. */ len = ulen * 2 + MAX_PORT_LEN + 3; if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) { return -1; } portbuf = &buf[len - MAX_PORT_LEN - 1]; hostbuf = &buf[ulen+1]; gstrcpy(buf, url); url = buf; /* * Convert the current listen port to a string. We use this if the URL has * no explicit port setting */ stritoa(websGetPort(), portbuf, MAX_PORT_LEN); port = portbuf; path = T("/"); proto = T("http"); host = T("localhost"); query = T(""); ext = htmExt; tag = T(""); if (gstrncmp(url, T("http://"), 7) == 0) { tok = &url[7]; tok[-3] = '\0'; proto = url; host = tok; for (cp = tok; *cp; cp++) { if (*cp == '/') { break; } if (*cp == ':') { *cp++ = '\0'; port = cp; tok = cp; } } if ((cp = gstrchr(tok, '/')) != NULL) { /* * If a full URL is supplied, we need to copy the host and port * portions into static buffers. */ c = *cp; *cp = '\0'; gstrncpy(hostbuf, host, ulen); gstrncpy(portbuf, port, MAX_PORT_LEN); *cp = c; host = hostbuf; port = portbuf; path = cp; tok = cp; } } else { path = url; tok = url; } /* * Parse the query string */ if ((cp = gstrchr(tok, '?')) != NULL) { *cp++ = '\0'; query = cp; path = tok; tok = query; } /* * Parse the fragment identifier */ if ((cp = gstrchr(tok, '#')) != NULL) { *cp++ = '\0'; if (*query == 0) { path = tok; } } /* * Only do the following if asked for the extension */ if (pext) { if ((cp = gstrrchr(path, '.')) != NULL) { if ((last_delim = gstrrchr(path, '/')) != NULL) { if (last_delim > cp) { ext = htmExt; } else { ext = cp; } } else { ext = cp; } } else { if (path[gstrlen(path) - 1] == '/') { ext = htmExt; } } } /* * Pass back the fields requested (if not NULL) */ if (phost) *phost = host; if (ppath) *ppath = path; if (pport) *pport = port; if (pproto) *pproto = proto; if (pquery) *pquery = query; if (ptag) *ptag = tag; if (pext) *pext = ext; *pbuf = buf; return 0; }
int websValidateUrl(webs_t wp, char_t *path) { /* Thanks to Dhanwa T ([email protected]) 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'. Also fixes: http://www.securiteam.com/securitynews/5MP0C1580W.html */ char_t *parts[MAX_URL_DEPTH]; /* 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; /* * Fixed by Matt Moore, 22 Jul 02 * http://www.securiteam.com/securitynews/5RP0I007PG.html * http://www.securiteam.com/securitynews/5QP010U3FS.html * * 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 >= MAX_URL_DEPTH) { /* * 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; }
int websLaunchCgiProc( char_t* cgiPath, char_t** argp, char_t** envp, char_t* stdIn, char_t* stdOut ) { STARTUPINFO newinfo; SECURITY_ATTRIBUTES security; PROCESS_INFORMATION procinfo; /* Information about created proc */ DWORD dwCreateFlags; char_t* cmdLine; char_t** pArgs; BOOL bReturn; int i, nLen; unsigned char* pEnvData; /* * Replace directory delimiters with Windows-friendly delimiters */ nLen = gstrlen( cgiPath ); for ( i = 0; i < nLen; i++ ) { if ( cgiPath[i] == '/' ) { cgiPath[i] = '\\'; } } /* * Calculate length of command line */ nLen = 0; pArgs = argp; while ( pArgs && *pArgs &&** pArgs ) { nLen += gstrlen( *pArgs ) + 1; pArgs++; } /* * Construct command line */ cmdLine = balloc( B_L, sizeof( char_t ) * nLen ); a_assert( cmdLine ); gstrcpy( cmdLine, "" ); pArgs = argp; while ( pArgs && *pArgs &&** pArgs ) { gstrcat( cmdLine, *pArgs ); gstrcat( cmdLine, T( " " ) ); pArgs++; } /* * Create the process start-up information */ memset( &newinfo, 0, sizeof( newinfo ) ); newinfo.cb = sizeof( newinfo ); newinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; newinfo.wShowWindow = SW_HIDE; newinfo.lpTitle = NULL; /* * Create file handles for the spawned processes stdin and stdout files */ security.nLength = sizeof( SECURITY_ATTRIBUTES ); security.lpSecurityDescriptor = NULL; security.bInheritHandle = TRUE; /* * Stdin file should already exist. */ newinfo.hStdInput = CreateFile( stdIn, GENERIC_READ, FILE_SHARE_READ, &security, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); /* * Stdout file is created and file pointer is reset to start. */ newinfo.hStdOutput = CreateFile( stdOut, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, &security, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); SetFilePointer( newinfo.hStdOutput, 0, NULL, FILE_END ); /* * Stderr file is set to Stdout. */ newinfo.hStdError = newinfo.hStdOutput; dwCreateFlags = CREATE_NEW_CONSOLE; pEnvData = tableToBlock( envp ); /* * CreateProcess returns errors sometimes, even when the process was * started correctly. The cause is not evident. For now: we detect * an error by checking the value of procinfo.hProcess after the call. */ procinfo.hProcess = NULL; bReturn = CreateProcess( NULL, /* Name of executable module */ cmdLine, /* Command line string */ NULL, /* Process security attributes */ NULL, /* Thread security attributes */ TRUE, /* Handle inheritance flag */ dwCreateFlags, /* Creation flags */ pEnvData, /* New environment block */ NULL, /* Current directory name */ &newinfo, /* STARTUPINFO */ &procinfo ); /* PROCESS_INFORMATION */ if ( procinfo.hThread != NULL ) { CloseHandle( procinfo.hThread ); } if ( newinfo.hStdInput ) { CloseHandle( newinfo.hStdInput ); } if ( newinfo.hStdOutput ) { CloseHandle( newinfo.hStdOutput ); } bfree( B_L, pEnvData ); bfree( B_L, cmdLine ); if ( bReturn == 0 ) { return -1; } else { return ( int ) procinfo.hProcess; } }