From 957558165d0d75bf535c5fd530686d614eac8314 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 9 Jun 2021 13:20:51 -0700 Subject: [PATCH 1/4] Update Server State on ServerStateChangeEvent in addition to individual groups. --- peer/cwtch_peer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index 2dab063..8e924ac 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -811,6 +811,10 @@ func (cp *cwtchPeer) eventHandler() { cp.mutex.Unlock() case event.ServerStateChange: cp.mutex.Lock() + // We update both the server contact status, as well as the groups the server belongs to + cp.Profile.Contacts[ev.Data[event.GroupServer]].State = ev.Data[event.ConnectionState] + + // TODO deprecate this, the UI should consult the server contact entry instead (it's far more efficient) for _, group := range cp.Profile.Groups { if group.GroupServer == ev.Data[event.GroupServer] { group.State = ev.Data[event.ConnectionState] From aa6f2499b9f3e2d08125edc19bffdb3c91f8708e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 9 Jun 2021 13:26:02 -0700 Subject: [PATCH 2/4] reject group invites without a corresponding key bundle --- model/profile.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/model/profile.go b/model/profile.go index f434ae5..b55feb0 100644 --- a/model/profile.go +++ b/model/profile.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "encoding/json" "errors" + "fmt" "git.openprivacy.ca/openprivacy/connectivity/tor" "golang.org/x/crypto/ed25519" "io" @@ -390,6 +391,9 @@ func (p *Profile) GetGroup(groupID string) (g *Group) { func (p *Profile) ProcessInvite(invite string) (string, error) { gci, err := ValidateInvite(invite) if err == nil { + if _, exists := p.GetContact(gci.ServerHost); !exists { + return "", fmt.Errorf("unknown server. a server key bundle needs to be imported before this group can be verified") + } group := new(Group) group.Version = CurrentGroupVersion group.GroupID = gci.GroupID From b4b2b15e764c019547414695fec0a88a40ee40b4 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 9 Jun 2021 13:38:11 -0700 Subject: [PATCH 3/4] Fix IsServer check in Invite --- model/message_test.go | 3 +++ model/profile.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/model/message_test.go b/model/message_test.go index b440b8e..958b050 100644 --- a/model/message_test.go +++ b/model/message_test.go @@ -47,6 +47,9 @@ func TestTranscriptConsistency(t *testing.T) { sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) + // The lightest weight server entry possible (usually we would import a key bundle...) + sarah.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &PublicProfile{Attributes: map[string]string{string(KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) + gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") sarah.ProcessInvite(invite) diff --git a/model/profile.go b/model/profile.go index b55feb0..be05f55 100644 --- a/model/profile.go +++ b/model/profile.go @@ -391,7 +391,7 @@ func (p *Profile) GetGroup(groupID string) (g *Group) { func (p *Profile) ProcessInvite(invite string) (string, error) { gci, err := ValidateInvite(invite) if err == nil { - if _, exists := p.GetContact(gci.ServerHost); !exists { + if server, exists := p.GetContact(gci.ServerHost); !exists || !server.IsServer() { return "", fmt.Errorf("unknown server. a server key bundle needs to be imported before this group can be verified") } group := new(Group) From 78ee588538721a2c65334f5da1b500198e674ff4 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 9 Jun 2021 13:41:17 -0700 Subject: [PATCH 4/4] More test fixes --- model/profile_test.go | 8 ++++++++ storage/profile_store_test.go | 3 +++ storage/v1/profile_store_test.go | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/model/profile_test.go b/model/profile_test.go index 0dba56e..2cd8ae5 100644 --- a/model/profile_test.go +++ b/model/profile_test.go @@ -62,6 +62,8 @@ func TestRejectGroupInvite(t *testing.T) { alice := GenerateNewProfile("Alice") sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) + // The lightest weight server entry possible (usually we would import a key bundle...) + sarah.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &PublicProfile{Attributes: map[string]string{string(KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") sarah.ProcessInvite(invite) @@ -86,6 +88,9 @@ func TestProfileGroup(t *testing.T) { alice.AddContact(sarah.Onion, &sarah.PublicProfile) gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + + // The lightest weight server entry possible (usually we would import a key bundle...) + sarah.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &PublicProfile{Attributes: map[string]string{string(KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) sarah.ProcessInvite(invite) if len(sarah.GetGroups()) != 1 { t.Errorf("sarah should only be in 1 group instead: %v", sarah.GetGroups()) @@ -109,6 +114,9 @@ func TestProfileGroup(t *testing.T) { bob := GenerateNewProfile("bob") bob.AddContact(alice.Onion, &alice.PublicProfile) + // The lightest weight server entry possible (usually we would import a key bundle...) + bob.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &PublicProfile{Attributes: map[string]string{string(KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) + bob.ProcessInvite(invite2) c3, s3, err := bob.EncryptMessageToGroup("Bobs Message", group2.GroupID) if err == nil { diff --git a/storage/profile_store_test.go b/storage/profile_store_test.go index e9f8a44..fcec0a3 100644 --- a/storage/profile_store_test.go +++ b/storage/profile_store_test.go @@ -4,6 +4,7 @@ package storage import ( "cwtch.im/cwtch/event" + "cwtch.im/cwtch/model" "cwtch.im/cwtch/storage/v0" "fmt" "git.openprivacy.ca/openprivacy/log" @@ -32,6 +33,8 @@ func TestProfileStoreUpgradeV0toV1(t *testing.T) { fmt.Println("Creating and initializing v0 profile and store...") profile := NewProfile(testProfileName) + profile.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &model.PublicProfile{Attributes: map[string]string{string(model.KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) + ps1 := v0.NewProfileWriterStore(eventBus, testingDir, password, profile) groupid, invite, err := profile.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") diff --git a/storage/v1/profile_store_test.go b/storage/v1/profile_store_test.go index ae23fd3..1fb8133 100644 --- a/storage/v1/profile_store_test.go +++ b/storage/v1/profile_store_test.go @@ -4,6 +4,7 @@ package v1 import ( "cwtch.im/cwtch/event" + "cwtch.im/cwtch/model" "fmt" "log" "os" @@ -22,6 +23,9 @@ func TestProfileStoreWriteRead(t *testing.T) { os.RemoveAll(testingDir) eventBus := event.NewEventManager() profile := NewProfile(testProfileName) + // The lightest weight server entry possible (usually we would import a key bundle...) + profile.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &model.PublicProfile{Attributes: map[string]string{string(model.KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) + ps1 := CreateProfileWriterStore(eventBus, testingDir, password, profile) eventBus.Publish(event.NewEvent(event.SetAttribute, map[event.Field]string{event.Key: testKey, event.Data: testVal})) @@ -79,6 +83,8 @@ func TestProfileStoreChangePassword(t *testing.T) { eventBus.Subscribe(event.ChangePasswordSuccess, queue) profile := NewProfile(testProfileName) + profile.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &model.PublicProfile{Attributes: map[string]string{string(model.KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) + ps1 := CreateProfileWriterStore(eventBus, testingDir, password, profile) groupid, invite, err := profile.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")