From 55cf66418551b72c1a251680267693b083efc6d5 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 11 Jan 2018 02:54:24 +0100 Subject: domain mask --- mask.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mask_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 mask.go create mode 100644 mask_test.go diff --git a/mask.go b/mask.go new file mode 100644 index 0000000..14fb1b3 --- /dev/null +++ b/mask.go @@ -0,0 +1,63 @@ +package main + +import ( + "strings" + "unicode" +) + +func isIPv4(addr string) bool { + for _, v := range addr { + if v != '.' && !unicode.IsDigit(v) { + return false + } + } + return true +} + +func domainMask(addr string) string { + // no dots - TLD or IPv6 + if !strings.Contains(addr, ".") { + if i := strings.LastIndex(addr, ":"); i >= 0 { + // IPv6, ban last 64k addresses + return addr[:i+1] + "*" + } + } + if isIPv4(addr) { + // IPv4, change last digit to * + if i := strings.LastIndex(addr, "."); i >= 0 { + return addr[:i+1] + "*" + } + } + // more then one dot, skip the first + if i := strings.Index(addr, "."); i >= 0 { + if strings.Index(addr[i+1:], ".") >= 0 { + return "*" + addr[i:] + } + } + return addr +} + +func isHostFlag(addr string) bool { + if addr == "" { + return false + } + switch addr[0] { + case '^', '~', '+', '=', '-': + return true + } + return false +} + +func mask(addr string) string { + // strip -, ^ or ~ from start + if isHostFlag(addr) { + addr = addr[1:] + } + // split user and host + s := strings.SplitN(addr, "@", 2) + if len(s) != 2 { + return "*!*" + addr + } + user, host := s[0], domainMask(s[1]) + return "*!*" + user + "@" + host +} diff --git a/mask_test.go b/mask_test.go new file mode 100644 index 0000000..87ba406 --- /dev/null +++ b/mask_test.go @@ -0,0 +1,45 @@ +package main + +import ( + "testing" +) + +func TestDomainMask(t *testing.T) { + testCases := []struct { + in, out string + }{ + {"192.0.2.1", "192.0.2.*"}, + {"gateway/ip.192.0.2.1", "*.192.0.2.1"}, + {"example.com", "example.com"}, + {"www.example.com", "*.example.com"}, + {"2001:db8::1", "2001:db8::*"}, + {"cloaked/user", "cloaked/user"}, + } + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + out := domainMask(tc.in) + if out != tc.out { + t.Errorf("got %v; want %v", out, tc.out) + } + }) + } +} + +func TestMask(t *testing.T) { + testCases := []struct { + in, out string + }{ + {"~test@gateway/web/freenode/ip.192.0.2.1", "*!*test@*.192.0.2.1"}, + {"~test@192.0.2.1", "*!*test@192.0.2.*"}, + {"test@192.0.2.1", "*!*test@192.0.2.*"}, + {"bogus", "*!*bogus"}, + } + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + out := mask(tc.in) + if out != tc.out { + t.Errorf("got %v; want %v", out, tc.out) + } + }) + } +} -- cgit v1.2.3