diff --git a/app/app.go b/app/app.go index 974bc8c..c3b0ff7 100644 --- a/app/app.go +++ b/app/app.go @@ -217,7 +217,7 @@ func (app *application) setupPeer(profile peer.CwtchPeer) { // Initialize the Peer with the Given Event Bus app.peers[profile.GetOnion()] = profile - profile.Init(app.eventBuses[profile.GetOnion()]) + profile.Init(eventBus) // Update the Peer with the Most Recent Experiment State... globalSettings := app.settings.ReadGlobalSettings() @@ -259,7 +259,8 @@ func (app *application) DeleteProfile(onion string, password string) { defer app.appmutex.Unlock() // short circuit to prevent nil-pointer panic if this function is called twice (or incorrectly) - if app.peers[onion] == nil { + peer := app.peers[onion] + if peer == nil { log.Errorf("shutdownPeer called with invalid onion %v", onion) return } @@ -269,11 +270,11 @@ func (app *application) DeleteProfile(onion string, password string) { password = DefactoPasswordForUnencryptedProfiles } - if app.peers[onion].CheckPassword(password) { + if peer.CheckPassword(password) { // soft-shutdown - app.peers[onion].Shutdown() + peer.Shutdown() // delete the underlying storage - app.peers[onion].Delete() + peer.Delete() // hard shutdown / remove from app app.shutdownPeer(onion) @@ -341,6 +342,7 @@ func (app *application) LoadProfiles(password string) { cps, err := peer.CreateEncryptedStore(profileDirectory, password) if err != nil { log.Errorf("error creating encrypted store: %v", err) + continue } profile := peer.ImportLegacyProfile(legacyProfile, cps) loaded = app.installProfile(profile) @@ -390,10 +392,23 @@ func (app *application) ActivatePeerEngine(onion string) { profile := app.GetPeer(onion) if profile != nil { if _, exists := app.engines[onion]; !exists { - log.Debugf("restartFlow: Creating a New Protocol Engine...") - app.engines[profile.GetOnion()], _ = profile.GenerateProtocolEngine(app.acn, app.eventBuses[profile.GetOnion()], app.engineHooks) - app.eventBuses[profile.GetOnion()].Publish(event.NewEventList(event.ProtocolEngineCreated)) - app.QueryACNStatus() + eventBus, exists := app.eventBuses[profile.GetOnion()] + + if !exists { + // todo handle this case? + log.Errorf("cannot activate peer engine without an event bus") + return + } + + engine, err := profile.GenerateProtocolEngine(app.acn, eventBus, app.engineHooks) + if err == nil { + log.Debugf("restartFlow: Creating a New Protocol Engine...") + app.engines[profile.GetOnion()] = engine + eventBus.Publish(event.NewEventList(event.ProtocolEngineCreated)) + app.QueryACNStatus() + } else { + log.Errorf("corrupted profile detected for %v", onion) + } } } } @@ -403,21 +418,24 @@ func (app *application) ConfigureConnections(onion string, listen bool, peers bo profile := app.GetPeer(onion) if profile != nil { - // if we are making a decision to ignore - if !peers || !servers { - app.eventBuses[profile.GetOnion()].Publish(event.NewEventList(event.PurgeRetries)) - } + profileBus, exists := app.eventBuses[profile.GetOnion()] + if exists { + // if we are making a decision to ignore + if !peers || !servers { + profileBus.Publish(event.NewEventList(event.PurgeRetries)) + } - // enable the engine if it doesn't exist... - // note: this function is idempotent - app.ActivatePeerEngine(onion) - if listen { - profile.Listen() - } + // enable the engine if it doesn't exist... + // note: this function is idempotent + app.ActivatePeerEngine(onion) + if listen { + profile.Listen() + } - app.eventBuses[profile.GetOnion()].Publish(event.NewEventList(event.ResumeRetries)) - // do this in the background, for large contact lists it can take a long time... - go profile.StartConnections(peers, servers) + profileBus.Publish(event.NewEventList(event.ResumeRetries)) + // do this in the background, for large contact lists it can take a long time... + go profile.StartConnections(peers, servers) + } } else { log.Errorf("profile does not exist %v", onion) } @@ -532,21 +550,26 @@ func (app *application) ShutdownPeer(onion string) { } // shutdownPeer mutex unlocked helper shutdown peer +// +//nolint:nilaway func (app *application) shutdownPeer(onion string) { // short circuit to prevent nil-pointer panic if this function is called twice (or incorrectly) - if app.eventBuses[onion] == nil || app.peers[onion] == nil { + onionEventBus := app.eventBuses[onion] + onionPeer := app.peers[onion] + if onionEventBus == nil || onionPeer == nil { log.Errorf("shutdownPeer called with invalid onion %v", onion) return } + // we are an internal locked method, app.eventBuses[onion] cannot fail... + onionEventBus.Publish(event.NewEventList(event.ShutdownPeer, event.Identity, onion)) + onionEventBus.Shutdown() - app.eventBuses[onion].Publish(event.NewEventList(event.ShutdownPeer, event.Identity, onion)) - app.eventBuses[onion].Shutdown() delete(app.eventBuses, onion) - app.peers[onion].Shutdown() + onionPeer.Shutdown() delete(app.peers, onion) - if _, ok := app.engines[onion]; ok { - app.engines[onion].Shutdown() + if onionEngine, ok := app.engines[onion]; ok { + onionEngine.Shutdown() delete(app.engines, onion) } log.Debugf("shutting down plugins for %v", onion) diff --git a/app/utils.go b/app/utils.go index 799a1f3..c6dbf43 100644 --- a/app/utils.go +++ b/app/utils.go @@ -15,6 +15,9 @@ func WaitGetPeer(app Application, name string) peer.CwtchPeer { for { for _, handle := range app.ListProfiles() { peer := app.GetPeer(handle) + if peer == nil { + continue + } localName, _ := peer.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name) if localName == name { return peer diff --git a/event/infinitechannel.go b/event/infinitechannel.go index df608a2..ea4e603 100644 --- a/event/infinitechannel.go +++ b/event/infinitechannel.go @@ -1,3 +1,4 @@ +// nolint:nilaway - the infiniteBuffer function causes issues with static analysis because it is very unidomatic. package event /* diff --git a/functionality/servers/servers_functionality.go b/functionality/servers/servers_functionality.go index aad78c8..9092359 100644 --- a/functionality/servers/servers_functionality.go +++ b/functionality/servers/servers_functionality.go @@ -9,6 +9,8 @@ import ( "cwtch.im/cwtch/protocol/connections" "cwtch.im/cwtch/settings" "encoding/json" + "errors" + "git.openprivacy.ca/openprivacy/log" ) const ( @@ -98,7 +100,12 @@ func (f *Functionality) PublishServerUpdate(profile peer.CwtchPeer) error { func (f *Functionality) GetServerInfoList(profile peer.CwtchPeer) []Server { var servers []Server for _, server := range profile.GetServers() { - servers = append(servers, f.GetServerInfo(profile, server)) + server, err := f.GetServerInfo(profile, server) + if err != nil { + log.Errorf("profile server list is corrupted: %v", err) + continue + } + servers = append(servers, server) } return servers } @@ -120,8 +127,11 @@ func (f *Functionality) DeleteServerInfo(profile peer.CwtchPeer, serverOnion str // GetServerInfo compiles all the information the UI might need regarding a particular server including any verified // cryptographic keys -func (f *Functionality) GetServerInfo(profile peer.CwtchPeer, serverOnion string) Server { - serverInfo, _ := profile.FetchConversationInfo(serverOnion) +func (f *Functionality) GetServerInfo(profile peer.CwtchPeer, serverOnion string) (Server, error) { + serverInfo, err := profile.FetchConversationInfo(serverOnion) + if err != nil { + return Server{}, errors.New("server not found") + } keyTypes := []model.KeyType{model.KeyTypeServerOnion, model.KeyTypeTokenOnion, model.KeyTypePrivacyPass} var serverKeys []ServerKey @@ -136,5 +146,5 @@ func (f *Functionality) GetServerInfo(profile peer.CwtchPeer, serverOnion string recentTimeStr := serverInfo.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.SyncMostRecentMessageTime)).ToString()] syncStatus := SyncStatus{startTimeStr, recentTimeStr} - return Server{Onion: serverOnion, Identifier: serverInfo.ID, Status: connections.ConnectionStateName[profile.GetPeerState(serverInfo.Handle)], Keys: serverKeys, Description: description, SyncProgress: syncStatus} + return Server{Onion: serverOnion, Identifier: serverInfo.ID, Status: connections.ConnectionStateName[profile.GetPeerState(serverInfo.Handle)], Keys: serverKeys, Description: description, SyncProgress: syncStatus}, nil } diff --git a/go.mod b/go.mod index f1a2219..afcb490 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module cwtch.im/cwtch -go 1.17 +go 1.20 require ( git.openprivacy.ca/cwtch.im/tapir v0.6.0 diff --git a/go.sum b/go.sum index a5222bf..a033e11 100644 --- a/go.sum +++ b/go.sum @@ -1,48 +1,23 @@ -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.openprivacy.ca/cwtch.im/tapir v0.6.0 h1:TtnKjxitkIDMM7Qn0n/u+mOHRLJzuQUYjYRu5n0/QFY= git.openprivacy.ca/cwtch.im/tapir v0.6.0/go.mod h1:iQIq4y7N+DuP3CxyG66WNEC/d6vzh+wXvvOmelB+KoY= -git.openprivacy.ca/openprivacy/bine v0.0.4/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU= git.openprivacy.ca/openprivacy/bine v0.0.5 h1:DJs5gqw3SkvLSgRDvroqJxZ7F+YsbxbBRg5t0rU5gYE= git.openprivacy.ca/openprivacy/bine v0.0.5/go.mod h1:fwdeq6RO08WDkV0k7HfArsjRvurVULoUQmT//iaABZM= -git.openprivacy.ca/openprivacy/connectivity v1.8.6/go.mod h1:Hn1gpOx/bRZp5wvCtPQVJPXrfeUH0EGiG/Aoa0vjGLg= git.openprivacy.ca/openprivacy/connectivity v1.11.0 h1:roASjaFtQLu+HdH5fa2wx6F00NL3YsUTlmXBJh8aLZk= git.openprivacy.ca/openprivacy/connectivity v1.11.0/go.mod h1:OQO1+7OIz/jLxDrorEMzvZA6SEbpbDyLGpjoFqT3z1Y= git.openprivacy.ca/openprivacy/log v1.0.3 h1:E/PMm4LY+Q9s3aDpfySfEDq/vYQontlvNj/scrPaga0= git.openprivacy.ca/openprivacy/log v1.0.3/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.3-0.20210930101514-6bb39798585c h1:gkfmnY4Rlt3VINCo4uKdpvngiibQyoENVj5Q88sxXhE= github.com/gtank/ristretto255 v0.1.3-0.20210930101514-6bb39798585c/go.mod h1:tDPFhGdt3hJWqtKwx57i9baiB1Cj0yAg22VOPUqm5vY= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -53,115 +28,43 @@ github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaG github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= github.com/mutecomm/go-sqlcipher/v4 v4.4.2 h1:eM10bFtI4UvibIsKr10/QT7Yfz+NADfjZYh0GKrXUNc= github.com/mutecomm/go-sqlcipher/v4 v4.4.2/go.mod h1:mF2UmIpBnzFeBdu/ypTDb/LdbS0nk0dfSN1WUsWTjMA= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/model/group.go b/model/group.go index eeacc8e..f4fd9f2 100644 --- a/model/group.go +++ b/model/group.go @@ -59,21 +59,26 @@ func NewGroup(server string) (*Group, error) { // Derive Group ID from the group key and the server public key. This binds the group to a particular server // and key. - group.GroupID = deriveGroupID(groupKey[:], server) - return group, nil + var err error + group.GroupID, err = deriveGroupID(groupKey[:], server) + return group, err } // CheckGroup returns true only if the ID of the group is cryptographically valid. func (g *Group) CheckGroup() bool { - return g.GroupID == deriveGroupID(g.GroupKey[:], g.GroupServer) + id, _ := deriveGroupID(g.GroupKey[:], g.GroupServer) + return g.GroupID == id } // deriveGroupID hashes together the key and the hostname to create a bound identifier that can later // be referenced and checked by profiles when they receive invites and messages. -func deriveGroupID(groupKey []byte, serverHostname string) string { - data, _ := base32.StdEncoding.DecodeString(strings.ToUpper(serverHostname)) +func deriveGroupID(groupKey []byte, serverHostname string) (string, error) { + data, err := base32.StdEncoding.DecodeString(strings.ToUpper(serverHostname)) + if err != nil { + return "", err + } pubkey := data[0:ed25519.PublicKeySize] - return hex.EncodeToString(pbkdf2.Key(groupKey, pubkey, 4096, 16, sha512.New)) + return hex.EncodeToString(pbkdf2.Key(groupKey, pubkey, 4096, 16, sha512.New)), nil } // Invite generates a invitation that can be sent to a cwtch peer @@ -148,7 +153,7 @@ func ValidateInvite(invite string) (*groups.GroupInvite, error) { // Derive the servers public key (we can ignore the error checking here because it's already been // done by IsValidHostname, and check that we derive the same groupID... - derivedGroupID := deriveGroupID(gci.SharedKey, gci.ServerHost) + derivedGroupID, _ := deriveGroupID(gci.SharedKey, gci.ServerHost) if derivedGroupID != gci.GroupID { return nil, errors.New("group id is invalid") } @@ -166,7 +171,9 @@ func ValidateInvite(invite string) (*groups.GroupInvite, error) { // If successful, adds the message to the group's timeline func (g *Group) AttemptDecryption(ciphertext []byte, signature []byte) (bool, *groups.DecryptedGroupMessage) { success, dgm := g.DecryptMessage(ciphertext) - if success { + // the second check here is not needed, but DecryptMessage violates the usual + // go calling convention and we want static analysis tools to pick it up + if success && dgm != nil { // Attempt to serialize this message serialized, err := json.Marshal(dgm) diff --git a/model/group_test.go b/model/group_test.go index 1d90ca6..c2b5fe2 100644 --- a/model/group_test.go +++ b/model/group_test.go @@ -9,7 +9,10 @@ import ( ) func TestGroup(t *testing.T) { - g, _ := NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + g, err := NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + if err != nil { + t.Fatalf("Group with real group server should not fail") + } dgm := &groups.DecryptedGroupMessage{ Onion: "onion", Text: "Hello World!", @@ -37,7 +40,7 @@ func TestGroup(t *testing.T) { encMessage, _ := g.EncryptMessage(dgm) ok, message := g.DecryptMessage(encMessage) - if !ok || message.Text != "Hello World!" { + if (!ok || message == nil) || message.Text != "Hello World!" { t.Errorf("group encryption was invalid, or returned wrong message decrypted:%v message:%v", ok, message) return } @@ -73,7 +76,10 @@ func TestGroupValidation(t *testing.T) { t.Logf("Error: %v", err) // Generate a valid group but replace the group server... - group, _ = NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + group, err = NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + if err != nil { + t.Fatalf("Group with real group server should not fail") + } group.GroupServer = "tcnkoch4nyr3cldkemejtkpqok342rbql6iclnjjs3ndgnjgufzyxvqd" invite, _ = group.Invite() _, err = ValidateInvite(invite) @@ -84,7 +90,10 @@ func TestGroupValidation(t *testing.T) { t.Logf("Error: %v", err) // Generate a valid group but replace the group key... - group, _ = NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + group, err = NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") + if err != nil { + t.Fatalf("Group with real group server should not fail") + } group.GroupKey = sha256.Sum256([]byte{}) invite, _ = group.Invite() _, err = ValidateInvite(invite) diff --git a/model/profile.go b/model/profile.go index acf06e4..2927fed 100644 --- a/model/profile.go +++ b/model/profile.go @@ -80,11 +80,19 @@ func (p *Profile) GetCopy(timeline bool) *Profile { if timeline { for groupID := range newp.Groups { - newp.Groups[groupID].Timeline = *p.Groups[groupID].Timeline.GetCopy() + if group, exists := newp.Groups[groupID]; exists { + if pGroup, exists := p.Groups[groupID]; exists { + group.Timeline = *(pGroup).Timeline.GetCopy() + } + } } for peerID := range newp.Contacts { - newp.Contacts[peerID].Timeline = *p.Contacts[peerID].Timeline.GetCopy() + if peer, exists := newp.Contacts[peerID]; exists { + if pPeer, exists := p.Contacts[peerID]; exists { + peer.Timeline = *(pPeer).Timeline.GetCopy() + } + } } } diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index 185c1a1..3ecc838 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -145,7 +145,7 @@ func (cp *cwtchPeer) EnhancedGetMessageByContentHash(conversation int, contentHa offset, err := cp.GetChannelMessageByContentHash(conversation, 0, contentHash) if err == nil { messages, err := cp.GetMostRecentMessages(conversation, 0, offset, 1) - if err == nil { + if len(messages) > 0 && err == nil { sentTime, _ := time.Parse(time.RFC3339Nano, messages[0].Attr[constants.AttrSentTimestamp]) message.Message = model.Message{ Message: messages[0].Body, @@ -1053,13 +1053,12 @@ func (cp *cwtchPeer) DisconnectFromServer(onion string) { // QueuePeeringWithOnion sends the request to peer with an onion directly to the contact retry queue; this is a mechanism to not flood tor with circuit requests // Status: Ready for 1.10 func (cp *cwtchPeer) QueuePeeringWithOnion(handle string) { - lastSeen := event.CwtchEpoch ci, err := cp.FetchConversationInfo(handle) if err == nil { - lastSeen = cp.GetConversationLastSeenTime(ci.ID) - } - if !ci.ACL[ci.Handle].Blocked && ci.Accepted { - cp.eventBus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: handle, event.LastSeen: lastSeen.Format(time.RFC3339Nano)})) + lastSeen := cp.GetConversationLastSeenTime(ci.ID) + if !ci.ACL[ci.Handle].Blocked && ci.Accepted { + cp.eventBus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: handle, event.LastSeen: lastSeen.Format(time.RFC3339Nano)})) + } } } diff --git a/protocol/files/chunkspec.go b/protocol/files/chunkspec.go index 49725b3..8041da2 100644 --- a/protocol/files/chunkspec.go +++ b/protocol/files/chunkspec.go @@ -13,7 +13,7 @@ type ChunkSpec []uint64 // CreateChunkSpec given a full list of chunks with their downloaded status (true for downloaded, false otherwise) // derives a list of identifiers of chunks that have not been downloaded yet func CreateChunkSpec(progress []bool) ChunkSpec { - var chunks ChunkSpec + chunks := []uint64{} for i, p := range progress { if !p { chunks = append(chunks, uint64(i)) diff --git a/protocol/files/manifest_test.go b/protocol/files/manifest_test.go index b876139..57ae241 100644 --- a/protocol/files/manifest_test.go +++ b/protocol/files/manifest_test.go @@ -93,7 +93,12 @@ func TestManifestLarge(t *testing.T) { } // Prepare Download - cwtchPngOutManifest, _ := LoadManifest("testdata/cwtch.png.manifest") + cwtchPngOutManifest, err := LoadManifest("testdata/cwtch.png.manifest") + + if err != nil { + t.Fatalf("could not prepare download %v", err) + } + cwtchPngOutManifest.FileName = "testdata/cwtch.out.png" defer cwtchPngOutManifest.Close() diff --git a/storage/v1/profile_store.go b/storage/v1/profile_store.go index 98c6802..2c97f77 100644 --- a/storage/v1/profile_store.go +++ b/storage/v1/profile_store.go @@ -67,7 +67,9 @@ func (ps *ProfileStoreV1) load() error { if contact.Attributes[event.SaveHistoryKey] == event.SaveHistoryConfirmed { ss := NewStreamStore(ps.directory, contact.LocalID, ps.key) - cp.Contacts[contact.Onion].Timeline.SetMessages(ss.Read()) + if contact, exists := cp.Contacts[contact.Onion]; exists { + contact.Timeline.SetMessages(ss.Read()) + } } } @@ -78,8 +80,10 @@ func (ps *ProfileStoreV1) load() error { continue } ss := NewStreamStore(ps.directory, group.LocalID, ps.key) - cp.Groups[gid].Timeline.SetMessages(ss.Read()) - cp.Groups[gid].Timeline.Sort() + if group, exists := cp.Groups[gid]; exists { + group.Timeline.SetMessages(ss.Read()) + group.Timeline.Sort() + } } } diff --git a/testing/autodownload/file_sharing_integration_test.go b/testing/autodownload/file_sharing_integration_test.go index 38afeca..f12f80d 100644 --- a/testing/autodownload/file_sharing_integration_test.go +++ b/testing/autodownload/file_sharing_integration_test.go @@ -64,7 +64,6 @@ func TestFileSharing(t *testing.T) { os.MkdirAll(dataDir, 0700) // we don't need real randomness for the port, just to avoid a possible conflict... - mrand.Seed(int64(time.Now().Nanosecond())) socksPort := mrand.Intn(1000) + 9051 controlPort := mrand.Intn(1000) + 9052 @@ -99,7 +98,10 @@ func TestFileSharing(t *testing.T) { app := app2.NewApp(acn, "./storage", app2.LoadAppSettings("./storage")) - usr, _ := user.Current() + usr, err := user.Current() + if err != nil { + t.Fatalf("current user is undefined") + } cwtchDir := path.Join(usr.HomeDir, ".cwtch") os.Mkdir(cwtchDir, 0700) os.RemoveAll(path.Join(cwtchDir, "testing")) diff --git a/testing/cwtch_peer_server_integration_test.go b/testing/cwtch_peer_server_integration_test.go index e3d211f..7b59689 100644 --- a/testing/cwtch_peer_server_integration_test.go +++ b/testing/cwtch_peer_server_integration_test.go @@ -99,7 +99,6 @@ func TestCwtchPeerIntegration(t *testing.T) { os.MkdirAll(dataDir, 0700) // we don't need real randomness for the port, just to avoid a possible conflict... - mrand.Seed(int64(time.Now().Nanosecond())) socksPort := mrand.Intn(1000) + 9051 controlPort := mrand.Intn(1000) + 9052 diff --git a/testing/encryptedstorage/encrypted_storage_integration_test.go b/testing/encryptedstorage/encrypted_storage_integration_test.go index 78b4f2d..8620af6 100644 --- a/testing/encryptedstorage/encrypted_storage_integration_test.go +++ b/testing/encryptedstorage/encrypted_storage_integration_test.go @@ -29,7 +29,6 @@ func TestEncryptedStorage(t *testing.T) { os.MkdirAll(dataDir, 0700) // we don't need real randomness for the port, just to avoid a possible conflict... - mrand.Seed(int64(time.Now().Nanosecond())) socksPort := mrand.Intn(1000) + 9051 controlPort := mrand.Intn(1000) + 9052 @@ -99,6 +98,10 @@ func TestEncryptedStorage(t *testing.T) { ci, err = bob.FetchConversationInfo(alice.GetOnion()) } + if ci == nil { + t.Fatalf("could not fetch bobs conversation") + } + body, _, err := bob.GetChannelMessage(ci.ID, 0, 1) if body != "Hello Bob" || err != nil { t.Fatalf("unexpected message in conversation channel %v %v", body, err) diff --git a/testing/filesharing/file_sharing_integration_test.go b/testing/filesharing/file_sharing_integration_test.go index a6f2eb0..1965deb 100644 --- a/testing/filesharing/file_sharing_integration_test.go +++ b/testing/filesharing/file_sharing_integration_test.go @@ -66,7 +66,6 @@ func TestFileSharing(t *testing.T) { os.MkdirAll(dataDir, 0700) // we don't need real randomness for the port, just to avoid a possible conflict... - mrand.Seed(int64(time.Now().Nanosecond())) socksPort := mrand.Intn(1000) + 9051 controlPort := mrand.Intn(1000) + 9052 @@ -101,7 +100,10 @@ func TestFileSharing(t *testing.T) { app := app2.NewApp(acn, "./storage", app2.LoadAppSettings("./storage")) - usr, _ := user.Current() + usr, err := user.Current() + if err != nil { + t.Fatalf("current user is undefined") + } cwtchDir := path.Join(usr.HomeDir, ".cwtch") os.Mkdir(cwtchDir, 0700) os.RemoveAll(path.Join(cwtchDir, "testing")) @@ -124,9 +126,17 @@ func TestFileSharing(t *testing.T) { bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.NewRetValMessageFromPeer}) aliceQueueOracle := event.NewQueue() - app.GetEventBus(alice.GetOnion()).Subscribe(event.SearchResult, aliceQueueOracle) + aliceEb := app.GetEventBus(alice.GetOnion()) + if aliceEb == nil { + t.Fatalf("alice's eventbus is undefined") + } + aliceEb.Subscribe(event.SearchResult, aliceQueueOracle) queueOracle := event.NewQueue() - app.GetEventBus(bob.GetOnion()).Subscribe(event.FileDownloaded, queueOracle) + bobEb := app.GetEventBus(bob.GetOnion()) + if bobEb == nil { + t.Fatalf("bob's eventbus is undefined") + } + bobEb.Subscribe(event.FileDownloaded, queueOracle) // Turn on File Sharing Experiment... settings := app.ReadSettings() diff --git a/testing/quality.sh b/testing/quality.sh index c0bb82b..0827cb5 100755 --- a/testing/quality.sh +++ b/testing/quality.sh @@ -8,6 +8,12 @@ echo "Linting:" staticcheck ./... +# In the future we should enable this by default. However, there are a few false positives that make this +# too noisy right now, specifically assigning nil to initialize slices (safe), and using go internal context channels assigned +# nil (also safe). +# We also have one file infinite_channel.go written in a way that static analysis cannot reason about easily. So it is explictly +# ignored. +# nilaway -exclude-file-docstrings="nolint:nilaway" ./... echo "Time to format" gofmt -l -s -w . diff --git a/tools/cwtch_tools.go b/tools/cwtch_tools.go index de94f05..1088be4 100644 --- a/tools/cwtch_tools.go +++ b/tools/cwtch_tools.go @@ -18,7 +18,6 @@ import ( "os" path "path/filepath" "strings" - "time" ) var tool = flag.String("tool", "", "the tool to use") @@ -86,7 +85,6 @@ func getTokens(bundle string) { os.MkdirAll(dataDir, 0700) // we don't need real randomness for the port, just to avoid a possible conflict... - mrand.Seed(int64(time.Now().Nanosecond())) socksPort := mrand.Intn(1000) + 9051 controlPort := mrand.Intn(1000) + 9052 diff --git a/utils/timeoutpolicy.go b/utils/timeoutpolicy.go index d0c8fbc..e4b7469 100644 --- a/utils/timeoutpolicy.go +++ b/utils/timeoutpolicy.go @@ -1,3 +1,4 @@ +// nolint:nilaway - the context timeout here is reported as an error, even though it is a by-the-doc example package utils import (