Browse Source

give cloaks their own package

tags/v1.1.0-rc1
Shivaram Lingamneni 5 years ago
parent
commit
2451737f87
5 changed files with 85 additions and 66 deletions
  1. 1
    0
      Makefile
  2. 11
    4
      irc/cloaks/cloak_test.go
  3. 70
    0
      irc/cloaks/cloaks.go
  4. 3
    34
      irc/config.go
  5. 0
    28
      irc/server.go

+ 1
- 0
Makefile View File

20
 	python3 ./gencapdefs.py | diff - ${capdef_file}
20
 	python3 ./gencapdefs.py | diff - ${capdef_file}
21
 	cd irc && go test . && go vet .
21
 	cd irc && go test . && go vet .
22
 	cd irc/caps && go test . && go vet .
22
 	cd irc/caps && go test . && go vet .
23
+	cd irc/cloaks && go test . && go vet .
23
 	cd irc/connection_limits && go test . && go vet .
24
 	cd irc/connection_limits && go test . && go vet .
24
 	cd irc/history && go test . && go vet .
25
 	cd irc/history && go test . && go vet .
25
 	cd irc/isupport && go test . && go vet .
26
 	cd irc/isupport && go test . && go vet .

irc/cloak_test.go → irc/cloaks/cloak_test.go View File

1
 // Copyright (c) 2019 Shivaram Lingamneni
1
 // Copyright (c) 2019 Shivaram Lingamneni
2
 // released under the MIT license
2
 // released under the MIT license
3
 
3
 
4
-package irc
4
+package cloaks
5
 
5
 
6
 import (
6
 import (
7
 	"net"
7
 	"net"
8
+	"reflect"
8
 	"testing"
9
 	"testing"
9
 )
10
 )
10
 
11
 
12
+func assertEqual(supplied, expected interface{}, t *testing.T) {
13
+	if !reflect.DeepEqual(supplied, expected) {
14
+		t.Errorf("expected %v but got %v", expected, supplied)
15
+	}
16
+}
17
+
11
 func easyParseIP(ipstr string) (result net.IP) {
18
 func easyParseIP(ipstr string) (result net.IP) {
12
 	result = net.ParseIP(ipstr)
19
 	result = net.ParseIP(ipstr)
13
 	if result == nil {
20
 	if result == nil {
25
 		CidrLenIPv6: 64,
32
 		CidrLenIPv6: 64,
26
 		NumBits:     80,
33
 		NumBits:     80,
27
 	}
34
 	}
28
-	config.postprocess()
35
+	config.Initialize()
29
 	return config
36
 	return config
30
 }
37
 }
31
 
38
 
64
 		CidrLenIPv6: 64,
71
 		CidrLenIPv6: 64,
65
 		NumBits:     60,
72
 		NumBits:     60,
66
 	}
73
 	}
67
-	config.postprocess()
74
+	config.Initialize()
68
 
75
 
69
 	v4ip := easyParseIP("8.8.8.8")
76
 	v4ip := easyParseIP("8.8.8.8")
70
 	assertEqual(config.ComputeCloak(v4ip), "3cay3zc72tnui.oragono", t)
77
 	assertEqual(config.ComputeCloak(v4ip), "3cay3zc72tnui.oragono", t)
76
 	config := cloakConfForTesting()
83
 	config := cloakConfForTesting()
77
 	config.NumBits = 0
84
 	config.NumBits = 0
78
 	config.Netname = "example.com"
85
 	config.Netname = "example.com"
79
-	config.postprocess()
86
+	config.Initialize()
80
 
87
 
81
 	v4ip := easyParseIP("8.8.8.8").To4()
88
 	v4ip := easyParseIP("8.8.8.8").To4()
82
 	assertEqual(config.ComputeCloak(v4ip), "example.com", t)
89
 	assertEqual(config.ComputeCloak(v4ip), "example.com", t)

+ 70
- 0
irc/cloaks/cloaks.go View File

1
+// Copyright (c) 2019 Shivaram Lingamneni
2
+
3
+package cloaks
4
+
5
+import (
6
+	"fmt"
7
+	"net"
8
+
9
+	"golang.org/x/crypto/sha3"
10
+
11
+	"github.com/oragono/oragono/irc/utils"
12
+)
13
+
14
+type CloakConfig struct {
15
+	Enabled     bool
16
+	Netname     string
17
+	Secret      string
18
+	CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
19
+	CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
20
+	NumBits     int `yaml:"num-bits"`
21
+
22
+	numBytes int
23
+	ipv4Mask net.IPMask
24
+	ipv6Mask net.IPMask
25
+}
26
+
27
+func (cloakConfig *CloakConfig) Initialize() {
28
+	// sanity checks:
29
+	numBits := cloakConfig.NumBits
30
+	if 0 == numBits {
31
+		numBits = 80
32
+	} else if 256 < numBits {
33
+		numBits = 256
34
+	}
35
+
36
+	// derived values:
37
+	cloakConfig.numBytes = numBits / 8
38
+	// round up to the nearest byte
39
+	if numBits%8 != 0 {
40
+		cloakConfig.numBytes += 1
41
+	}
42
+	cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
43
+	cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
44
+}
45
+
46
+// simple cloaking algorithm: normalize the IP to its CIDR,
47
+// then hash the resulting bytes with a secret key,
48
+// then truncate to the desired length, b32encode, and append the fake TLD.
49
+func (config *CloakConfig) ComputeCloak(ip net.IP) string {
50
+	if !config.Enabled {
51
+		return ""
52
+	} else if config.NumBits == 0 {
53
+		return config.Netname
54
+	}
55
+	var masked net.IP
56
+	v4ip := ip.To4()
57
+	if v4ip != nil {
58
+		masked = v4ip.Mask(config.ipv4Mask)
59
+	} else {
60
+		masked = ip.Mask(config.ipv6Mask)
61
+	}
62
+	// SHA3(K || M):
63
+	// https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
64
+	input := make([]byte, len(config.Secret)+len(masked))
65
+	copy(input, config.Secret[:])
66
+	copy(input[len(config.Secret):], masked)
67
+	digest := sha3.Sum512(input)
68
+	b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
69
+	return fmt.Sprintf("%s.%s", b32digest, config.Netname)
70
+}

+ 3
- 34
irc/config.go View File

18
 	"time"
18
 	"time"
19
 
19
 
20
 	"code.cloudfoundry.org/bytefmt"
20
 	"code.cloudfoundry.org/bytefmt"
21
+	"github.com/oragono/oragono/irc/cloaks"
21
 	"github.com/oragono/oragono/irc/connection_limits"
22
 	"github.com/oragono/oragono/irc/connection_limits"
22
 	"github.com/oragono/oragono/irc/custime"
23
 	"github.com/oragono/oragono/irc/custime"
23
 	"github.com/oragono/oragono/irc/isupport"
24
 	"github.com/oragono/oragono/irc/isupport"
263
 	MaxConnectionsPerDuration int           `yaml:"max-connections-per-duration"`
264
 	MaxConnectionsPerDuration int           `yaml:"max-connections-per-duration"`
264
 }
265
 }
265
 
266
 
266
-type CloakConfig struct {
267
-	Enabled     bool
268
-	Netname     string
269
-	Secret      string
270
-	CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
271
-	CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
272
-	NumBits     int `yaml:"num-bits"`
273
-
274
-	numBytes int
275
-	ipv4Mask net.IPMask
276
-	ipv6Mask net.IPMask
277
-}
278
-
279
-func (cloakConfig *CloakConfig) postprocess() {
280
-	// sanity checks:
281
-	numBits := cloakConfig.NumBits
282
-	if 0 == numBits {
283
-		numBits = 80
284
-	} else if 256 < numBits {
285
-		numBits = 256
286
-	}
287
-
288
-	// derived values:
289
-	cloakConfig.numBytes = numBits / 8
290
-	// round up to the nearest byte
291
-	if numBits%8 != 0 {
292
-		cloakConfig.numBytes += 1
293
-	}
294
-	cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
295
-	cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
296
-}
297
-
298
 // Config defines the overall configuration.
267
 // Config defines the overall configuration.
299
 type Config struct {
268
 type Config struct {
300
 	Network struct {
269
 	Network struct {
329
 		isupport            isupport.List
298
 		isupport            isupport.List
330
 		ConnectionLimiter   connection_limits.LimiterConfig   `yaml:"connection-limits"`
299
 		ConnectionLimiter   connection_limits.LimiterConfig   `yaml:"connection-limits"`
331
 		ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"`
300
 		ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"`
332
-		Cloaks              CloakConfig                       `yaml:"ip-cloaking"`
301
+		Cloaks              cloaks.CloakConfig                `yaml:"ip-cloaking"`
333
 	}
302
 	}
334
 
303
 
335
 	Languages struct {
304
 	Languages struct {
761
 		config.History.ClientLength = 0
730
 		config.History.ClientLength = 0
762
 	}
731
 	}
763
 
732
 
764
-	config.Server.Cloaks.postprocess()
733
+	config.Server.Cloaks.Initialize()
765
 
734
 
766
 	for _, listenAddress := range config.Server.TorListeners.Listeners {
735
 	for _, listenAddress := range config.Server.TorListeners.Listeners {
767
 		found := false
736
 		found := false

+ 0
- 28
irc/server.go View File

21
 	"time"
21
 	"time"
22
 	"unsafe"
22
 	"unsafe"
23
 
23
 
24
-	"golang.org/x/crypto/sha3"
25
-
26
 	"github.com/goshuirc/irc-go/ircfmt"
24
 	"github.com/goshuirc/irc-go/ircfmt"
27
 	"github.com/oragono/oragono/irc/caps"
25
 	"github.com/oragono/oragono/irc/caps"
28
 	"github.com/oragono/oragono/irc/connection_limits"
26
 	"github.com/oragono/oragono/irc/connection_limits"
285
 	}
283
 	}
286
 }
284
 }
287
 
285
 
288
-// simple cloaking algorithm: normalize the IP to its CIDR,
289
-// then hash the resulting bytes with a secret key,
290
-// then truncate to the desired length, b32encode, and append the fake TLD.
291
-func (config *CloakConfig) ComputeCloak(ip net.IP) string {
292
-	if !config.Enabled {
293
-		return ""
294
-	} else if config.NumBits == 0 {
295
-		return config.Netname
296
-	}
297
-	var masked net.IP
298
-	v4ip := ip.To4()
299
-	if v4ip != nil {
300
-		masked = v4ip.Mask(config.ipv4Mask)
301
-	} else {
302
-		masked = ip.Mask(config.ipv6Mask)
303
-	}
304
-	// SHA3(K || M):
305
-	// https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
306
-	input := make([]byte, len(config.Secret)+len(masked))
307
-	copy(input, config.Secret[:])
308
-	copy(input[len(config.Secret):], masked)
309
-	digest := sha3.Sum512(input)
310
-	b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
311
-	return fmt.Sprintf("%s.%s", b32digest, config.Netname)
312
-}
313
-
314
 //
286
 //
315
 // IRC protocol listeners
287
 // IRC protocol listeners
316
 //
288
 //

Loading…
Cancel
Save