mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-28 23:19:30 +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}
|
python3 ./gencapdefs.py | diff - ${capdef_file}
|
||||||
cd irc && go test . && go vet .
|
cd irc && go test . && go vet .
|
||||||
cd irc/caps && 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/connection_limits && go test . && go vet .
|
||||||
cd irc/history && go test . && go vet .
|
cd irc/history && go test . && go vet .
|
||||||
cd irc/isupport && go test . && go vet .
|
cd irc/isupport && go test . && go vet .
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
// Copyright (c) 2019 Shivaram Lingamneni
|
// Copyright (c) 2019 Shivaram Lingamneni
|
||||||
// released under the MIT license
|
// released under the MIT license
|
||||||
|
|
||||||
package irc
|
package cloaks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"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) {
|
func easyParseIP(ipstr string) (result net.IP) {
|
||||||
result = net.ParseIP(ipstr)
|
result = net.ParseIP(ipstr)
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@ -25,7 +32,7 @@ func cloakConfForTesting() CloakConfig {
|
|||||||
CidrLenIPv6: 64,
|
CidrLenIPv6: 64,
|
||||||
NumBits: 80,
|
NumBits: 80,
|
||||||
}
|
}
|
||||||
config.postprocess()
|
config.Initialize()
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +71,7 @@ func TestCloakShortv4Cidr(t *testing.T) {
|
|||||||
CidrLenIPv6: 64,
|
CidrLenIPv6: 64,
|
||||||
NumBits: 60,
|
NumBits: 60,
|
||||||
}
|
}
|
||||||
config.postprocess()
|
config.Initialize()
|
||||||
|
|
||||||
v4ip := easyParseIP("8.8.8.8")
|
v4ip := easyParseIP("8.8.8.8")
|
||||||
assertEqual(config.ComputeCloak(v4ip), "3cay3zc72tnui.oragono", t)
|
assertEqual(config.ComputeCloak(v4ip), "3cay3zc72tnui.oragono", t)
|
||||||
@ -76,7 +83,7 @@ func TestCloakZeroBits(t *testing.T) {
|
|||||||
config := cloakConfForTesting()
|
config := cloakConfForTesting()
|
||||||
config.NumBits = 0
|
config.NumBits = 0
|
||||||
config.Netname = "example.com"
|
config.Netname = "example.com"
|
||||||
config.postprocess()
|
config.Initialize()
|
||||||
|
|
||||||
v4ip := easyParseIP("8.8.8.8").To4()
|
v4ip := easyParseIP("8.8.8.8").To4()
|
||||||
assertEqual(config.ComputeCloak(v4ip), "example.com", t)
|
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"
|
"time"
|
||||||
|
|
||||||
"code.cloudfoundry.org/bytefmt"
|
"code.cloudfoundry.org/bytefmt"
|
||||||
|
"github.com/oragono/oragono/irc/cloaks"
|
||||||
"github.com/oragono/oragono/irc/connection_limits"
|
"github.com/oragono/oragono/irc/connection_limits"
|
||||||
"github.com/oragono/oragono/irc/custime"
|
"github.com/oragono/oragono/irc/custime"
|
||||||
"github.com/oragono/oragono/irc/isupport"
|
"github.com/oragono/oragono/irc/isupport"
|
||||||
@ -263,38 +264,6 @@ type TorListenersConfig struct {
|
|||||||
MaxConnectionsPerDuration int `yaml:"max-connections-per-duration"`
|
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.
|
// Config defines the overall configuration.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Network struct {
|
Network struct {
|
||||||
@ -329,7 +298,7 @@ type Config struct {
|
|||||||
isupport isupport.List
|
isupport isupport.List
|
||||||
ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"`
|
ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"`
|
||||||
ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"`
|
ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"`
|
||||||
Cloaks CloakConfig `yaml:"ip-cloaking"`
|
Cloaks cloaks.CloakConfig `yaml:"ip-cloaking"`
|
||||||
}
|
}
|
||||||
|
|
||||||
Languages struct {
|
Languages struct {
|
||||||
@ -761,7 +730,7 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
config.History.ClientLength = 0
|
config.History.ClientLength = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Server.Cloaks.postprocess()
|
config.Server.Cloaks.Initialize()
|
||||||
|
|
||||||
for _, listenAddress := range config.Server.TorListeners.Listeners {
|
for _, listenAddress := range config.Server.TorListeners.Listeners {
|
||||||
found := false
|
found := false
|
||||||
|
@ -21,8 +21,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
|
|
||||||
"github.com/goshuirc/irc-go/ircfmt"
|
"github.com/goshuirc/irc-go/ircfmt"
|
||||||
"github.com/oragono/oragono/irc/caps"
|
"github.com/oragono/oragono/irc/caps"
|
||||||
"github.com/oragono/oragono/irc/connection_limits"
|
"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
|
// IRC protocol listeners
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user