Example #1
0
ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header)
{
	String::SizeType pos = auth_header.FindFirstOf(" ");
	String username, password;

	if (pos != String::NPos && auth_header.SubStr(0, pos) == "Basic") {
		String credentials_base64 = auth_header.SubStr(pos + 1);
		String credentials = Base64::Decode(credentials_base64);

		String::SizeType cpos = credentials.FindFirstOf(":");

		if (cpos != String::NPos) {
			username = credentials.SubStr(0, cpos);
			password = credentials.SubStr(cpos + 1);
		}
	}

	const ApiUser::Ptr& user = ApiUser::GetByName(username);

	/* Deny authentication if:
	 * 1) user does not exist
	 * 2) given password is empty
	 * 2) configured password does not match.
	 */
	if (!user || password.IsEmpty())
		return nullptr;
	else if (user && user->GetPassword() != password)
		return nullptr;

	return user;
}
Example #2
0
static String StringSubstr(const std::vector<Value>& args)
{
	ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
	String self = vframe->Self;

	if (args.empty())
		BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments"));

	if (static_cast<double>(args[0]) < 0 || static_cast<double>(args[0]) >= self.GetLength())
		BOOST_THROW_EXCEPTION(std::invalid_argument("String index is out of range"));

	if (args.size() > 1)
		return self.SubStr(args[0], args[1]);
	else
		return self.SubStr(args[0]);
}
Example #3
0
/**
 * Prints a stacktrace to the specified stream.
 *
 * @param fp The stream.
 * @param ignoreFrames The number of stackframes to ignore (in addition to
 *		       the one this function is executing in).
 * @returns true if the stacktrace was printed, false otherwise.
 */
void StackTrace::Print(std::ostream& fp, int ignoreFrames) const
{
	fp << std::endl;

#ifndef _WIN32
#	ifdef HAVE_BACKTRACE_SYMBOLS
	char **messages = backtrace_symbols(m_Frames, m_Count);

	for (int i = ignoreFrames + 1; i < m_Count && messages != NULL; ++i) {
		String message = messages[i];

		char *sym_begin = strchr(messages[i], '(');

		if (sym_begin) {
			char *sym_end = strchr(sym_begin, '+');

			if (sym_end != NULL) {
				String sym = String(sym_begin + 1, sym_end);
				String sym_demangled = Utility::DemangleSymbolName(sym);

				if (sym_demangled.IsEmpty())
					sym_demangled = "<unknown function>";

				String path = String(messages[i], sym_begin);

				size_t slashp = path.RFind("/");

				if (slashp != String::NPos)
					path = path.SubStr(slashp + 1);

				message = path + ": " + sym_demangled + " (" + String(sym_end);
			}
		}

		fp << "\t(" << i - ignoreFrames - 1 << ") " << message << std::endl;
	}

	std::free(messages);

	fp << std::endl;
#	else /* HAVE_BACKTRACE_SYMBOLS */
	fp << "(not available)" << std::endl;
#	endif /* HAVE_BACKTRACE_SYMBOLS */
#else /* _WIN32 */
	for (int i = ignoreFrames + 1; i < m_Count; i++) {
		fp << "\t(" << i - ignoreFrames - 1 << "): "
		   << Utility::GetSymbolName(m_Frames[i])
		   << std::endl;
	}
#endif /* _WIN32 */
}
Example #4
0
void ApiListener::ConfigGlobHandler(Dictionary::Ptr& config, const String& path, const String& file)
{
	CONTEXT("Creating config update for file '" + file + "'");

	Log(LogNotice, "ApiListener")
	    << "Creating config update for file '" << file << "'";

	std::ifstream fp(file.CStr());
	if (!fp)
		return;

	String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
	config->Set(file.SubStr(path.GetLength()), content);
}
void LegacyTimePeriod::ParseTimeRange(const String& timerange, tm *begin, tm *end, int *stride, tm *reference)
{
	String def = timerange;

	/* Figure out the stride. */
	size_t pos = def.FindFirstOf('/');

	if (pos != String::NPos) {
		String strStride = def.SubStr(pos + 1).Trim();
		*stride = Convert::ToLong(strStride);

		/* Remove the stride parameter from the definition. */
		def = def.SubStr(0, pos);
	} else {
		*stride = 1; /* User didn't specify anything, assume default. */
	}

	/* Figure out whether the user has specified two dates. */
	pos = def.Find("- ");

	if (pos != String::NPos) {
		String first = def.SubStr(0, pos).Trim();

		String second = def.SubStr(pos + 1).Trim();

		ParseTimeSpec(first, begin, NULL, reference);

		/* If the second definition starts with a number we need
		 * to add the first word from the first definition, e.g.:
		 * day 1 - 15 --> "day 15" */
		bool is_number = true;
		size_t xpos = second.FindFirstOf(' ');
		String fword = second.SubStr(0, xpos);

		try {
			Convert::ToLong(fword);
		} catch (...) {
			is_number = false;
		}

		if (is_number) {
			xpos = first.FindFirstOf(' ');
			ASSERT(xpos != String::NPos);
			second = first.SubStr(0, xpos + 1) + second;
		}

		ParseTimeSpec(second, NULL, end, reference);
	} else {
		ParseTimeSpec(def, begin, end, reference);
	}
}
Example #6
0
void CLICommand::ShowCommands(int argc, char **argv, po::options_description *visibleDesc,
    po::options_description *hiddenDesc,
    ArgumentCompletionCallback globalArgCompletionCallback,
    bool autocomplete, int autoindex)
{
	boost::mutex::scoped_lock lock(GetRegistryMutex());

	typedef std::map<std::vector<String>, CLICommand::Ptr>::value_type CLIKeyValue;

	std::vector<String> best_match;
	int arg_begin = 0;
	CLICommand::Ptr command;

	BOOST_FOREACH(const CLIKeyValue& kv, GetRegistry()) {
		const std::vector<String>& vname = kv.first;

		arg_begin = 0;

		for (int i = 0, k = 1; i < vname.size() && k < argc; i++, k++) {
			if (strcmp(argv[k], "--no-stack-rlimit") == 0 || strcmp(argv[k], "--autocomplete") == 0 || strcmp(argv[k], "--scm") == 0) {
				i--;
				arg_begin++;
				continue;
			}

			if (autocomplete && i >= autoindex - 1)
				break;

			if (vname[i] != argv[k])
				break;

			if (i >= best_match.size()) {
				best_match.push_back(vname[i]);
			}

			if (i == vname.size() - 1) {
				command = kv.second;
				break;
			}
		}
	}

	String aword;

	if (autocomplete) {
		if (autoindex < argc)
			aword = argv[autoindex];

		if (autoindex - 1 > best_match.size() && !command)
			return;
	} else
		std::cout << "Supported commands: " << std::endl;

	BOOST_FOREACH(const CLIKeyValue& kv, GetRegistry()) {
		const std::vector<String>& vname = kv.first;

		if (vname.size() < best_match.size())
			continue;

		bool match = true;

		for (int i = 0; i < best_match.size(); i++) {
			if (vname[i] != best_match[i]) {
				match = false;
				break;
			}
		}

		if (!match)
			continue;

		if (autocomplete) {
			String cname;

			if (autoindex - 1 < vname.size()) {
				cname = vname[autoindex - 1];

				if (cname.Find(aword) == 0)
					std::cout << cname << "\n";
			}
		} else
			std::cout << "  * " << boost::algorithm::join(vname, " ") << " (" << kv.second->GetShortDescription() << ")" << std::endl;
	}

	if (!autocomplete)
		std::cout << std::endl;

	if (command && autocomplete) {
		String aname, prefix, pword;
		const po::option_description *odesc;
	
		if (autoindex - 2 >= 0 && strcmp(argv[autoindex - 1], "=") == 0 && strstr(argv[autoindex - 2], "--") == argv[autoindex - 2]) {
			aname = argv[autoindex - 2] + 2;
			pword = aword;
		} else if (autoindex - 1 >= 0 && argv[autoindex - 1][0] == '-' && argv[autoindex - 1][1] == '-') {
			aname = argv[autoindex - 1] + 2;
			pword = aword;
			
			if (pword == "=")
				pword = "";
		} else if (aword.GetLength() > 1 && aword[0] == '-' && aword[1] != '-') {
			aname = aword.SubStr(1, 1);
			prefix = aword.SubStr(0, 2);
			pword = aword.SubStr(2);
		} else {
			goto complete_option;
		}

		odesc = visibleDesc->find_nothrow(aname, false);

		if (!odesc)
			return;

		if (odesc->semantic()->min_tokens() == 0)
			goto complete_option;

		BOOST_FOREACH(const String& suggestion, globalArgCompletionCallback(aname, pword)) {
			std::cout << prefix << suggestion << "\n";
		}
Example #7
0
bool HttpRequest::ParseHeaders(StreamReadContext& src, bool may_wait)
{
	if (!m_Stream)
		return false;

	if (m_State != HttpRequestStart && m_State != HttpRequestHeaders)
		BOOST_THROW_EXCEPTION(std::runtime_error("Invalid HTTP state"));

	String line;
	StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait);

	if (srs != StatusNewItem) {
		if (src.Size > 8 * 1024)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Line length for HTTP header exceeded"));

		return false;
	}

	if (line.GetLength() > 8 * 1024) {
#ifdef I2_DEBUG /* I2_DEBUG */
		Log(LogDebug, "HttpRequest")
			<< "Header size: " << line.GetLength() << " content: '" << line << "'.";
#endif /* I2_DEBUG */

		BOOST_THROW_EXCEPTION(std::invalid_argument("Line length for HTTP header exceeded"));
	}

	if (m_State == HttpRequestStart) {
		/* ignore trailing new-lines */
		if (line == "")
			return true;

		std::vector<String> tokens = line.Split(" ");
		Log(LogDebug, "HttpRequest")
			<< "line: " << line << ", tokens: " << tokens.size();
		if (tokens.size() != 3)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request"));

		RequestMethod = tokens[0];
		RequestUrl = new class Url(tokens[1]);

		if (tokens[2] == "HTTP/1.0")
			ProtocolVersion = HttpVersion10;
		else if (tokens[2] == "HTTP/1.1") {
			ProtocolVersion = HttpVersion11;
		} else
			BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version"));

		m_State = HttpRequestHeaders;
		return true;
	} else { // m_State = HttpRequestHeaders
		if (line == "") {
			m_State = HttpRequestBody;
			CompleteHeaders = true;
			return true;

		} else {
			if (Headers->GetLength() > 128)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Maximum number of HTTP request headers exceeded"));

			String::SizeType pos = line.FindFirstOf(":");
			if (pos == String::NPos)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request"));

			String key = line.SubStr(0, pos).ToLower().Trim();
			String value = line.SubStr(pos + 1).Trim();
			Headers->Set(key, value);

			if (key == "x-http-method-override")
				RequestMethod = value;

			return true;
		}
	}
}
Example #8
0
bool HttpResponse::Parse(StreamReadContext& src, bool may_wait)
{
	if (m_State != HttpResponseBody) {
		String line;
		StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait);

		if (srs != StatusNewItem)
			return false;

		if (m_State == HttpResponseStart) {
			/* ignore trailing new-lines */
			if (line == "")
				return true;

			std::vector<String> tokens;
			boost::algorithm::split(tokens, line, boost::is_any_of(" "));
			Log(LogDebug, "HttpRequest")
				<< "line: " << line << ", tokens: " << tokens.size();
			if (tokens.size() < 3)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request"));

			if (tokens[0] == "HTTP/1.0")
				ProtocolVersion = HttpVersion10;
			else if (tokens[0] == "HTTP/1.1") {
				ProtocolVersion = HttpVersion11;
			} else
				BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version"));

			StatusCode = Convert::ToLong(tokens[1]);
			StatusMessage = tokens[2]; // TODO: Join tokens[2..end]

			m_State = HttpResponseHeaders;
		} else if (m_State == HttpResponseHeaders) {
			if (!Headers)
				Headers = new Dictionary();

			if (line == "") {
				m_State = HttpResponseBody;

				/* we're done if the request doesn't contain a message body */
				if (!Headers->Contains("content-length") && !Headers->Contains("transfer-encoding"))
					Complete = true;
				else
					m_Body = new FIFO();

				return true;

			} else {
				String::SizeType pos = line.FindFirstOf(":");
				if (pos == String::NPos)
					BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request"));
				String key = line.SubStr(0, pos).ToLower().Trim();

				String value = line.SubStr(pos + 1).Trim();
				Headers->Set(key, value);
			}
		} else {
			VERIFY(!"Invalid HTTP request state.");
		}
	} else if (m_State == HttpResponseBody) {
		if (Headers->Get("transfer-encoding") == "chunked") {
			if (!m_ChunkContext)
				m_ChunkContext = boost::make_shared<ChunkReadContext>(boost::ref(src));

			char *data;
			size_t size;
			StreamReadStatus srs = HttpChunkedEncoding::ReadChunkFromStream(m_Stream, &data, &size, *m_ChunkContext.get(), may_wait);

			if (srs != StatusNewItem)
				return false;

			Log(LogNotice, "HttpResponse")
				<< "Read " << size << " bytes";

			m_Body->Write(data, size);

			delete[] data;

			if (size == 0) {
				Complete = true;
				return true;
			}
		} else {
			if (src.Eof)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body"));

			if (src.MustRead) {
				if (!src.FillFromStream(m_Stream, false)) {
					src.Eof = true;
					BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body"));
				}

				src.MustRead = false;
			}

			size_t length_indicator = Convert::ToLong(Headers->Get("content-length"));

			if (src.Size < length_indicator) {
				src.MustRead = true;
				return false;
			}

			m_Body->Write(src.Buffer, length_indicator);
			src.DropData(length_indicator);
			Complete = true;
			return true;
		}
	}

	return true;
}
Example #9
0
PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata)
{
	size_t eqp = perfdata.FindLastOf('=');

	if (eqp == String::NPos)
		BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data value: " + perfdata));

	String label = perfdata.SubStr(0, eqp);

	if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'')
		label = label.SubStr(1, label.GetLength() - 2);

	size_t spq = perfdata.FindFirstOf(' ', eqp);

	if (spq == String::NPos)
		spq = perfdata.GetLength();

	String valueStr = perfdata.SubStr(eqp + 1, spq - eqp - 1);

	size_t pos = valueStr.FindFirstNotOf("+-0123456789.e");

	double value = Convert::ToDouble(valueStr.SubStr(0, pos));

	std::vector<String> tokens = valueStr.Split(";");

	bool counter = false;
	String unit;
	Value warn, crit, min, max;

	if (pos != String::NPos)
		unit = valueStr.SubStr(pos, tokens[0].GetLength() - pos);

	unit = unit.ToLower();

	double base = 1.0;

	if (unit == "us") {
		base /= 1000.0 * 1000.0;
		unit = "seconds";
	} else if (unit == "ms") {
		base /= 1000.0;
		unit = "seconds";
	} else if (unit == "s") {
		unit = "seconds";
	} else if (unit == "tb") {
		base *= 1024.0 * 1024.0 * 1024.0 * 1024.0;
		unit = "bytes";
	} else if (unit == "gb") {
		base *= 1024.0 * 1024.0 * 1024.0;
		unit = "bytes";
	} else if (unit == "mb") {
		base *= 1024.0 * 1024.0;
		unit = "bytes";
	} else if (unit == "kb") {
		base *= 1024.0;
		unit = "bytes";
	} else if (unit == "b") {
		unit = "bytes";
	} else if (unit == "%") {
		unit = "percent";
	} else if (unit == "c") {
		counter = true;
		unit = "";
	} else if (unit != "") {
		BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data unit: " + unit));
	}

	warn = ParseWarnCritMinMaxToken(tokens, 1, "warning");
	crit = ParseWarnCritMinMaxToken(tokens, 2, "critical");
	min = ParseWarnCritMinMaxToken(tokens, 3, "minimum");
	max = ParseWarnCritMinMaxToken(tokens, 4, "maximum");

	value = value * base;

	if (!warn.IsEmpty())
		warn = warn * base;

	if (!crit.IsEmpty())
		crit = crit * base;

	if (!min.IsEmpty())
		min = min * base;

	if (!max.IsEmpty())
		max = max * base;

	return new PerfdataValue(label, value, counter, unit, warn, crit, min, max);
}
void LegacyTimePeriod::ParseTimeSpec(const String& timespec, tm *begin, tm *end, tm *reference)
{
	/* Let mktime() figure out whether we're in DST or not. */
	reference->tm_isdst = -1;

	/* YYYY-MM-DD */
	if (timespec.GetLength() == 10 && timespec[4] == '-' && timespec[7] == '-') {
		int year = Convert::ToLong(timespec.SubStr(0, 4));
		int month = Convert::ToLong(timespec.SubStr(5, 2));
		int day = Convert::ToLong(timespec.SubStr(8, 2));

		if (month < 1 || month > 12)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid month in time specification: " + timespec));
		if (day < 1 || day > 31)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid day in time specification: " + timespec));

		if (begin) {
			*begin = *reference;
			begin->tm_year = year - 1900;
			begin->tm_mon = month - 1;
			begin->tm_mday = day;
			begin->tm_hour = 0;
			begin->tm_min = 0;
			begin->tm_sec = 0;
		}

		if (end) {
			*end = *reference;
			end->tm_year = year - 1900;
			end->tm_mon = month - 1;
			end->tm_mday = day;
			end->tm_hour = 24;
			end->tm_min = 0;
			end->tm_sec = 0;
		}

		return;
	}

	std::vector<String> tokens;
	boost::algorithm::split(tokens, timespec, boost::is_any_of(" "));

	int mon = -1;

	if (tokens.size() > 1 && (tokens[0] == "day" || (mon = MonthFromString(tokens[0])) != -1)) {
		if (mon == -1)
			mon = reference->tm_mon;

		int mday = Convert::ToLong(tokens[1]);

		if (begin) {
			*begin = *reference;
			begin->tm_mon = mon;
			begin->tm_mday = mday;
			begin->tm_hour = 0;
			begin->tm_min = 0;
			begin->tm_sec = 0;

			/* Negative days are relative to the next month. */
			if (mday < 0) {
				begin->tm_mday = mday * -1 - 1;
				begin->tm_mon++;
			}
		}

		if (end) {
			*end = *reference;
			end->tm_mon = mon;
			end->tm_mday = mday;
			end->tm_hour = 24;
			end->tm_min = 0;
			end->tm_sec = 0;

			/* Negative days are relative to the next month. */
			if (mday < 0) {
				end->tm_mday = mday * -1 - 1;
				end->tm_mon++;
			}
		}

		return;
	}

	int wday;

	if (tokens.size() >= 1 && (wday = WeekdayFromString(tokens[0])) != -1) {
		tm myref = *reference;

		if (tokens.size() > 2) {
			mon = MonthFromString(tokens[2]);

			if (mon == -1)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid month in time specification: " + timespec));

			myref.tm_mon = mon;
		}

		int n = 0;

		if (tokens.size() > 1)
			n = Convert::ToLong(tokens[1]);

		if (begin) {
			*begin = myref;

			if (tokens.size() > 1)
				FindNthWeekday(wday, n, begin);
			else
				begin->tm_mday += (7 - begin->tm_wday + wday) % 7;

			begin->tm_hour = 0;
			begin->tm_min = 0;
			begin->tm_sec = 0;
		}

		if (end) {
			*end = myref;

			if (tokens.size() > 1)
				FindNthWeekday(wday, n, end);
			else
				end->tm_mday += (7 - end->tm_wday + wday) % 7;

			end->tm_hour = 0;
			end->tm_min = 0;
			end->tm_sec = 0;
			end->tm_mday++;
		}

		return;
	}

	BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid time specification: " + timespec));
}