diff --git a/.gitignore b/.gitignore index 1348703249512ef3a56de1dada944640e8269c15..30f29f0e733db9a0ae86702d463517e7be394e29 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,3 @@ localdev_* *.class *.aar *.jar -# Ignore genered version file -cmd/version_vars.go diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ed10c896c25c4df7300a9b73a053068f4bf44929..3c1912c63e8f0725b3eb21eb6820e6b493a04efa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -83,13 +83,11 @@ build: - tags script: - mkdir -p release - - go generate cmd/version.go - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' ./... - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.linux64 main.go - GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.win64 main.go - GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.win32 main.go - GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.darwin64 main.go - - release/client.linux64 --version artifacts: paths: - release/ @@ -101,26 +99,29 @@ tag: image: $DOCKER_IMAGE script: - git remote add origin_tags git@gitlab.com:elixxir/client.git || true - - git tag $(release/client.linux64 -V | grep "Elixxir Client v"| cut -d ' ' -f3) -f + - git tag $(release/client.linux64 version | grep "Elixxir Client v"| cut -d ' ' -f3) -f - git push origin_tags -f --tags -#bindings: -# stage: build -# except: -# - tags -# tags: -# - ios -# script: -# - GO111MODULE=off go get golang.org/x/mobile/cmd/gomobile -# - GO111MODULE=off go get gitlab.com/elixxir/client -# - GO111MODULE=off gomobile bind -target android -androidapi 21 gitlab.com/elixxir/client/bindings -# - GO111MODULE=off gomobile bind -target ios gitlab.com/elixxir/client/bindings -# - zip -r iOS.zip Bindings.framework -# artifacts: -# paths: -# - iOS.zip -# - bindings.aar -# - bindings-sources.jar +bindings: + stage: build + except: + - tags + tags: + - ios + script: + - go get -u golang.org/x/mobile/cmd/gomobile + - go get -u golang.org/x/mobile/bind + - rm -rf $HOME/go/src/gitlab.com/elixxir/client/ + - mkdir -p $HOME/go/src/gitlab.com/elixxir/client/ + - cp -r * $HOME/go/src/gitlab.com/elixxir/client/ + - GO111MODULE=off gomobile bind -target android -androidapi 21 gitlab.com/elixxir/client/bindings + - GO111MODULE=off gomobile bind -target ios gitlab.com/elixxir/client/bindings + - zip -r iOS.zip Bindings.framework + artifacts: + paths: + - iOS.zip + - bindings.aar + - bindings-sources.jar trigger_integration: stage: trigger_integration diff --git a/api/client.go b/api/client.go index 416c6e0feba27ae902fca569ebf15cf86d2cd8a2..9506b4ab6a9dbabc610b3c2b29b01df8d3995375 100644 --- a/api/client.go +++ b/api/client.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// @@ -15,7 +15,6 @@ import ( "fmt" "github.com/golang/protobuf/proto" "github.com/pkg/errors" - jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/bots" "gitlab.com/elixxir/client/cmixproto" "gitlab.com/elixxir/client/globals" @@ -74,7 +73,7 @@ func NewTestClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDef case *testing.B: break default: - jww.FATAL.Panicf("GenerateId is restricted to testing only. Got %T", i) + globals.Log.FATAL.Panicf("GenerateId is restricted to testing only. Got %T", i) } return newClient(s, locA, locB, ndfJSON, sendFunc) } @@ -103,7 +102,10 @@ func newClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit cl := new(Client) cl.storage = store - cl.receptionManager = io.NewReceptionManager(cl.rekeyChan) + cl.receptionManager, err = io.NewReceptionManager(cl.rekeyChan, "client", nil, nil, nil) + if err != nil { + return nil, errors.Wrap(err, "Failed to create reception manager") + } cl.ndf = ndfJSON cl.sendFunc = sendFunc @@ -160,27 +162,41 @@ func (cl *Client) Login(password string) (*id.User, error) { } cl.session = session + newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User.String(), + rsa.CreatePrivateKeyPem(cl.session.GetRSAPrivateKey()), + rsa.CreatePublicKeyPem(cl.session.GetRSAPublicKey()), + cl.session.GetSalt()) + if err != nil { + return nil, errors.Wrap(err, "Failed to create new reception manager") + } + newRm.Comms.Manager = cl.receptionManager.Comms.Manager + cl.receptionManager = newRm return cl.session.GetCurrentUser().User, nil } -// Logout closes the connection to the server at this time and does +// Logout closes the connection to the server and the messageReceiver and clears out the client values, +// so we can effectively shut everything down. at this time it does // nothing with the user id. In the future this will release resources -// and safely release any sensitive memory. -// fixme: blocks forever is message reciever -func (cl *Client) Logout() error { +// and safely release any sensitive memory. Recommended time out is 500ms. +func (cl *Client) Logout(timeoutDuration time.Duration) error { if cl.session == nil { err := errors.New("Logout: Cannot Logout when you are not logged in") globals.Log.ERROR.Printf(err.Error()) return err } - // Stop reception runner goroutine - close(cl.session.GetQuitChan()) - - cl.receptionManager.Comms.DisconnectAll() + // Here using a select statement and the fact that making cl.sess.GetQuitChan is blocking, we can detect when + // killing the reception manager is taking too long and we use the time out to stop the attempt and return an error. + timer := time.NewTimer(timeoutDuration) + select { + case cl.session.GetQuitChan() <- struct{}{}: + cl.receptionManager.Comms.DisconnectAll() + case <-timer.C: + return errors.Errorf("Message receiver shut down timed out after %s ms", timeoutDuration) + } + // Store the user session files before logging out errStore := cl.session.StoreSession() - if errStore != nil { err := errors.New(fmt.Sprintf("Logout: Store Failed: %s" + errStore.Error())) @@ -188,9 +204,9 @@ func (cl *Client) Logout() error { return err } + // Clear all keys from ram errImmolate := cl.session.Immolate() cl.session = nil - if errImmolate != nil { err := errors.New(fmt.Sprintf("Logout: Immolation Failed: %s" + errImmolate.Error())) @@ -198,6 +214,12 @@ func (cl *Client) Logout() error { return err } + // Here we clear away all state in the client struct that should not be persistent + cl.session = nil + cl.receptionManager = nil + cl.topology = nil + cl.registrationVersion = "" + return nil } diff --git a/api/client_test.go b/api/client_test.go index 4d78c2eae293c540d3a5cb21fed4a45e1d95bc1b..c16790f352b0ba237b55f4e1d8ee2a708a320aab 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -559,5 +559,194 @@ func TestClient_GetCommManager(t *testing.T) { if !reflect.DeepEqual(testClient.GetCommManager(), testClient.receptionManager) { t.Error("Received session not the same as the real session") } +} + +// Test that client.Shutcown clears out all the expected variables and stops the message reciever. +func TestClient_LogoutHappyPath(t *testing.T) { + //Initialize a client + d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} + tc, _ := NewClient(&d, "", "", def) + + tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil) + + err := tc.InitNetwork() + if err != nil { + t.Errorf("Could not connect: %+v", err) + } + + err = tc.GenerateKeys(nil, "") + if err != nil { + t.Errorf("Could not generate Keys: %+v", err) + } + + //Start Message reciever + callBack := func(err error) { + t.Log(err) + } + + err = tc.StartMessageReceiver(callBack) + if err != nil { + t.Logf("Failed to start message reciever %+v", err) + t.Fail() + } + + //Introduce a delay to allow things to startup and run + time.Sleep(1 * time.Second) + + err = tc.Logout(500 * time.Millisecond) + if err != nil { + t.Logf("Timeout occured failed to shutdown %+v", err) + t.Fail() + } + //Check everything that should be nil is nil + if tc.session != nil { + t.Logf("Session should be set to nil on shutdown") + t.Fail() + } + if tc.registrationVersion != "" { + t.Logf("RegistrationVerison should be set to empty string on shutdown") + t.Fail() + } + if tc.receptionManager != nil { + t.Logf("ReceptionManager should be set to nil on shutdown") + t.Fail() + } + if tc.topology != nil { + t.Logf("Topology should be set to nil on shutdown") + t.Fail() + } + + + //Test that the things that should not be nil are not nil + if tc.ndf == nil { + t.Logf("NDF should not be set to nil") + t.Fail() + } + if tc.storage == nil { + t.Logf("Storage should not be set to nil") + t.Fail() + } + if tc.opStatus == nil { + t.Logf("OPstatus should not be set to nil on shutdown") + t.Fail() + } + if tc.rekeyChan == nil { + t.Logf("rekeyChan should not be set to nil on shutdown") + t.Fail() + } } + +//Test that the client shutdown will timeout when it fails to shutdown +func TestClient_LogoutTimeout(t *testing.T) { + //Initialize a client + d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} + tc, _ := NewClient(&d, "", "", def) + + tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil) + + err := tc.InitNetwork() + if err != nil { + t.Errorf("Could not connect: %+v", err) + } + + err = tc.GenerateKeys(nil, "") + if err != nil { + t.Errorf("Could not generate Keys: %+v", err) + } + + // Because we never initiated startMessageReceiver this should timeout. + err = tc.Logout(500 * time.Millisecond) + if err == nil { + t.Logf("Timeout out should have occured") + t.Fail() + } + + //Check everything that should be nil is nil + if tc.session == nil { + t.Logf("Session should not be set to nil on shutdown timeout") + t.Fail() + } + if tc.registrationVersion == "" { + t.Logf("RegistrationVerison should not be set to empty string on shutdown timeout") + t.Fail() + } + if tc.receptionManager == nil { + t.Logf("ReceptionManager should not be set to nil on shutdown timeout") + t.Fail() + } + if tc.topology == nil { + t.Logf("Topology should not be set to nil on shutdown timeout") + t.Fail() + } + if tc.opStatus == nil { + t.Logf("OPstatus should not be set to nil on shutdown timeout") + t.Fail() + } + if tc.rekeyChan == nil { + t.Logf("rekeyChan should not be set to nil on shutdown timeout") + t.Fail() + } + + //Test that the things that should not be nil are not nil + if tc.ndf == nil { + t.Logf("NDF should not be set to nil on shutdown timeout") + t.Fail() + } + if tc.storage == nil { + t.Logf("Storage should not be set to nil on shutdown timeout") + t.Fail() + } + +} + +// Test that if we logout we can logback in. +func TestClient_LogoutAndLoginAgain(t *testing.T){ + //Initialize a client + storage := globals.RamStorage{} + tc, initialId := NewClient(&storage, "", "", def) + + tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil) + + err := tc.InitNetwork() + if err != nil { + t.Errorf("Could not connect: %+v", err) + } + + err = tc.GenerateKeys(nil, "") + if err != nil { + t.Errorf("Could not generate Keys: %+v", err) + } + + //Start Message receiver + callBack := func(err error) { + t.Log(err) + } + + err = tc.StartMessageReceiver(callBack) + if err != nil { + t.Logf("Failed to start message reciever %+v", err) + t.Fail() + } + + // Because we never initiated startMessageReceiver this should timeout. + err = tc.Logout(500 * time.Millisecond) + if err != nil { + t.Logf("Timeout out should have not occured. %+v", err) + t.Fail() + } + + //Redefine client with old session files and attempt to login. + tc, newId := NewClient(&storage, "", "", def) + _, err = tc.Login("") + if err != nil{ + t.Logf("Login failed %+v", err) + t.Fail() + } + + if newId != initialId{ + t.Logf("Failed to log user back in to original session") + t.Fail() + } + +} \ No newline at end of file diff --git a/api/connect.go b/api/connect.go index d371dcb84065258c4539ebe248c9aefe6053e879..abd064fd7560a8d9c6ba06512a33763b4a908bd1 100644 --- a/api/connect.go +++ b/api/connect.go @@ -22,7 +22,7 @@ var ErrNoPermissioning = errors.New("No Permissioning In NDF") // credential information for connection establishment func (cl *Client) InitNetwork() error { //InitNetwork to permissioning - err := AddPermissioningHost(cl.receptionManager, cl.ndf) + err := addPermissioningHost(cl.receptionManager, cl.ndf) if err != nil { if err != ErrNoPermissioning { @@ -43,15 +43,39 @@ func (cl *Client) InitNetwork() error { } } + // InitNetwork to nodes + cl.topology = BuildNodeTopology(cl.ndf) + + err = addNotificationBotHost(cl.receptionManager, cl.ndf) + if err != nil { + return errors.Errorf("Failed to connect to notification bot at %+v", cl.ndf) + } + + return addGatewayHosts(cl.receptionManager, cl.ndf) +} + +// AddNotificationBotHost adds notification bot as a host within the reception manager +func addNotificationBotHost(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error { + + err := addHost(rm, id.NOTIFICATION_BOT, definition.Notification.Address, + definition.Notification.TlsCertificate, false, true) + if err != nil { + return errors.Errorf("Failed to connect to notification bot at %+v", + definition.Notification.Address) + } + return nil +} + +// BuildNodeTopology is a helper function which goes through the ndf and +// builds a circuit for all the node's in the definition +func BuildNodeTopology(definition *ndf.NetworkDefinition) *connect.Circuit { //build the topology - nodeIDs := make([]*id.Node, len(cl.ndf.Nodes)) - for i, node := range cl.ndf.Nodes { + nodeIDs := make([]*id.Node, len(definition.Nodes)) + for i, node := range definition.Nodes { nodeIDs[i] = id.NewNodeFromBytes(node.ID) } - cl.topology = connect.NewCircuit(nodeIDs) - - return AddGatewayHosts(cl.receptionManager, cl.ndf) + return connect.NewCircuit(nodeIDs) } // DisableTls disables tls for communications @@ -72,7 +96,7 @@ func (cl *Client) setupPermissioning() error { cl.registrationVersion = ver //Request a new ndf from permissioning - def, err = io.PollNdf(cl.ndf, cl.receptionManager.Comms) + def, err = cl.receptionManager.Comms.RetrieveNdf(cl.ndf) if err != nil { return err } @@ -80,7 +104,6 @@ func (cl *Client) setupPermissioning() error { cl.ndf = def } - globals.Log.DEBUG.Printf("Local version: %v; Remote version: %v", globals.SEMVER, cl.GetRegistrationVersion()) @@ -108,7 +131,7 @@ func (cl *Client) setupPermissioning() error { // Connects to gateways using tls filepaths to create credential information // for connection establishment -func AddGatewayHosts(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error { +func addGatewayHosts(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error { if len(definition.Gateways) < 1 { return errors.New("could not connect due to invalid number of nodes") } @@ -146,7 +169,7 @@ func addHost(rm *io.ReceptionManager, id, address, cert string, disableTimeout, // There's currently no need to keep connected to permissioning constantly, // so we have functions to connect to and disconnect from it when a connection // to permissioning is needed -func AddPermissioningHost(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error { +func addPermissioningHost(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error { if definition.Registration.Address != "" { err := addHost(rm, PermissioningAddrID, definition.Registration.Address, definition.Registration.TlsCertificate, false, false) diff --git a/api/mockserver.go b/api/mockserver.go index 948980e4139764802b9b8ace5e6c506d6ed4b76c..24a6b600bcc161a5bbbd821dae6dc884d1138eac 100644 --- a/api/mockserver.go +++ b/api/mockserver.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// @@ -31,6 +31,8 @@ var def *ndf.NetworkDefinition const InvalidClientVersion = "1.1.0" const BatchSize = 10 +// ---------------------------------------- MOCK MESSAGE -------------------------------------------------- + // APIMessage are an implementation of the interface in bindings and API // easy to use from Go type APIMessage struct { @@ -71,164 +73,7 @@ func (m APIMessage) Pack() []byte { return m.Payload } -// Blank struct implementing ServerHandler interface for testing purposes (Passing to StartServer) -type GatewayHandler struct { - LastReceivedMessage pb.Slot -} - -// Returns message contents for MessageID, or a null/randomized message -// if that ID does not exist of the same size as a regular message -func (m *GatewayHandler) GetMessage(userId *id.User, - msgId, ipaddr string) (*pb.Slot, error) { - return &pb.Slot{}, nil -} - -// Return any MessageIDs in the globals for this User -func (m *GatewayHandler) CheckMessages(userId *id.User, - messageID, ipAddress string) ([]string, error) { - return make([]string, 0), nil -} - -// PutMessage adds a message to the outgoing queue and -// calls SendBatch when it's size is the batch size -func (m *GatewayHandler) PutMessage(msg *pb.Slot, ipaddr string) error { - m.LastReceivedMessage = *msg - return nil -} - -func (m *GatewayHandler) ConfirmNonce(message *pb.RequestRegistrationConfirmation, ipaddr string) (*pb.RegistrationConfirmation, error) { - regConfirmation := &pb.RegistrationConfirmation{ - ClientSignedByServer: &pb.RSASignature{}, - } - - return regConfirmation, nil -} - -// Pass-through for Registration Nonce Communication -func (m *GatewayHandler) RequestNonce(message *pb.NonceRequest, ipaddr string) (*pb.Nonce, error) { - dh := getDHPubKey().Bytes() - return &pb.Nonce{ - DHPubKey: dh, - }, nil -} - -//Blank struct that has an error path f -type GatewayHandlerMultipleMessages struct { - LastReceivedMessage []pb.Slot -} - -func (m *GatewayHandlerMultipleMessages) GetMessage(userId *id.User, - msgId, ipaddr string) (*pb.Slot, error) { - msg := []byte("Hello") - payload, err := e2e.Pad(msg, format.PayloadLen) - if err != nil { - fmt.Println("hello!") - } - return &pb.Slot{ - PayloadA: payload, - PayloadB: payload, - }, nil -} - -// Return any MessageIDs in the globals for this User -func (m *GatewayHandlerMultipleMessages) CheckMessages(userId *id.User, - messageID, ipaddr string) ([]string, error) { - msgs := []string{"a", "b", "c", "d", "e", "f", "g"} - return msgs, nil -} - -// PutMessage adds a message to the outgoing queue and -// calls SendBatch when it's size is the batch size -func (m *GatewayHandlerMultipleMessages) PutMessage(msg *pb.Slot, ipaddr string) error { - for i := 0; i < BatchSize; i++ { - msg.Index = uint32(i) - m.LastReceivedMessage = append(m.LastReceivedMessage, *msg) - } - return nil -} - -func (m *GatewayHandlerMultipleMessages) ConfirmNonce(message *pb.RequestRegistrationConfirmation, ipaddr string) (*pb.RegistrationConfirmation, error) { - return nil, nil -} - -// Pass-through for Registration Nonce Communication -func (m *GatewayHandlerMultipleMessages) RequestNonce(message *pb.NonceRequest, ipaddr string) (*pb.Nonce, error) { - return nil, nil -} - -// Blank struct implementing Registration Handler interface for testing purposes (Passing to StartServer) -type MockRegistration struct { - //LastReceivedMessage pb.CmixMessage -} - -func (s *MockRegistration) RegisterNode(ID []byte, - NodeTLSCert, GatewayTLSCert, RegistrationCode, Addr, Addr2 string) error { - return nil -} - -func (s *MockRegistration) PollNdf(clientNdfHash []byte, auth *connect.Auth) ([]byte, error) { - - ndfData := def - - ndfJson, _ := json.Marshal(ndfData) - return ndfJson, nil -} - -func buildMockNDF() ndf.NetworkDefinition { - - ExampleJSON := `{"Timestamp":"2019-06-04T20:48:48-07:00","gateways":[{"Address":"0.0.0.0:7900","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7901","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7902","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"}],"nodes":[{"Id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAERwUmUlL9YP\nq6MSn+bUr6qNZPsVYoQAo8nTjZWiuSjJa2XWnh7sftnISWkwkiiRxo7qfq3sAiD5\nB8+tM6kONeICBXukldXJerxoVBspYa+RiPuDWy2pwGRDBpfty3QqJOpu5g2ThYFJ\nD5Xu0yCuX8ZJRj33nliI8dQgKdQQva6p2VuXzyRT8LwXMfRwLuSB6Schc9mF8C\nkWCb4m0ujlEKe1xKoKt2zG9b1o7XyaVhxguSUAuEznifMzsEUfuONJOy+XoQELex\nF0wvLzNzABcyxkM3lx52uG41mKgJiV6Z0ZyuBRvt+V3VL/38tPn9lsTaFi8N6/IH\nRyy0bWP5s44=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5900","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAFbADcqA8KQh\nxzgylW6VS1dYYelO5DjPZVVSjfdcbj1twu4ZHDNZLOexpv4nGY8xS6vesELXcVOR\n/CHXgh/3byBZYm0zkrBi/FsJJ3nP2uZ1+QCRldI2KzqcLOWH/CAYj8koork9k1Dp\nFq7rMSDgw4pktqvFj9Eev8dSZuRnoCfZbt/6vxi1r30AYAjDYOwcysqcVyUa1tPa\nLEh3JksttXUCd5cvfqatWedTs5Vxo7ICW1toGBHABYvSJkwK0YFfi5RLw+Oda1sA\njJ+aLcIxQjrpoRC2alXCdwmZXVb+O6zluQctw6LJjt4J704ueSvR4VNNhr0uLYGW\nk7e+WoQCS98=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5901","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNTCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAQCN19tTnkS3\nitBQXXR/h8OKl+rliFBLgO6h6GvZL4yQDZFtBAOmkrs3wLoDroJRGCeqz/IUb+JF\njslEr/mpm2kcmK77hr535dq7HsWz1fFl9YyGTaOH055FLSV9QEPAV9j3zWADdQ1v\nuSQll+QfWi6lIibWV4HNQ2ywRFoOY8OBLCJB90UXLeJpaPanpqiM8hjda2VGRDbi\nIixEE2lCOWITydiz2DmvXrLhVGF49+g5MDwbWO65dmasCe//Ff6Z4bJ6n049xv\nVtac8nX6FO3eBsV5d+rG6HZXSG3brCKRCSKYCTX1IkTSiutYxYqvwaluoCjOakh0\nKkqvQ8IeVZ+B\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5902","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"}],"registration":{"Address":"0.0.0.0:5000","Tls_certificate":""},"udb":{"Id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBACvR2lUslz3D\nB/MUo0rHVIHVkhVJCxNjtgTOYgJ9ckArSXQbYzr/fcigcNGjUO2LbK5NFp9GK43C\nrLxMUnJ9nkyIVPaWvquJFZItjcDK3NiNGyD4XyM0eRj4dYeSxQM48hvFbmtbjlXn\n9SQTnGIlr1XnTI4RVHZSQOL6kFJIaLw6wYrQ4w08Ng+p45brp5ercAHnLiftNUWP\nqROhQkdSEpS9LEwfotUSY1jP2AhQfaIMxaeXsZuTU1IYvdhMFRL3DR0r5Ww2Upf8\ng0Ace0mtnsUQ2OG+7MTh2jYIEWRjvuoe3RCz603ujW6g7BfQ1H7f4YFwc5xOOJ3u\nr4dj49dCCjc=\n-----END PUBLIC KEY-----\n"},"E2e":{"Prime":"E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873847AEF49F66E43873","Small_prime":"02","Generator":"02"},"CMIX":{"Prime":"9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B","Small_prime":"F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F","Generator":"5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7"}}` - retNDF, _, _ := ndf.DecodeNDF(ExampleJSON) - /* - var grp ndf.Group - grp.Prime = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + - "15728E5A8AACAA68FFFFFFFFFFFFFFFF" - grp.Generator = "2" - grp.SmallPrime = "2" - retNDF := ndf.NetworkDefinition{Timestamp: time.Now(), Registration: reg, Nodes: Nodes, CMIX: grp, E2E: grp}*/ - return *retNDF -} - -// Registers a user and returns a signed public key -func (s *MockRegistration) RegisterUser(registrationCode, - key string) (hash []byte, err error) { - return nil, nil -} - -func (s *MockRegistration) GetCurrentClientVersion() (version string, err error) { - return globals.SEMVER, nil -} - -func getDHPubKey() *cyclic.Int { - cmixGrp := cyclic.NewGroup( - large.NewIntFromString("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"+ - "C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"+ - "FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"+ - "B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"+ - "35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"+ - "F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"+ - "92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"+ - "3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B", 16), - large.NewIntFromString("5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"+ - "D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"+ - "6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"+ - "085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"+ - "AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"+ - "3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"+ - "BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"+ - "DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7", 16)) - - dh := cmixGrp.RandomCoprime(cmixGrp.NewMaxInt()) - return cmixGrp.ExpG(dh, cmixGrp.NewMaxInt()) -} +// -------------------------------------- MOCK DUMMY STORAGE --------------------------------------- // Mock dummy storage interface for testing. type DummyStorage struct { @@ -290,26 +135,54 @@ func (d *DummyReceiver) Receive(message APIMessage) { d.LastMessage = message } +// --------------------------------- MOCK REGISTRATION SERVER ------------------------------------------------ +// Blank struct implementing Registration Handler interface for testing purposes (Passing to StartServer) +type MockRegistration struct { + //LastReceivedMessage pb.CmixMessage +} + +func (s *MockRegistration) RegisterNode(ID []byte, + NodeTLSCert, GatewayTLSCert, RegistrationCode, Addr, Addr2 string) error { + return nil +} + +func (s *MockRegistration) PollNdf(clientNdfHash []byte, auth *connect.Auth) ([]byte, error) { + + ndfData := def + ndfJson, _ := json.Marshal(ndfData) + return ndfJson, nil +} + +// Registers a user and returns a signed public key +func (s *MockRegistration) RegisterUser(registrationCode, + key string) (hash []byte, err error) { + return nil, nil +} + +func (s *MockRegistration) GetCurrentClientVersion() (version string, err error) { + return globals.SEMVER, nil +} + //registration handler for getUpdatedNDF error case -type MockPerm_NDF_ErrorCase struct { +type MockPermNdfErrorCase struct { } -func (s *MockPerm_NDF_ErrorCase) RegisterNode(ID []byte, +func (s *MockPermNdfErrorCase) RegisterNode(ID []byte, NodeTLSCert, GatewayTLSCert, RegistrationCode, Addr, Addr2 string) error { return nil } -func (s *MockPerm_NDF_ErrorCase) PollNdf(clientNdfHash []byte) ([]byte, error) { +func (s *MockPermNdfErrorCase) PollNdf(clientNdfHash []byte) ([]byte, error) { errMsg := fmt.Sprintf("Permissioning server does not have an ndf to give to client") return nil, errors.New(errMsg) } -func (s *MockPerm_NDF_ErrorCase) RegisterUser(registrationCode, +func (s *MockPermNdfErrorCase) RegisterUser(registrationCode, key string) (hash []byte, err error) { return nil, nil } -func (s *MockPerm_NDF_ErrorCase) GetCurrentClientVersion() (version string, err error) { +func (s *MockPermNdfErrorCase) GetCurrentClientVersion() (version string, err error) { return globals.SEMVER, nil } @@ -335,25 +208,180 @@ func (s *MockpermCheckversionErrorcase) GetCurrentClientVersion() (version strin } //Registration handler for handling a bad client version (aka client is not up to date) -type MockPerm_CheckVersion_BadVersion struct { +type MockPermCheckversionBadversion struct { } -func (s *MockPerm_CheckVersion_BadVersion) RegisterNode(ID []byte, +func (s *MockPermCheckversionBadversion) RegisterNode(ID []byte, NodeTLSCert, GatewayTLSCert, RegistrationCode, Addr, Addr2 string) error { return nil } -func (s *MockPerm_CheckVersion_BadVersion) GetUpdatedNDF(clientNdfHash []byte) ([]byte, error) { +func (s *MockPermCheckversionBadversion) GetUpdatedNDF(clientNdfHash []byte) ([]byte, error) { ndfData := buildMockNDF() ndfJson, _ := json.Marshal(ndfData) return ndfJson, nil } -func (s *MockPerm_CheckVersion_BadVersion) RegisterUser(registrationCode, +func (s *MockPermCheckversionBadversion) RegisterUser(registrationCode, key string) (hash []byte, err error) { return nil, nil } -func (s *MockPerm_CheckVersion_BadVersion) GetCurrentClientVersion() (version string, err error) { +func (s *MockPermCheckversionBadversion) GetCurrentClientVersion() (version string, err error) { return InvalidClientVersion, nil } + +func buildMockNDF() ndf.NetworkDefinition { + + ExampleJSON := `{"Timestamp":"2019-06-04T20:48:48-07:00","gateways":[{"Address":"0.0.0.0:7900","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7901","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7902","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"}],"nodes":[{"Id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAERwUmUlL9YP\nq6MSn+bUr6qNZPsVYoQAo8nTjZWiuSjJa2XWnh7sftnISWkwkiiRxo7qfq3sAiD5\nB8+tM6kONeICBXukldXJerxoVBspYa+RiPuDWy2pwGRDBpfty3QqJOpu5g2ThYFJ\nD5Xu0yCuX8ZJRj33nliI8dQgKdQQva6p2VuXzyRT8LwXMfRwLuSB6Schc9mF8C\nkWCb4m0ujlEKe1xKoKt2zG9b1o7XyaVhxguSUAuEznifMzsEUfuONJOy+XoQELex\nF0wvLzNzABcyxkM3lx52uG41mKgJiV6Z0ZyuBRvt+V3VL/38tPn9lsTaFi8N6/IH\nRyy0bWP5s44=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5900","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAFbADcqA8KQh\nxzgylW6VS1dYYelO5DjPZVVSjfdcbj1twu4ZHDNZLOexpv4nGY8xS6vesELXcVOR\n/CHXgh/3byBZYm0zkrBi/FsJJ3nP2uZ1+QCRldI2KzqcLOWH/CAYj8koork9k1Dp\nFq7rMSDgw4pktqvFj9Eev8dSZuRnoCfZbt/6vxi1r30AYAjDYOwcysqcVyUa1tPa\nLEh3JksttXUCd5cvfqatWedTs5Vxo7ICW1toGBHABYvSJkwK0YFfi5RLw+Oda1sA\njJ+aLcIxQjrpoRC2alXCdwmZXVb+O6zluQctw6LJjt4J704ueSvR4VNNhr0uLYGW\nk7e+WoQCS98=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5901","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNTCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAQCN19tTnkS3\nitBQXXR/h8OKl+rliFBLgO6h6GvZL4yQDZFtBAOmkrs3wLoDroJRGCeqz/IUb+JF\njslEr/mpm2kcmK77hr535dq7HsWz1fFl9YyGTaOH055FLSV9QEPAV9j3zWADdQ1v\nuSQll+QfWi6lIibWV4HNQ2ywRFoOY8OBLCJB90UXLeJpaPanpqiM8hjda2VGRDbi\nIixEE2lCOWITydiz2DmvXrLhVGF49+g5MDwbWO65dmasCe//Ff6Z4bJ6n049xv\nVtac8nX6FO3eBsV5d+rG6HZXSG3brCKRCSKYCTX1IkTSiutYxYqvwaluoCjOakh0\nKkqvQ8IeVZ+B\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5902","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"}],"registration":{"Address":"0.0.0.0:5000","Tls_certificate":""},"udb":{"Id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBACvR2lUslz3D\nB/MUo0rHVIHVkhVJCxNjtgTOYgJ9ckArSXQbYzr/fcigcNGjUO2LbK5NFp9GK43C\nrLxMUnJ9nkyIVPaWvquJFZItjcDK3NiNGyD4XyM0eRj4dYeSxQM48hvFbmtbjlXn\n9SQTnGIlr1XnTI4RVHZSQOL6kFJIaLw6wYrQ4w08Ng+p45brp5ercAHnLiftNUWP\nqROhQkdSEpS9LEwfotUSY1jP2AhQfaIMxaeXsZuTU1IYvdhMFRL3DR0r5Ww2Upf8\ng0Ace0mtnsUQ2OG+7MTh2jYIEWRjvuoe3RCz603ujW6g7BfQ1H7f4YFwc5xOOJ3u\nr4dj49dCCjc=\n-----END PUBLIC KEY-----\n"},"E2e":{"Prime":"E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873847AEF49F66E43873","Small_prime":"02","Generator":"02"},"CMIX":{"Prime":"9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B","Small_prime":"F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F","Generator":"5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7"}}` + retNDF, _, _ := ndf.DecodeNDF(ExampleJSON) + /* + var grp ndf.Group + grp.Prime = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" + grp.Generator = "2" + grp.SmallPrime = "2" + retNDF := ndf.NetworkDefinition{Timestamp: time.Now(), Registration: reg, Nodes: Nodes, CMIX: grp, E2E: grp}*/ + return *retNDF +} + +// ------------------------------------ MOCK GATEWAYS ---------------------------------------------------------------- + +// Blank struct implementing ServerHandler interface for testing purposes (Passing to StartServer) +type GatewayHandler struct { + LastReceivedMessage pb.Slot +} + +func (m *GatewayHandler) PollForNotifications(auth *connect.Auth) ([]string, error) { + + return nil, nil +} + +// Returns message contents for MessageID, or a null/randomized message +// if that ID does not exist of the same size as a regular message +func (m *GatewayHandler) GetMessage(userId *id.User, + msgId, ipaddr string) (*pb.Slot, error) { + return &pb.Slot{}, nil +} + +// Return any MessageIDs in the globals for this User +func (m *GatewayHandler) CheckMessages(userId *id.User, + messageID, ipAddress string) ([]string, error) { + return make([]string, 0), nil +} + +// PutMessage adds a message to the outgoing queue and +// calls SendBatch when it's size is the batch size +func (m *GatewayHandler) PutMessage(msg *pb.Slot, ipaddr string) error { + m.LastReceivedMessage = *msg + return nil +} + +func (m *GatewayHandler) ConfirmNonce(message *pb.RequestRegistrationConfirmation, ipaddr string) (*pb.RegistrationConfirmation, error) { + regConfirmation := &pb.RegistrationConfirmation{ + ClientSignedByServer: &pb.RSASignature{}, + } + + return regConfirmation, nil +} + +// Pass-through for Registration Nonce Communication +func (m *GatewayHandler) RequestNonce(message *pb.NonceRequest, ipaddr string) (*pb.Nonce, error) { + dh := getDHPubKey().Bytes() + return &pb.Nonce{ + DHPubKey: dh, + }, nil +} + +//Blank struct that has an error path f +type GatewayHandlerMultipleMessages struct { + LastReceivedMessage []pb.Slot +} + +func (m *GatewayHandlerMultipleMessages) GetMessage(userId *id.User, + msgId, ipaddr string) (*pb.Slot, error) { + msg := []byte("Hello") + payload, err := e2e.Pad(msg, format.PayloadLen) + if err != nil { + fmt.Println("hello!") + } + return &pb.Slot{ + PayloadA: payload, + PayloadB: payload, + }, nil +} + +func (m *GatewayHandlerMultipleMessages) PollForNotifications(auth *connect.Auth) ([]string, error) { + return nil, nil +} + +// Return any MessageIDs in the globals for this User +func (m *GatewayHandlerMultipleMessages) CheckMessages(userId *id.User, + messageID, ipaddr string) ([]string, error) { + msgs := []string{"a", "b", "c", "d", "e", "f", "g"} + return msgs, nil +} + +// PutMessage adds a message to the outgoing queue and +// calls SendBatch when it's size is the batch size +func (m *GatewayHandlerMultipleMessages) PutMessage(msg *pb.Slot, ipaddr string) error { + for i := 0; i < BatchSize; i++ { + msg.Index = uint32(i) + m.LastReceivedMessage = append(m.LastReceivedMessage, *msg) + } + return nil +} + +func (m *GatewayHandlerMultipleMessages) ConfirmNonce(message *pb.RequestRegistrationConfirmation, ipaddr string) (*pb.RegistrationConfirmation, error) { + return nil, nil +} + +// Pass-through for Registration Nonce Communication +func (m *GatewayHandlerMultipleMessages) RequestNonce(message *pb.NonceRequest, ipaddr string) (*pb.Nonce, error) { + return nil, nil +} + +func getDHPubKey() *cyclic.Int { + cmixGrp := cyclic.NewGroup( + large.NewIntFromString("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"+ + "C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"+ + "FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"+ + "B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"+ + "35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"+ + "F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"+ + "92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"+ + "3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B", 16), + large.NewIntFromString("5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"+ + "D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"+ + "6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"+ + "085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"+ + "AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"+ + "3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"+ + "BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"+ + "DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7", 16)) + + dh := cmixGrp.RandomCoprime(cmixGrp.NewMaxInt()) + return cmixGrp.ExpG(dh, cmixGrp.NewMaxInt()) +} + +// --------------------------- MOCK NOTIFICATION BOT ------------------------------------------------------- + +type MockNotificationHandler struct { +} + +func (nb *MockNotificationHandler) RegisterForNotifications(clientToken []byte, auth *connect.Auth) error { + return nil +} + +func (nb *MockNotificationHandler) UnregisterForNotifications(auth *connect.Auth) error { + return nil +} diff --git a/api/mockserver_test.go b/api/mockserver_test.go index 314e979db65843089eed29f871206c20ae6b42cc..253153c39aae15a3116fce667d6434084db871d2 100644 --- a/api/mockserver_test.go +++ b/api/mockserver_test.go @@ -10,9 +10,11 @@ package api import ( "fmt" jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/client/user" "gitlab.com/elixxir/comms/gateway" pb "gitlab.com/elixxir/comms/mixmessages" + "gitlab.com/elixxir/comms/notificationBot" "gitlab.com/elixxir/comms/registration" "gitlab.com/elixxir/primitives/id" "gitlab.com/elixxir/primitives/ndf" @@ -28,10 +30,12 @@ const RegPort = 5000 const GWErrorPort = 7800 const GWsStartPort = 7900 const PermErrorServerPort = 4000 +const NotificationBotPort = 6500 +const NotificationErrorPort = 6600 var RegHandler = MockRegistration{} var RegComms *registration.Comms -var NDFErrorReg = MockPerm_NDF_ErrorCase{} +var NDFErrorReg = MockPermNdfErrorCase{} var ErrorDef *ndf.NetworkDefinition const ValidRegCode = "UAV6IWD6" @@ -45,6 +49,9 @@ var RegGWHandlers [3]*GatewayHandler = [NumGWs]*GatewayHandler{ var GWComms [NumGWs]*gateway.Comms var GWErrComms [NumGWs]*gateway.Comms +var NotificationBotHandler = MockNotificationHandler{} +var NotificationBotComms *notificationBot.Comms + // Setups general testing params and calls test wrapper func TestMain(m *testing.M) { @@ -340,7 +347,7 @@ func TestSend(t *testing.T) { t.Errorf("Error sending message: %v", err) } - err = client.Logout() + err = client.Logout(100* time.Millisecond) if err != nil { t.Errorf("Logout failed: %v", err) @@ -350,7 +357,7 @@ func TestSend(t *testing.T) { func TestLogout(t *testing.T) { // Initialize client with dummy storage - storage := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} + storage := globals.RamStorage{} client, err := NewClient(&storage, "hello", "", def) if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) @@ -363,7 +370,7 @@ func TestLogout(t *testing.T) { } // Logout before logging in should return an error - err = client.Logout() + err = client.Logout(500 * time.Millisecond) if err == nil { t.Errorf("Logout did not throw an error when called on a client that" + @@ -404,14 +411,14 @@ func TestLogout(t *testing.T) { t.Errorf("Failed to start message reciever: %s", err.Error()) } - err = client.Logout() + err = client.Logout(500 * time.Millisecond) if err != nil { t.Errorf("Logout failed: %v", err) } // Logout after logout has been called should return an error - err = client.Logout() + err = client.Logout(500 * time.Millisecond) if err == nil { t.Errorf("Logout did not throw an error when called on a client that" + @@ -435,6 +442,10 @@ func testMainWrapper(m *testing.M) int { Address: fmtAddress(PermErrorServerPort), } + def.Notification = ndf.Notification{ + Address: fmtAddress(NotificationBotPort), + } + for i := 0; i < NumNodes; i++ { nIdBytes := make([]byte, id.NodeIdLen) nIdBytes[0] = byte(i) @@ -456,6 +467,7 @@ func testWrapperShutdown() { } RegComms.Shutdown() + NotificationBotComms.Shutdown() } func fmtAddress(port int) string { return fmt.Sprintf("localhost:%d", port) } @@ -514,6 +526,9 @@ func startServers() { def.Gateways = append(def.Gateways, gw) GWComms[i] = gateway.StartGateway("testGateway", gw.Address, handler, nil, nil) } + + NotificationBotComms = notificationBot.StartNotificationBot(id.NOTIFICATION_BOT, def.Notification.Address, &NotificationBotHandler, nil, nil) + } func disconnectServers() { @@ -522,4 +537,5 @@ func disconnectServers() { } RegComms.DisconnectAll() + NotificationBotComms.DisconnectAll() } diff --git a/api/notifications.go b/api/notifications.go new file mode 100644 index 0000000000000000000000000000000000000000..663daa315379e88496d186f027377978dda0c80f --- /dev/null +++ b/api/notifications.go @@ -0,0 +1,52 @@ +package api + +import ( + "github.com/pkg/errors" + "gitlab.com/elixxir/comms/mixmessages" + "gitlab.com/elixxir/primitives/id" +) + +// RegisterForNotifications sends a message to notification bot indicating it +// is registering for notifications +func (cl *Client) RegisterForNotifications(notificationToken []byte) error { + // Pull the host from the manage + notificationBotHost, ok := cl.receptionManager.Comms.GetHost(id.NOTIFICATION_BOT) + if !ok { + return errors.New("Failed to retrieve host for notification bot") + } + + // Send the register message + _, err := cl.receptionManager.Comms.RegisterForNotifications(notificationBotHost, + &mixmessages.NotificationToken{ + Token: notificationToken, + }) + if err != nil { + err := errors.Errorf( + "RegisterForNotifications: Unable to register for notifications! %s", err) + return err + } + + return nil + +} + +// UnregisterForNotifications sends a message to notification bot indicating it +// no longer wants to be registered for notifications +func (cl *Client) UnregisterForNotifications() error { + // Pull the host from the manage + notificationBotHost, ok := cl.receptionManager.Comms.GetHost(id.NOTIFICATION_BOT) + if !ok { + return errors.New("Failed to retrieve host for notification bot") + } + + // Send the unregister message + _, err := cl.receptionManager.Comms.UnregisterForNotifications(notificationBotHost) + if err != nil { + err := errors.Errorf( + "RegisterForNotifications: Unable to register for notifications! %s", err) + return err + } + + return nil + +} diff --git a/api/notifications_test.go b/api/notifications_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6ea54071fdd8115e3c1c43b4bd9c505a8548f1f7 --- /dev/null +++ b/api/notifications_test.go @@ -0,0 +1,126 @@ +package api + +import ( + "gitlab.com/elixxir/crypto/signature/rsa" + "testing" +) + +var dummy_key = `-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCrfJyqwVp2Wz6y +FlmPtHBdXffUE1qAkVgZJ1GfErYfO/9wHMYfkihjib9ZFRsOBsIdNEK9Pp/nVJAH +serTLEAwXpvB1EeTXyR/MTh8tVjQuX6RVIiU2gTIKVjZcUs7BaLBLhYXQ8XpjiUT +BltqHa1pj7iU16941i8TxkR0KM90aXfKZBpcJdf0+hc2K1FPVYrtMsuEhOA3cODv +pIU4jRejFSFKJeNwaSw9Y0xf/qTLBz5+ddiSw+3x3AwLuuwTzPVTGdKe57dOVzwq +8N7KTzYprksZgCdEFVeGLy0WahSVYl7IGfzQFHX4J3rrvd5zU/VnL57eqDpB7h57 +pyle1roWNToRCOgSn9euSP+Jcq8Pg20i63djDDaL004U41FNTccnpSEIkd6f74h2 +LqY64Y1AtMbdozAW5d6EjWAGh0tZXc3aHh8pMBqJ9g/PAFdwCTAn2Q9gmI6NzoIu +F4DFjka0GxrkFyp+f2ijOYmiDwx/ppMnKU4FnTim4FNUT6hKzdob4AvKXhOMEHNe +AoA33h6AvuYcyHaBaOF2pFlNG+3QZNovw40gALse1/ydRHWqGo1g4B9boXXp2Xq3 +gcVqEShVMJNJeXKEOHQ8DsFncAr77jCN9qEICSUyICZDl/KVlRSe54i4VJ+6Noa9 +S8XmAfzAlsBAdRogFbLHAu45iXipzwIDAQABAoICAEdxL7e3u99JHjKFOySyUIml +R0U0FuUvKBu6lLeHzRXwIffsFOI8OtVVIsGTGGVcjWwrRI6g029FfIeoKKN3cPp1 +v8AdlwAfiA3xTI4v4uN6E++p3wjcV1eoWhqkp2ncbDS85XklxAMMNAfcAyOPX5p1 +xLlFrhXSbWR4mjYmdl8SPVS1JYI0RecKdbccjtBVW/57xevci6itPxi3WsT3itxn +Riok5L8FIeglQUFQzgjDaNa4c9SZCb1UJjSQ2B9bqOzI+kU3VdeuYiOlm7t/CpqM +wT7LdBBaL894Qflvkkm15LTKltd9XrRWhlBGFrHHTZqCbVZnkXW8JTjwqDyZioZd +Yl1B5VsCZr3TTdJbv4wihtb6gYm7F6uwInWsRqBnfDaEy2Y344SjgTAEGA1JfOOh +DzQN8UEjSPA/yB3K7v3p05PB6zIQt9NmHOZMhesdZNk9I3oLkkB9VZIVE3dtES4F +L7iAJTAtgmgj3LsEI0fY1MLr7ffGR/8voyRHrPxvCT5tnxTcpGVok9wWphV0+Udy +eUxAw5VLsnJotm7syW+zIFHG0VUb7wW3aIYfs9Uc61T1o5kfA2Av9xtHU616pnTh +WgxCmRadB5NDOLAxBwlup6GlvDf1avwcC0MQtuUD55Qu6pomP2gAguxrK/uMiS/f +W0WnRDgtEO+ewv/tuxbZAoIBAQDV34plYw3rgitlGlUHuD1pVC8S2Lds2tZ6HLoc +l4SLVJIQc7jmam37DSjBR/1VW0JpJTMK6VwzbPYSoJpFFHv6sny8NH7y9o3zUq+R +pHNrvAO343EnYcT+TIGn1VlGi9tXyDPGs+ejsuLSnmq0+wtaRnMcaxa+wUCvrOmK +0l6xPuYvHrhAcmlYrGr7DXd+bF3SjLL24tuTmFFlW2A3P3Fg/nfBfbaDjEdPr5dV +vHEsJK9pfMr+tClsZzS4430VFap+WEY58W7Tz7pNJ1/DD0nnyySgPi0I3DVK0p1D +WLdB0gnKvqUNn0Oo73sDKpSfD7Mwdpwyj+zgvflT6kTvFwvTAoIBAQDNQ8EdtIwq +X8RMbz7F88ZHHPX4qbtvMEn7kcgnHsdmIe3/ssltWRfB7S5+B3M/8iY4U84Li4ze +xhjnYK4F9IKsbLUtWCukMjA34W7kaoL+H41NniVTtkIxYBGxmSwMPb9z+WH+5IhD +Ik3GVTTjGXPPNvF+8LgNlZFONdiypw8JwO95PFVHzSqCghMQIQlPqjgKd9xSKg+p +DQrs53tkQEoQMBi92zSrh1HQRVH9mD0KWJYAKSdwEtEhoc/kF8QZ4XIhi8/ByLm/ +m/spdoSp9j5Vjy4MRKEYxF1ok9HfwSXsmm2FcJZxeJbiGYruEz4t0kKy0Lmt+8xz +I3jXOXMvYRiVAoIBAE/Cu0FObK2M8RQWeumTG0wBukCEE/wDrQMDXaE2HJc9pe9+ +yNEdlgCPishySZcgnqbJ2bxTBTCkjSyrOn1Sw13eXMhvp3yC2LOK/bEKLIVcK+LT +bqqqOqY/8AageVfm5plZL34GL/gLya2UqOTvzu8O4PUTNvtS5QXfLYW5KNlfRMcD +5OEcCg+o1YjlH9BFJ8RS9pc+SXdE0e5D4qEYBveOTykY8g0jLqEYMg8mZOp6j/R+ +NtJAbEZiQvZE2KwZVWkjEKWhVZymlqsZaQw80mogh3s/VNo+DZ3m6AFqv4VLiJ1U +9gcbg0cocK7gnWaom0ISqfPtWwEBuE9ESgsEhEMCggEAC29h28jKIjYxllyAL8Dz +49ROM6spAPm8tWIat2s0ipELVDpelFPpSelvtJ+voPlZfbvVd7kvgN2iV4mASF6l +xPtNYJhP3hbZrtNFPT5dy9BwK8nKpI47w8ppUe6JkKkD+G8FMZEDslG/6XOnvZsW +Y43ZCExaxI73iFbhmppJ8S4paSSeT6CzZI/ghf6BKUn/Uz34LS+grbdHS4ldy2j1 +d09moXULyx5/xU2HUsxfYisrOBkS1GCH/AqqrTdRumtf01SZn18SUgVbiaTLoThR +oqyWUSKlot6VoZTSlVeKSFMWFN//0ZR5O2FW5wp1ZVIYWyPbpECp1CQ+wCa4LwSG +vQKCAQBcfmjb+R0fVZKXhgig6fjO8LkOFYSYwKnN0ZY53EhPYnGlmD6C9aufihjg +QKdmqP0yJbaKT+DwZYfCmDk3WOTQ5J7rl8yku+I5dX3oY54J3VgQA1/KABrtPmby +Byj2iMMkYutn1ffCsptTd06N4PZ+yU/sQVik3/9R0UVQ3eZqI0Hqon7FED8HWXp5 +UJDpahnI/gl8Bl6qtyM17IVh5//VZNMBvZG9cVThlJ3cNfkuuN3CkzWyZM46z/4A +EN240SdmgfmeGSZ4gGmkSTtV/kC7eChAtW/oB/mRJ1QeORSPB+eThnJHla/plYYd +jR+QSAa9eEozCngV6LUagC0YYWDZ +-----END PRIVATE KEY-----` + +// Happy path +func TestClient_RegisterForNotifications(t *testing.T) { + // Initialize client with dummy storage + storage := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} + client, err := NewClient(&storage, "hello", "", def) + if err != nil { + t.Errorf("Failed to initialize dummy client: %s", err.Error()) + return + } + + privKey, err := rsa.LoadPrivateKeyFromPem([]byte(dummy_key)) + if err != nil { + t.Errorf("Failed to load private key: %+v", err) + } + err = client.GenerateKeys(privKey, "test") + if err != nil { + t.Errorf("Failed to properly set up keys: %+v", err) + } + + // InitNetwork to gateways and reg server + err = client.InitNetwork() + + if err != nil { + t.Errorf("Client failed of connect: %+v", err) + } + + token := make([]byte, 32) + + err = client.RegisterForNotifications(token) + if err != nil { + t.Errorf("Expected happy path, received error: %+v", err) + } +} + +// Happy path +func TestClient_UnregisterForNotifications(t *testing.T) { + // Initialize client with dummy storage + storage := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} + client, err := NewClient(&storage, "hello", "", def) + if err != nil { + t.Errorf("Failed to initialize dummy client: %s", err.Error()) + } + + privKey, err := rsa.LoadPrivateKeyFromPem([]byte(dummy_key)) + if err != nil { + t.Errorf("Failed to load private key: %+v", err) + return + } + err = client.GenerateKeys(privKey, "test") + if err != nil { + t.Errorf("Failed to properly set up keys: %+v", err) + return + } + + // InitNetwork to gateways and reg server + err = client.InitNetwork() + + if err != nil { + t.Errorf("Client failed of connect: %+v", err) + } + + err = client.UnregisterForNotifications() + if err != nil { + t.Errorf("Expected happy path, received error: %+v", err) + } +} diff --git a/api/private.go b/api/private.go index e2c7ace3102fb6ee73080db56b1dffc113a33b8a..87b193dcc4ad0cc65093b91278bf4063134587b7 100644 --- a/api/private.go +++ b/api/private.go @@ -11,6 +11,7 @@ import ( "fmt" "github.com/pkg/errors" "gitlab.com/elixxir/client/globals" + "gitlab.com/elixxir/client/io" "gitlab.com/elixxir/client/keyStore" "gitlab.com/elixxir/client/user" pb "gitlab.com/elixxir/comms/mixmessages" @@ -70,7 +71,7 @@ func (cl *Client) precannedRegister(registrationCode string) (*user.User, *id.Us // It sends a registration message and returns the registration signature func (cl *Client) sendRegistrationMessage(registrationCode string, publicKeyRSA *rsa.PublicKey) ([]byte, error) { - err := AddPermissioningHost(cl.receptionManager, cl.ndf) + err := addPermissioningHost(cl.receptionManager, cl.ndf) if err != nil { if err == ErrNoPermissioning { @@ -301,6 +302,14 @@ func (cl *Client) GenerateKeys(rsaPrivKey *rsa.PrivateKey, cl.session = user.NewSession(cl.storage, usr, pubKey, privKey, cmixPubKey, cmixPrivKey, e2ePubKey, e2ePrivKey, salt, cmixGrp, e2eGrp, password) + + newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User.String(), + rsa.CreatePrivateKeyPem(privKey), rsa.CreatePublicKeyPem(pubKey), salt) + if err != nil { + return errors.Wrap(err, "Failed to create new reception manager") + } + newRm.Comms.Manager = cl.receptionManager.Comms.Manager + cl.receptionManager = newRm //store the session return cl.session.StoreSession() } diff --git a/bindings/client.go b/bindings/client.go index 610b58b7fc13a65bceaebde645672bb3d29d7297..746843b824a3c0e42c8f192adbc92d93ab91ef77 100644 --- a/bindings/client.go +++ b/bindings/client.go @@ -306,11 +306,18 @@ func (cl *Client) Send(m Message, encrypt bool) (int64, error) { }) } +//a version of the send function which does not return a timestamp for use +//on iOS +func (cl *Client) SendNoTimestamp(m Message, encrypt bool) error { + _, err := cl.Send(m, encrypt) + return err +} + // Logs the user out, saving the state for the system and clearing all data // from RAM func (cl *Client) Logout() error { globals.Log.INFO.Printf("Binding call: Logout()\n") - return cl.client.Logout() + return cl.client.Logout(500 * time.Millisecond) } // Get the version string from the locally built client repository @@ -446,3 +453,15 @@ func (cl *Client) InitListeners() error { globals.Log.INFO.Printf("Binding call: InitListeners") return cl.client.InitListeners() } + +// RegisterForNotifications sends a message to notification bot indicating it +// is registering for notifications +func (cl *Client) RegisterForNotifications(notificationToken []byte) error { + return cl.client.RegisterForNotifications(notificationToken) +} + +// UnregisterForNotifications sends a message to notification bot indicating it +// no longer wants to be registered for notifications +func (cl *Client) UnregisterForNotifications() error { + return cl.client.UnregisterForNotifications() +} diff --git a/bindings/client_test.go b/bindings/client_test.go index 3b134fa883b8e14499032d0753f1f90e6a478a7c..043ebaca8d51a66bab7f94bbec89398f0c006806 100644 --- a/bindings/client_test.go +++ b/bindings/client_test.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// diff --git a/cmd/gen.go b/cmd/gen.go deleted file mode 100644 index fae0ee14b5e302b964eee663bfaa217e3d76ce67..0000000000000000000000000000000000000000 --- a/cmd/gen.go +++ /dev/null @@ -1,76 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 Privategrity Corporation / -// / -// All rights reserved. / -//////////////////////////////////////////////////////////////////////////////// - -// The following directive is necessary to make the package coherent: - -// +build ignore - -// This program generates cmd/version.go. It can be invoked by running -// go generate -package main - -import ( - "bufio" - "io/ioutil" - "log" - "os" - "os/exec" - "strings" - "text/template" - "time" -) - -func GenerateGitVersion() string { - cmd := exec.Command("git", "show", "--oneline") - stdoutStderr, err := cmd.CombinedOutput() - if err != nil { - log.Fatal(err) - } - scanner := bufio.NewScanner(strings.NewReader(string(stdoutStderr))) - for scanner.Scan() { - return scanner.Text() - } - return "UNKNOWNVERSION" -} - -func ReadGlideLock() string { - r, _ := ioutil.ReadFile("../glide.lock") - return string(r) -} - -func main() { - gitversion := GenerateGitVersion() - glidedependencies := ReadGlideLock() - - f, err := os.Create("../globals/version.go") - die(err) - defer f.Close() - - packageTemplate.Execute(f, struct { - Timestamp time.Time - GITVER string - GLIDEDEPS string - }{ - Timestamp: time.Now(), - GITVER: gitversion, - GLIDEDEPS: glidedependencies, - }) -} - -func die(err error) { - if err != nil { - log.Fatal(err) - } -} - -var packageTemplate = template.Must(template.New("").Parse( - "// Code generated by go generate; DO NOT EDIT.\n" + - "// This file was generated by robots at\n" + - "// {{ .Timestamp }}\n" + - "package globals\n\n" + - "const GITVERSION = `{{ .GITVER }}`\n" + - "const SEMVER = \"1.1.1\"\n" + - "const GLIDEDEPS = `{{ .GLIDEDEPS }}`\n")) diff --git a/cmd/root.go b/cmd/root.go index 7edd3e7449d5e3f8e3e83b3ceac393871f639262..388bac8e7b474aed14f349135e7a707dfa2613e3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// @@ -12,7 +12,6 @@ import ( "fmt" "github.com/golang/protobuf/proto" "github.com/spf13/cobra" - jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" "gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/bots" @@ -26,7 +25,6 @@ import ( "gitlab.com/elixxir/primitives/switchboard" "gitlab.com/elixxir/primitives/utils" "io/ioutil" - "log" "os" "strconv" "strings" @@ -36,14 +34,13 @@ import ( var verbose bool var userId uint64 -var sourcePublicKeyPath string +var privateKeyPath string var destinationUserId uint64 var destinationUserIDBase64 string var message string var sessionFile string var noBlockingTransmission bool var rateLimiting uint32 -var showVer bool var registrationCode string var username string var end2end bool @@ -57,6 +54,9 @@ var searchForUser string var waitForMessages uint var messageTimeout uint var messageCnt uint +var precanned = false +var logPath string = "" +var notificationToken string // Execute adds all child commands to the root command and sets flags // appropriately. This is called by main.main(). It only needs to @@ -177,7 +177,7 @@ func sessionInitialization() (*id.User, string, *api.Client) { client.DisableTls() } - // InitNetwork to gateways and reg server + // InitNetwork to gateways, notificationBot and reg server err = client.InitNetwork() if err != nil { globals.Log.FATAL.Panicf("Could not call connect on client: %+v", err) @@ -193,6 +193,7 @@ func sessionInitialization() (*id.User, string, *api.Client) { regCode := registrationCode // If precanned user, use generated code instead if userId != 0 { + precanned = true regCode = id.NewUserFromUints(&[4]uint64{0, 0, 0, userId}).RegistrationCode() } @@ -200,17 +201,16 @@ func sessionInitialization() (*id.User, string, *api.Client) { var privKey *rsa.PrivateKey - if sourcePublicKeyPath != "" { - pubKeyBytes, err := utils.ReadFile(sourcePublicKeyPath) + if privateKeyPath != "" { + privateKeyBytes, err := utils.ReadFile(privateKeyPath) if err != nil { - globals.Log.FATAL.Panicf("Could not load user public key PEM from "+ - "path %s: %+v", sourcePublicKeyPath, err) + globals.Log.FATAL.Panicf("Could not load user private key PEM from "+ + "path %s: %+v", privateKeyPath, err) } - privKey, err = rsa.LoadPrivateKeyFromPem(pubKeyBytes) + privKey, err = rsa.LoadPrivateKeyFromPem(privateKeyBytes) if err != nil { - globals.Log.FATAL.Panicf("Could not public key from "+ - "PEM: %+v", err) + globals.Log.FATAL.Panicf("Could not load private key from PEM bytes: %+v", err) } } @@ -251,12 +251,16 @@ func sessionInitialization() (*id.User, string, *api.Client) { globals.Log.INFO.Printf("Skipped Registration, user: %v", uid) } - _, err = client.Login(sessFilePassword) + if !precanned { + // If we are sending to a non precanned user we retrieve the uid from the session returned by client.login + uid, err = client.Login(sessFilePassword) + } else { + _, err = client.Login(sessFilePassword) + } if err != nil { globals.Log.FATAL.Panicf("Could not login: %v", err) } - return uid, client.GetSession().GetCurrentUser().Username, client } @@ -343,9 +347,12 @@ func (l *TextListener) Hear(item switchboard.Item, isHeardElsewhere bool, i ...i } else { senderNick = sender.Username } - fmt.Printf("Message from %v, %v Received: %s\n Timestamp: %s", + logMsg := fmt.Sprintf("Message from %v, %v Received: %s\n", large.NewIntFromBytes(message.Sender[:]).Text(10), - senderNick, result.Message, message.Timestamp.String()) + senderNick, result.Message) + globals.Log.INFO.Printf("%s -- Timestamp: %s\n", logMsg, + message.Timestamp.String()) + fmt.Printf(logMsg) atomic.AddInt64(&l.MessagesReceived, 1) } @@ -374,13 +381,14 @@ var rootCmd = &cobra.Command{ Short: "Runs a client for cMix anonymous communication platform", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - // Main client run function - - if showVer { - printVersion() - return + if !verbose && viper.Get("verbose") != nil { + verbose = viper.GetBool("verbose") } - + if logPath == "" && viper.Get("logPath") != nil { + logPath = viper.GetString("logPath") + } + globals.Log = globals.InitLog(verbose, logPath) + // Main client run function userID, _, client := sessionInitialization() err := client.RegisterWithNodes() if err != nil { @@ -414,7 +422,6 @@ var rootCmd = &cobra.Command{ globals.Log.FATAL.Panicf("Could not initialize receivers: %s\n", err) } - err = client.StartMessageReceiver(cb) if err != nil { @@ -425,7 +432,7 @@ var rootCmd = &cobra.Command{ if username != "" { err := client.RegisterWithUDB(username, 2*time.Minute) if err != nil { - jww.ERROR.Printf("Could not register with UDB: %+v", err) + globals.Log.ERROR.Printf("%+v", err) } } @@ -469,8 +476,15 @@ var rootCmd = &cobra.Command{ wireOut := api.FormatTextMessage(message) for i := uint(0); i < messageCnt; i++ { - fmt.Printf("Sending Message to %s, %v: %s\n", base64.StdEncoding.EncodeToString(recipientId.Bytes()), + logMsg := fmt.Sprintf( + "Sending Message to "+ + "%s, %v: %s\n", + large.NewIntFromBytes( + recipientId[:]).Text( + 10), recipientNick, message) + globals.Log.INFO.Printf(logMsg) + fmt.Printf(logMsg) if i != 0 { time.Sleep(1 * time.Second) } @@ -533,8 +547,15 @@ var rootCmd = &cobra.Command{ } } + if notificationToken != "" { + err = client.RegisterForNotifications([]byte(notificationToken)) + if err != nil { + globals.Log.FATAL.Printf("failed to register for notifications: %+v", err) + } + } + //Logout - err = client.Logout() + err = client.Logout(500 * time.Millisecond) if err != nil { globals.Log.ERROR.Printf("Could not logout: %s\n", err.Error()) @@ -563,7 +584,7 @@ func init() { // There is one init in each sub command. Do not put variable declarations // here, and ensure all the Flags are of the *P variety, unless there's a // very good reason not to have them as local params to sub command." - cobra.OnInitialize(initConfig, initLog) + cobra.OnInitialize(initConfig) // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, @@ -628,8 +649,9 @@ func init() { rootCmd.Flags().StringVarP(&message, "message", "m", "", "Message to send") rootCmd.PersistentFlags().Uint64VarP(&destinationUserId, "destid", "d", 0, "ID to send message to") - rootCmd.Flags().BoolVarP(&showVer, "version", "V", false, - "Show the server version information.") + + rootCmd.Flags().StringVarP(¬ificationToken, "nbRegistration", "x", "", + "Token to register user with notification bot") rootCmd.PersistentFlags().BoolVarP(&end2end, "end2end", "", false, "Send messages with E2E encryption to destination user. Must have found each other via UDB first") @@ -641,7 +663,7 @@ func init() { rootCmd.Flags().BoolVarP(&noTLS, "noTLS", "", false, "Set to ignore tls. Connections will fail if the network requires tls. For debugging") - rootCmd.Flags().StringVar(&sourcePublicKeyPath, "privateKey", "", + rootCmd.Flags().StringVar(&privateKeyPath, "privateKey", "", "The path for a PEM encoded private key which will be used "+ "to create the user") @@ -655,6 +677,9 @@ func init() { rootCmd.Flags().StringVarP(&searchForUser, "SearchForUser", "s", "", "Sets the email to search for to find a user with user discovery") + rootCmd.Flags().StringVarP(&logPath, "log", "l", "", + "Print logs to specified log file, not stdout") + rootCmd.Flags().UintVarP(&messageTimeout, "messageTimeout", "t", 45, "The number of seconds to wait for "+ "'waitForMessages' messages to arrive") @@ -665,28 +690,3 @@ func init() { // initConfig reads in config file and ENV variables if set. func initConfig() {} - -// initLog initializes logging thresholds and the log path. -func initLog() { - globals.Log = jww.NewNotepad(jww.LevelError, jww.LevelInfo, os.Stdout, - ioutil.Discard, "CLIENT", log.Ldate|log.Ltime) - // If verbose flag set then log more info for debugging - if verbose || viper.GetBool("verbose") { - globals.Log.SetLogThreshold(jww.LevelDebug) - globals.Log.SetStdoutThreshold(jww.LevelDebug) - globals.Log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) - } else { - globals.Log.SetLogThreshold(jww.LevelInfo) - globals.Log.SetStdoutThreshold(jww.LevelInfo) - } - if viper.Get("logPath") != nil { - // Create log file, overwrites if existing - logPath := viper.GetString("logPath") - logFile, err := os.Create(logPath) - if err != nil { - globals.Log.WARN.Println("Invalid or missing log path, default path used.") - } else { - globals.Log.SetLogOutput(logFile) - } - } -} diff --git a/cmd/udb.go b/cmd/udb.go index a18ffc1c033e3e311c7d95b895062de112df5ef7..3b234d6e06ff687e219ccfff9c4c22e4ab1a1e83 100644 --- a/cmd/udb.go +++ b/cmd/udb.go @@ -7,9 +7,8 @@ package cmd import ( - "fmt" - jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/api" + "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/primitives/id" "strings" "time" @@ -19,11 +18,11 @@ type callbackSearch struct{} func (cs callbackSearch) Callback(userID, pubKey []byte, err error) { if err != nil { - fmt.Printf("UDB search failed: %v\n", err.Error()) + globals.Log.INFO.Printf("UDB search failed: %v\n", err.Error()) } else if len(pubKey) == 0 { - fmt.Printf("Public Key returned is empty\n") + globals.Log.INFO.Printf("Public Key returned is empty\n") } else { - fmt.Printf("UDB search successful. Returned user %v\n", + globals.Log.INFO.Printf("UDB search successful. Returned user %v\n", *id.NewUserFromBytes(userID)) } } @@ -35,7 +34,7 @@ func parseUdbMessage(msg string, client *api.Client) { // Split the message on spaces args := strings.Fields(msg) if len(args) < 3 { - jww.ERROR.Printf("UDB command must have at least three arguments!") + globals.Log.ERROR.Printf("UDB command must have at least three arguments!") } // The first arg is the command // the second is the valueType @@ -45,8 +44,8 @@ func parseUdbMessage(msg string, client *api.Client) { if strings.EqualFold(keyword, "SEARCH") { client.SearchForUser(args[2], searchCallback, 2*time.Minute) } else if strings.EqualFold(keyword, "REGISTER") { - jww.ERROR.Printf("UDB REGISTER not allowed, it is already done during user registration") + globals.Log.ERROR.Printf("UDB REGISTER not allowed, it is already done during user registration") } else { - jww.ERROR.Printf("UDB command not recognized!") + globals.Log.ERROR.Printf("UDB command not recognized!") } } diff --git a/cmd/version.go b/cmd/version.go index 0dac058f7eb768199646c92cab48c7bab9dbb512..1d8652bd5734bf59fd117664f239002e97e83740 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,35 +1,47 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// +// Handles command-line version functionality + package cmd import ( "fmt" "github.com/spf13/cobra" "gitlab.com/elixxir/client/globals" + "gitlab.com/elixxir/primitives/utils" ) -//go:generate go run gen.go -// The above generates: GITVERSION, GLIDEDEPS, and SEMVER - -func init() { - rootCmd.AddCommand(versionCmd) -} +// Change this value to set the version for this build +const currentVersion = "1.2.0" func printVersion() { fmt.Printf("Elixxir Client v%s -- %s\n\n", globals.SEMVER, globals.GITVERSION) - fmt.Printf("Dependencies:\n\n%s\n", globals.GLIDEDEPS) + fmt.Printf("Dependencies:\n\n%s\n", globals.DEPENDENCIES) +} + +func init() { + rootCmd.AddCommand(versionCmd) + rootCmd.AddCommand(generateCmd) } var versionCmd = &cobra.Command{ Use: "version", - Short: "Print the version number of Elixxir Client", - Long: `Print the version number of Elixxir Client. This also prints -the glide cache versions of all of its dependencies.`, + Short: "Print the version and dependency information for the Elixxir binary", + Long: `Print the version and dependency information for the Elixxir binary`, Run: func(cmd *cobra.Command, args []string) { printVersion() }, } + +var generateCmd = &cobra.Command{ + Use: "generate", + Short: "Generates version and dependency information for the Elixxir binary", + Long: `Generates version and dependency information for the Elixxir binary`, + Run: func(cmd *cobra.Command, args []string) { + utils.GenerateVersionFile(currentVersion) + }, +} diff --git a/globals/checkVersion.go b/globals/checkVersion.go index 0c3c71d607b09a8c475fd7ac7dcc24549ba31bca..a9517bacdf154906be194753f66c82904837bf88 100644 --- a/globals/checkVersion.go +++ b/globals/checkVersion.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright © 2019 Privategrity Corporation / +// Copyright © 2020 Privategrity Corporation / // / // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// diff --git a/globals/log.go b/globals/log.go index bb092c64074e1cfe5e6a197aa508bfb630c08837..e9bfc4a45df68296c87ff7eebc42727fd8f73a35 100644 --- a/globals/log.go +++ b/globals/log.go @@ -8,12 +8,47 @@ package globals import ( jww "github.com/spf13/jwalterweatherman" + "io" "io/ioutil" "log" "os" ) -// We're now logging everything to this notepad so that the CUI can replace it +// Log is logging everything to this notepad so that the CUI can replace it // with its own notepad and get logging statements from the client var Log = jww.NewNotepad(jww.LevelInfo, jww.LevelInfo, os.Stdout, ioutil.Discard, "CLIENT", log.Ldate|log.Ltime) + +// InitLog initializes logging thresholds and the log path. +// verbose turns on debug logging, setting the log path to nil +// uses std out. +func InitLog(verbose bool, logPath string) *jww.Notepad { + logLevel := jww.LevelInfo + logFlags := (log.Ldate | log.Ltime) + stdOut := io.Writer(os.Stdout) + logFile := ioutil.Discard + + // If the verbose flag is set, print all logs and + // print microseconds as well + if verbose { + logLevel = jww.LevelDebug + logFlags = (log.Ldate | log.Ltime | log.Lmicroseconds) + } + // If the logpath is empty or not set to - (stdout), + // set up the log file and do not log to stdout + if logPath != "" && logPath != "-" { + // Create log file, overwrites if existing + lF, err := os.OpenFile(logPath, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + Log.WARN.Println("Invalid or missing log path," + + " stdout used.") + } else { + logFile = io.Writer(lF) + stdOut = ioutil.Discard + } + } + + return jww.NewNotepad(logLevel, logLevel, stdOut, logFile, + "CLIENT", logFlags) +} diff --git a/globals/version.go b/globals/version.go deleted file mode 100644 index 5135ae6151f78ac1c06ea2d0936ac9523e66be89..0000000000000000000000000000000000000000 --- a/globals/version.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots at -// 2020-02-06 15:07:00.1145694 -0800 STD m=+0.048066801 -package globals - -const GITVERSION = `e77ca12 Merge branch 'authClient' into 'release'` -const SEMVER = "1.1.1" -const GLIDEDEPS = `` diff --git a/globals/version_vars.go b/globals/version_vars.go new file mode 100644 index 0000000000000000000000000000000000000000..463253e5d4bc0afca70a7a13e9f3fecf6eb626c5 --- /dev/null +++ b/globals/version_vars.go @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 Privategrity Corporation / +// / +// All rights reserved. / +//////////////////////////////////////////////////////////////////////////////// + +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots at +// 2020-02-18 10:36:50.458984 -0800 PST m=+0.016074930 +package globals + +const GITVERSION = `116f089 Merge branch 'patch/fixVersion' into 'release'` +const SEMVER = "1.2.0" +const DEPENDENCIES = `module gitlab.com/elixxir/client + +go 1.13 + +require ( + github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 + github.com/golang/protobuf v1.3.3 + github.com/google/go-cmp v0.4.0 // indirect + github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/pelletier/go-toml v1.6.0 // indirect + github.com/pkg/errors v0.9.1 + github.com/smartystreets/assertions v1.0.1 // indirect + github.com/spf13/afero v1.2.2 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cobra v0.0.5 + github.com/spf13/jwalterweatherman v1.1.0 + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.6.2 + gitlab.com/elixxir/comms v0.0.0-20200206201144-aa6e356b3770 + gitlab.com/elixxir/crypto v0.0.0-20200206203107-b8926242da23 + gitlab.com/elixxir/primitives v0.0.0-20200207225613-9a4445ddec16 + golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 + golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect + golang.org/x/sys v0.0.0-20200217220822-9197077df867 // indirect + google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce // indirect + google.golang.org/grpc v1.27.1 // indirect + gopkg.in/ini.v1 v1.52.0 // indirect +) +` diff --git a/go.mod b/go.mod index fcf1ec6ffd384942f9e08a1e1fb24b0ac2b37e8d..b6d06c5239eea66d953afb08da8bfcd04611f793 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,8 @@ require ( github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang/protobuf v1.3.3 github.com/google/go-cmp v0.4.0 // indirect - github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de // indirect + github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect + github.com/kr/text v0.2.0 // indirect github.com/pelletier/go-toml v1.6.0 // indirect github.com/pkg/errors v0.9.1 github.com/smartystreets/assertions v1.0.1 // indirect @@ -16,12 +17,12 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.6.2 - gitlab.com/elixxir/comms v0.0.0-20200206201144-aa6e356b3770 + github.com/stretchr/testify v1.5.0 // indirect + gitlab.com/elixxir/comms v0.0.0-20200218232629-9f5cd47b8798 gitlab.com/elixxir/crypto v0.0.0-20200206203107-b8926242da23 - gitlab.com/elixxir/primitives v0.0.0-20200131183153-e93c6b75019f - golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a - golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect - google.golang.org/genproto v0.0.0-20200205142000-a86caf926a67 // indirect - google.golang.org/grpc v1.27.1 // indirect + gitlab.com/elixxir/primitives v0.0.0-20200218211222-4193179f359c + golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 + golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c // indirect + google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 // indirect gopkg.in/ini.v1 v1.52.0 // indirect ) diff --git a/go.sum b/go.sum index 0c7f60f8ac2d037a3b3403196ce10460aa3c8877..7f631324865cdd73a34c976753d854fe5c9db71c 100644 --- a/go.sum +++ b/go.sum @@ -1,134 +1,74 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/aclements/go-gg v0.0.0-20170323211221-abd1f791f5ee/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= -github.com/aclements/go-moremath v0.0.0-20190830160640-d16893ddf098/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ= -github.com/ajstarks/deck v0.0.0-20191209003357-2008160658d2/go.mod h1:j3f/59diR4DorW5A78eDYvRkdrkh+nps4p5LA1Tl05U= -github.com/ajstarks/svgo v0.0.0-20191124160048-bd5c74aaa11c/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cznic/cc v0.0.0-20181122101902-d673e9b70d4d/go.mod h1:m3fD/V+XTB35Kh9zw6dzjMY+We0Q7PMf6LLIC4vuG9k= -github.com/cznic/fileutil v0.0.0-20181122101858-4d67cfea8c87/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= -github.com/cznic/golex v0.0.0-20181122101858-9c343928389c/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= -github.com/cznic/internal v0.0.0-20181122101858-3279554c546e/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= -github.com/cznic/ir v0.0.0-20181122101859-da7ba2ecce8b/go.mod h1:bctvsSxTD8Lpaj5RRQ0OrAAu4+0mD4KognDQItBNMn0= -github.com/cznic/lex v0.0.0-20181122101858-ce0fb5e9bb1b/go.mod h1:LcYbbl1tn/c31gGxe2EOWyzr7EaBcdQOoIVGvJMc7Dc= -github.com/cznic/lexer v0.0.0-20181122101858-e884d4bd112e/go.mod h1:YNGh5qsZlhFHDfWBp/3DrJ37Uy4pRqlwxtL+LS7a/Qw= -github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= -github.com/cznic/xc v0.0.0-20181122101856-45b06973881e/go.mod h1:3oFoiOvCDBYH+swwf5+k/woVmWy7h1Fcyu8Qig/jjX0= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= -github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= -github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= -github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= -github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.2-0.20191028172631-481baca67f93/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d h1:vr95xIx8Eg3vCzZPxY3rCwTfkjqNDt/FgVqTOk0WByk= +github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -138,34 +78,26 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -180,11 +112,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= -github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -216,157 +145,100 @@ github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfD github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw= +github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -gitlab.com/elixxir/comms v0.0.0-20200206201144-aa6e356b3770 h1:zYoqjUaa94+uqznpNb6UT+6aiDNBBfva4LmwFeq+rzU= -gitlab.com/elixxir/comms v0.0.0-20200206201144-aa6e356b3770/go.mod h1:DblaR0msnWpNGzNK2fXvXbfGZQNPH4KPiBl4YkkGF4Y= -gitlab.com/elixxir/crypto v0.0.0-20191121235352-86d305a9b253 h1:BqgqJ0mLANRjhAFLvGAcB5AWdgAnFZhsGx0qTk5G+3Y= -gitlab.com/elixxir/crypto v0.0.0-20191121235352-86d305a9b253/go.mod h1:+46Zj/NE6JEkXExYnzdvvDokPpDbA+fJsRszvrezK9k= +gitlab.com/elixxir/comms v0.0.0-20200214222036-cf76d94ea96d h1:bn0rbNdEdH3R1BQ5hudIKqSnLC8c2rvQAb1X7LfMWoY= +gitlab.com/elixxir/comms v0.0.0-20200214222036-cf76d94ea96d/go.mod h1:juAeTqtxFZaCIQiJ8FHKy25dbJgKT7EnTKGx6MxipgQ= +gitlab.com/elixxir/comms v0.0.0-20200218232629-9f5cd47b8798 h1:IHlY06a/U7k631Am07VSfkPMGv4QUHr213BpcaQvwKM= +gitlab.com/elixxir/comms v0.0.0-20200218232629-9f5cd47b8798/go.mod h1:juAeTqtxFZaCIQiJ8FHKy25dbJgKT7EnTKGx6MxipgQ= gitlab.com/elixxir/crypto v0.0.0-20200206203107-b8926242da23 h1:J9MKdOxLGzDZoLy2Q0CAxPlPjSH+k4NG3JhgvatAZjo= gitlab.com/elixxir/crypto v0.0.0-20200206203107-b8926242da23/go.mod h1:wWulHuSqxiGhvasduZrtyTTqy+7y5ebe440GdORhzig= -gitlab.com/elixxir/primitives v0.0.0-20191028233752-882c08b8f095 h1:fnRh0PUwgy0qlWM7xMdk2w5MXh7gvQ0v/xyedn2gbcY= -gitlab.com/elixxir/primitives v0.0.0-20191028233752-882c08b8f095/go.mod h1:+UiRRWzNpl/WoWUuQtJSoimfXImJAJ5lrrmg0pQKY3g= -gitlab.com/elixxir/primitives v0.0.0-20200106183011-a68f1e6f188e/go.mod h1:g9v3S34ZUeqGRiOTV7esByK8a5TovJ3YgTv/328ny6w= gitlab.com/elixxir/primitives v0.0.0-20200131183153-e93c6b75019f h1:F0YwFZz4umoXOJ+xX34WIRrucuLgHCSyKxWOKGaEt5g= gitlab.com/elixxir/primitives v0.0.0-20200131183153-e93c6b75019f/go.mod h1:REJMcwIcyxh74VSHqy4S9yYiaEsQYObOPglRExDpk14= +gitlab.com/elixxir/primitives v0.0.0-20200210205543-5c55c1f6949f h1:1bYEOz3/a3Q09dxE0ND64+9l21MsyeailzoFYEGC93s= +gitlab.com/elixxir/primitives v0.0.0-20200210205543-5c55c1f6949f/go.mod h1:REJMcwIcyxh74VSHqy4S9yYiaEsQYObOPglRExDpk14= +gitlab.com/elixxir/primitives v0.0.0-20200218211222-4193179f359c h1:hZy85jE7bPyTp1ap57g4cUilPLXLuebVbsFq/JwNN+U= +gitlab.com/elixxir/primitives v0.0.0-20200218211222-4193179f359c/go.mod h1:REJMcwIcyxh74VSHqy4S9yYiaEsQYObOPglRExDpk14= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20200107151952-05d22632dd9a/go.mod h1:GmE16z2WpOngzI9wxhkkbWVskRyPq9wIuG+/v2LccNI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3ob3lmhYIefc+GU+DLg1Ow= -golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a h1:aczoJ0HPNE92XKa7DrIzkNN6esOKO2TBwiiYoKcINhA= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 h1:Sy5bstxEqwwbYs6n0/pBuxKENqOeZUgD45Gp3Q3pqLg= +golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20191210151939-1a1fef82734d/go.mod h1:p895TfNkDgPEmEQrNiOtIl3j98d/tGU95djDj7NfyjQ= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 h1:u/E0NqCIWRDAo9WCFo6Ko49njPFDLSd3z+X1HgWDMpE= -golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c h1:jceGD5YNJGgGMkJz79agzOln1K9TaZUjv5ird16qniQ= +golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200205142000-a86caf926a67 h1:MBO9fkVSrTpJ8vgHLPi5gb+ZWXEy7/auJN8yqyu9EiE= -google.golang.org/genproto v0.0.0-20200205142000-a86caf926a67/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 h1:jB9+PJSvu5tBfmJHy/OVapFdjDF3WvpkqRhxqrmzoEU= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= @@ -376,15 +248,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4= gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -394,8 +262,5 @@ gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/io/receptionManager.go b/io/receptionManager.go index ff8021f4d6d00431383d76ea92feb7cdf98f1f66..53b70ee3ba7fb8949f6db4fe25785afe14b53b40 100644 --- a/io/receptionManager.go +++ b/io/receptionManager.go @@ -50,19 +50,25 @@ type ReceptionManager struct { rekeyChan chan struct{} } -func NewReceptionManager(rekeyChan chan struct{}) *ReceptionManager { +// Build a new reception manager object using inputted key fields +func NewReceptionManager(rekeyChan chan struct{}, uid string, privKey, pubKey, salt []byte) (*ReceptionManager, error) { + comms, err := client.NewClientComms(uid, pubKey, privKey, salt) + if err != nil { + return nil, errors.Wrap(err, "Failed to get client comms using constructor: %+v") + } + cm := &ReceptionManager{ nextId: parse.IDCounter(), collator: NewCollator(), blockTransmissions: true, transmitDelay: 1000 * time.Millisecond, receivedMessages: make(map[string]struct{}), - Comms: &client.Comms{}, + Comms: comms, rekeyChan: rekeyChan, Tls: true, } - return cm + return cm, nil } // Connects to the permissioning server, if we know about it, to get the latest diff --git a/io/updateNdf.go b/io/updateNdf.go deleted file mode 100644 index 30d063364932bf6656dbe2334ae63c1f52d29df3..0000000000000000000000000000000000000000 --- a/io/updateNdf.go +++ /dev/null @@ -1,57 +0,0 @@ -package io - -import ( - "crypto/sha256" - "fmt" - "github.com/pkg/errors" - "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/comms/client" - "gitlab.com/elixxir/comms/mixmessages" - "gitlab.com/elixxir/primitives/ndf" -) - -var noNDFErr = errors.New("Failed to get ndf from permissioning: rpc error: code = Unknown desc = Permissioning server does not have an ndf to give to client") - -//GetUpdatedNDF: Connects to the permissioning server to get the updated NDF from it -func PollNdf(currentDef *ndf.NetworkDefinition, comms *client.Comms) (*ndf.NetworkDefinition, error) { - //Hash the client's ndf for comparison with registration's ndf - hash := sha256.New() - ndfBytes := currentDef.Serialize() - hash.Write(ndfBytes) - ndfHash := hash.Sum(nil) - - //Put the hash in a message - msg := &mixmessages.NDFHash{Hash: ndfHash} - - regHost, ok := comms.GetHost(PermissioningAddrID) - if !ok { - return nil, errors.New("Failed to find permissioning host") - } - //Send the hash to registration - response, err := comms.RequestNdf(regHost, msg) - if err != nil { - errMsg := fmt.Sprintf("Failed to get ndf from permissioning: %v", err) - if errMsg == noNDFErr.Error() { - globals.Log.WARN.Println("Continuing without an updated NDF") - return nil, nil - } - return nil, errors.New(errMsg) - } - - //If there was no error and the response is nil, client's ndf is up-to-date - if response == nil || response.Ndf == nil { - globals.Log.DEBUG.Printf("Client NDF up-to-date") - return nil, nil - } - - globals.Log.INFO.Printf("Remote NDF: %s", string(response.Ndf)) - - //Otherwise pull the ndf out of the response - updatedNdf, _, err := ndf.DecodeNDF(string(response.Ndf)) - if err != nil { - //If there was an error decoding ndf - errMsg := fmt.Sprintf("Failed to decode response to ndf: %v", err) - return nil, errors.New(errMsg) - } - return updatedNdf, nil -} diff --git a/rekey/rekey.go b/rekey/rekey.go index c67d42a8ec215cb4fba3930c7c794d9e21e0b33e..674723f744e31107b0487d6732c5f3fd4bb19a67 100644 --- a/rekey/rekey.go +++ b/rekey/rekey.go @@ -167,7 +167,7 @@ func rekeyProcess(rt rekeyType, partner *id.User, data []byte) error { if ctx == nil { if rt == RekeyTrigger { privKeyCyclic = e2egrp.RandomCoprime(e2egrp.NewInt(1)) - fmt.Println("Private key actual: ", privKeyCyclic.Text(16)) + globals.Log.DEBUG.Println("Private key actual: ", privKeyCyclic.Text(16)) pubKeyCyclic = e2egrp.ExpG(privKeyCyclic, e2egrp.NewInt(1)) // Get Current Partner Public Key from RekeyKeys partnerPubKeyCyclic = keys.CurrPubKey diff --git a/user/user.go b/user/user.go index 6f0e56b7619a3d15457b80e37a70bd7d1d9392a2..209f039c94751cb6a11d8d8b42ba877d6fd4daac 100644 --- a/user/user.go +++ b/user/user.go @@ -19,7 +19,7 @@ var Users Registry const NumDemoUsers = 40 var DemoUserNicks = []string{"David", "Payments", "UDB", "Jim", "Ben", "Steph", - "Rick", "Jake", "Spencer", "Stephanie", "Mario", "Jono", "Amanda", + "Rick", "Jake", "Niamh", "Stephanie", "Mario", "Jono", "Amanda", "Margaux", "Kevin", "Bruno", "Konstantino", "Bernardo", "Tigran", "Kate", "Will", "Katie", "Bryan"} var DemoChannelNames = []string{"#General", "#Engineering", "#Lunch",