mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
214 lines
6.1 KiB
C++
214 lines
6.1 KiB
C++
/*
|
|
* ModSecurity, http://www.modsecurity.org/
|
|
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
*
|
|
* You may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* If any of the files related to licensing are missing or if you have any
|
|
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
* directly using the email address security@modsecurity.org.
|
|
*
|
|
*/
|
|
|
|
#include "src/utils.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#include <random>
|
|
#include <memory>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <cstring>
|
|
|
|
#if defined _MSC_VER
|
|
#include <direct.h>
|
|
#elif defined __GNUC__
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include "modsecurity/modsecurity.h"
|
|
|
|
namespace ModSecurity {
|
|
|
|
std::vector<std::string> split(std::string str, char delimiter) {
|
|
std::vector<std::string> internal;
|
|
std::stringstream ss(str); // Turn the string into a stream.
|
|
std::string tok;
|
|
|
|
while (getline(ss, tok, delimiter)) {
|
|
internal.push_back(tok);
|
|
}
|
|
|
|
return internal;
|
|
}
|
|
|
|
|
|
double random_number(const double from, const double to) {
|
|
std::random_device rd;
|
|
|
|
return std::bind(
|
|
std::uniform_real_distribution<>{from, to},
|
|
std::default_random_engine{ rd() })();
|
|
}
|
|
|
|
|
|
std::string dash_if_empty(const std::string& str) {
|
|
if (&str == NULL || str.empty()) {
|
|
return "-";
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
double generate_assay_unique_id() {
|
|
return random_number(0, 100);
|
|
}
|
|
|
|
|
|
std::string ascTime(time_t *t) {
|
|
std::string ts = std::ctime(t);
|
|
ts.pop_back();
|
|
return ts;
|
|
}
|
|
|
|
|
|
void chomp(std::string *str) {
|
|
std::string::size_type pos = str->find_last_not_of("\n\t");
|
|
if (pos != std::string::npos) {
|
|
str->erase(pos+1, str->length()-pos-1);
|
|
}
|
|
}
|
|
|
|
|
|
std::string tolower(std::string str) {
|
|
std::locale loc;
|
|
std::string value;
|
|
|
|
for (std::string::size_type i=0; i < str.length(); ++i) {
|
|
value.assign(value + std::tolower(str[i], loc));
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
|
|
const char SAFE[256] = {
|
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
|
/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
|
|
/* 4 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
/* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
/* 6 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
/* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
|
|
/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
/* C */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* D */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* E */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
|
|
const char HEX2DEC[256] = {
|
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
|
/* 0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 1 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 2 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
|
|
|
/* 4 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 5 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 6 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 7 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
/* 8 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* A */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* B */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
/* C */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* D */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* E */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
/* F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
|
};
|
|
|
|
|
|
std::string uri_decode(const std::string & sSrc) {
|
|
// Note from RFC1630: "Sequences which start with a percent
|
|
// sign but are not followed by two hexadecimal characters
|
|
// (0-9, A-F) are reserved for future extension"
|
|
|
|
const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
|
|
const int SRC_LEN = sSrc.length();
|
|
const unsigned char * const SRC_END = pSrc + SRC_LEN;
|
|
// last decodable '%'
|
|
const unsigned char * const SRC_LAST_DEC = SRC_END - 2;
|
|
|
|
char * const pStart = new char[SRC_LEN];
|
|
char * pEnd = pStart;
|
|
|
|
while (pSrc < SRC_LAST_DEC) {
|
|
if (*pSrc == '%') {
|
|
char dec1, dec2;
|
|
if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
|
|
&& -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) {
|
|
*pEnd++ = (dec1 << 4) + dec2;
|
|
pSrc += 3;
|
|
continue;
|
|
}
|
|
}
|
|
*pEnd++ = *pSrc++;
|
|
}
|
|
|
|
// the last 2- chars
|
|
while (pSrc < SRC_END) {
|
|
*pEnd++ = *pSrc++;
|
|
}
|
|
|
|
std::string sResult(pStart, pEnd);
|
|
delete [] pStart;
|
|
return sResult;
|
|
}
|
|
|
|
|
|
void createDir(std::string dir, int mode) {
|
|
#if defined _MSC_VER
|
|
_mkdir(dir.data());
|
|
#elif defined __GNUC__
|
|
mkdir(dir.data(), mode);
|
|
#endif
|
|
}
|
|
|
|
|
|
double cpu_seconds(void) {
|
|
struct timespec t;
|
|
|
|
if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t))
|
|
return static_cast<double>(t.tv_sec)
|
|
+ static_cast<double>(t.tv_nsec / 1000000000.0);
|
|
else
|
|
return static_cast<double>(clock()) /
|
|
static_cast<double>(CLOCKS_PER_SEC);
|
|
}
|
|
|
|
|
|
} // namespace ModSecurity
|
|
|