summaryrefslogtreecommitdiff
path: root/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go')
-rw-r--r--vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go b/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go
new file mode 100644
index 0000000..9148e53
--- /dev/null
+++ b/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/safelog/log.go
@@ -0,0 +1,71 @@
+//Package for a safer logging wrapper around the standard logging package
+
+//import "git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
+package safelog
+
+import (
+ "bytes"
+ "io"
+ "regexp"
+ "sync"
+)
+
+const ipv4Address = `\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`
+const ipv6Address = `([0-9a-fA-F]{0,4}:){5,7}([0-9a-fA-F]{0,4})?`
+const ipv6Compressed = `([0-9a-fA-F]{0,4}:){0,5}([0-9a-fA-F]{0,4})?(::)([0-9a-fA-F]{0,4}:){0,5}([0-9a-fA-F]{0,4})?`
+const ipv6Full = `(` + ipv6Address + `(` + ipv4Address + `))` +
+ `|(` + ipv6Compressed + `(` + ipv4Address + `))` +
+ `|(` + ipv6Address + `)` + `|(` + ipv6Compressed + `)`
+const optionalPort = `(:\d{1,5})?`
+const addressPattern = `((` + ipv4Address + `)|(\[(` + ipv6Full + `)\])|(` + ipv6Full + `))` + optionalPort
+const fullAddrPattern = `(^|\s|[^\w:])` + addressPattern + `(\s|(:\s)|[^\w:]|$)`
+
+var scrubberPatterns = []*regexp.Regexp{
+ regexp.MustCompile(fullAddrPattern),
+}
+
+var addressRegexp = regexp.MustCompile(addressPattern)
+
+// An io.Writer that can be used as the output for a logger that first
+// sanitizes logs and then writes to the provided io.Writer
+type LogScrubber struct {
+ Output io.Writer
+ buffer []byte
+
+ lock sync.Mutex
+}
+
+func (ls *LogScrubber) Lock() { (*ls).lock.Lock() }
+func (ls *LogScrubber) Unlock() { (*ls).lock.Unlock() }
+
+func scrub(b []byte) []byte {
+ scrubbedBytes := b
+ for _, pattern := range scrubberPatterns {
+ // this is a workaround since go does not yet support look ahead or look
+ // behind for regular expressions.
+ scrubbedBytes = pattern.ReplaceAllFunc(scrubbedBytes, func(b []byte) []byte {
+ return addressRegexp.ReplaceAll(b, []byte("[scrubbed]"))
+ })
+ }
+ return scrubbedBytes
+}
+
+func (ls *LogScrubber) Write(b []byte) (n int, err error) {
+ ls.Lock()
+ defer ls.Unlock()
+
+ n = len(b)
+ ls.buffer = append(ls.buffer, b...)
+ for {
+ i := bytes.LastIndexByte(ls.buffer, '\n')
+ if i == -1 {
+ return
+ }
+ fullLines := ls.buffer[:i+1]
+ _, err = ls.Output.Write(scrub(fullLines))
+ if err != nil {
+ return
+ }
+ ls.buffer = ls.buffer[i+1:]
+ }
+}