M module-bluetooth/Bluetooth/interface/profiles/HFP/HFP.cpp => module-bluetooth/Bluetooth/interface/profiles/HFP/HFP.cpp +8 -4
@@ 16,6 16,7 @@
#include <BluetoothWorker.hpp>
#include "SCO/ScoUtils.hpp"
+#include <Anonymize.hpp>
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
@@ 145,7 146,7 @@ namespace bluetooth
std::uint8_t HFP::HFPImpl::serviceBuffer[serviceBufferSize];
std::unique_ptr<SCO> HFP::HFPImpl::sco;
- SCOCodec HFP::HFPImpl::codec = SCOCodec::CVSD;
+ SCOCodec HFP::HFPImpl::codec = SCOCodec::CVSD;
std::shared_ptr<CVSDAudioDevice> HFP::HFPImpl::audioDevice;
std::unique_ptr<CellularInterface> HFP::HFPImpl::cellularInterface;
@@ 202,8 203,8 @@ namespace bluetooth
void HFP::HFPImpl::sendAudioEvent(audio::EventType event, audio::Event::DeviceState state)
{
- auto evt = std::make_shared<audio::Event>(event, state);
- auto msg = std::make_shared<AudioEventRequest>(std::move(evt));
+ auto evt = std::make_shared<audio::Event>(event, state);
+ auto msg = std::make_shared<AudioEventRequest>(std::move(evt));
ownerService->bus.sendUnicast(std::move(msg), service::name::evt_manager);
}
@@ 526,7 527,10 @@ namespace bluetooth
auto HFP::HFPImpl::setIncomingCallNumber(const std::string &num) const noexcept -> Result::Code
{
- LOG_SENSITIVE(LOGDEBUG, "Setting number: %s", num.c_str());
+ LOG_SENSITIVE(
+ LOGDEBUG,
+ "Setting number: %s",
+ utils::anonymize::anonymizeNumbers(num, utils::anonymize::SIGNS_TO_LEAVE_FOR_PHONE_NUMBERS).c_str());
hfp_ag_set_clip(129, num.c_str());
return Result::Code::Success;
}
M module-cellular/modem/ATCommon.cpp => module-cellular/modem/ATCommon.cpp +11 -6
@@ 11,6 11,7 @@
#include "ATStream.hpp"
#include <at/ATFactory.hpp>
#include <gsl/util>
+#include <Anonymize.hpp>
using namespace at;
using namespace std::chrono_literals;
@@ 41,16 42,20 @@ void Channel::cmdLog(std::string cmd, const Result &result, std::chrono::millise
} break;
case Result::Code::ERROR: {
LOG_ERROR("AT response: error");
- LOG_SENSITIVE(
- LOGERROR, "[AT]: >%s<, >%s<", cmd.c_str(), result.response.size() ? result.response.back().c_str() : "");
+ LOG_SENSITIVE(LOGERROR,
+ "[AT]: >%s<, >%s<",
+ utils::anonymize::anonymizeCellularIfNecessary(cmd).c_str(),
+ result.response.size() ? result.response.back().c_str() : "");
} break;
default:
- LOG_SENSITIVE(
- LOGDEBUG, "[AT]: >%s<, >%s<", cmd.c_str(), result.response.size() ? result.response.back().c_str() : "");
+ LOG_SENSITIVE(LOGDEBUG,
+ "[AT]: >%s<, >%s<",
+ utils::anonymize::anonymizeCellularIfNecessary(cmd).c_str(),
+ result.response.size() ? result.response.back().c_str() : "");
break;
}
for ([[maybe_unused]] const auto &s : result.response) {
- LOG_SENSITIVE(LOGINFO, "[AT] > %s", s.c_str());
+ LOG_SENSITIVE(LOGINFO, "[AT] > %s", utils::anonymize::anonymizeCellularIfNecessary(s).c_str());
}
}
@@ 86,7 91,7 @@ Result Channel::cmd(const std::string &cmd, std::chrono::milliseconds timeout, s
cmdInit();
std::string cmdFixed = formatCommand(cmd);
- LOG_DEBUG("Start of %s", cmdFixed.c_str());
+ LOG_DEBUG("Start of %s", utils::anonymize::anonymizeCellularIfNecessary(cmdFixed).c_str());
cmdSend(cmdFixed);
auto startTime = std::chrono::steady_clock::now();
M module-cellular/modem/ATCommon.hpp => module-cellular/modem/ATCommon.hpp +1 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +2 -1
@@ 98,6 98,7 @@
#include <ticks.hpp>
#include "ServiceCellularPriv.hpp"
+#include "Anonymize.hpp"
#include <service-cellular/api/request/sim.hpp>
#include <service-cellular/api/notification/notification.hpp>
@@ 973,7 974,7 @@ std::optional<std::shared_ptr<sys::Message>> ServiceCellular::identifyNotificati
const std::string str(data.begin(), data.end());
const std::string logStr = utils::removeNewLines(str);
- LOG_SENSITIVE(LOGDEBUG, "Notification:: %s", logStr.c_str());
+ LOG_SENSITIVE(LOGDEBUG, "Notification:: %s", utils::anonymize::anonymizeCellularIfNecessary(logStr).c_str());
auto urc = at::urc::UrcFactory::Create(str);
urc->Handle(urcHandler);
A module-utils/utility/Anonymize.cpp => module-utils/utility/Anonymize.cpp +141 -0
@@ 0,0 1,141 @@
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "Anonymize.hpp"
+
+namespace utils::anonymize
+{
+ // Anonymized text will replace by this character
+ constexpr auto anonymizationCharacter = '*';
+
+ // Amount of 'anonymizationCharacter' used during anonymization can be fixed,
+ // otherwise their amount depend on length of substring to anonymize
+ constexpr auto isAmountOfAnonymizationCharactersFixed = false;
+ constexpr auto fixedAmountOfAnonymizationCharacters = 4;
+
+ // Substrings to find logs for anonymization from the cellular logs
+ constexpr auto cellularSubstringCPIN = "CPIN";
+ constexpr auto cellularSubstringCLCC = "CLCC";
+ constexpr auto cellularSubstringATD = "ATD";
+ constexpr auto cellularSubstringCPBR = "CPBR";
+ constexpr auto cellularSubstringCSPN = "CSPN";
+
+ std::string anonymizeInQuotationMarks(const std::string &textToAnonymize, std::size_t singsToLeaveAtEnd)
+ {
+ constexpr auto quotesMark = '\"';
+ std::size_t startPosition = 0;
+ std::size_t endPosition = 0;
+ auto anonymizedText = textToAnonymize;
+
+ // Find the position of the substring within the input string
+ while (startPosition < anonymizedText.length()) {
+ startPosition = anonymizedText.find(quotesMark, startPosition);
+ endPosition = anonymizedText.find(quotesMark, startPosition + 1);
+
+ if (startPosition != std::string::npos && endPosition != std::string::npos) {
+ // Extract the substring between the quotes
+ const auto &extractedSubstring =
+ anonymizedText.substr(startPosition + 1, endPosition - startPosition - 1);
+
+ // Determine the length of the extracted substring
+ const auto extractedLength = extractedSubstring.length();
+
+ // Amount of signs to left can't be higher than extracted substring
+ singsToLeaveAtEnd = std::min(extractedLength, singsToLeaveAtEnd);
+
+ // Determine amount of anonymization characters
+ const auto amountOfAnonymizationCharacters = isAmountOfAnonymizationCharactersFixed
+ ? fixedAmountOfAnonymizationCharacters
+ : extractedLength - singsToLeaveAtEnd;
+
+ // Replace the substring with the appropriate number of '*' characters
+ anonymizedText.replace(startPosition + 1,
+ extractedLength - singsToLeaveAtEnd,
+ amountOfAnonymizationCharacters,
+ anonymizationCharacter);
+ startPosition = endPosition + 1;
+ }
+ else {
+ break;
+ }
+ }
+ return anonymizedText;
+ }
+
+ std::string anonymizeNumbers(const std::string &textToAnonymize, std::size_t singsToLeaveAtEnd)
+ {
+ std::size_t startPosition = 0;
+ std::size_t endPosition = 0;
+ auto isDigitFunction = [](char c) { return std::isdigit(c); };
+ auto anonymizedText = textToAnonymize;
+ auto startSubstring = anonymizedText.begin();
+ auto endSubstring = anonymizedText.begin();
+
+ while (startPosition < anonymizedText.length()) {
+ // Find first number in string
+ startSubstring = std::find_if(endSubstring, anonymizedText.end(), isDigitFunction);
+
+ // If first number found then find last number and anonymize whole number in string
+ if (startSubstring != anonymizedText.end()) {
+ endSubstring = std::find_if_not(startSubstring, anonymizedText.end(), isDigitFunction);
+
+ // Calculate positions
+ startPosition = std::distance(anonymizedText.begin(), startSubstring);
+ endPosition = std::distance(anonymizedText.begin(), endSubstring);
+
+ if (startPosition != std::string::npos && endPosition != std::string::npos) {
+ // Extract the substring contained only numbers
+ const auto &extractedSubstring =
+ anonymizedText.substr(startPosition + 1, endPosition - startPosition);
+
+ // Determine the length of the extracted substring
+ const auto extractedLength = extractedSubstring.length();
+
+ // Amount of signs to left can't be higher than extracted substring
+ singsToLeaveAtEnd = std::min(extractedLength, singsToLeaveAtEnd);
+
+ // Determine amount of anonymization characters
+ const auto amountOfAnonymizationCharacters = isAmountOfAnonymizationCharactersFixed
+ ? fixedAmountOfAnonymizationCharacters
+ : extractedLength - singsToLeaveAtEnd;
+
+ // Replace the substring with the appropriate number of '*' characters
+ anonymizedText.replace(startPosition,
+ extractedLength - singsToLeaveAtEnd,
+ amountOfAnonymizationCharacters,
+ anonymizationCharacter);
+
+ startPosition = endPosition + 1;
+ }
+ else {
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ return anonymizedText;
+ }
+
+ std::string anonymizeCellularIfNecessary(const std::string &text)
+ {
+ std::map<std::string, std::function<std::string()>> anonymizeOption{
+ {cellularSubstringCPIN,
+ [&text]() { return anonymizeInQuotationMarks(text, SIGNS_TO_LEAVE_FOR_PIN_AND_PUK); }},
+ {cellularSubstringCLCC,
+ [&text]() { return anonymizeInQuotationMarks(text, SIGNS_TO_LEAVE_FOR_PHONE_NUMBERS); }},
+ {cellularSubstringATD, [&text]() { return anonymizeNumbers(text, SIGNS_TO_LEAVE_FOR_PHONE_NUMBERS); }},
+ {cellularSubstringCPBR,
+ [&text]() { return anonymizeInQuotationMarks(text, SIGNS_TO_LEAVE_FOR_PHONE_NUMBERS); }},
+ {cellularSubstringCSPN,
+ [&text]() { return anonymizeInQuotationMarks(text, SIGNS_TO_LEAVE_FOR_NET_PROVIDER_NAME); }}};
+
+ for (const auto &[key, anonymizeFunction] : anonymizeOption) {
+ if (text.find(key) != std::string::npos) {
+ return anonymizeFunction();
+ }
+ }
+ return text;
+ }
+} // namespace utils::anonymize
A module-utils/utility/Anonymize.hpp => module-utils/utility/Anonymize.hpp +25 -0
@@ 0,0 1,25 @@
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <string>
+#include <algorithm>
+#include <functional>
+#include <map>
+
+namespace utils::anonymize
+{
+ // Determine how many characters to leave at the end of anonymized substring
+ constexpr auto SIGNS_TO_LEAVE_FOR_PIN_AND_PUK = 0;
+ constexpr auto SIGNS_TO_LEAVE_FOR_PHONE_NUMBERS = 2;
+ constexpr auto SIGNS_TO_LEAVE_FOR_NET_PROVIDER_NAME = 1;
+
+ // Basic function to anonymize provided string
+ std::string anonymizeInQuotationMarks(const std::string &textToAnonymize, std::size_t singsToLeaveAtEnd = 0);
+ std::string anonymizeNumbers(const std::string &textToAnonymize, std::size_t singsToLeaveAtEnd = 0);
+
+ // To anonymize logs from cellular
+ std::string anonymizeCellularIfNecessary(const std::string &text);
+
+} // namespace utils::anonymize
M module-utils/utility/CMakeLists.txt => module-utils/utility/CMakeLists.txt +2 -0
@@ 3,6 3,7 @@ add_library(utility STATIC)
target_sources(utility
PRIVATE
Utils.cpp
+ Anonymize.cpp
PUBLIC
integer.hpp
@@ 12,6 13,7 @@ target_sources(utility
Utility.hpp
Utils.hpp
Units.hpp
+ Anonymize.hpp
)
target_include_directories(utility
M pure_changelog.md => pure_changelog.md +1 -0
@@ 9,6 9,7 @@
### Changed / Improved
* Hide the SOS label during onboarding when the modem is not ready for an emergency call.
+* Anonymization sensitive data in logs added.
### Fixed