mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-25 20:22:38 +01:00
give cloaks their own package
This commit is contained in:
parent
c28e6d13f9
commit
2451737f87
1
Makefile
1
Makefile
@ -20,6 +20,7 @@ test:
|
||||
python3 ./gencapdefs.py | diff - ${capdef_file}
|
||||
cd irc && go test . && go vet .
|
||||
cd irc/caps && go test . && go vet .
|
||||
cd irc/cloaks && go test . && go vet .
|
||||
cd irc/connection_limits && go test . && go vet .
|
||||
cd irc/history && go test . && go vet .
|
||||
cd irc/isupport && go test . && go vet .
|
||||
|
@ -1,13 +1,20 @@
|
||||
// Copyright (c) 2019 Shivaram Lingamneni
|
||||
// released under the MIT license
|
||||
|
||||
package irc
|
||||
package cloaks
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func assertEqual(supplied, expected interface{}, t *testing.T) {
|
||||
if !reflect.DeepEqual(supplied, expected) {
|
||||
t.Errorf("expected %v but got %v", expected, supplied)
|
||||
}
|
||||
}
|
||||
|
||||
func easyParseIP(ipstr string) (result net.IP) {
|
||||
result = net.ParseIP(ipstr)
|
||||
if result == nil {
|
||||
@ -25,7 +32,7 @@ func cloakConfForTesting() CloakConfig {
|
||||
CidrLenIPv6: 64,
|
||||
NumBits: 80,
|
||||
}
|
||||
config.postprocess()
|
||||
config.Initialize()
|
||||
return config
|
||||
}
|
||||
|
||||
@ -64,7 +71,7 @@ func TestCloakShortv4Cidr(t *testing.T) {
|
||||
CidrLenIPv6: 64,
|
||||
NumBits: 60,
|
||||
}
|
||||
config.postprocess()
|
||||
config.Initialize()
|
||||
|
||||
v4ip := easyParseIP("8.8.8.8")
|
||||
assertEqual(config.ComputeCloak(v4ip), "3cay3zc72tnui.oragono", t)
|
||||
@ -76,7 +83,7 @@ func TestCloakZeroBits(t *testing.T) {
|
||||
config := cloakConfForTesting()
|
||||
config.NumBits = 0
|
||||
config.Netname = "example.com"
|
||||
config.postprocess()
|
||||
config.Initialize()
|
||||
|
||||
v4ip := easyParseIP("8.8.8.8").To4()
|
||||
assertEqual(config.ComputeCloak(v4ip), "example.com", t)
|
70
irc/cloaks/cloaks.go
Normal file
70
irc/cloaks/cloaks.go
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2019 Shivaram Lingamneni
|
||||
|
||||
package cloaks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/oragono/oragono/irc/utils"
|
||||
)
|
||||
|
||||
type CloakConfig struct {
|
||||
Enabled bool
|
||||
Netname string
|
||||
Secret string
|
||||
CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
|
||||
CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
|
||||
NumBits int `yaml:"num-bits"`
|
||||
|
||||
numBytes int
|
||||
ipv4Mask net.IPMask
|
||||
ipv6Mask net.IPMask
|
||||
}
|
||||
|
||||
func (cloakConfig *CloakConfig) Initialize() {
|
||||
// sanity checks:
|
||||
numBits := cloakConfig.NumBits
|
||||
if 0 == numBits {
|
||||
numBits = 80
|
||||
} else if 256 < numBits {
|
||||
numBits = 256
|
||||
}
|
||||
|
||||
// derived values:
|
||||
cloakConfig.numBytes = numBits / 8
|
||||
// round up to the nearest byte
|
||||
if numBits%8 != 0 {
|
||||
cloakConfig.numBytes += 1
|
||||
}
|
||||
cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
|
||||
cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
|
||||
}
|
||||
|
||||
// simple cloaking algorithm: normalize the IP to its CIDR,
|
||||
// then hash the resulting bytes with a secret key,
|
||||
// then truncate to the desired length, b32encode, and append the fake TLD.
|
||||
func (config *CloakConfig) ComputeCloak(ip net.IP) string {
|
||||
if !config.Enabled {
|
||||
return ""
|
||||
} else if config.NumBits == 0 {
|
||||
return config.Netname
|
||||
}
|
||||
var masked net.IP
|
||||
v4ip := ip.To4()
|
||||
if v4ip != nil {
|
||||
masked = v4ip.Mask(config.ipv4Mask)
|
||||
} else {
|
||||
masked = ip.Mask(config.ipv6Mask)
|
||||
}
|
||||
// SHA3(K || M):
|
||||
// https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
|
||||
input := make([]byte, len(config.Secret)+len(masked))
|
||||
copy(input, config.Secret[:])
|
||||
copy(input[len(config.Secret):], masked)
|
||||
digest := sha3.Sum512(input)
|
||||
b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
|
||||
return fmt.Sprintf("%s.%s", b32digest, config.Netname)
|
||||
}
|
@ -18,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/bytefmt"
|
||||
"github.com/oragono/oragono/irc/cloaks"
|
||||
"github.com/oragono/oragono/irc/connection_limits"
|
||||
"github.com/oragono/oragono/irc/custime"
|
||||
"github.com/oragono/oragono/irc/isupport"
|
||||
@ -263,38 +264,6 @@ type TorListenersConfig struct {
|
||||
MaxConnectionsPerDuration int `yaml:"max-connections-per-duration"`
|
||||
}
|
||||
|
||||
type CloakConfig struct {
|
||||
Enabled bool
|
||||
Netname string
|
||||
Secret string
|
||||
CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
|
||||
CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
|
||||
NumBits int `yaml:"num-bits"`
|
||||
|
||||
numBytes int
|
||||
ipv4Mask net.IPMask
|
||||
ipv6Mask net.IPMask
|
||||
}
|
||||
|
||||
func (cloakConfig *CloakConfig) postprocess() {
|
||||
// sanity checks:
|
||||
numBits := cloakConfig.NumBits
|
||||
if 0 == numBits {
|
||||
numBits = 80
|
||||
} else if 256 < numBits {
|
||||
numBits = 256
|
||||
}
|
||||
|
||||
// derived values:
|
||||
cloakConfig.numBytes = numBits / 8
|
||||
// round up to the nearest byte
|
||||
if numBits%8 != 0 {
|
||||
cloakConfig.numBytes += 1
|
||||
}
|
||||
cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
|
||||
cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
|
||||
}
|
||||
|
||||
// Config defines the overall configuration.
|
||||
type Config struct {
|
||||
Network struct {
|
||||
@ -329,7 +298,7 @@ type Config struct {
|
||||
isupport isupport.List
|
||||
ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"`
|
||||
ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"`
|
||||
Cloaks CloakConfig `yaml:"ip-cloaking"`
|
||||
Cloaks cloaks.CloakConfig `yaml:"ip-cloaking"`
|
||||
}
|
||||
|
||||
Languages struct {
|
||||
@ -761,7 +730,7 @@ func LoadConfig(filename string) (config *Config, err error) {
|
||||
config.History.ClientLength = 0
|
||||
}
|
||||
|
||||
config.Server.Cloaks.postprocess()
|
||||
config.Server.Cloaks.Initialize()
|
||||
|
||||
for _, listenAddress := range config.Server.TorListeners.Listeners {
|
||||
found := false
|
||||
|
@ -21,8 +21,6 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/goshuirc/irc-go/ircfmt"
|
||||
"github.com/oragono/oragono/irc/caps"
|
||||
"github.com/oragono/oragono/irc/connection_limits"
|
||||
@ -285,32 +283,6 @@ func (server *Server) checkTorLimits() (banned bool, message string) {
|
||||
}
|
||||
}
|
||||
|
||||
// simple cloaking algorithm: normalize the IP to its CIDR,
|
||||
// then hash the resulting bytes with a secret key,
|
||||
// then truncate to the desired length, b32encode, and append the fake TLD.
|
||||
func (config *CloakConfig) ComputeCloak(ip net.IP) string {
|
||||
if !config.Enabled {
|
||||
return ""
|
||||
} else if config.NumBits == 0 {
|
||||
return config.Netname
|
||||
}
|
||||
var masked net.IP
|
||||
v4ip := ip.To4()
|
||||
if v4ip != nil {
|
||||
masked = v4ip.Mask(config.ipv4Mask)
|
||||
} else {
|
||||
masked = ip.Mask(config.ipv6Mask)
|
||||
}
|
||||
// SHA3(K || M):
|
||||
// https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
|
||||
input := make([]byte, len(config.Secret)+len(masked))
|
||||
copy(input, config.Secret[:])
|
||||
copy(input[len(config.Secret):], masked)
|
||||
digest := sha3.Sum512(input)
|
||||
b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
|
||||
return fmt.Sprintf("%s.%s", b32digest, config.Netname)
|
||||
}
|
||||
|
||||
//
|
||||
// IRC protocol listeners
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user