"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.isElasticCloudDeployment = exports.getPreviousDiagTaskTimestamp = exports.getPreviousDailyTaskTimestamp = exports.formatValueListMetaData = exports.extractEndpointPolicyConfig = exports.exceptionListItemToTelemetryEntry = exports.createUsageCounterLabel = exports.createTaskMetric = exports.batchTelemetryRecords = exports.addDefaultAdvancedPolicyConfigSettings = void 0; exports.isPackagePolicyList = isPackagePolicyList; exports.trustedApplicationToTelemetryEntry = exports.tlog = exports.templateExceptionList = exports.setIsElasticCloudDeployment = exports.ruleExceptionListItemToTelemetryEvent = exports.processK8sUsernames = void 0; var _moment = _interopRequireDefault(require("moment")); var _lodash = require("lodash"); var _jsSha = require("js-sha256"); var _filterlists = require("./filterlists"); var _constants = require("./constants"); var _mapping = require("../../../common/endpoint/service/trusted_apps/mapping"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ /** * Determines the when the last run was in order to execute to. * * @param executeTo * @param lastExecutionTimestamp * @returns the timestamp to search from */ const getPreviousDiagTaskTimestamp = (executeTo, lastExecutionTimestamp) => { if (lastExecutionTimestamp === undefined) { return (0, _moment.default)(executeTo).subtract(5, 'minutes').toISOString(); } if ((0, _moment.default)(executeTo).diff(lastExecutionTimestamp, 'minutes') >= 10) { return (0, _moment.default)(executeTo).subtract(10, 'minutes').toISOString(); } return lastExecutionTimestamp; }; /** * Determines the when the last run was in order to execute to. * * @param executeTo * @param lastExecutionTimestamp * @returns the timestamp to search from */ exports.getPreviousDiagTaskTimestamp = getPreviousDiagTaskTimestamp; const getPreviousDailyTaskTimestamp = (executeTo, lastExecutionTimestamp) => { if (lastExecutionTimestamp === undefined) { return (0, _moment.default)(executeTo).subtract(24, 'hours').toISOString(); } if ((0, _moment.default)(executeTo).diff(lastExecutionTimestamp, 'hours') >= 24) { return (0, _moment.default)(executeTo).subtract(24, 'hours').toISOString(); } return lastExecutionTimestamp; }; /** * Chunks an Array into an Array> * This is to prevent overloading the telemetry channel + user resources * * @param telemetryRecords * @param batchSize * @returns the batch of records */ exports.getPreviousDailyTaskTimestamp = getPreviousDailyTaskTimestamp; const batchTelemetryRecords = (telemetryRecords, batchSize) => [...Array(Math.ceil(telemetryRecords.length / batchSize))].map(_ => telemetryRecords.splice(0, batchSize)); /** * User defined type guard for PackagePolicy * * @param data the union type of package policies * @returns type confirmation */ exports.batchTelemetryRecords = batchTelemetryRecords; function isPackagePolicyList(data) { if (data === undefined || data.length < 1) { return false; } return data[0].inputs !== undefined; } /** * Maps trusted application to shared telemetry object * * @param trustedAppExceptionItem * @returns collection of trusted applications */ const trustedApplicationToTelemetryEntry = trustedAppExceptionItem => { return { id: trustedAppExceptionItem.id, name: trustedAppExceptionItem.name, created_at: trustedAppExceptionItem.created_at, updated_at: trustedAppExceptionItem.updated_at, entries: trustedAppExceptionItem.entries, os_types: trustedAppExceptionItem.os_types, scope: (0, _mapping.tagsToEffectScope)(trustedAppExceptionItem.tags) }; }; /** * Maps endpoint lists to shared telemetry object * * @param exceptionListItem * @returns collection of endpoint exceptions */ exports.trustedApplicationToTelemetryEntry = trustedApplicationToTelemetryEntry; const exceptionListItemToTelemetryEntry = exceptionListItem => { return { id: exceptionListItem.id, name: exceptionListItem.name, created_at: exceptionListItem.created_at, updated_at: exceptionListItem.updated_at, entries: exceptionListItem.entries, os_types: exceptionListItem.os_types }; }; /** * Maps detection rule exception list items to shared telemetry object * * @param exceptionListItem * @param ruleVersion * @returns collection of detection rule exceptions */ exports.exceptionListItemToTelemetryEntry = exceptionListItemToTelemetryEntry; const ruleExceptionListItemToTelemetryEvent = (exceptionListItem, ruleVersion) => { return { id: exceptionListItem.item_id, name: exceptionListItem.description, rule_version: ruleVersion, created_at: exceptionListItem.created_at, updated_at: exceptionListItem.updated_at, entries: exceptionListItem.entries, os_types: exceptionListItem.os_types }; }; /** * Consructs the list telemetry schema from a collection of endpoint exceptions * * @param listData * @param listType * @returns lists telemetry schema */ exports.ruleExceptionListItemToTelemetryEvent = ruleExceptionListItemToTelemetryEvent; const templateExceptionList = (listData, clusterInfo, licenseInfo, listType) => { return listData.map(item => { const template = { '@timestamp': (0, _moment.default)().toISOString(), cluster_uuid: clusterInfo.cluster_uuid, cluster_name: clusterInfo.cluster_name, license_id: licenseInfo === null || licenseInfo === void 0 ? void 0 : licenseInfo.uid }; // cast exception list type to a TelemetryEvent for allowlist filtering const filteredListItem = (0, _filterlists.copyAllowlistedFields)(_filterlists.filterList.exceptionLists, item); if (listType === _constants.LIST_DETECTION_RULE_EXCEPTION) { template.detection_rule = filteredListItem; return template; } if (listType === _constants.LIST_TRUSTED_APPLICATION) { template.trusted_application = filteredListItem; return template; } if (listType === _constants.LIST_ENDPOINT_EXCEPTION) { template.endpoint_exception = filteredListItem; return template; } if (listType === _constants.LIST_ENDPOINT_EVENT_FILTER) { template.endpoint_event_filter = filteredListItem; return template; } return null; }); }; /** * Convert counter label list to kebab case * * @param label_list the list of labels to create standardized UsageCounter from * @returns a string label for usage in the UsageCounter */ exports.templateExceptionList = templateExceptionList; const createUsageCounterLabel = labelList => labelList.join('-'); /** * Resiliantly handles an edge case where the endpoint config details are not present * * @returns the endpoint policy configuration */ exports.createUsageCounterLabel = createUsageCounterLabel; const extractEndpointPolicyConfig = policyData => { var _policyData$inputs$, _policyData$inputs$$c; const epPolicyConfig = policyData === null || policyData === void 0 ? void 0 : (_policyData$inputs$ = policyData.inputs[0]) === null || _policyData$inputs$ === void 0 ? void 0 : (_policyData$inputs$$c = _policyData$inputs$.config) === null || _policyData$inputs$$c === void 0 ? void 0 : _policyData$inputs$$c.policy; return epPolicyConfig ? epPolicyConfig : null; }; exports.extractEndpointPolicyConfig = extractEndpointPolicyConfig; const addDefaultAdvancedPolicyConfigSettings = policyConfig => { return (0, _lodash.merge)(_constants.DEFAULT_ADVANCED_POLICY_CONFIG_SETTINGS, policyConfig); }; exports.addDefaultAdvancedPolicyConfigSettings = addDefaultAdvancedPolicyConfigSettings; const formatValueListMetaData = (valueListResponse, clusterInfo, licenseInfo) => { var _valueListResponse$li, _valueListResponse$li2, _valueListResponse$li3, _valueListResponse$li4, _valueListResponse$li5, _valueListResponse$li6, _valueListResponse$li7, _valueListResponse$li8, _valueListResponse$it, _valueListResponse$it2, _valueListResponse$it3, _valueListResponse$it4, _valueListResponse$ex, _valueListResponse$ex2, _valueListResponse$ex3, _valueListResponse$ex4, _valueListResponse$in, _valueListResponse$in2, _valueListResponse$in3, _valueListResponse$in4; return { '@timestamp': (0, _moment.default)().toISOString(), cluster_uuid: clusterInfo.cluster_uuid, cluster_name: clusterInfo.cluster_name, license_id: licenseInfo === null || licenseInfo === void 0 ? void 0 : licenseInfo.uid, total_list_count: (_valueListResponse$li = (_valueListResponse$li2 = valueListResponse.listMetricsResponse) === null || _valueListResponse$li2 === void 0 ? void 0 : (_valueListResponse$li3 = _valueListResponse$li2.aggregations) === null || _valueListResponse$li3 === void 0 ? void 0 : (_valueListResponse$li4 = _valueListResponse$li3.total_value_list_count) === null || _valueListResponse$li4 === void 0 ? void 0 : _valueListResponse$li4.value) !== null && _valueListResponse$li !== void 0 ? _valueListResponse$li : 0, types: (_valueListResponse$li5 = (_valueListResponse$li6 = valueListResponse.listMetricsResponse) === null || _valueListResponse$li6 === void 0 ? void 0 : (_valueListResponse$li7 = _valueListResponse$li6.aggregations) === null || _valueListResponse$li7 === void 0 ? void 0 : (_valueListResponse$li8 = _valueListResponse$li7.type_breakdown) === null || _valueListResponse$li8 === void 0 ? void 0 : _valueListResponse$li8.buckets.map(breakdown => ({ type: breakdown.key, count: breakdown.doc_count }))) !== null && _valueListResponse$li5 !== void 0 ? _valueListResponse$li5 : [], lists: (_valueListResponse$it = (_valueListResponse$it2 = valueListResponse.itemMetricsResponse) === null || _valueListResponse$it2 === void 0 ? void 0 : (_valueListResponse$it3 = _valueListResponse$it2.aggregations) === null || _valueListResponse$it3 === void 0 ? void 0 : (_valueListResponse$it4 = _valueListResponse$it3.value_list_item_count) === null || _valueListResponse$it4 === void 0 ? void 0 : _valueListResponse$it4.buckets.map(itemCount => ({ id: itemCount.key, count: itemCount.doc_count }))) !== null && _valueListResponse$it !== void 0 ? _valueListResponse$it : [], included_in_exception_lists_count: (_valueListResponse$ex = (_valueListResponse$ex2 = valueListResponse.exceptionListMetricsResponse) === null || _valueListResponse$ex2 === void 0 ? void 0 : (_valueListResponse$ex3 = _valueListResponse$ex2.aggregations) === null || _valueListResponse$ex3 === void 0 ? void 0 : (_valueListResponse$ex4 = _valueListResponse$ex3.vl_included_in_exception_lists_count) === null || _valueListResponse$ex4 === void 0 ? void 0 : _valueListResponse$ex4.value) !== null && _valueListResponse$ex !== void 0 ? _valueListResponse$ex : 0, used_in_indicator_match_rule_count: (_valueListResponse$in = (_valueListResponse$in2 = valueListResponse.indicatorMatchMetricsResponse) === null || _valueListResponse$in2 === void 0 ? void 0 : (_valueListResponse$in3 = _valueListResponse$in2.aggregations) === null || _valueListResponse$in3 === void 0 ? void 0 : (_valueListResponse$in4 = _valueListResponse$in3.vl_used_in_indicator_match_rule_count) === null || _valueListResponse$in4 === void 0 ? void 0 : _valueListResponse$in4.value) !== null && _valueListResponse$in !== void 0 ? _valueListResponse$in : 0 }; }; exports.formatValueListMetaData = formatValueListMetaData; let isElasticCloudDeployment = false; exports.isElasticCloudDeployment = isElasticCloudDeployment; const setIsElasticCloudDeployment = value => { exports.isElasticCloudDeployment = isElasticCloudDeployment = value; }; exports.setIsElasticCloudDeployment = setIsElasticCloudDeployment; const tlog = (logger, message) => { if (isElasticCloudDeployment) { logger.info(message); } else { logger.debug(message); } }; exports.tlog = tlog; const createTaskMetric = (name, passed, startTime, errorMessage) => { const endTime = Date.now(); return { name, passed, time_executed_in_ms: endTime - startTime, start_time: startTime, end_time: endTime, error_message: errorMessage }; }; exports.createTaskMetric = createTaskMetric; function obfuscateString(clusterId, toHash) { const valueToObfuscate = toHash + clusterId; return _jsSha.sha256.create().update(valueToObfuscate).hex(); } function isAllowlistK8sUsername(username) { return username === 'edit' || username === 'view' || username === 'admin' || username === 'elastic-agent' || username === 'cluster-admin' || username.startsWith('system'); } const processK8sUsernames = (clusterId, event) => { var _event$kubernetes, _event$kubernetes$aud, _event$kubernetes$aud2, _event$kubernetes2, _event$kubernetes2$au, _event$kubernetes2$au2; // if there is no kubernetes key, return the event as is if (event.kubernetes === undefined && event.kubernetes === null) { return event; } const username = event === null || event === void 0 ? void 0 : (_event$kubernetes = event.kubernetes) === null || _event$kubernetes === void 0 ? void 0 : (_event$kubernetes$aud = _event$kubernetes.audit) === null || _event$kubernetes$aud === void 0 ? void 0 : (_event$kubernetes$aud2 = _event$kubernetes$aud.user) === null || _event$kubernetes$aud2 === void 0 ? void 0 : _event$kubernetes$aud2.username; const impersonatedUser = event === null || event === void 0 ? void 0 : (_event$kubernetes2 = event.kubernetes) === null || _event$kubernetes2 === void 0 ? void 0 : (_event$kubernetes2$au = _event$kubernetes2.audit) === null || _event$kubernetes2$au === void 0 ? void 0 : (_event$kubernetes2$au2 = _event$kubernetes2$au.impersonated_user) === null || _event$kubernetes2$au2 === void 0 ? void 0 : _event$kubernetes2$au2.username; if (username !== undefined && username !== null && !isAllowlistK8sUsername(username)) { (0, _lodash.set)(event, 'kubernetes.audit.user.username', obfuscateString(clusterId, username)); } if (impersonatedUser !== undefined && impersonatedUser !== null && !isAllowlistK8sUsername(impersonatedUser)) { (0, _lodash.set)(event, 'kubernetes.audit.impersonated_user.username', obfuscateString(clusterId, impersonatedUser)); } return event; }; exports.processK8sUsernames = processK8sUsernames;