package privacy import ( "path" "strings" ) // Public infrastructure, documentation, and vendor-default values that are not // customer leaks. These are reference data (RFC 2606 / 5737 names, well-known // NTP pools, standards-body domains, factory defaults), not vendor-detection // logic. var ( allowlistedZones = []string{ "example.com", "example.net", "example.org", "example.local", "example.edu", "foobar.edu", "issue.net", "localhost", "localdomain", "local.lan", "localhost.localdomain", "host.name", "other.host.name", "some.host.name", "other.domain", "some.domain", "pool.ntp.org", "ntp.org", "nist.gov", "windows.com", "microsoft.com", "dmtf.org", "iana.org", "openssl.org", "openssh.com", "openssh.org", "libssh.org", "rsyslog.com", "adiscon.com", "redhat.com", "kernel.org", "megarac.com", "ami.com", "commond.com", "oasis-open.org", "w3.org", "xmlsoap.org", "purl.org", "ietf.org", "nvidia.com", "mellanox.com", "gnu.org", "debian.org", "ubuntu.com", "smartmontools.org", "openib.org", "apache.org", "freebsd.org", "freedesktop.org", "golang.org", "go.dev", "x.org", "sourceforge.net", "xyz.com", "yandex.net", "haxx.se", "curl.se", "python.org", "perl.org", "isc.org", "sourceware.org", "ipxe.org", "gnupg.org", "gnutls.org", "openldap.org", "netfilter.org", "github.com", "githubusercontent.com", "typoland.com", "schemas.dell.com", "googleapis.com", "gstatic.com", "jquery.com", "jsdelivr.net", "unpkg.com", "cloudflare.com", "cloudflare.net", "certificate.fi", "inspur.com", "inspurcloud.com", "inservice-iq.com", "ieisystem.com", "kaytus.com", "jd.com", "jd.local", "jdcloud.com", "in-addr.arpa", "ip6.arpa", "arpa", } allowlistedValues = map[string]struct{}{ "asia/shanghai": {}, "etc/utc": {}, "etc/universal": {}, "utc": {}, // neutral decoy zones the sanitizer writes in place of a real timezone "pacific/tarawa": {}, "atlantic/azores": {}, "antarctica/troll": {}, "antarctica/vostok": {}, "antarctica/mcmurdo": {}, "pacific/guadalcanal": {}, "pacific/bougainville": {}, "to be filled by o.e.m.": {}, "default string": {}, "unknown": {}, "n/a": {}, "none": {}, "null": {}, "0": {}, "0.0.0.0": {}, "not specified": {}, "not available": {}, "not present": {}, "unspecified": {}, "no asset tag": {}, "no asset information": {}, "empty": {}, "[empty]": {}, } // Archive members that are vendor factory templates or LOGPile's own derived // export artifacts (operator-entered target host, Redfish annotation keys) - // not customer data from the source. allowlistedFilenameParts = []string{ "_tencent", "_jingdong", "_pdd", "_baidu", "_kuaishou", "_tianyiyun", "_jd.", "syslog_jd", "snmptrapcfg", ".json_bak", ".conf_bak", "_bak", "ntp_auto", "raw_export.json", "parser_fields.json", "collect.log", } ) // IsAllowlistedFile reports whether a member path is a vendor factory template // or a LOGPile-derived artifact that should not be scanned or redacted. func IsAllowlistedFile(name string) bool { return isAllowlistedFilename(name) } func isAllowlistedDomain(domain string) bool { d := strings.ToLower(strings.TrimSuffix(strings.TrimSpace(domain), ".")) for _, z := range allowlistedZones { if d == z || strings.HasSuffix(d, "."+z) { return true } } return false } func isAllowlistedValue(v string) bool { lv := strings.ToLower(strings.TrimSpace(v)) if _, ok := allowlistedValues[lv]; ok { return true } return isRedactionFiller(lv) || isAllowlistedDomain(v) } // isRedactionFiller recognises the internal/sanitize output so a re-scan or a // second sanitize pass of an already-cleaned file finds nothing: an all-'x' // hostname filler ("xxxxx.xxxx.xx", "x@xxxx.xxxx.xx", "xxxxxx/xxxxxx") or an // all-zero IP / offset filler ("00.000.000.00", "000", "-000"). func isRedactionFiller(s string) bool { if len(s) < 2 { return false } hasFill := false for _, r := range s { switch { case r == 'x' || r == '0': hasFill = true case r == '.' || r == '-' || r == '@' || r == ':' || r == '/' || r == '+': default: return false } } return hasFill } func isAllowlistedFilename(p string) bool { lp := strings.ToLower(p) for _, part := range allowlistedFilenameParts { if strings.Contains(lp, part) { return true } } return false } func isCertFilename(p string) bool { switch strings.ToLower(path.Ext(p)) { case ".pem", ".csr", ".crt", ".cer": return true } return false }