fmt and spamguard
This commit is contained in:
parent
086e964514
commit
487ce6d2da
|
@ -50,7 +50,7 @@ func TestPeerFetchChannelOpenInbound(t *testing.T) {
|
||||||
|
|
||||||
func TestPeerFetchChannel(t *testing.T) {
|
func TestPeerFetchChannel(t *testing.T) {
|
||||||
pfc := new(CwtchPeerFetchChannel)
|
pfc := new(CwtchPeerFetchChannel)
|
||||||
th := new(TestHandler)
|
th := new(TestHandler)
|
||||||
pfc.Handler = th
|
pfc.Handler = th
|
||||||
channel := new(channels.Channel)
|
channel := new(channels.Channel)
|
||||||
channel.ID = 3
|
channel.ID = 3
|
||||||
|
@ -69,11 +69,9 @@ func TestPeerFetchChannel(t *testing.T) {
|
||||||
t.Errorf("once opened channel should no longer be pending")
|
t.Errorf("once opened channel should no longer be pending")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
csp := &protocol.CwtchServerPacket{
|
csp := &protocol.CwtchServerPacket{
|
||||||
GroupMessages: []*protocol.GroupMessage{
|
GroupMessages: []*protocol.GroupMessage{
|
||||||
{Ciphertext: []byte("hello"),Spamguard: []byte{},},
|
{Ciphertext: []byte("hello"), Spamguard: []byte{}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
packet, _ := proto.Marshal(csp)
|
packet, _ := proto.Marshal(csp)
|
||||||
|
@ -83,7 +81,7 @@ func TestPeerFetchChannel(t *testing.T) {
|
||||||
if th.Received != true {
|
if th.Received != true {
|
||||||
t.Errorf("group message should not have been received")
|
t.Errorf("group message should not have been received")
|
||||||
}
|
}
|
||||||
|
|
||||||
pfc.Closed(nil)
|
pfc.Closed(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func TestPeerListenChannelOpenInbound(t *testing.T) {
|
||||||
|
|
||||||
func TestPeerListenChannel(t *testing.T) {
|
func TestPeerListenChannel(t *testing.T) {
|
||||||
pfc := new(CwtchPeerListenChannel)
|
pfc := new(CwtchPeerListenChannel)
|
||||||
th := new(TestHandler)
|
th := new(TestHandler)
|
||||||
pfc.Handler = th
|
pfc.Handler = th
|
||||||
channel := new(channels.Channel)
|
channel := new(channels.Channel)
|
||||||
channel.ID = 3
|
channel.ID = 3
|
||||||
|
@ -69,10 +69,8 @@ func TestPeerListenChannel(t *testing.T) {
|
||||||
t.Errorf("once opened channel should no longer be pending")
|
t.Errorf("once opened channel should no longer be pending")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
csp := &protocol.CwtchServerPacket{
|
csp := &protocol.CwtchServerPacket{
|
||||||
GroupMessage: &protocol.GroupMessage{Ciphertext: []byte("hello"),Spamguard: []byte{},},
|
GroupMessage: &protocol.GroupMessage{Ciphertext: []byte("hello"), Spamguard: []byte{}},
|
||||||
}
|
}
|
||||||
packet, _ := proto.Marshal(csp)
|
packet, _ := proto.Marshal(csp)
|
||||||
|
|
||||||
|
@ -81,7 +79,7 @@ func TestPeerListenChannel(t *testing.T) {
|
||||||
if th.Received != true {
|
if th.Received != true {
|
||||||
t.Errorf("group message should not have been received")
|
t.Errorf("group message should not have been received")
|
||||||
}
|
}
|
||||||
|
|
||||||
pfc.Closed(nil)
|
pfc.Closed(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
// CwtchPeerSendChannel is the peer implementation of im.cwtch.server.send
|
// CwtchPeerSendChannel is the peer implementation of im.cwtch.server.send
|
||||||
type CwtchPeerSendChannel struct {
|
type CwtchPeerSendChannel struct {
|
||||||
channel *channels.Channel
|
channel *channels.Channel
|
||||||
spamGuard spam.SpamGuard
|
spamGuard spam.SpamGuard
|
||||||
challenge []byte
|
challenge []byte
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,9 @@ func (cc *CwtchPeerSendChannel) OpenInbound(channel *channels.Channel, raw *Prot
|
||||||
return nil, errors.New("client does not receive inbound listen channels")
|
return nil, errors.New("client does not receive inbound listen channels")
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenOutbound is used to set up a new send channel and initialize spamguard
|
// OpenOutbound is used to set up a new send channel and initialize spamguard
|
||||||
func (cplc *CwtchPeerSendChannel) OpenOutbound(channel *channels.Channel) ([]byte, error) {
|
func (cplc *CwtchPeerSendChannel) OpenOutbound(channel *channels.Channel) ([]byte, error) {
|
||||||
cplc.spamGuard.Difficulty = 2
|
cplc.spamGuard.Difficulty = 2
|
||||||
cplc.channel = channel
|
cplc.channel = channel
|
||||||
messageBuilder := new(utils.MessageBuilder)
|
messageBuilder := new(utils.MessageBuilder)
|
||||||
return messageBuilder.OpenChannel(channel.ID, cplc.Type()), nil
|
return messageBuilder.OpenChannel(channel.ID, cplc.Type()), nil
|
||||||
|
@ -66,16 +66,15 @@ func (cplc *CwtchPeerSendChannel) OpenOutboundResult(err error, crm *Protocol_Da
|
||||||
if crm.GetOpened() {
|
if crm.GetOpened() {
|
||||||
cplc.channel.Pending = false
|
cplc.channel.Pending = false
|
||||||
ce, _ := proto.GetExtension(crm, protocol.E_ServerNonce)
|
ce, _ := proto.GetExtension(crm, protocol.E_ServerNonce)
|
||||||
cplc.challenge = ce.([]byte)[:]
|
cplc.challenge = ce.([]byte)[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// SendGroupMessage performs the spamguard proof of work and sends a message.
|
// SendGroupMessage performs the spamguard proof of work and sends a message.
|
||||||
func (cplc *CwtchPeerSendChannel) SendGroupMessage(gm *protocol.GroupMessage) {
|
func (cplc *CwtchPeerSendChannel) SendGroupMessage(gm *protocol.GroupMessage) {
|
||||||
sgsolve := cplc.spamGuard.SolveChallenge(cplc.challenge, gm.GetCiphertext())
|
sgsolve := cplc.spamGuard.SolveChallenge(cplc.challenge, gm.GetCiphertext())
|
||||||
gm.Spamguard = sgsolve
|
gm.Spamguard = sgsolve
|
||||||
csp := &protocol.CwtchServerPacket{
|
csp := &protocol.CwtchServerPacket{
|
||||||
GroupMessage: gm,
|
GroupMessage: gm,
|
||||||
}
|
}
|
||||||
|
@ -83,7 +82,7 @@ func (cplc *CwtchPeerSendChannel) SendGroupMessage(gm *protocol.GroupMessage) {
|
||||||
cplc.channel.SendMessage(packet)
|
cplc.channel.SendMessage(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packet should never be called
|
// Packet should never be
|
||||||
func (cc *CwtchPeerSendChannel) Packet(data []byte) {
|
func (cc *CwtchPeerSendChannel) Packet(data []byte) {
|
||||||
// If we receive a packet on this channel, close the connection
|
// If we receive a packet on this channel, close the connection
|
||||||
cc.channel.CloseChannel()
|
cc.channel.CloseChannel()
|
||||||
|
|
|
@ -2,10 +2,10 @@ package listen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.mascherari.press/cwtch/protocol"
|
"git.mascherari.press/cwtch/protocol"
|
||||||
|
"git.mascherari.press/cwtch/protocol/spam"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/s-rah/go-ricochet/channels"
|
"github.com/s-rah/go-ricochet/channels"
|
||||||
"github.com/s-rah/go-ricochet/wire/control"
|
"github.com/s-rah/go-ricochet/wire/control"
|
||||||
"git.mascherari.press/cwtch/protocol/spam"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,20 +50,19 @@ func TestPeerSendChannelOpenInbound(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestPeerSendChannelClosesOnPacket(t *testing.T) {
|
func TestPeerSendChannelClosesOnPacket(t *testing.T) {
|
||||||
pfc := new(CwtchPeerSendChannel)
|
pfc := new(CwtchPeerSendChannel)
|
||||||
channel := new(channels.Channel)
|
channel := new(channels.Channel)
|
||||||
closed := false
|
closed := false
|
||||||
channel.CloseChannel = func () {
|
channel.CloseChannel = func() {
|
||||||
closed = true
|
closed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
pfc.OpenOutbound(channel)
|
pfc.OpenOutbound(channel)
|
||||||
pfc.Packet([]byte{})
|
pfc.Packet([]byte{})
|
||||||
if !closed {
|
if !closed {
|
||||||
t.Errorf("send channel should close if server attempts to send packets")
|
t.Errorf("send channel should close if server attempts to send packets")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeerSendChannel(t *testing.T) {
|
func TestPeerSendChannel(t *testing.T) {
|
||||||
|
@ -72,26 +71,24 @@ func TestPeerSendChannel(t *testing.T) {
|
||||||
channel := new(channels.Channel)
|
channel := new(channels.Channel)
|
||||||
channel.ID = 3
|
channel.ID = 3
|
||||||
success := false
|
success := false
|
||||||
|
|
||||||
var sg spam.SpamGuard
|
var sg spam.SpamGuard
|
||||||
sg.Difficulty = 2
|
sg.Difficulty = 2
|
||||||
|
|
||||||
channel.SendMessage = func(message []byte) {
|
channel.SendMessage = func(message []byte) {
|
||||||
packet := new(protocol.CwtchServerPacket)
|
packet := new(protocol.CwtchServerPacket)
|
||||||
proto.Unmarshal(message[:], packet)
|
proto.Unmarshal(message[:], packet)
|
||||||
if packet.GetGroupMessage() != nil {
|
if packet.GetGroupMessage() != nil {
|
||||||
success = sg.ValidateChallenge(packet.GetGroupMessage().GetCiphertext(), packet.GetGroupMessage().GetSpamguard())
|
success = sg.ValidateChallenge(packet.GetGroupMessage().GetCiphertext(), packet.GetGroupMessage().GetSpamguard())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result, err := pfc.OpenOutbound(channel)
|
result, err := pfc.OpenOutbound(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected result but also got non-nil error: result:%v, err: %v", result, err)
|
t.Errorf("expected result but also got non-nil error: result:%v, err: %v", result, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
challenge := sg.GenerateChallenge(3)
|
challenge := sg.GenerateChallenge(3)
|
||||||
control := new(Protocol_Data_Control.Packet)
|
control := new(Protocol_Data_Control.Packet)
|
||||||
proto.Unmarshal(challenge[:], control)
|
proto.Unmarshal(challenge[:], control)
|
||||||
|
|
||||||
pfc.OpenOutboundResult(nil, control.GetChannelResult())
|
pfc.OpenOutboundResult(nil, control.GetChannelResult())
|
||||||
|
@ -99,13 +96,12 @@ func TestPeerSendChannel(t *testing.T) {
|
||||||
t.Errorf("once opened channel should no longer be pending")
|
t.Errorf("once opened channel should no longer be pending")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gm := &protocol.GroupMessage{Ciphertext: []byte("hello")}
|
||||||
|
pfc.SendGroupMessage(gm)
|
||||||
|
if !success {
|
||||||
|
t.Errorf("send channel should have successfully sent a valid group message")
|
||||||
|
}
|
||||||
|
|
||||||
gm := &protocol.GroupMessage{Ciphertext: []byte("hello"),}
|
|
||||||
pfc.SendGroupMessage(gm)
|
|
||||||
if !success {
|
|
||||||
t.Errorf("send channel should have successfully sent a valid group message")
|
|
||||||
}
|
|
||||||
|
|
||||||
pfc.Closed(nil)
|
pfc.Closed(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ type CwtchServerPacket struct {
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CwtchServerPacket) Reset() { *m = CwtchServerPacket{} }
|
func (m *CwtchServerPacket) Reset() { *m = CwtchServerPacket{} }
|
||||||
func (m *CwtchServerPacket) String() string { return proto.CompactTextString(m) }
|
func (m *CwtchServerPacket) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CwtchServerPacket) ProtoMessage() {}
|
func (*CwtchServerPacket) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *CwtchServerPacket) GetGroupMessage() *GroupMessage {
|
func (m *CwtchServerPacket) GetGroupMessage() *GroupMessage {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -49,9 +49,9 @@ type FetchMessage struct {
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FetchMessage) Reset() { *m = FetchMessage{} }
|
func (m *FetchMessage) Reset() { *m = FetchMessage{} }
|
||||||
func (m *FetchMessage) String() string { return proto.CompactTextString(m) }
|
func (m *FetchMessage) String() string { return proto.CompactTextString(m) }
|
||||||
func (*FetchMessage) ProtoMessage() {}
|
func (*FetchMessage) ProtoMessage() {}
|
||||||
|
|
||||||
type GroupMessage struct {
|
type GroupMessage struct {
|
||||||
Ciphertext []byte `protobuf:"bytes,1,req,name=ciphertext" json:"ciphertext,omitempty"`
|
Ciphertext []byte `protobuf:"bytes,1,req,name=ciphertext" json:"ciphertext,omitempty"`
|
||||||
|
@ -59,10 +59,9 @@ type GroupMessage struct {
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GroupMessage) Reset() { *m = GroupMessage{} }
|
func (m *GroupMessage) Reset() { *m = GroupMessage{} }
|
||||||
func (m *GroupMessage) String() string { return proto.CompactTextString(m) }
|
func (m *GroupMessage) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GroupMessage) ProtoMessage() {}
|
func (*GroupMessage) ProtoMessage() {}
|
||||||
|
|
||||||
|
|
||||||
func (m *GroupMessage) GetCiphertext() []byte {
|
func (m *GroupMessage) GetCiphertext() []byte {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -88,9 +87,9 @@ type DecryptedGroupMessage struct {
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DecryptedGroupMessage) Reset() { *m = DecryptedGroupMessage{} }
|
func (m *DecryptedGroupMessage) Reset() { *m = DecryptedGroupMessage{} }
|
||||||
func (m *DecryptedGroupMessage) String() string { return proto.CompactTextString(m) }
|
func (m *DecryptedGroupMessage) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DecryptedGroupMessage) ProtoMessage() {}
|
func (*DecryptedGroupMessage) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *DecryptedGroupMessage) GetOnion() string {
|
func (m *DecryptedGroupMessage) GetOnion() string {
|
||||||
if m != nil && m.Onion != nil {
|
if m != nil && m.Onion != nil {
|
||||||
|
|
|
@ -15,6 +15,8 @@ type SpamGuard struct {
|
||||||
nonce [24]byte
|
nonce [24]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//GenerateChallenge returns a channel result packet with a spamguard challenge nonce
|
||||||
func (sg *SpamGuard) GenerateChallenge(channelID int32) []byte {
|
func (sg *SpamGuard) GenerateChallenge(channelID int32) []byte {
|
||||||
|
|
||||||
cr := &Protocol_Data_Control.ChannelResult{
|
cr := &Protocol_Data_Control.ChannelResult{
|
||||||
|
@ -38,6 +40,9 @@ func (sg *SpamGuard) GenerateChallenge(channelID int32) []byte {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SolveChallenge takes in a challenge and a message and returns a solution
|
||||||
|
// The solution is a 24 byte nonce which when hashed with the challenge and the message
|
||||||
|
// produces a sha256 hash with Difficulty leading 0s
|
||||||
func (sg *SpamGuard) SolveChallenge(challenge []byte, message []byte) []byte {
|
func (sg *SpamGuard) SolveChallenge(challenge []byte, message []byte) []byte {
|
||||||
solved := false
|
solved := false
|
||||||
var spamguard [24]byte
|
var spamguard [24]byte
|
||||||
|
@ -67,8 +72,11 @@ func (sg *SpamGuard) SolveChallenge(challenge []byte, message []byte) []byte {
|
||||||
return spamguard[:]
|
return spamguard[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidateChallenge returns true if the message and spamguard pass the challenge
|
||||||
func (sg *SpamGuard) ValidateChallenge(message []byte, spamguard []byte) bool {
|
func (sg *SpamGuard) ValidateChallenge(message []byte, spamguard []byte) bool {
|
||||||
//log.Printf("%v %v\n", sg.nonce[:], spamguard[:])
|
if len(spamguard) != 24 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
solve := make([]byte, len(sg.nonce)+len(message)+len(spamguard))
|
solve := make([]byte, len(sg.nonce)+len(message)+len(spamguard))
|
||||||
copy(solve[0:], sg.nonce[:])
|
copy(solve[0:], sg.nonce[:])
|
||||||
copy(solve[len(sg.nonce):], message[:])
|
copy(solve[len(sg.nonce):], message[:])
|
||||||
|
|
Loading…
Reference in New Issue