blob: 7b924bb27d61a71ba573796be4bc2313c38bb16e [file] [log] [blame] [edit]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/forensics/utils/redact/redactor.h"
#include <lib/inspect/cpp/hierarchy.h>
#include <lib/inspect/cpp/vmo/types.h>
#include <lib/syslog/cpp/macros.h>
#include <string>
#include <string_view>
#include <vector>
namespace forensics {
namespace {
// Email stub alice@website.tld
constexpr std::string_view kEmailPattern = R"([a-zA-Z0-9]*@[a-zA-Z0-9]*\.[a-zA-Z]*)";
// uuid
constexpr std::string_view kUuidPattern =
R"([0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-\b[0-9a-fA-F]{12})";
// http(s) urls
constexpr std::string_view kUrlPattern = R"(https?://[^"',!<> ]*)";
// Hex strings
constexpr std::string_view k16HexPattern = R"((\b[0-9a-fA-F]{16}\b))";
constexpr std::string_view k32HexPattern = R"((\b[0-9a-fA-F]{32}\b))";
const auto* kHexIgnorePrefixes = new std::vector<std::string>({"elf:", "build_id: '"});
// Obfuscated gaia ids
constexpr std::string_view kGaiaPattern = R"((\b1[0-9]{20}\b))";
constexpr std::string_view kUnredactedCanary =
R"(Email: alice@website.tld,
IPv4: 8.8.8.8,
IPv4_New: 8.9.10.42,
IPv4_Dup: 8.8.8.8,
IPv4_WithPort: 8.8.8.8:8080,
IPv4_Fidl: Ipv4Address { addr: [1, 255, FF, FF] }
IPv461: ::ffff:12.34.56.78,
IPv462: ::ffff:ab12:cd34,
IPv6: 2001:503:eEa3:0:0:0:0:30,
IPv6_WithPort: [2001:503:eEa3:0:0:0:0:30]:8080,
IPv6_Fidl: Ipv6Address { addr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 255, FF, FF] }
IPv6C: fec8::7d84:c1dc:ab34:656a,
IPv6LL: fe80::7d84:c1dc:ab34:656a,
UUID: ddd0fA34-1016-11eb-adc1-0242ac120002,
MAC: de:ad:BE:EF:42:5a,
MAC_dashes: de-ad-BE-EF-42-5a,
MAC_dots: de.ad.BE.EF.42.5a,
MAC_mixed: de.ad-BE:EF.42-5a,
MAC_Fidl: MacAddress { octets: [1, 2, 3, 255, FF, FF] }
SSID: <ssid-666F6F>,
HTTP: http://fuchsia.dev/fuchsia/testing?q=Test,
HTTPS: https://fuchsia.dev/fuchsia/testing?q=Test,
HEX: 1234567890abcdef,
HEX: 1234567890abcdefABCDEF0123456789,
v4Current: 0.1.2.3,
v4Loopback: 127.1.2.3,
v4LocalAddr: 169.254.12.34,
v4LocalMulti: 224.0.0.123,
v4Multi: 224.0.1.123,
broadcast: 255.255.255.255,
v6zeroes: :: ::1,
v6LeadingZeroes: ::abcd:dcba:bcde:f,
v6TrailingZeroes: f:e:d:c:abcd:dcba:bcde::,
v6LinkLocal: feB2:111:222:333:444:555:666:777,
v6LocalMulticast: ff72:111:222:333:444:555:666:777,
v6Multicast: ff77:111:222:333:444:555:666:777,
obfuscatedGaiaId: 106986199446298680449)";
constexpr std::string_view kRedactedCanary =
R"(Email: <REDACTED-EMAIL>,
IPv4: <REDACTED-IPV4: 1>,
IPv4_New: <REDACTED-IPV4: 2>,
IPv4_Dup: <REDACTED-IPV4: 1>,
IPv4_WithPort: <REDACTED-IPV4: 1>:8080,
IPv4_Fidl: Ipv4Address { <REDACTED-IPV4: 5> }
IPv461: ::ffff:<REDACTED-IPV4: 3>,
IPv462: ::ffff:<REDACTED-IPV4: 6>,
IPv6: <REDACTED-IPV6: 7>,
IPv6_WithPort: [<REDACTED-IPV6: 7>]:8080,
IPv6_Fidl: Ipv6Address { <REDACTED-IPV6: 14> }
IPv6C: <REDACTED-IPV6: 8>,
IPv6LL: fe80:<REDACTED-IPV6-LL: 9>,
UUID: <REDACTED-UUID>,
MAC: de:ad:BE:<REDACTED-MAC: 15>,
MAC_dashes: de-ad-BE-<REDACTED-MAC: 15>,
MAC_dots: de.ad.BE.<REDACTED-MAC: 15>,
MAC_mixed: de.ad-BE:<REDACTED-MAC: 15>,
MAC_Fidl: MacAddress { <REDACTED-MAC: 16> }
SSID: <REDACTED-SSID: 17>,
HTTP: <REDACTED-URL>,
HTTPS: <REDACTED-URL>,
HEX: <REDACTED-HEX: 18>,
HEX: <REDACTED-HEX: 19>,
v4Current: 0.1.2.3,
v4Loopback: 127.1.2.3,
v4LocalAddr: 169.254.12.34,
v4LocalMulti: 224.0.0.123,
v4Multi: <REDACTED-IPV4: 4>,
broadcast: 255.255.255.255,
v6zeroes: :: ::1,
v6LeadingZeroes: <REDACTED-IPV6: 10>,
v6TrailingZeroes: <REDACTED-IPV6: 11>,
v6LinkLocal: feB2:<REDACTED-IPV6-LL: 12>,
v6LocalMulticast: ff72:111:222:333:444:555:666:777,
v6Multicast: ff77:<REDACTED-IPV6-MULTI: 13>,
obfuscatedGaiaId: <REDACTED-OBFUSCATED-GAIA-ID: 20>)";
} // namespace
RedactorBase::RedactorBase(inspect::BoolProperty redaction_enabled)
: redaction_enabled_(std::move(redaction_enabled)) {}
Redactor::Redactor(const int starting_id, inspect::UintProperty cache_size,
inspect::BoolProperty redaction_enabled)
: RedactorBase(std::move(redaction_enabled)), cache_(std::move(cache_size), starting_id) {
Add(ReplaceIPv4())
.Add(ReplaceFidlIPv4())
.Add(ReplaceIPv6())
.Add(ReplaceFidlIPv6())
.Add(ReplaceMac())
.Add(ReplaceFidlMac())
.Add(ReplaceSsid())
.AddJsonReplacer(ReplaceIPv4())
.AddJsonReplacer(ReplaceIPv6())
.AddJsonReplacer(ReplaceMac())
.AddJsonReplacer(ReplaceSsid())
.AddTextReplacer(kUrlPattern, "<REDACTED-URL>")
.AddTextReplacer(kEmailPattern, "<REDACTED-EMAIL>")
.AddTextReplacer(kUuidPattern, "<REDACTED-UUID>")
.AddIdReplacer(k16HexPattern, "<REDACTED-HEX: %d>", *kHexIgnorePrefixes)
.AddIdReplacer(k32HexPattern, "<REDACTED-HEX: %d>", *kHexIgnorePrefixes)
.AddIdReplacer(kGaiaPattern, "<REDACTED-OBFUSCATED-GAIA-ID: %d>", /*ignore_prefixes=*/{});
}
std::string& Redactor::Redact(std::string& text) {
for (const auto& replacer : replacers_) {
replacer(cache_, text);
}
return text;
}
std::string& Redactor::RedactJson(std::string& text) {
for (const auto& replacer : json_replacers_) {
replacer(cache_, text);
}
return text;
}
Redactor& Redactor::Add(Replacer replacer) {
FX_CHECK(replacer != nullptr);
replacers_.push_back(std::move(replacer));
return *this;
}
Redactor& Redactor::AddTextReplacer(std::string_view pattern, std::string_view replacement) {
auto replacer = ReplaceWithText(pattern, replacement);
FX_CHECK(replacer != nullptr) << "Failed to build replacer for " << pattern << " " << replacement;
return Add(std::move(replacer));
}
Redactor& Redactor::AddIdReplacer(std::string_view pattern, std::string_view format,
const std::vector<std::string>& ignore_prefixes) {
auto replacer = ReplaceWithIdFormatString(pattern, format, ignore_prefixes);
FX_CHECK(replacer != nullptr) << "Failed to build replacer for " << pattern << " " << format;
return Add(std::move(replacer));
}
Redactor& Redactor::AddJsonReplacer(Replacer replacer) {
FX_CHECK(replacer != nullptr);
json_replacers_.push_back(std::move(replacer));
return *this;
}
std::string Redactor::UnredactedCanary() const { return std::string(kUnredactedCanary); }
std::string Redactor::RedactedCanary() const { return std::string(kRedactedCanary); }
IdentityRedactor::IdentityRedactor(inspect::BoolProperty redaction_enabled)
: RedactorBase(std::move(redaction_enabled)) {}
std::string& IdentityRedactor::Redact(std::string& text) { return text; }
std::string& IdentityRedactor::RedactJson(std::string& text) { return text; }
std::string IdentityRedactor::UnredactedCanary() const { return std::string(kUnredactedCanary); }
std::string IdentityRedactor::RedactedCanary() const { return std::string(kUnredactedCanary); }
} // namespace forensics