diff --git a/api/client.go b/api/client.go index d3f6254563940a6b85921df9bb093b3f22b8a834..20fdcc1e9991ad34f3039c07f7d08121c85fefce 100644 --- a/api/client.go +++ b/api/client.go @@ -205,6 +205,8 @@ func OpenClient(storageDir string, password []byte, parameters params.Network) ( func NewProtoClient_Unsafe(storageDir string, password []byte, protoClientJSON []byte, parameters params.Network, def *ndf.NetworkDefinition) (*Client, error) { + jww.INFO.Printf("NewProtoClient_Unsafe") + // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) @@ -368,7 +370,8 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, // cryptographic primitives. This is designed for some specific deployment // procedures and is generally unsafe. It is unsafe because all network relationships // will no longer be present in the new session file. -func LoginWithProtoClient(storageDir string, password []byte, protoClientJSON []byte, +func LoginWithProtoClient(storageDir string, password []byte, + protoClientJSON []byte, newBaseNdf string, parameters params.Network) (*Client, error) { jww.INFO.Printf("LoginWithNewBaseNDF_UNSAFE()") diff --git a/api/permissioning.go b/api/permissioning.go index 0f79b94aef4d354648fb78f61c58e7aff2c3d397..85aac34b93f333f4994c49b1dac1ec868965807a 100644 --- a/api/permissioning.go +++ b/api/permissioning.go @@ -53,11 +53,6 @@ func (c *Client) registerWithPermissioning() error { // ConstructProtoUerFile is a helper function which is used for proto client testing. // This is used for development testing. func (c *Client) ConstructProtoUerFile() ([]byte, error) { - username, err := c.GetStorage().User().GetUsername() - if err != nil { - return nil, errors.WithMessage(err, "failed to register with "+ - "permissioning") - } //load the registration code regCode, err := c.storage.GetRegCode() @@ -75,7 +70,6 @@ func (c *Client) ConstructProtoUerFile() ([]byte, error) { ReceptionRSA: c.GetUser().ReceptionRSA, Precanned: c.GetUser().Precanned, RegistrationTimestamp: c.GetUser().RegistrationTimestamp, - Username: username, RegCode: regCode, TransmissionRegValidationSig: c.storage.User().GetTransmissionRegistrationValidationSignature(), ReceptionRegValidationSig: c.storage.User().GetReceptionRegistrationValidationSignature(), diff --git a/cmd/proto.go b/cmd/proto.go index 70ffc5a04915d46f7d290dcb8a3f73689ce0cfd5..d1a93b889759d75dad4e0330426e3446e9350efa 100644 --- a/cmd/proto.go +++ b/cmd/proto.go @@ -8,18 +8,13 @@ package cmd import ( - "fmt" - "github.com/pkg/errors" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" "gitlab.com/elixxir/client/api" - "gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/params" - "gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/utils" "io/ioutil" - "sync" "time" ) @@ -30,10 +25,12 @@ var protoCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { // If output path is specified, only write to file var client *api.Client + jww.INFO.Printf("In proto user path") protoOutputPath := viper.GetString("protoUserOut") if protoOutputPath != "" { client = initClient() + jsonBytes, err := client.ConstructProtoUerFile() if err != nil { jww.FATAL.Panicf("Failed to construct proto user file: %v", err) @@ -44,240 +41,15 @@ var protoCmd = &cobra.Command{ jww.FATAL.Panicf("Failed to write proto user to file: %v", err) } } else { + jww.INFO.Printf("Loading proto client") client = loadProtoClient() } - - // Write user to contact file - user := client.GetUser() - jww.INFO.Printf("User: %s", user.ReceptionID) - jww.INFO.Printf("User Transmission: %s", user.TransmissionID) - writeContact(user.GetContact()) - - // Get Recipient and/or set it to myself - isPrecanPartner := false - recipientContact := readContact() - recipientID := recipientContact.ID - - // Try to get recipientID from destid - if recipientID == nil { - recipientID, isPrecanPartner = parseRecipient( - viper.GetString("destid")) - } - - // Set it to myself - if recipientID == nil { - jww.INFO.Printf("sending message to self") - recipientID = user.ReceptionID - recipientContact = user.GetContact() - } - - confCh, recvCh := initClientCallbacks(client) - // The following block is used to check if the request from - // a channel authorization is from the recipient we intend in - // this run. - authConfirmed := false - go func() { - for { - requestor := <-confCh - authConfirmed = recipientID.Cmp(requestor) - } - }() - - err := client.StartNetworkFollower(5 * time.Second) - if err != nil { - jww.FATAL.Panicf("%+v", err) - } - - // Wait until connected or crash on timeout - connected := make(chan bool, 10) - client.GetHealth().AddChannel(connected) - waitUntilConnected(connected) - - // After connection, make sure we have registered with at least - // 85% of the nodes - numReg := 1 - total := 100 - for numReg < (total*3)/4 { - time.Sleep(1 * time.Second) - numReg, total, err = client.GetNodeRegistrationStatus() - if err != nil { - jww.FATAL.Panicf("%+v", err) - } - jww.INFO.Printf("Registering with nodes (%d/%d)...", - numReg, total) - } - - // Send Messages - msgBody := viper.GetString("message") - - time.Sleep(10 * time.Second) - - // Accept auth request for this recipient - if viper.GetBool("accept-channel") { - acceptChannel(client, recipientID) - // Do not wait for channel confirmations if we - // accepted one - authConfirmed = true - } - - if client.HasAuthenticatedChannel(recipientID) { - jww.INFO.Printf("Authenticated channel already in "+ - "place for %s", recipientID) - authConfirmed = true - } - - // Send unsafe messages or not? - unsafe := viper.GetBool("unsafe") - - sendAuthReq := viper.GetBool("send-auth-request") - if !unsafe && !authConfirmed && !isPrecanPartner && - sendAuthReq { - addAuthenticatedChannel(client, recipientID, - recipientContact) - } else if !unsafe && !authConfirmed && isPrecanPartner { - addPrecanAuthenticatedChannel(client, - recipientID, recipientContact) - authConfirmed = true - } - - if !unsafe && !authConfirmed { - jww.INFO.Printf("Waiting for authentication channel"+ - " confirmation with partner %s", recipientID) - scnt := uint(0) - waitSecs := viper.GetUint("auth-timeout") - for !authConfirmed && scnt < waitSecs { - time.Sleep(1 * time.Second) - scnt++ - } - if scnt == waitSecs { - jww.FATAL.Panicf("Could not confirm "+ - "authentication channel for %s, "+ - "waited %d seconds.", recipientID, - waitSecs) - } - jww.INFO.Printf("Authentication channel confirmation"+ - " took %d seconds", scnt) - } - - // Delete this recipient - if viper.GetBool("delete-channel") { - deleteChannel(client, recipientID) - } - - msg := message.Send{ - Recipient: recipientID, - Payload: []byte(msgBody), - MessageType: message.Text, - } - paramsE2E := params.GetDefaultE2E() - paramsUnsafe := params.GetDefaultUnsafe() - wg := &sync.WaitGroup{} - sendCnt := int(viper.GetUint("sendCount")) - wg.Add(sendCnt) - go func() { - //sendDelay := time.Duration(viper.GetUint("sendDelay")) - for i := 0; i < sendCnt; i++ { - go func(i int) { - defer wg.Done() - fmt.Printf("Sending to %s: %s\n", recipientID, msgBody) - var roundIDs []id.Round - var roundTimeout time.Duration - if unsafe { - roundIDs, err = client.SendUnsafe(msg, - paramsUnsafe) - roundTimeout = paramsUnsafe.Timeout - } else { - roundIDs, _, _, err = client.SendE2E(msg, - paramsE2E) - roundTimeout = paramsE2E.Timeout - } - if err != nil { - jww.FATAL.Panicf("%+v", err) - } - - // Construct the callback function which prints out the rounds' results - f := func(allRoundsSucceeded, timedOut bool, - rounds map[id.Round]api.RoundResult) { - printRoundResults(allRoundsSucceeded, timedOut, rounds, roundIDs, msg) - } - - // Have the client report back the round results - err = errors.New("derp") - for j := 0; j < 5 && err != nil; j++ { - err = client.GetRoundResults(roundIDs, roundTimeout, f) - } - - if err != nil { - jww.FATAL.Panicf("Message sending for send %d failed: %+v", i, err) - } - }(i) - } - }() - - // Wait until message timeout or we receive enough then exit - // TODO: Actually check for how many messages we've received - expectedCnt := viper.GetUint("receiveCount") - receiveCnt := uint(0) - waitSecs := viper.GetUint("waitTimeout") - waitTimeout := time.Duration(waitSecs) * time.Second - done := false - - for !done && expectedCnt != 0 { - timeoutTimer := time.NewTimer(waitTimeout) - select { - case <-timeoutTimer.C: - fmt.Println("Timed out!") - jww.ERROR.Printf("Timed out on message reception after %s!", waitTimeout) - done = true - break - case m := <-recvCh: - fmt.Printf("Message received: %s\n", string( - m.Payload)) - //fmt.Printf("%s", m.Timestamp) - receiveCnt++ - if receiveCnt == expectedCnt { - done = true - break - } - } - } - - //wait an extra 5 seconds to make sure no messages were missed - done = false - timer := time.NewTimer(5 * time.Second) - for !done { - select { - case <-timer.C: - done = true - break - case m := <-recvCh: - fmt.Printf("Message received: %s\n", string( - m.Payload)) - //fmt.Printf("%s", m.Timestamp) - receiveCnt++ - } - } - - jww.INFO.Printf("Received %d/%d Messages!", receiveCnt, expectedCnt) - fmt.Printf("Received %d\n", receiveCnt) - if roundsNotepad != nil { - roundsNotepad.INFO.Printf("\n%s", client.GetNetworkInterface().GetVerboseRounds()) - } - wg.Wait() - err = client.StopNetworkFollower() - if err != nil { - jww.WARN.Printf( - "Failed to cleanly close threads: %+v\n", - err) - } - }, } func loadProtoClient() *api.Client { protoUserPath := viper.GetString("protoUserPath") - protoUserFile, err := utils.ReadFile(protoUserPath) if err != nil { jww.FATAL.Panicf("Failed to read proto user: %v", err) @@ -292,7 +64,7 @@ func loadProtoClient() *api.Client { netParams.E2EParams.NumRekeys = uint16( viper.GetUint("e2eNumReKeys")) netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds") - netParams.FastPolling = viper.GetBool(" slowPolling") + netParams.FastPolling = viper.GetBool("slowPolling") netParams.ForceMessagePickupRetry = viper.GetBool("forceMessagePickupRetry") if netParams.ForceMessagePickupRetry { period := 3 * time.Second @@ -308,6 +80,8 @@ func loadProtoClient() *api.Client { jww.FATAL.Panicf(err.Error()) } + jww.INFO.Printf("login with proto") + client, err := api.LoginWithProtoClient(storeDir, []byte(pass), protoUserFile, string(ndfJSON), netParams) if err != nil { @@ -324,150 +98,5 @@ func init() { // Cobra supports persistent flags, which, if defined here, // will be global for your application. - // Proto user flags - protoCmd.Flags().String("protoUserPath", "protoUser.json", - "Path to proto user JSON file containing cryptographic primitives "+ - "the client will load") - viper.BindPFlag("protoUserPath", protoCmd.Flags().Lookup("protoUserPath")) - protoCmd.Flags().String("protoUserOut", "protoUser.json", - "Path to which a normally constructed client "+ - "will write proto user JSON file") - viper.BindPFlag("protoUserOut", protoCmd.Flags().Lookup("protoUserOut")) - - protoCmd.Flags().UintP("logLevel", "v", 0, - "Verbose mode for debugging") - viper.BindPFlag("logLevel", protoCmd.Flags().Lookup("logLevel")) - - protoCmd.Flags().Bool("verboseRoundTracking", false, - "Verbose round tracking, keeps track and prints all rounds the "+ - "client was aware of while running. Defaults to false if not set.") - viper.BindPFlag("verboseRoundTracking", protoCmd.Flags().Lookup("verboseRoundTracking")) - - protoCmd.Flags().StringP("session", "s", - "", "Sets the initial storage directory for "+ - "client session data") - viper.BindPFlag("session", protoCmd.Flags().Lookup("session")) - - protoCmd.Flags().StringP("writeContact", "w", - "-", "Write contact information, if any, to this file, "+ - " defaults to stdout") - viper.BindPFlag("writeContact", protoCmd.Flags().Lookup( - "writeContact")) - - protoCmd.Flags().StringP("password", "p", "", - "Password to the session file") - viper.BindPFlag("password", protoCmd.Flags().Lookup( - "password")) - - protoCmd.Flags().StringP("ndf", "n", "ndf.json", - "Path to the network definition JSON file") - viper.BindPFlag("ndf", protoCmd.Flags().Lookup("ndf")) - - protoCmd.Flags().StringP("log", "l", "-", - "Path to the log output path (- is stdout)") - viper.BindPFlag("log", protoCmd.Flags().Lookup("log")) - - protoCmd.Flags().StringP("regcode", "", "", - "Identity code (optional)") - viper.BindPFlag("regcode", protoCmd.Flags().Lookup("regcode")) - - protoCmd.Flags().StringP("message", "m", "", - "Message to send") - viper.BindPFlag("message", protoCmd.Flags().Lookup("message")) - - protoCmd.Flags().UintP("sendid", "", 0, - "Use precanned user id (must be between 1 and 40, inclusive)") - viper.BindPFlag("sendid", protoCmd.Flags().Lookup("sendid")) - - protoCmd.Flags().StringP("destid", "d", "0", - "ID to send message to (if below 40, will be precanned. Use "+ - "'0x' or 'b64:' for hex and base64 representations)") - viper.BindPFlag("destid", protoCmd.Flags().Lookup("destid")) - - protoCmd.Flags().StringP("destfile", "", - "", "Read this contact file for the destination id") - viper.BindPFlag("destfile", protoCmd.Flags().Lookup("destfile")) - - protoCmd.Flags().UintP("sendCount", - "", 1, "The number of times to send the message") - viper.BindPFlag("sendCount", protoCmd.Flags().Lookup("sendCount")) - protoCmd.Flags().UintP("sendDelay", - "", 500, "The delay between sending the messages in ms") - viper.BindPFlag("sendDelay", protoCmd.Flags().Lookup("sendDelay")) - - protoCmd.Flags().UintP("receiveCount", - "", 1, "How many messages we should wait for before quitting") - viper.BindPFlag("receiveCount", protoCmd.Flags().Lookup("receiveCount")) - protoCmd.Flags().UintP("waitTimeout", "", 15, - "The number of seconds to wait for messages to arrive") - viper.BindPFlag("waitTimeout", - protoCmd.Flags().Lookup("waitTimeout")) - - protoCmd.Flags().BoolP("unsafe", "", false, - "Send raw, unsafe messages without e2e encryption.") - viper.BindPFlag("unsafe", protoCmd.Flags().Lookup("unsafe")) - - protoCmd.Flags().BoolP("unsafe-channel-creation", "", false, - "Turns off the user identity authenticated channel check, "+ - "automatically approving authenticated channels") - viper.BindPFlag("unsafe-channel-creation", - protoCmd.Flags().Lookup("unsafe-channel-creation")) - - protoCmd.Flags().BoolP("accept-channel", "", false, - "Accept the channel request for the corresponding recipient ID") - viper.BindPFlag("accept-channel", - protoCmd.Flags().Lookup("accept-channel")) - - protoCmd.Flags().Bool("delete-channel", false, - "Delete the channel information for the corresponding recipient ID") - viper.BindPFlag("delete-channel", - protoCmd.Flags().Lookup("delete-channel")) - - protoCmd.Flags().BoolP("send-auth-request", "", false, - "Send an auth request to the specified destination and wait"+ - "for confirmation") - viper.BindPFlag("send-auth-request", - protoCmd.Flags().Lookup("send-auth-request")) - protoCmd.Flags().UintP("auth-timeout", "", 120, - "The number of seconds to wait for an authentication channel"+ - "to confirm") - viper.BindPFlag("auth-timeout", - protoCmd.Flags().Lookup("auth-timeout")) - - protoCmd.Flags().BoolP("forceHistoricalRounds", "", false, - "Force all rounds to be sent to historical round retrieval") - viper.BindPFlag("forceHistoricalRounds", - protoCmd.Flags().Lookup("forceHistoricalRounds")) - - // Network params - protoCmd.Flags().BoolP("slowPolling", "", false, - "Enables polling for unfiltered network updates with RSA signatures") - viper.BindPFlag("slowPolling", - protoCmd.Flags().Lookup("slowPolling")) - protoCmd.Flags().Bool("forceMessagePickupRetry", false, - "Enable a mechanism which forces a 50% chance of no message pickup, "+ - "instead triggering the message pickup retry mechanism") - viper.BindPFlag("forceMessagePickupRetry", - protoCmd.Flags().Lookup("forceMessagePickupRetry")) - - // E2E Params - defaultE2EParams := params.GetDefaultE2ESessionParams() - protoCmd.Flags().UintP("e2eMinKeys", - "", uint(defaultE2EParams.MinKeys), - "Minimum number of keys used before requesting rekey") - viper.BindPFlag("e2eMinKeys", protoCmd.Flags().Lookup("e2eMinKeys")) - protoCmd.Flags().UintP("e2eMaxKeys", - "", uint(defaultE2EParams.MaxKeys), - "Max keys used before blocking until a rekey completes") - viper.BindPFlag("e2eMaxKeys", protoCmd.Flags().Lookup("e2eMaxKeys")) - protoCmd.Flags().UintP("e2eNumReKeys", - "", uint(defaultE2EParams.NumRekeys), - "Number of rekeys reserved for rekey operations") - viper.BindPFlag("e2eNumReKeys", protoCmd.Flags().Lookup("e2eNumReKeys")) - - protoCmd.Flags().String("profile-cpu", "", - "Enable cpu profiling to this file") - viper.BindPFlag("profile-cpu", protoCmd.Flags().Lookup("profile-cpu")) - rootCmd.AddCommand(protoCmd) } diff --git a/cmd/root.go b/cmd/root.go index 59146f00102a7280ededd08bc39c5b2c104d3810..cb68de315961afedadca2cb338c1b5833a580c12 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -58,8 +58,13 @@ var rootCmd = &cobra.Command{ pprof.StartCPUProfile(f) } - client := initClient() - + protoUserPath := viper.GetString("protoUserPath") + var client *api.Client + if protoUserPath != "" { + loadProtoClient() + } else { + client = initClient() + } user := client.GetUser() jww.INFO.Printf("User: %s", user.ReceptionID) writeContact(user.GetContact()) @@ -453,6 +458,13 @@ func initClient() *api.Client { jww.FATAL.Panicf("%+v", err) } + jsoBytes, err := client.ConstructProtoUerFile() + if err != nil { + jww.WARN.Printf("err: %v", err) + } + + jww.WARN.Printf("json %s", string(jsoBytes)) + return client } @@ -823,30 +835,30 @@ func init() { rootCmd.Flags().UintP("receiveCount", "", 1, "How many messages we should wait for before quitting") viper.BindPFlag("receiveCount", rootCmd.Flags().Lookup("receiveCount")) - rootCmd.Flags().UintP("waitTimeout", "", 15, + rootCmd.PersistentFlags().UintP("waitTimeout", "", 15, "The number of seconds to wait for messages to arrive") viper.BindPFlag("waitTimeout", - rootCmd.Flags().Lookup("waitTimeout")) + rootCmd.PersistentFlags().Lookup("waitTimeout")) rootCmd.Flags().BoolP("unsafe", "", false, "Send raw, unsafe messages without e2e encryption.") viper.BindPFlag("unsafe", rootCmd.Flags().Lookup("unsafe")) - rootCmd.Flags().BoolP("unsafe-channel-creation", "", false, + rootCmd.PersistentFlags().BoolP("unsafe-channel-creation", "", false, "Turns off the user identity authenticated channel check, "+ "automatically approving authenticated channels") viper.BindPFlag("unsafe-channel-creation", - rootCmd.Flags().Lookup("unsafe-channel-creation")) + rootCmd.PersistentFlags().Lookup("unsafe-channel-creation")) rootCmd.Flags().BoolP("accept-channel", "", false, "Accept the channel request for the corresponding recipient ID") viper.BindPFlag("accept-channel", rootCmd.Flags().Lookup("accept-channel")) - rootCmd.Flags().Bool("delete-channel", false, + rootCmd.PersistentFlags().Bool("delete-channel", false, "Delete the channel information for the corresponding recipient ID") viper.BindPFlag("delete-channel", - rootCmd.Flags().Lookup("delete-channel")) + rootCmd.PersistentFlags().Lookup("delete-channel")) rootCmd.Flags().BoolP("send-auth-request", "", false, "Send an auth request to the specified destination and wait"+ @@ -895,14 +907,15 @@ func init() { viper.BindPFlag("profile-cpu", rootCmd.Flags().Lookup("profile-cpu")) // Proto user flags - rootCmd.PersistentFlags().String("protoUserPath", "protoUser.json", + protoCmd.Flags().String("protoUserPath", "protoUser.json", "Path to proto user JSON file containing cryptographic primitives "+ "the client will load") - viper.BindPFlag("protoUserPath", rootCmd.Flags().Lookup("protoUserPath")) - rootCmd.PersistentFlags().String("protoUserOut", "protoUser.json", + viper.BindPFlag("protoUserPath", protoCmd.Flags().Lookup("protoUserPath")) + protoCmd.Flags().String("protoUserOut", "protoUser.json", "Path to which a normally constructed client "+ "will write proto user JSON file") - viper.BindPFlag("protoUserOut", rootCmd.Flags().Lookup("protoUserOut")) + viper.BindPFlag("protoUserOut", protoCmd.Flags().Lookup("protoUserOut")) + } diff --git a/interfaces/user/proto.go b/interfaces/user/proto.go index 8eff94714df122bb71a2cee836f4b3a594245dc5..0fcc0920a6b134800b9d8c73df6ee08417a92274 100644 --- a/interfaces/user/proto.go +++ b/interfaces/user/proto.go @@ -19,7 +19,6 @@ type Proto struct { // Timestamp in which user has registered with the network RegistrationTimestamp time.Time - Username string RegCode string TransmissionRegValidationSig []byte diff --git a/storage/session.go b/storage/session.go index 0b57d6d9f41f1e19b6c1ce6cffba1965c420c3e3..8ee2b43d3119b222612389685360d53b26bc9abf 100644 --- a/storage/session.go +++ b/storage/session.go @@ -94,7 +94,7 @@ func New(baseDir, password string, u userInterface.User, currentVersion version. s, err := initStore(baseDir, password) if err != nil { - return nil, errors.WithMessage(err, "Failed to create session") + return nil, errors.WithMessagef(err, "Failed to create session for %s", baseDir) } err = s.newRegStatus() diff --git a/storage/user/registation.go b/storage/user/registation.go index 4da19b4cd0faf8e83fe22ad2e177afb8d8109897..5644be40d0558addddff8dd8b6d6433b0c21c07c 100644 --- a/storage/user/registation.go +++ b/storage/user/registation.go @@ -112,6 +112,7 @@ func (u *User) SetReceptionRegistrationValidationSignature(b []byte) { defer u.rvsMux.Unlock() //check if the signature already exists + jww.WARN.Printf("receptionValidationSig: %v", u.receptionRegValidationSig) if u.receptionRegValidationSig != nil { jww.FATAL.Panicf("cannot overwrite existing reception Identity Validation Signature") }