diff --git a/README.md b/README.md index a5041e876b23c787616d2f260830f2aca19de0d3..70f68111713b9158077701f20fcccd73423a4fd9 100644 --- a/README.md +++ b/README.md @@ -145,59 +145,48 @@ Usage: client [command] Available Commands: - generate Generates version and dependency information for the - Elixxir binary + generate Generates version and dependency information for the Elixxir binary + getndf Download the network definition file from the network and print it. + group Group commands for cMix client help Help about any command - version Print the version and dependency information for the - Elixxir binary + init Initialize a user ID but do not connect to the network + single Send and respond to single-use messages. + ud Register for and search users using the xx network user discovery service. + version Print the version and dependency information for the Elixxir binary Flags: - --accept-channel Accept the channel request for the - corresponding recipient ID - --delete-channel Delete the channel information for the - corresponding recipient ID + --accept-channel Accept the channel request for the corresponding recipient ID + --auth-timeout uint The number of seconds to wait for an authentication channelto confirm (default 120) + --delete-channel Delete the channel information for the corresponding recipient ID --destfile string Read this contact file for the destination id - -d, --destid string ID to send message to (if below 40, will be - precanned. Use '0x' or 'b64:' for hex and - base64 representations) (default "0") - --forceHistoricalRounds Force all rounds to be sent to historical - round retrieval - --forceMessagePickupRetry Enable a mechanism which forces a 50% chance - of no message pickup, instead triggering the - message pickup retry mechanism + -d, --destid string ID to send message to (if below 40, will be precanned. Use '0x' or 'b64:' for hex and base64 representations) (default "0") + --e2eMaxKeys uint Max keys used before blocking until a rekey completes (default 800) + --e2eMinKeys uint Minimum number of keys used before requesting rekey (default 500) + --e2eNumReKeys uint Number of rekeys reserved for rekey operations (default 16) + --forceHistoricalRounds Force all rounds to be sent to historical round retrieval + --forceMessagePickupRetry Enable a mechanism which forces a 50% chance of no message pickup, instead triggering the message pickup retry mechanism -h, --help help for client - -l, --log string Path to the log output path (- is stdout) - (default "-") + -l, --log string Path to the log output path (- is stdout) (default "-") + -v, --logLevel uint Verbose mode for debugging -m, --message string Message to send - -n, --ndf string Path to the network definition JSON file - (default "ndf.json") + -n, --ndf string Path to the network definition JSON file (default "ndf.json") -p, --password string Password to the session file - --receiveCount uint How many messages we should wait for before - quitting (default 1) - --regcode string Registration code (optional) - --sendCount uint The number of times to send the message - (default 1) - --sendDelay uint The delay between sending the messages in ms - (default 500) - --sendid uint Use precanned user id (must be between 1 and - 40, inclusive) - --slowPolling bool Enables polling for all network updates and RSA signed rounds. - Defaults to true (filtered updates with ECC signed rounds) if not set - - -s, --session string Sets the initial directory for client storage - --unsafe Send raw, unsafe messages without e2e - encryption. - --unsafe-channel-creation Turns off the user identity authenticated - channel check, automatically approving - authenticated channels - --verboseRoundTracking Verbose round tracking, keeps track and prints - all rounds the client was aware of while running. - Defaults to false if not set. - -v, --logLevel uint Level of debugging to print (0 = info, - 1 = debug, >1 = trace). (Default info) - --waitTimeout uint The number of seconds to wait for messages to - arrive (default 15) - -w, --writeContact string Write the contact file for this user to this + --profile-cpu string Enable cpu profiling to this file + --protoUserOut string Path to which a normally constructed client will write proto user JSON file (default "protoUser.json") + --protoUserPath string Path to proto user JSON file containing cryptographic primitives the client will load (default "protoUser.json") + --receiveCount uint How many messages we should wait for before quitting (default 1) + --regcode string Identity code (optional) + --send-auth-request Send an auth request to the specified destination and waitfor confirmation + --sendCount uint The number of times to send the message (default 1) + --sendDelay uint The delay between sending the messages in ms (default 500) + --sendid uint Use precanned user id (must be between 1 and 40, inclusive) + -s, --session string Sets the initial storage directory for client session data + --slowPolling Enables polling for unfiltered network updates with RSA signatures + --unsafe Send raw, unsafe messages without e2e encryption. + --unsafe-channel-creation Turns off the user identity authenticated channel check, automatically approving authenticated channels + --verboseRoundTracking Verbose round tracking, keeps track and prints all rounds the client was aware of while running. Defaults to false if not set. + --waitTimeout uint The number of seconds to wait for messages to arrive (default 15) + -w, --writeContact string Write contact information, if any, to this file, defaults to stdout (default "-") file Use "client [command] --help" for more information about a command. diff --git a/api/client.go b/api/client.go index 8a8fa597878365eb924b84d777b423bb44390a29..d3f6254563940a6b85921df9bb093b3f22b8a834 100644 --- a/api/client.go +++ b/api/client.go @@ -366,7 +366,8 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, // LoginWithProtoClient creates a client object with a protoclient JSON containing the // cryptographic primitives. This is designed for some specific deployment -//// procedures and is generally unsafe. +// 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, newBaseNdf string, parameters params.Network) (*Client, error) { jww.INFO.Printf("LoginWithNewBaseNDF_UNSAFE()") diff --git a/api/permissioning.go b/api/permissioning.go index 606c436441ba76b80dda1400228903263bc9741c..0f79b94aef4d354648fb78f61c58e7aff2c3d397 100644 --- a/api/permissioning.go +++ b/api/permissioning.go @@ -10,7 +10,6 @@ package api import ( "encoding/json" "github.com/pkg/errors" - jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/interfaces/user" "gitlab.com/elixxir/client/storage" ) @@ -42,13 +41,6 @@ func (c *Client) registerWithPermissioning() error { userData.SetReceptionRegistrationValidationSignature(receptionRegValidationSignature) userData.SetRegistrationTimestamp(registrationTimestamp) - - - err = c.printProtoUser(regCode, transmissionRegValidationSignature, receptionRegValidationSignature) - if err != nil { - return errors.WithMessage(err, "failed to print proto user") - } - //update the registration state err = c.storage.ForwardRegistrationStatus(storage.PermissioningComplete) if err != nil { @@ -58,29 +50,35 @@ func (c *Client) registerWithPermissioning() error { return nil } -// todo: remove once deploy has been tested -func (c *Client) printProtoUser(regCode string, - transmissionRegValidationSignature, receptionRegValidationSignature []byte) error { - // todo: remove this once proto has been generated +// 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 errors.WithMessage(err, "failed to register with "+ + return nil, errors.WithMessage(err, "failed to register with "+ + "permissioning") + } + + //load the registration code + regCode, err := c.storage.GetRegCode() + if err != nil { + return nil, errors.WithMessage(err, "failed to register with "+ "permissioning") } Usr := user.Proto{ TransmissionID: c.GetUser().TransmissionID, - TransmissionSalt: c.GetUser().TransmissionSalt, - TransmissionRSA: c.GetUser().TransmissionRSA, - ReceptionID: c.GetUser().ReceptionID, + TransmissionSalt: c.GetUser().TransmissionSalt, + TransmissionRSA: c.GetUser().TransmissionRSA, + ReceptionID: c.GetUser().ReceptionID, ReceptionSalt: c.GetUser().ReceptionSalt, ReceptionRSA: c.GetUser().ReceptionRSA, Precanned: c.GetUser().Precanned, - RegistrationTimestamp: c.GetUser().RegistrationTimestamp, - Username: username, - RegCode: regCode, - TransmissionRegValidationSig: transmissionRegValidationSignature, - ReceptionRegValidationSig: receptionRegValidationSignature, + RegistrationTimestamp: c.GetUser().RegistrationTimestamp, + Username: username, + RegCode: regCode, + TransmissionRegValidationSig: c.storage.User().GetTransmissionRegistrationValidationSignature(), + ReceptionRegValidationSig: c.storage.User().GetReceptionRegistrationValidationSignature(), CmixDhPrivateKey: c.GetStorage().Cmix().GetDHPrivateKey(), CmixDhPublicKey: c.GetStorage().Cmix().GetDHPublicKey(), E2eDhPrivateKey: c.GetStorage().E2e().GetDHPrivateKey(), @@ -89,11 +87,9 @@ func (c *Client) printProtoUser(regCode string, jsonBytes, err := json.Marshal(Usr) if err != nil { - return errors.WithMessage(err, "failed to register with "+ + return nil, errors.WithMessage(err, "failed to register with "+ "permissioning") } - jww.INFO.Printf("PROTO USER JSON: \n%s", string(jsonBytes)) - - return nil -} \ No newline at end of file + return jsonBytes, nil +} diff --git a/cmd/proto.go b/cmd/proto.go new file mode 100644 index 0000000000000000000000000000000000000000..f2a43c57392c69757a462935d479e4202cc48ae3 --- /dev/null +++ b/cmd/proto.go @@ -0,0 +1,476 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +/////////////////////////////////////////////////////////////////////////////// + +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" +) + +var protoCmd = &cobra.Command{ + Use: "proto", + Short: "Load client with a proto client JSON file.", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + // If output path is specified, only write to file + 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) + } + + err = utils.WriteFileDef(protoOutputPath, jsonBytes) + if err != nil { + jww.FATAL.Panicf("Failed to write proto user to file: %v", err) + } + return + } + + 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) + } + + pass := viper.GetString("password") + storeDir := viper.GetString("session") + + netParams := params.GetDefaultNetwork() + netParams.E2EParams.MinKeys = uint16(viper.GetUint("e2eMinKeys")) + netParams.E2EParams.MaxKeys = uint16(viper.GetUint("e2eMaxKeys")) + netParams.E2EParams.NumRekeys = uint16( + viper.GetUint("e2eNumReKeys")) + netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds") + netParams.FastPolling = viper.GetBool(" slowPolling") + netParams.ForceMessagePickupRetry = viper.GetBool("forceMessagePickupRetry") + if netParams.ForceMessagePickupRetry { + period := 3 * time.Second + jww.INFO.Printf("Setting Uncheck Round Period to %v", period) + netParams.UncheckRoundPeriod = period + } + netParams.VerboseRoundTracking = viper.GetBool("verboseRoundTracking") + + // Load NDF + ndfPath := viper.GetString("ndf") + ndfJSON, err := ioutil.ReadFile(ndfPath) + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + + client, err := api.LoginWithProtoClient(storeDir, []byte(pass), + protoUserFile, string(ndfJSON), netParams) + if err != nil { + jww.FATAL.Panicf("Failed to login: %v", err) + } + + return client +} + +// init is the initialization function for Cobra which defines commands +// and flags. +func init() { + // NOTE: The point of init() is to be declarative. + // 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) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + + // Proto user flags + protoCmd.PersistentFlags().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.PersistentFlags().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.PersistentFlags().UintP("logLevel", "v", 0, + "Verbose mode for debugging") + viper.BindPFlag("logLevel", protoCmd.PersistentFlags().Lookup("logLevel")) + + protoCmd.PersistentFlags().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.PersistentFlags().Lookup("verboseRoundTracking")) + + protoCmd.PersistentFlags().StringP("session", "s", + "", "Sets the initial storage directory for "+ + "client session data") + viper.BindPFlag("session", protoCmd.PersistentFlags().Lookup("session")) + + protoCmd.PersistentFlags().StringP("writeContact", "w", + "-", "Write contact information, if any, to this file, "+ + " defaults to stdout") + viper.BindPFlag("writeContact", protoCmd.PersistentFlags().Lookup( + "writeContact")) + + protoCmd.PersistentFlags().StringP("password", "p", "", + "Password to the session file") + viper.BindPFlag("password", protoCmd.PersistentFlags().Lookup( + "password")) + + protoCmd.PersistentFlags().StringP("ndf", "n", "ndf.json", + "Path to the network definition JSON file") + viper.BindPFlag("ndf", protoCmd.PersistentFlags().Lookup("ndf")) + + protoCmd.PersistentFlags().StringP("log", "l", "-", + "Path to the log output path (- is stdout)") + viper.BindPFlag("log", protoCmd.PersistentFlags().Lookup("log")) + + protoCmd.Flags().StringP("regcode", "", "", + "Identity code (optional)") + viper.BindPFlag("regcode", protoCmd.Flags().Lookup("regcode")) + + protoCmd.PersistentFlags().StringP("message", "m", "", + "Message to send") + viper.BindPFlag("message", protoCmd.PersistentFlags().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")) +} diff --git a/cmd/root.go b/cmd/root.go index 23416872ee7e210fbe6b886bee12788a17d0e1bc..9cd04f06c83547e04d567d0559be4e5fce403a63 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -893,6 +893,17 @@ func init() { rootCmd.Flags().String("profile-cpu", "", "Enable cpu profiling to this file") viper.BindPFlag("profile-cpu", rootCmd.Flags().Lookup("profile-cpu")) + + // Proto user flags + rootCmd.PersistentFlags().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", + "Path to which a normally constructed client "+ + "will write proto user JSON file") + viper.BindPFlag("protoUserOut", rootCmd.Flags().Lookup("protoUserOut")) + } // initConfig reads in config file and ENV variables if set.