bool Endpoint::HasFeature(const String& type) const { Dictionary::Ptr features = GetFeatures(); if (!features) return false; return features->Get(type); }
Object::Ptr DynamicObject::GetExtension(const String& key) { Dictionary::Ptr extensions = m_Extensions; if (!extensions) return Object::Ptr(); return extensions->Get(key); }
bool DynamicObject::HasAuthority(const String& type) const { Dictionary::Ptr authorityInfo = GetAuthorityInfo(); if (!authorityInfo || !authorityInfo->Contains(type)) return true; return authorityInfo->Get(type); }
String CompatUtility::GetCustomAttributeConfig(const CustomVarObject::Ptr& object, const String& name) { Dictionary::Ptr vars = object->GetVars(); if (!vars) return Empty; return vars->Get(name); }
void InfluxdbWriter::SendMetric(const Dictionary::Ptr& tmpl, const String& label, const Dictionary::Ptr& fields, double ts) { std::ostringstream msgbuf; msgbuf << EscapeKey(tmpl->Get("measurement")); Dictionary::Ptr tags = tmpl->Get("tags"); if (tags) { ObjectLock olock(tags); for (const Dictionary::Pair& pair : tags) { // Empty macro expansion, no tag if (!pair.second.IsEmpty()) { msgbuf << "," << EscapeKey(pair.first) << "=" << EscapeKey(pair.second); } } } msgbuf << ",metric=" << EscapeKey(label) << " "; bool first = true; ObjectLock fieldLock(fields); for (const Dictionary::Pair& pair : fields) { if (first) first = false; else msgbuf << ","; msgbuf << EscapeKey(pair.first) << "=" << EscapeField(pair.second); } msgbuf << " " << static_cast<unsigned long>(ts); Log(LogDebug, "InfluxdbWriter") << "Add to metric list:'" << msgbuf.str() << "'."; // Atomically buffer the data point ObjectLock olock(m_DataBuffer); m_DataBuffer->Add(String(msgbuf.str())); // Flush if we've buffered too much to prevent excessive memory use if (static_cast<int>(m_DataBuffer->GetLength()) >= GetFlushThreshold()) { Log(LogDebug, "InfluxdbWriter") << "Data buffer overflow writing " << m_DataBuffer->GetLength() << " data points"; Flush(); } }
void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) { if (permissionFilter) *permissionFilter = NULL; if (permission.IsEmpty()) return; bool foundPermission = false; String requiredPermission = permission.ToLower(); Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); BOOST_FOREACH(const Value& item, permissions) { String permission; Function::Ptr filter; if (item.IsObjectType<Dictionary>()) { Dictionary::Ptr dict = item; permission = dict->Get("permission"); filter = dict->Get("filter"); } else permission = item; permission = permission.ToLower(); if (!Utility::Match(permission, requiredPermission)) continue; foundPermission = true; if (filter && permissionFilter) { std::vector<Expression *> args; args.push_back(new GetScopeExpression(ScopeLocal)); FunctionCallExpression *fexpr = new FunctionCallExpression(new IndexerExpression(MakeLiteral(filter), MakeLiteral("call")), args); if (!*permissionFilter) *permissionFilter = fexpr; else *permissionFilter = new LogicalOrExpression(*permissionFilter, fexpr); } } }
Value ClusterEvents::SendNotificationsAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'send notification' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) { Log(LogNotice, "ClusterEvents") << "Discarding 'send custom notification' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } CheckResult::Ptr cr; Array::Ptr vperf; if (params->Contains("cr")) { cr = new CheckResult(); Dictionary::Ptr vcr = params->Get("cr"); if (vcr && vcr->Contains("performance_data")) { vperf = vcr->Get("performance_data"); if (vperf) vcr->Remove("performance_data"); Deserialize(cr, vcr, true); } } NotificationType type = static_cast<NotificationType>(static_cast<int>(params->Get("type"))); String author = params->Get("author"); String text = params->Get("text"); Checkable::OnNotificationsRequested(checkable, type, cr, author, text, origin); return Empty; }
Value ClusterEvents::NextCheckChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'next check changed' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) { Log(LogNotice, "ClusterEvents") << "Discarding 'next check changed' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } double nextCheck = params->Get("next_check"); if (nextCheck < Application::GetStartTime() + 60) return Empty; checkable->SetNextCheck(params->Get("next_check"), false, origin); return Empty; }
bool TroubleshootCommand::CheckFeatures(InfoLog& log) { Dictionary::Ptr features = new Dictionary; std::vector<String> disabled_features; std::vector<String> enabled_features; if (!FeatureUtility::GetFeatures(disabled_features, true) || !FeatureUtility::GetFeatures(enabled_features, false)) { InfoLogLine(log, 0, LogCritical) << "Failed to collect enabled and/or disabled features. Check\n" << FeatureUtility::GetFeaturesAvailablePath() << '\n' << FeatureUtility::GetFeaturesEnabledPath() << '\n'; return false; } for (const String& feature : disabled_features) features->Set(feature, false); for (const String& feature : enabled_features) features->Set(feature, true); InfoLogLine(log) << "Enabled features:\n"; InfoLogLine(log, Console_ForegroundGreen) << '\t' << boost::algorithm::join(enabled_features, " ") << '\n'; InfoLogLine(log) << "Disabled features:\n"; InfoLogLine(log, Console_ForegroundRed) << '\t' << boost::algorithm::join(disabled_features, " ") << '\n'; if (!features->Get("checker").ToBool()) InfoLogLine(log, 0, LogWarning) << "checker is disabled, no checks can be run from this instance\n"; if (!features->Get("mainlog").ToBool()) InfoLogLine(log, 0, LogWarning) << "mainlog is disabled, please activate it and rerun icinga2\n"; if (!features->Get("debuglog").ToBool()) InfoLogLine(log, 0, LogWarning) << "debuglog is disabled, please activate it and rerun icinga2\n"; return true; }
Value API::GetAnswerToEverything(const Dictionary::Ptr& params) { String text; if (params) text = params->Get("text"); Log(LogInformation, "API") << "Hello from the Icinga 2 API: " << text; return 42; }
void ConfigObject::RestoreObject(const String& message, int attributeTypes) { Dictionary::Ptr persistentObject = JsonDecode(message); String type = persistentObject->Get("type"); String name = persistentObject->Get("name"); ConfigObject::Ptr object = GetObject(type, name); if (!object) return; #ifdef I2_DEBUG Log(LogDebug, "ConfigObject") << "Restoring object '" << name << "' of type '" << type << "'."; #endif /* I2_DEBUG */ Dictionary::Ptr update = persistentObject->Get("update"); Deserialize(object, update, false, attributeTypes); object->OnStateLoaded(); object->SetStateLoaded(true); }
void ApiClient::AutocompleteScriptHttpCompletionCallback(HttpRequest& request, HttpResponse& response, const AutocompleteScriptCompletionCallback& callback) { Dictionary::Ptr result; String body; char buffer[1024]; size_t count; while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0) body += String(buffer, buffer + count); try { if (response.StatusCode < 200 || response.StatusCode > 299) { std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body; BOOST_THROW_EXCEPTION(ScriptError(message)); } result = JsonDecode(body); Array::Ptr results = result->Get("results"); Array::Ptr suggestions; String errorMessage = "Unexpected result from API."; if (results && results->GetLength() > 0) { Dictionary::Ptr resultInfo = results->Get(0); errorMessage = resultInfo->Get("status"); if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) suggestions = resultInfo->Get("suggestions"); else BOOST_THROW_EXCEPTION(ScriptError(errorMessage)); } callback(boost::exception_ptr(), suggestions); } catch (const std::exception&) { callback(boost::current_exception(), nullptr); } }
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response) { if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4) return false; if (request.RequestMethod != "GET") return false; Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]); if (!type) { HttpUtility::SendJsonError(response, 400, "Invalid type specified."); return true; } QueryDescription qd; qd.Types.insert(type->GetName()); qd.Permission = "objects/query/" + type->GetName(); std::vector<String> joinAttrs; joinAttrs.push_back(""); for (int fid = 0; fid < type->GetFieldCount(); fid++) { Field field = type->GetFieldInfo(fid); if (field.Attributes & FANavigation) joinAttrs.push_back(field.Name); } Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request); params->Set("type", type->GetName()); if (request.RequestUrl->GetPath().size() >= 4) { String attr = type->GetName(); boost::algorithm::to_lower(attr); params->Set(attr, request.RequestUrl->GetPath()[3]); } std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user); Array::Ptr results = new Array(); std::set<String> attrs; Array::Ptr uattrs = params->Get("attrs"); if (uattrs) { ObjectLock olock(uattrs); BOOST_FOREACH(const String& uattr, uattrs) { attrs.insert(uattr); } }
void InfluxdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { CONTEXT("Processing check result for '" + checkable->GetName() + "'"); if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !checkable->GetEnablePerfdata()) return; Host::Ptr host; Service::Ptr service; boost::tie(host, service) = GetHostService(checkable); MacroProcessor::ResolverList resolvers; if (service) resolvers.push_back(std::make_pair("service", service)); resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); String prefix; double ts = cr->GetExecutionEnd(); // Clone the template and perform an in-place macro expansion of measurement and tag values Dictionary::Ptr tmpl_clean = service ? GetServiceTemplate() : GetHostTemplate(); Dictionary::Ptr tmpl = static_pointer_cast<Dictionary>(tmpl_clean->Clone()); tmpl->Set("measurement", MacroProcessor::ResolveMacros(tmpl->Get("measurement"), resolvers, cr)); Dictionary::Ptr tags = tmpl->Get("tags"); if (tags) { ObjectLock olock(tags); for (const Dictionary::Pair& pair : tags) { // Prevent missing macros from warning; will return an empty value // which will be filtered out in SendMetric() String missing_macro; tags->Set(pair.first, MacroProcessor::ResolveMacros(pair.second, resolvers, cr, &missing_macro)); } } SendPerfdata(tmpl, checkable, cr, ts); }
/** * The entry point for the "ca sign" CLI command. * * @returns An exit status. */ int CASignCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const { String requestFile = ApiListener::GetCertificateRequestsDir() + "/" + ap[0] + ".json"; if (!Utility::PathExists(requestFile)) { Log(LogCritical, "cli") << "No request exists for fingerprint '" << ap[0] << "'."; return 1; } Dictionary::Ptr request = Utility::LoadJsonFile(requestFile); if (!request) return 1; String certRequestText = request->Get("cert_request"); std::shared_ptr<X509> certRequest = StringToCertificate(certRequestText); if (!certRequest) { Log(LogCritical, "cli", "Certificate request is invalid. Could not parse X.509 certificate for the 'cert_request' attribute."); return 1; } std::shared_ptr<X509> certResponse = CreateCertIcingaCA(certRequest); BIO *out = BIO_new(BIO_s_mem()); X509_NAME_print_ex(out, X509_get_subject_name(certRequest.get()), 0, XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB); char *data; long length; length = BIO_get_mem_data(out, &data); String subject = String(data, data + length); BIO_free(out); if (!certResponse) { Log(LogCritical, "cli") << "Could not sign certificate for '" << subject << "'."; return 1; } request->Set("cert_response", CertificateToString(certResponse)); Utility::SaveJsonFile(requestFile, 0600, request); Log(LogInformation, "cli") << "Signed certificate for '" << subject << "'."; return 0; }
void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { if (resolvedMacros && !useResolvedMacros) return; ApiListener::Ptr listener = ApiListener::GetInstance(); if (!listener) { cr->SetOutput("No API listener is configured for this instance."); cr->SetState(ServiceUnknown); checkable->ProcessCheckResult(cr); return; } std::pair<Dictionary::Ptr, Dictionary::Ptr> stats = listener->GetStatus(); Dictionary::Ptr status = stats.first; /* use feature stats perfdata */ std::pair<Dictionary::Ptr, Array::Ptr> feature_stats = CIB::GetFeatureStats(); cr->SetPerformanceData(feature_stats.second); String connected_endpoints = FormatArray(status->Get("conn_endpoints")); String not_connected_endpoints = FormatArray(status->Get("not_conn_endpoints")); if (status->Get("num_not_conn_endpoints") > 0) { cr->SetState(ServiceCritical); cr->SetOutput("Icinga 2 Cluster Problem: " + Convert::ToString(status->Get("num_not_conn_endpoints")) + " Endpoints (" + not_connected_endpoints + ") not connected."); } else { cr->SetState(ServiceOK); cr->SetOutput("Icinga 2 Cluster is running: Connected Endpoints: "+ Convert::ToString(status->Get("num_conn_endpoints")) + " (" + connected_endpoints + ")."); } checkable->ProcessCheckResult(cr); }
Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& key) { Value varr = params->Get(key); if (!varr.IsObjectType<Array>()) return varr; Array::Ptr arr = varr; if (arr->GetLength() == 0) return Empty; else return arr->Get(arr->GetLength() - 1); }
bool ObjectListUtility::PrintObject(std::ostream& fp, bool& first, const String& message, std::map<String, int>& type_count, const String& name_filter, const String& type_filter) { Dictionary::Ptr object = JsonDecode(message); Dictionary::Ptr properties = object->Get("properties"); String internal_name = properties->Get("__name"); String name = object->Get("name"); String type = object->Get("type"); if (!name_filter.IsEmpty() && !Utility::Match(name_filter, name) && !Utility::Match(name_filter, internal_name)) return false; if (!type_filter.IsEmpty() && !Utility::Match(type_filter, type)) return false; if (first) first = false; else fp << "\n"; Dictionary::Ptr debug_hints = object->Get("debug_hints"); fp << "Object '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << internal_name << ConsoleColorTag(Console_Normal) << "'"; fp << " of type '" << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << type << ConsoleColorTag(Console_Normal) << "':\n"; Array::Ptr di = object->Get("debug_info"); if (di) { fp << ConsoleColorTag(Console_ForegroundCyan) << " % declared in '" << di->Get(0) << "', lines " << di->Get(1) << ":" << di->Get(2) << "-" << di->Get(3) << ":" << di->Get(4) << ConsoleColorTag(Console_Normal) << "\n"; } PrintProperties(fp, properties, debug_hints, 2); type_count[type]++; return true; }
Value ClusterEvents::CheckResultAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'check result' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } if (!params) return Empty; CheckResult::Ptr cr = new CheckResult(); Dictionary::Ptr vcr = params->Get("cr"); Array::Ptr vperf = vcr->Get("performance_data"); vcr->Remove("performance_data"); Deserialize(cr, params->Get("cr"), true); Array::Ptr rperf = new Array(); if (vperf) { ObjectLock olock(vperf); BOOST_FOREACH(const Value& vp, vperf) { Value p; if (vp.IsObjectType<Dictionary>()) { PerfdataValue::Ptr val = new PerfdataValue(); Deserialize(val, vp, true); rperf->Add(val); } else rperf->Add(vp); } }
Value ClusterEvents::AcknowledgementClearedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'acknowledgement cleared' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) { Log(LogNotice, "ClusterEvents") << "Discarding 'acknowledgement cleared' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } checkable->ClearAcknowledgement(origin); return Empty; }
Value SetLogPositionHandler(const MessageOrigin& origin, const Dictionary::Ptr& params) { if (!params) return Empty; double log_position = params->Get("log_position"); Endpoint::Ptr endpoint = origin.FromClient->GetEndpoint(); if (!endpoint) return Empty; if (log_position > endpoint->GetLocalLogPosition()) endpoint->SetLocalLogPosition(log_position); return Empty; }
void ObjectListUtility::PrintHints(std::ostream& fp, const Dictionary::Ptr& debug_hints, int indent) { if (!debug_hints) return; Array::Ptr messages = debug_hints->Get("messages"); if (messages) { ObjectLock olock(messages); for (const Value& msg : messages) { PrintHint(fp, msg, indent); } } }
String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const String& fullName, bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs) { NameComposer *nc = dynamic_cast<NameComposer *>(type.get()); Dictionary::Ptr nameParts; String name; if (nc) { nameParts = nc->ParseName(fullName); name = nameParts->Get("name"); } else name = fullName; Dictionary::Ptr allAttrs = new Dictionary(); if (attrs) { attrs->CopyTo(allAttrs); ObjectLock olock(attrs); for (const Dictionary::Pair& kv : attrs) { int fid = type->GetFieldId(kv.first.SubStr(0, kv.first.FindFirstOf("."))); if (fid < 0) BOOST_THROW_EXCEPTION(ScriptError("Invalid attribute specified: " + kv.first)); Field field = type->GetFieldInfo(fid); if (!(field.Attributes & FAConfig) || kv.first == "name") BOOST_THROW_EXCEPTION(ScriptError("Attribute is marked for internal use only and may not be set: " + kv.first)); } } if (nameParts) nameParts->CopyTo(allAttrs); allAttrs->Remove("name"); /* update the version for config sync */ allAttrs->Set("version", Utility::GetTime()); std::ostringstream config; ConfigWriter::EmitConfigItem(config, type->GetName(), name, false, ignoreOnError, templates, allAttrs); ConfigWriter::EmitRaw(config, "\n"); return config.str(); }
void ApiClient::TypesHttpCompletionCallback(HttpRequest& request, HttpResponse& response, const TypesCompletionCallback& callback) { Dictionary::Ptr result; String body; char buffer[1024]; size_t count; while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0) body += String(buffer, buffer + count); try { if (response.StatusCode < 200 || response.StatusCode > 299) { std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body; BOOST_THROW_EXCEPTION(ScriptError(message)); } std::vector<ApiType::Ptr> types; result = JsonDecode(body); Array::Ptr results = result->Get("results"); ObjectLock olock(results); for (const Dictionary::Ptr typeInfo : results) { ApiType::Ptr type = new ApiType();; type->Abstract = typeInfo->Get("abstract"); type->BaseName = typeInfo->Get("base"); type->Name = typeInfo->Get("name"); type->PluralName = typeInfo->Get("plural_name"); // TODO: attributes types.push_back(type); } callback(boost::exception_ptr(), types); } catch (const std::exception& ex) { Log(LogCritical, "ApiClient") << "Error while decoding response: " << DiagnosticInformation(ex); callback(boost::current_exception(), std::vector<ApiType::Ptr>()); } }
void ClusterEvents::SendNotificationsHandler(const Checkable::Ptr& checkable, NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text, const MessageOrigin::Ptr& origin) { ApiListener::Ptr listener = ApiListener::GetInstance(); if (!listener) return; Dictionary::Ptr message = MakeCheckResultMessage(checkable, cr); message->Set("method", "event::SendNotifications"); Dictionary::Ptr params = message->Get("params"); params->Set("type", type); params->Set("author", author); params->Set("text", text); listener->RelayMessage(origin, nullptr, message, true); }
bool StatusQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response) { if (request.RequestMethod != "GET") return false; if (request.RequestUrl->GetPath().size() < 2) return false; Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[1]); if (!type) return false; QueryDescription qd; qd.Types.insert(type); std::vector<String> joinTypes; joinTypes.push_back(type->GetName()); Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request); params->Set("type", type->GetName()); if (request.RequestUrl->GetPath().size() >= 3) { String attr = type->GetName(); boost::algorithm::to_lower(attr); params->Set(attr, request.RequestUrl->GetPath()[2]); } std::vector<ConfigObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params); Array::Ptr results = new Array(); std::set<String> attrs; Array::Ptr uattrs = params->Get("attrs"); if (uattrs) { ObjectLock olock(uattrs); BOOST_FOREACH(const String& uattr, uattrs) { attrs.insert(uattr); } }
void ApiClient::SendMessageSync(const Dictionary::Ptr& message) { try { ObjectLock olock(m_Stream); if (m_Stream->IsEof()) return; JsonRpc::SendMessage(m_Stream, message); if (message->Get("method") != "log::SetLogPosition") m_Seen = Utility::GetTime(); } catch (const std::exception& ex) { std::ostringstream info; info << "Error while sending JSON-RPC message for identity '" << m_Identity << "'"; Log(LogWarning, "ApiClient") << info.str(); Log(LogDebug, "ApiClient") << info.str() << "\n" << DiagnosticInformation(ex); Disconnect(); } }
Value ClusterEvents::AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'acknowledgement set' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) { Log(LogNotice, "ClusterEvents") << "Discarding 'acknowledgement set' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } checkable->AcknowledgeProblem(params->Get("author"), params->Get("comment"), static_cast<AcknowledgementType>(static_cast<int>(params->Get("acktype"))), params->Get("notify"), params->Get("persistent"), params->Get("expiry"), origin); return Empty; }
bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params) { if (request.RequestUrl->GetPath().size() > 2) return false; if (request.RequestMethod != "GET") return false; if (request.RequestUrl->GetPath().empty()) { response.SetStatus(302, "Found"); response.AddHeader("Location", "/v1"); return true; } if (request.RequestUrl->GetPath()[0] != "v1" || request.RequestUrl->GetPath().size() != 1) return false; response.SetStatus(200, "OK"); std::vector<String> permInfo; Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); BOOST_FOREACH(const Value& permission, permissions) { String name; bool hasFilter = false; if (permission.IsObjectType<Dictionary>()) { Dictionary::Ptr dpermission = permission; name = dpermission->Get("permission"); hasFilter = dpermission->Contains("filter"); } else name = permission; if (hasFilter) name += " (filtered)"; permInfo.push_back(name); } }
Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { if (!params) return Empty; Dictionary::Ptr result = new Dictionary(); if (!origin->FromClient->IsAuthenticated()) { ApiListener::Ptr listener = ApiListener::GetInstance(); String salt = listener->GetTicketSalt(); if (salt.IsEmpty()) { result->Set("error", "Ticket salt is not configured."); return result; } String ticket = params->Get("ticket"); String realTicket = PBKDF2_SHA1(origin->FromClient->GetIdentity(), salt, 50000); if (ticket != realTicket) { result->Set("error", "Invalid ticket."); return result; } } boost::shared_ptr<X509> cert = origin->FromClient->GetStream()->GetPeerCertificate(); EVP_PKEY *pubkey = X509_get_pubkey(cert.get()); X509_NAME *subject = X509_get_subject_name(cert.get()); boost::shared_ptr<X509> newcert = CreateCertIcingaCA(pubkey, subject); result->Set("cert", CertificateToString(newcert)); String cacertfile = GetIcingaCADir() + "/ca.crt"; boost::shared_ptr<X509> cacert = GetX509Certificate(cacertfile); result->Set("ca", CertificateToString(cacert)); return result; }