Beispiel #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;
}
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);
	}
}
  kt_bool StringHelper::FromString(const String& rStringValue, Quaternion& rValue)
  {
    kt_size_t index = rStringValue.FindFirstOf(" ");
    if (index != -1)
    {
      std::stringstream converter;
      converter.str(rStringValue.ToCString());

      kt_double valueX = 0.0;
      kt_double valueY = 0.0;
      kt_double valueZ = 0.0;
      kt_double valueW = 0.0;

      converter >> valueX;
      converter >> valueY;
      converter >> valueZ;
      converter >> valueW;

      rValue.SetX(valueX);
      rValue.SetY(valueY);
      rValue.SetZ(valueZ);
      rValue.SetW(valueW);

      return true;
    }
Beispiel #4
0
Url::Url(const String& base_url)
{
	String url = base_url;

	if (url.GetLength() == 0)
		BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Empty URL."));

	size_t pHelper = url.Find(":");

	if (pHelper != String::NPos) {
		if (!ParseScheme(url.SubStr(0, pHelper)))
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Scheme."));
		url = url.SubStr(pHelper + 1);
	}

	if (*url.Begin() != '/')
		BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: '/' expected after scheme."));

	if (url.GetLength() == 1) {
		return;
	}

	if (*(url.Begin() + 1) == '/') {
		pHelper = url.Find("/", 2);

		if (pHelper == String::NPos)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: Missing '/' after authority."));

		if (!ParseAuthority(url.SubStr(0, pHelper)))
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Authority"));

		url = url.SubStr(pHelper);
	}

	if (*url.Begin() == '/') {
		pHelper = url.FindFirstOf("#?");
		if (!ParsePath(url.SubStr(1, pHelper - 1)))
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Path"));

		if (pHelper != String::NPos)
			url = url.SubStr(pHelper);
	} else
		BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL: Missing path."));

	if (*url.Begin() == '?') {
		pHelper = url.Find("#");
		if (!ParseQuery(url.SubStr(1, pHelper - 1)))
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Query"));

		if (pHelper != String::NPos)
			url = url.SubStr(pHelper);
	}

	if (*url.Begin() == '#') {
		if (!ParseFragment(url.SubStr(1)))
			BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Fragment"));
	}
}
Beispiel #5
0
bool Url::ParseScheme(const String& scheme)
{
	m_Scheme = scheme;

	if (scheme.FindFirstOf(ALPHA) != 0)
		return false;

	return (ValidateToken(scheme, ACSCHEME));
}
Beispiel #6
0
bool Url::ValidateToken(const String& token, const String& symbols)
{
	for (const char ch : token) {
		if (symbols.FindFirstOf(ch) == String::NPos)
			return false;
	}

	return true;
}
Beispiel #7
0
void HttpConnection::ProcessMessageAsync(HttpRequest& request)
{
	Log(LogInformation, "HttpConnection", "Processing Http message");

	String auth_header = request.Headers->Get("authorization");

	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);
		}
	}

	ApiUser::Ptr user;

	if (m_ApiUser)
		user = m_ApiUser;
	else {
		user = ApiUser::GetByName(username);

		if (!user || !user->CheckPassword(password))
			user.reset();
	}

	HttpResponse response(m_Stream, request);

	if (!user) {
		response.SetStatus(401, "Unauthorized");
		response.AddHeader("Content-Type", "text/html");
		response.AddHeader("WWW-Authenticate", "Basic realm=\"Icinga 2\"");
		String msg = "<h1>Unauthorized</h1>";
		response.WriteBody(msg.CStr(), msg.GetLength());
	} else {
		try {
			HttpHandler::ProcessRequest(user, request, response);
		} catch (const std::exception& ex) {
			response.SetStatus(503, "Unhandled exception");
			response.AddHeader("Content-Type", "text/plain");
			String errorInfo = DiagnosticInformation(ex);
			response.WriteBody(errorInfo.CStr(), errorInfo.GetLength());
		}
	}

	response.Finish();

	m_PendingRequests--;
}
Beispiel #8
0
static String LoadAppType(const String& typeSpec)
{
	int index;

	Log(LogInformation, "icinga-app", "Loading application type: " + typeSpec);

	index = typeSpec.FindFirstOf('/');

	if (index == String::NPos)
		return typeSpec;

	String library = typeSpec.SubStr(0, index);

	(void) Utility::LoadExtensionLibrary(library);

	return typeSpec.SubStr(index + 1);
}
Beispiel #9
0
	static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter,
		const String& zone, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
	{
		ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo);

		String checkName = name;

		if (!abstract) {
			Type::Ptr ptype = Type::GetByName(type);

			NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get());

			if (nc)
				checkName = nc->MakeName(name, Dictionary::Ptr());
		}

		if (!checkName.IsEmpty()) {
			ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName);

			if (oldItem) {
				std::ostringstream msgbuf;
				msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo();
				BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
			}
		}

		item->SetType(type);

		if (name.FindFirstOf("!") != String::NPos) {
			std::ostringstream msgbuf;
			msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'";
			BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
		}

		item->SetName(name);

		item->AddExpression(new OwnedExpression(expression));
		item->SetAbstract(abstract);
		item->SetScope(EvaluateClosedVars(frame, closedVars));
		item->SetZone(zone);
		item->SetFilter(filter);
		item->Compile()->Register();

		return Empty;
	}
Beispiel #10
0
String Utility::EscapeShellCmd(const String& s)
{
	String result;
	size_t prev_quote = String::NPos;
	int index = -1;

	BOOST_FOREACH(char ch, s) {
		bool escape = false;

		index++;

#ifdef _WIN32
		if (ch == '%' || ch == '"' || ch == '\'')
			escape = true;
#else /* _WIN32 */
		if (ch == '"' || ch == '\'') {
			/* Find a matching closing quotation character. */
			if (prev_quote == String::NPos && (prev_quote = s.FindFirstOf(ch, index + 1)) != String::NPos)
				; /* Empty statement. */
			else if (prev_quote != String::NPos && s[prev_quote] == ch)
				prev_quote = String::NPos;
			else
				escape = true;
		}
#endif /* _WIN32 */

		if (ch == '#' || ch == '&' || ch == ';' || ch == '`' || ch == '|' ||
		    ch == '*' || ch == '?' || ch == '~' || ch == '<' || ch == '>' ||
		    ch == '^' || ch == '(' || ch == ')' || ch == '[' || ch == ']' ||
		    ch == '{' || ch == '}' || ch == '$' || ch == '\\' || ch == '\x0A' ||
		    ch == '\xFF')
			escape = true;

		if (escape)
#ifdef _WIN32
			result += '^';
#else /* _WIN32 */
			result += '\\';
#endif /* _WIN32 */

		result += ch;
	}
Beispiel #11
0
NAMESPACE_UPP

#ifdef PLATFORM_WIN32
static void fixSpecials(String &s)
{
	// this stuff just for windows... sig
	if(s.FindFirstOf(" \t\n\v\"") >= 0)
	{
		String sOld = s;
		s.Clear();
		s = "\"";

		const char *sp = sOld;
		for(;;) {
			int num_backslashes = 0;
			while(*sp == '\\') {
				sp++;
				num_backslashes++;
			}
			if(*sp == '\0') {
				s.Cat('\\', 2 * num_backslashes);
				break;
			}
			else
			if(*sp == '\"') {
				s.Cat('\\', 2 * num_backslashes + 1);
				s << '\"';
			}
			else {
				s.Cat('\\', num_backslashes);
				s.Cat(*sp);
			}
			sp++;
		}
		s << '\"';
	}
}
Beispiel #12
0
bool HttpRequest::Parse(StreamReadContext& src, bool may_wait)
{
	if (m_State != HttpRequestBody) {
		String line;
		StreamReadStatus srs = m_Stream->ReadLine(&line, src, may_wait);

		if (srs != StatusNewItem)
			return false;

		if (m_State == HttpRequestStart) {
			/* 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"));
			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;
		} else if (m_State == HttpRequestHeaders) {
			if (line == "") {
				m_State = HttpRequestBody;

				/* 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);

				if (key == "x-http-method-override")
					RequestMethod = value;
			}
		} else {
			VERIFY(!"Invalid HTTP request state.");
		}
	} else if (m_State == HttpRequestBody) {
		if (Headers->Get("transfer-encoding") == "chunked") {
			if (!m_ChunkContext)
				m_ChunkContext = boost::make_shared<ChunkReadContext>(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(LogInformation, "HttpRequest")
			    << "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;
}
Beispiel #13
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;
		}
	}
}
Beispiel #14
0
/**
 * Handles an include directive.
 *
 * @param include The path from the include directive.
 * @param search Whether to search global include dirs.
 * @param debuginfo Debug information.
 */
void ConfigCompiler::HandleInclude(const String& include, bool search, const DebugInfo& debuginfo)
{
	String path;

	if (search || (include.GetLength() > 0 && include[0] == '/'))
		path = include;
	else
		path = Utility::DirName(GetPath()) + "/" + include;

	String includePath = path;

	if (search) {
		BOOST_FOREACH(const String& dir, m_IncludeSearchDirs) {
			String spath = dir + "/" + include;

#ifndef _WIN32
			struct stat statbuf;
			if (lstat(spath.CStr(), &statbuf) >= 0) {
#else /* _WIN32 */
			struct _stat statbuf;
			if (_stat(spath.CStr(), &statbuf) >= 0) {
#endif /* _WIN32 */
				includePath = spath;
				break;
			}
		}
	}

	std::vector<ConfigItem::Ptr> items;

	if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
		std::ostringstream msgbuf;
		msgbuf << "Include file '" + include + "' does not exist: " << debuginfo;
		BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
	}
}
Dictionary::Ptr LivestatusLogUtility::GetAttributes(const String& text)
{
	Dictionary::Ptr bag = new Dictionary();

	/*
	 * [1379025342] SERVICE NOTIFICATION: contactname;hostname;servicedesc;WARNING;true;foo output
	 */
	unsigned long time = atoi(text.SubStr(1, 11).CStr());

	Log(LogDebug, "LivestatusLogUtility")
		<< "Processing log line: '" << text << "'.";
	bag->Set("time", time);

	size_t colon = text.FindFirstOf(':');
	size_t colon_offset = colon - 13;

	String type = String(text.SubStr(13, colon_offset)).Trim();
	String options = String(text.SubStr(colon + 1)).Trim();

	bag->Set("type", type);
	bag->Set("options", options);

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

	/* set default values */
	bag->Set("class", LogEntryClassInfo);
	bag->Set("log_type", 0);
	bag->Set("state", 0);
	bag->Set("attempt", 0);
	bag->Set("message", text); /* used as 'message' in log table, and 'log_output' in statehist table */

	if (type.Contains("INITIAL HOST STATE") ||
		type.Contains("CURRENT HOST STATE") ||
		type.Contains("HOST ALERT")) {
		if (tokens.size() < 5)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("state", Host::StateFromString(tokens[1]));
		bag->Set("state_type", tokens[2]);
		bag->Set("attempt", atoi(tokens[3].CStr()));
		bag->Set("plugin_output", tokens[4]);

		if (type.Contains("INITIAL HOST STATE")) {
			bag->Set("class", LogEntryClassState);
			bag->Set("log_type", LogEntryTypeHostInitialState);
		}
		else if (type.Contains("CURRENT HOST STATE")) {
			bag->Set("class", LogEntryClassState);
			bag->Set("log_type", LogEntryTypeHostCurrentState);
		}
		else {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeHostAlert);
		}

		return bag;
	} else if (type.Contains("HOST DOWNTIME ALERT") ||  type.Contains("HOST FLAPPING ALERT")) {
		if (tokens.size() < 3)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("state_type", tokens[1]);
		bag->Set("comment", tokens[2]);

		if (type.Contains("HOST FLAPPING ALERT")) {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeHostFlapping);
		} else {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeHostDowntimeAlert);
		}

		return bag;
	} else if (type.Contains("INITIAL SERVICE STATE") ||
		type.Contains("CURRENT SERVICE STATE") ||
		type.Contains("SERVICE ALERT")) {
		if (tokens.size() < 6)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("service_description", tokens[1]);
		bag->Set("state", Service::StateFromString(tokens[2]));
		bag->Set("state_type", tokens[3]);
		bag->Set("attempt", atoi(tokens[4].CStr()));
		bag->Set("plugin_output", tokens[5]);

		if (type.Contains("INITIAL SERVICE STATE")) {
			bag->Set("class", LogEntryClassState);
			bag->Set("log_type", LogEntryTypeServiceInitialState);
		}
		else if (type.Contains("CURRENT SERVICE STATE")) {
			bag->Set("class", LogEntryClassState);
			bag->Set("log_type", LogEntryTypeServiceCurrentState);
		}
		else {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeServiceAlert);
		}

		return bag;
	} else if (type.Contains("SERVICE DOWNTIME ALERT") ||
		type.Contains("SERVICE FLAPPING ALERT")) {
		if (tokens.size() < 4)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("service_description", tokens[1]);
		bag->Set("state_type", tokens[2]);
		bag->Set("comment", tokens[3]);

		if (type.Contains("SERVICE FLAPPING ALERT")) {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeServiceFlapping);
		} else {
			bag->Set("class", LogEntryClassAlert);
			bag->Set("log_type", LogEntryTypeServiceDowntimeAlert);
		}

		return bag;
	} else if (type.Contains("TIMEPERIOD TRANSITION")) {
		if (tokens.size() < 4)
			return bag;

		bag->Set("class", LogEntryClassState);
		bag->Set("log_type", LogEntryTypeTimeperiodTransition);

		bag->Set("host_name", tokens[0]);
		bag->Set("service_description", tokens[1]);
		bag->Set("state_type", tokens[2]);
		bag->Set("comment", tokens[3]);
	} else if (type.Contains("HOST NOTIFICATION")) {
		if (tokens.size() < 6)
			return bag;

		bag->Set("contact_name", tokens[0]);
		bag->Set("host_name", tokens[1]);
		bag->Set("state_type", tokens[2].CStr());
		bag->Set("state", Service::StateFromString(tokens[3]));
		bag->Set("command_name", tokens[4]);
		bag->Set("plugin_output", tokens[5]);

		bag->Set("class", LogEntryClassNotification);
		bag->Set("log_type", LogEntryTypeHostNotification);

		return bag;
	} else if (type.Contains("SERVICE NOTIFICATION")) {
		if (tokens.size() < 7)
			return bag;

		bag->Set("contact_name", tokens[0]);
		bag->Set("host_name", tokens[1]);
		bag->Set("service_description", tokens[2]);
		bag->Set("state_type", tokens[3].CStr());
		bag->Set("state", Service::StateFromString(tokens[4]));
		bag->Set("command_name", tokens[5]);
		bag->Set("plugin_output", tokens[6]);

		bag->Set("class", LogEntryClassNotification);
		bag->Set("log_type", LogEntryTypeServiceNotification);

		return bag;
	} else if (type.Contains("PASSIVE HOST CHECK")) {
		if (tokens.size() < 3)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("state", Host::StateFromString(tokens[1]));
		bag->Set("plugin_output", tokens[2]);

		bag->Set("class", LogEntryClassPassive);

		return bag;
	} else if (type.Contains("PASSIVE SERVICE CHECK")) {
		if (tokens.size() < 4)
			return bag;

		bag->Set("host_name", tokens[0]);
		bag->Set("service_description", tokens[1]);
		bag->Set("state", Host::StateFromString(tokens[2]));
		bag->Set("plugin_output", tokens[3]);

		bag->Set("class", LogEntryClassPassive);

		return bag;
	} else if (type.Contains("EXTERNAL COMMAND")) {
		bag->Set("class", LogEntryClassCommand);
		/* string processing not implemented in 1.x */

		return bag;
	} else if (type.Contains("LOG VERSION")) {
		bag->Set("class", LogEntryClassProgram);
		bag->Set("log_type", LogEntryTypeVersion);

		return bag;
	} else if (type.Contains("logging initial states")) {
		bag->Set("class", LogEntryClassProgram);
		bag->Set("log_type", LogEntryTypeInitialStates);

		return bag;
	} else if (type.Contains("starting... (PID=")) {
		bag->Set("class", LogEntryClassProgram);
		bag->Set("log_type", LogEntryTypeProgramStarting);

		return bag;
	}
	/* program */
	else if (type.Contains("restarting...") ||
		type.Contains("shutting down...") ||
		type.Contains("Bailing out") ||
		type.Contains("active mode...") ||
		type.Contains("standby mode...")) {
		bag->Set("class", LogEntryClassProgram);

		return bag;
	}

	return bag;
}
Beispiel #16
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);
}
Beispiel #17
0
	BOOST_FOREACH(const String& line, lines) {
		msg += line + "\n";
	}
	Log(LogDebug, "LivestatusQuery", msg);

	m_CompatLogPath = compat_log_path;

	/* default separators */
	m_Separators.push_back("\n");
	m_Separators.push_back(";");
	m_Separators.push_back(",");
	m_Separators.push_back("|");

	String line = lines[0];

	size_t sp_index = line.FindFirstOf(" ");

	if (sp_index == String::NPos)
		BOOST_THROW_EXCEPTION(std::runtime_error("Livestatus header must contain a verb."));

	String verb = line.SubStr(0, sp_index);
	String target = line.SubStr(sp_index + 1);

	m_Verb = verb;

	if (m_Verb == "COMMAND") {
		m_KeepAlive = true;
		m_Command = target;
	} else if (m_Verb == "GET") {
		m_Table = target;
	} else {
Beispiel #18
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 = line.Split(" ");
			Log(LogDebug, "HttpRequest")
				<< "line: " << line << ", tokens: " << tokens.size();
			if (tokens.size() < 2)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP response (Status line)"));

			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]);

			if (tokens.size() >= 3)
				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;
				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 = std::make_shared<ChunkReadContext>(std::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 {
			bool hasLengthIndicator = false;
			size_t lengthIndicator = 0;
			Value contentLengthHeader;

			if (Headers->Get("content-length", &contentLengthHeader)) {
				hasLengthIndicator = true;
				lengthIndicator = Convert::ToLong(contentLengthHeader);
			}

			if (!hasLengthIndicator && ProtocolVersion != HttpVersion10 && !Headers->Contains("transfer-encoding")) {
				Complete = true;
				return true;
			}

			if (hasLengthIndicator && src.Eof)
				BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected EOF in HTTP body"));

			if (src.MustRead) {
				if (!src.FillFromStream(m_Stream, may_wait))
					src.Eof = true;

				src.MustRead = false;
			}

			if (!hasLengthIndicator)
				lengthIndicator = src.Size;

			if (src.Size < lengthIndicator) {
				src.MustRead = true;
				return may_wait;
			}

			m_Body->Write(src.Buffer, lengthIndicator);
			src.DropData(lengthIndicator);

			if (!hasLengthIndicator && !src.Eof) {
				src.MustRead = true;
				return may_wait;
			}

			Complete = true;
			return true;
		}
	}

	return true;
}