fmt and spamguard

This commit is contained in:
Sarah Jamie Lewis 2018-03-09 13:02:42 -08:00
parent 086e964514
commit 487ce6d2da
6 changed files with 56 additions and 58 deletions

View File

@ -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)
} }

View File

@ -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)
} }

View File

@ -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()

View File

@ -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)
} }

View File

@ -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 {

View File

@ -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[:])