summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-01-11 02:54:24 +0100
committerDimitri Sokolyuk <demon@dim13.org>2018-01-11 02:54:24 +0100
commit55cf66418551b72c1a251680267693b083efc6d5 (patch)
tree5ca1e38707def8488288ade250c8eda0805be0bd
parent43ee99e80b8e77fcd5eabd22b087a73e9a220fb4 (diff)
domain maskknockout
-rw-r--r--mask.go63
-rw-r--r--mask_test.go45
2 files changed, 108 insertions, 0 deletions
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)
+ }
+ })
+ }
+}