Allow Explicit Server Resyncing
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is failing Details

This commit is contained in:
Sarah Jamie Lewis 2021-06-01 11:34:35 -07:00
parent 77e5eda0b5
commit d84735cec7
5 changed files with 48 additions and 8 deletions

View File

@ -230,6 +230,10 @@ const (
// Onion: the local onion we attempt to check
NetworkStatus = Type("NetworkError")
// Notify the UI that a Server has been added
// Onion = Server Onion
ServerCreated = Type("ServerAdded")
// For debugging. Allows test to emit a Syn and get a response Ack(eventID) when the subsystem is done processing a queue
Syn = Type("Syn")
Ack = Type("Ack")

2
go.mod
View File

@ -3,7 +3,7 @@ module cwtch.im/cwtch
go 1.14
require (
git.openprivacy.ca/cwtch.im/tapir v0.4.1
git.openprivacy.ca/cwtch.im/tapir v0.4.2
git.openprivacy.ca/openprivacy/connectivity v1.4.3
git.openprivacy.ca/openprivacy/log v1.0.2
github.com/gtank/ristretto255 v0.1.2

2
go.sum
View File

@ -12,6 +12,8 @@ git.openprivacy.ca/cwtch.im/tapir v0.4.0 h1:clG8uORt0NKEhT4P+Dpw1pzyUuYzYBMevGqn
git.openprivacy.ca/cwtch.im/tapir v0.4.0/go.mod h1:eH6dZxXrhW0C4KZX18ksUa6XJCrEvtg8cJJ/Fy6gv+E=
git.openprivacy.ca/cwtch.im/tapir v0.4.1 h1:9LMpQX41IzecNNlRc1FZKXHg6wlFss679tFsa3vzb3Y=
git.openprivacy.ca/cwtch.im/tapir v0.4.1/go.mod h1:eH6dZxXrhW0C4KZX18ksUa6XJCrEvtg8cJJ/Fy6gv+E=
git.openprivacy.ca/cwtch.im/tapir v0.4.2 h1:bxMWZnVJXX4dqqOFS7ELW4iFkVL4GS8wiRkjRv5rJe8=
git.openprivacy.ca/cwtch.im/tapir v0.4.2/go.mod h1:eH6dZxXrhW0C4KZX18ksUa6XJCrEvtg8cJJ/Fy6gv+E=
git.openprivacy.ca/openprivacy/bine v0.0.4 h1:CO7EkGyz+jegZ4ap8g5NWRuDHA/56KKvGySR6OBPW+c=
git.openprivacy.ca/openprivacy/bine v0.0.4/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU=
git.openprivacy.ca/openprivacy/connectivity v1.4.0 h1:c7AANUCrlA4hIqXxIGDOWMtSe8CpDleD1877PShScbM=

View File

@ -122,6 +122,7 @@ type ModifyGroups interface {
// ModifyServers provides write-only access to servers
type ModifyServers interface {
AddServer(string) error
ResyncServer(onion string) error
}
// SendMessages enables a caller to sender messages to a contact
@ -326,6 +327,8 @@ func (cp *cwtchPeer) AddServer(serverSpecification string) error {
cp.mutex.Unlock()
pd, _ := json.Marshal(pp)
// Sync the Storage Engine
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
event.Data: string(pd),
event.RemotePeer: onion,
@ -473,6 +476,20 @@ func (cp *cwtchPeer) JoinServer(onion string) error {
return errors.New("no keys found for server connection")
}
// ResyncServer completely tears down and resyncs a new server connection with the given onion address
func (cp *cwtchPeer) ResyncServer(onion string) error {
if cp.GetContact(onion) != nil {
tokenY, yExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypePrivacyPass))
tokenOnion, onionExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypeTokenOnion))
if yExists && onionExists {
signature := base64.StdEncoding.EncodeToString([]byte{})
cp.eventBus.Publish(event.NewEvent(event.JoinServer, map[event.Field]string{event.GroupServer: onion, event.ServerTokenY: tokenY, event.ServerTokenOnion: tokenOnion, event.Signature: signature}))
return nil
}
}
return errors.New("no keys found for server connection")
}
// SendMessageToGroupTracked attempts to sent the given message to the given group id.
// It returns the signature of the message which can be used to identify it in any UX layer.
func (cp *cwtchPeer) SendMessageToGroupTracked(groupid string, message string) (string, error) {
@ -684,7 +701,14 @@ func (cp *cwtchPeer) eventHandler() {
ciphertext, _ := base64.StdEncoding.DecodeString(ev.Data[event.Ciphertext])
signature, _ := base64.StdEncoding.DecodeString(ev.Data[event.Signature])
// SECURITY NOTE: A malicious server could insert posts such that everyone always has a different lastKnownSignature
// However the server can always replace **all** messages in an attempt to track users
// This is mitigated somewhat by resync events which do wipe things entire.
// The security of cwtch groups are also not dependent on the servers inability to uniquely tag connections (as long as
// it learns nothing else about each connection).
cp.SetContactAttribute(ev.Data[event.GroupServer], lastKnownSignature, ev.Data[event.Signature])
cp.mutex.Lock()
ok, groupID, message, seen := cp.Profile.AttemptDecryption(ciphertext, signature)
cp.mutex.Unlock()

View File

@ -136,12 +136,7 @@ func (e *engine) eventHandler() {
}
go e.peerWithTokenServer(ev.Data[event.GroupServer], ev.Data[event.ServerTokenOnion], ev.Data[event.ServerTokenY], signature)
case event.LeaveServer:
es, ok := e.ephemeralServices.Load(ev.Data[event.GroupServer])
if ok {
ephemeralService := es.(tapir.Service)
ephemeralService.Shutdown()
e.ephemeralServices.Delete(ev.Data[event.GroupServer])
}
e.leaveServer(ev.Data[event.GroupServer])
case event.DeleteContact:
onion := ev.Data[event.RemotePeer]
// We remove this peer from out blocklist which will prevent them from contacting us if we have "block unknown peers" turned on.
@ -279,8 +274,14 @@ func (e *engine) peerWithTokenServer(onion string, tokenServerOnion string, toke
if exists {
connection := service.(*tor.BaseOnionService)
if conn, err := connection.GetConnection(onion); err == nil {
if conn.IsClosed() == false {
// We are already peered and synced so return...
// This will only not-trigger it lastKnownSignature has been wiped, which only happens when ResyncServer is called
// in CwtchPeer.
if conn.IsClosed() == false && len(lastKnownSignature) != 0 {
return
} else {
// Otherwise...we are going to rebuild the connection(which will result in a bandwidth heavy resync)...
e.leaveServer(onion)
}
}
// Otherwise...let's reconnect
@ -508,3 +509,12 @@ func (e *engine) handlePeerRetVal(hostname string, getValData, retValData []byte
e.eventManager.Publish(event.NewEventList(event.NewRetValMessageFromPeer, event.RemotePeer, hostname, event.Scope, getVal.Scope, event.Path, getVal.Path, event.Exists, strconv.FormatBool(retVal.Exists), event.Data, retVal.Val))
}
func (e *engine) leaveServer(server string) {
es, ok := e.ephemeralServices.Load(server)
if ok {
ephemeralService := es.(tapir.Service)
ephemeralService.Shutdown()
e.ephemeralServices.Delete(server)
}
}