diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/faucet/faucet.go | 4 | ||||
-rw-r--r-- | cmd/geth/accountcmd.go | 123 | ||||
-rw-r--r-- | cmd/geth/accountcmd_test.go | 16 | ||||
-rw-r--r-- | cmd/puppeth/ssh.go | 49 | ||||
-rw-r--r-- | cmd/puppeth/wizard.go | 14 | ||||
-rw-r--r-- | cmd/puppeth/wizard_genesis.go | 2 | ||||
-rw-r--r-- | cmd/puppeth/wizard_intro.go | 9 | ||||
-rw-r--r-- | cmd/puppeth/wizard_netstats.go | 4 | ||||
-rw-r--r-- | cmd/puppeth/wizard_network.go | 18 | ||||
-rw-r--r-- | cmd/utils/flags.go | 32 | ||||
-rw-r--r-- | cmd/wnode/main.go | 38 |
11 files changed, 197 insertions, 112 deletions
diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index f87cfdb72..1c5c43edc 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -61,7 +61,7 @@ var ( apiPortFlag = flag.Int("apiport", 8080, "Listener port for the HTTP API connection") ethPortFlag = flag.Int("ethport", 30303, "Listener port for the devp2p connection") bootFlag = flag.String("bootnodes", "", "Comma separated bootnode enode URLs to seed with") - netFlag = flag.Int("network", 0, "Network ID to use for the Ethereum protocol") + netFlag = flag.Uint64("network", 0, "Network ID to use for the Ethereum protocol") statsFlag = flag.String("ethstats", "", "Ethstats network monitoring auth string") netnameFlag = flag.String("faucet.name", "", "Network name to assign to the faucet") @@ -179,7 +179,7 @@ type faucet struct { lock sync.RWMutex // Lock protecting the faucet's internals } -func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network int, stats string, ks *keystore.KeyStore, index []byte) (*faucet, error) { +func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network uint64, stats string, ks *keystore.KeyStore, index []byte) (*faucet, error) { // Assemble the raw devp2p protocol stack stack, err := node.New(&node.Config{ Name: "geth", diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 90f79a47e..1a3c63da9 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -31,41 +31,33 @@ import ( var ( walletCommand = cli.Command{ - Name: "wallet", - Usage: "Manage Ethereum presale wallets", - ArgsUsage: "", - Category: "ACCOUNT COMMANDS", + Name: "wallet", + Usage: "Import Ethereum presale wallets", + Action: utils.MigrateFlags(importWallet), + Category: "ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, Description: ` - geth wallet import /path/to/my/presale.wallet + geth wallet [options] /path/to/my/presale.wallet -will prompt for your password and imports your ether presale account. -It can be used non-interactively with the --password option taking a -passwordfile as argument containing the wallet password in plaintext. + will prompt for your password and imports your ether presale account. + It can be used non-interactively with the --password option taking a + passwordfile as argument containing the wallet password in plaintext. -`, - Subcommands: []cli.Command{ - { - Action: importWallet, - Name: "import", - Usage: "Import Ethereum presale wallet", - ArgsUsage: "<keyFile>", - Description: ` -TODO: Please write this -`, - }, - }, + `, } accountCommand = cli.Command{ - Action: accountList, - Name: "account", - Usage: "Manage accounts", - ArgsUsage: "", - Category: "ACCOUNT COMMANDS", + Name: "account", + Usage: "Manage accounts", + Category: "ACCOUNT COMMANDS", Description: ` -Manage accounts lets you create new accounts, list all existing accounts, -import a private key into a new account. -' help' shows a list of subcommands or help for one subcommand. +Manage accounts, list all existing accounts, import a private key into a new +account, create a new account or update an existing account. It supports interactive mode, when you are prompted for password as well as non-interactive mode where passwords are supplied via a given password file. @@ -80,36 +72,34 @@ Note that exporting your key in unencrypted format is NOT supported. Keys are stored under <DATADIR>/keystore. It is safe to transfer the entire directory or the individual keys therein between ethereum nodes by simply copying. -Make sure you backup your keys regularly. -In order to use your account to send transactions, you need to unlock them using -the '--unlock' option. The argument is a space separated list of addresses or -indexes. If used non-interactively with a passwordfile, the file should contain -the respective passwords one per line. If you unlock n accounts and the password -file contains less than n entries, then the last password is meant to apply to -all remaining accounts. - -And finally. DO NOT FORGET YOUR PASSWORD. -`, +Make sure you backup your keys regularly.`, Subcommands: []cli.Command{ { - Action: accountList, - Name: "list", - Usage: "Print account addresses", - ArgsUsage: " ", + Name: "list", + Usage: "Print summary of existing accounts", + Action: utils.MigrateFlags(accountList), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + }, Description: ` -TODO: Please write this -`, +Print a short summary of all accounts`, }, { - Action: accountCreate, - Name: "new", - Usage: "Create a new account", - ArgsUsage: " ", + Name: "new", + Usage: "Create a new account", + Action: utils.MigrateFlags(accountCreate), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, Description: ` geth account new -Creates a new account. Prints the address. +Creates a new account and prints the address. The account is saved in encrypted format, you are prompted for a passphrase. @@ -117,17 +107,20 @@ You must remember this passphrase to unlock your account in the future. For non-interactive use the passphrase can be specified with the --password flag: - geth --password <passwordfile> account new - Note, this is meant to be used for testing only, it is a bad idea to save your password to file or expose in any other way. `, }, { - Action: accountUpdate, Name: "update", Usage: "Update an existing account", + Action: utils.MigrateFlags(accountUpdate), ArgsUsage: "<address>", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.LightKDFFlag, + }, Description: ` geth account update <address> @@ -141,16 +134,22 @@ format to the newest format or change the password for an account. For non-interactive use the passphrase can be specified with the --password flag: - geth --password <passwordfile> account update <address> + geth account update [options] <address> Since only one password can be given, only format update can be performed, changing your password is only possible interactively. `, }, { - Action: accountImport, - Name: "import", - Usage: "Import a private key into a new account", + Name: "import", + Usage: "Import a private key into a new account", + Action: utils.MigrateFlags(accountImport), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, ArgsUsage: "<keyFile>", Description: ` geth account import <keyfile> @@ -166,7 +165,7 @@ You must remember this passphrase to unlock your account in the future. For non-interactive use the passphrase can be specified with the -password flag: - geth --password <passwordfile> account import <keyfile> + geth account import [options] <keyfile> Note: As you can directly copy your encrypted accounts to another ethereum instance, @@ -298,10 +297,12 @@ func accountUpdate(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - account, oldPassword := unlockAccount(ctx, ks, ctx.Args().First(), 0, nil) - newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) - if err := ks.Update(account, oldPassword, newPassword); err != nil { - utils.Fatalf("Could not update the account: %v", err) + for _, addr := range ctx.Args() { + account, oldPassword := unlockAccount(ctx, ks, addr, 0, nil) + newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) + if err := ks.Update(account, oldPassword, newPassword); err != nil { + utils.Fatalf("Could not update the account: %v", err) + } } return nil } diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index adcb72454..5f9f67677 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -43,13 +43,13 @@ func tmpDatadirWithKeystore(t *testing.T) string { } func TestAccountListEmpty(t *testing.T) { - geth := runGeth(t, "account") + geth := runGeth(t, "account", "list") geth.expectExit() } func TestAccountList(t *testing.T) { datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, "--datadir", datadir, "account") + geth := runGeth(t, "account", "list", "--datadir", datadir) defer geth.expectExit() if runtime.GOOS == "windows" { geth.expect(` @@ -67,7 +67,7 @@ Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/k } func TestAccountNew(t *testing.T) { - geth := runGeth(t, "--lightkdf", "account", "new") + geth := runGeth(t, "account", "new", "--lightkdf") defer geth.expectExit() geth.expect(` Your new account is locked with a password. Please give a password. Do not forget this password. @@ -79,7 +79,7 @@ Repeat passphrase: {{.InputLine "foobar"}} } func TestAccountNewBadRepeat(t *testing.T) { - geth := runGeth(t, "--lightkdf", "account", "new") + geth := runGeth(t, "account", "new", "--lightkdf") defer geth.expectExit() geth.expect(` Your new account is locked with a password. Please give a password. Do not forget this password. @@ -92,9 +92,9 @@ Fatal: Passphrases do not match func TestAccountUpdate(t *testing.T) { datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, + geth := runGeth(t, "account", "update", "--datadir", datadir, "--lightkdf", - "account", "update", "f466859ead1932d743d622cb74fc058882e8648a") + "f466859ead1932d743d622cb74fc058882e8648a") defer geth.expectExit() geth.expect(` Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 @@ -107,7 +107,7 @@ Repeat passphrase: {{.InputLine "foobar2"}} } func TestWalletImport(t *testing.T) { - geth := runGeth(t, "--lightkdf", "wallet", "import", "testdata/guswallet.json") + geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") defer geth.expectExit() geth.expect(` !! Unsupported terminal, password will be echoed. @@ -122,7 +122,7 @@ Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} } func TestWalletImportBadPassword(t *testing.T) { - geth := runGeth(t, "--lightkdf", "wallet", "import", "testdata/guswallet.json") + geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") defer geth.expectExit() geth.expect(` !! Unsupported terminal, password will be echoed. diff --git a/cmd/puppeth/ssh.go b/cmd/puppeth/ssh.go index 34fbc566d..93668945c 100644 --- a/cmd/puppeth/ssh.go +++ b/cmd/puppeth/ssh.go @@ -17,6 +17,8 @@ package main import ( + "bufio" + "bytes" "errors" "fmt" "io/ioutil" @@ -37,18 +39,26 @@ import ( type sshClient struct { server string // Server name or IP without port number address string // IP address of the remote server + pubkey []byte // RSA public key to authenticate the server client *ssh.Client logger log.Logger } // dial establishes an SSH connection to a remote node using the current user and -// the user's configured private RSA key. -func dial(server string) (*sshClient, error) { +// the user's configured private RSA key. If that fails, password authentication +// is fallen back to. The caller may override the login user via user@server:port. +func dial(server string, pubkey []byte) (*sshClient, error) { // Figure out a label for the server and a logger label := server if strings.Contains(label, ":") { label = label[:strings.Index(label, ":")] } + login := "" + if strings.Contains(server, "@") { + login = label[:strings.Index(label, "@")] + label = label[strings.Index(label, "@")+1:] + server = server[strings.Index(server, "@")+1:] + } logger := log.New("server", label) logger.Debug("Attempting to establish SSH connection") @@ -56,6 +66,9 @@ func dial(server string) (*sshClient, error) { if err != nil { return nil, err } + if login == "" { + login = user.Username + } // Configure the supported authentication methods (private key and password) var auths []ssh.AuthMethod @@ -71,7 +84,7 @@ func dial(server string) (*sshClient, error) { } } auths = append(auths, ssh.PasswordCallback(func() (string, error) { - fmt.Printf("What's the login password for %s at %s? (won't be echoed)\n> ", user.Username, server) + fmt.Printf("What's the login password for %s at %s? (won't be echoed)\n> ", login, server) blob, err := terminal.ReadPassword(int(syscall.Stdin)) fmt.Println() @@ -86,11 +99,36 @@ func dial(server string) (*sshClient, error) { return nil, errors.New("no IPs associated with domain") } // Try to dial in to the remote server - logger.Trace("Dialing remote SSH server", "user", user.Username, "key", path) + logger.Trace("Dialing remote SSH server", "user", login) if !strings.Contains(server, ":") { server += ":22" } - client, err := ssh.Dial("tcp", server, &ssh.ClientConfig{User: user.Username, Auth: auths}) + keycheck := func(hostname string, remote net.Addr, key ssh.PublicKey) error { + // If no public key is known for SSH, ask the user to confirm + if pubkey == nil { + fmt.Printf("The authenticity of host '%s (%s)' can't be established.\n", hostname, remote) + fmt.Printf("SSH key fingerprint is %s [MD5]\n", ssh.FingerprintLegacyMD5(key)) + fmt.Printf("Are you sure you want to continue connecting (yes/no)? ") + + text, err := bufio.NewReader(os.Stdin).ReadString('\n') + switch { + case err != nil: + return err + case strings.TrimSpace(text) == "yes": + pubkey = key.Marshal() + return nil + default: + return fmt.Errorf("unknown auth choice: %v", text) + } + } + // If a public key exists for this SSH server, check that it matches + if bytes.Compare(pubkey, key.Marshal()) == 0 { + return nil + } + // We have a mismatch, forbid connecting + return errors.New("ssh key mismatch, readd the machine to update") + } + client, err := ssh.Dial("tcp", server, &ssh.ClientConfig{User: login, Auth: auths, HostKeyCallback: keycheck}) if err != nil { return nil, err } @@ -98,6 +136,7 @@ func dial(server string) (*sshClient, error) { c := &sshClient{ server: label, address: addr[0], + pubkey: pubkey, client: client, logger: logger, } diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go index 92d7962a0..9687d5e0d 100644 --- a/cmd/puppeth/wizard.go +++ b/cmd/puppeth/wizard.go @@ -44,14 +44,24 @@ type config struct { bootLight []string // Bootnodes to always connect to by light nodes ethstats string // Ethstats settings to cache for node deploys - Servers []string `json:"servers,omitempty"` + Servers map[string][]byte `json:"servers,omitempty"` +} + +// servers retrieves an alphabetically sorted list of servers. +func (c config) servers() []string { + servers := make([]string, 0, len(c.Servers)) + for server := range c.Servers { + servers = append(servers, server) + } + sort.Strings(servers) + + return servers } // flush dumps the contents of config to disk. func (c config) flush() { os.MkdirAll(filepath.Dir(c.path), 0755) - sort.Strings(c.Servers) out, _ := json.MarshalIndent(c, "", " ") if err := ioutil.WriteFile(c.path, out, 0644); err != nil { log.Warn("Failed to save puppeth configs", "file", c.path, "err", err) diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index a67812e92..705e01031 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -120,7 +120,7 @@ func (w *wizard) makeGenesis() { // Query the user for some custom extras fmt.Println() fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)") - genesis.Config.ChainId = big.NewInt(int64(w.readDefaultInt(rand.Intn(65536)))) + genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) fmt.Println() fmt.Println("Anything fun to embed into the genesis block? (max 32 bytes)") diff --git a/cmd/puppeth/wizard_intro.go b/cmd/puppeth/wizard_intro.go index 46383bb54..c3eaf5324 100644 --- a/cmd/puppeth/wizard_intro.go +++ b/cmd/puppeth/wizard_intro.go @@ -31,7 +31,10 @@ import ( // makeWizard creates and returns a new puppeth wizard. func makeWizard(network string) *wizard { return &wizard{ - network: network, + network: network, + conf: config{ + Servers: make(map[string][]byte), + }, servers: make(map[string]*sshClient), services: make(map[string][]string), in: bufio.NewReader(os.Stdin), @@ -77,9 +80,9 @@ func (w *wizard) run() { } else if err := json.Unmarshal(blob, &w.conf); err != nil { log.Crit("Previous configuration corrupted", "path", w.conf.path, "err", err) } else { - for _, server := range w.conf.Servers { + for server, pubkey := range w.conf.Servers { log.Info("Dialing previously configured server", "server", server) - client, err := dial(server) + client, err := dial(server, pubkey) if err != nil { log.Error("Previous server unreachable", "server", server, "err", err) } diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go index c2a933a55..1225abb75 100644 --- a/cmd/puppeth/wizard_netstats.go +++ b/cmd/puppeth/wizard_netstats.go @@ -41,14 +41,14 @@ func (w *wizard) networkStats(tips bool) { stats.SetHeader([]string{"Server", "IP", "Status", "Service", "Details"}) stats.SetColWidth(128) - for _, server := range w.conf.Servers { + for server, pubkey := range w.conf.Servers { client := w.servers[server] logger := log.New("server", server) logger.Info("Starting remote server health-check") // If the server is not connected, try to connect again if client == nil { - conn, err := dial(server) + conn, err := dial(server, pubkey) if err != nil { logger.Error("Failed to establish remote connection", "err", err) stats.Append([]string{server, "", err.Error(), "", ""}) diff --git a/cmd/puppeth/wizard_network.go b/cmd/puppeth/wizard_network.go index 001d4e5b4..0455e1ef3 100644 --- a/cmd/puppeth/wizard_network.go +++ b/cmd/puppeth/wizard_network.go @@ -28,7 +28,9 @@ import ( func (w *wizard) manageServers() { // List all the servers we can disconnect, along with an entry to connect a new one fmt.Println() - for i, server := range w.conf.Servers { + + servers := w.conf.servers() + for i, server := range servers { fmt.Printf(" %d. Disconnect %s\n", i+1, server) } fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) @@ -40,14 +42,14 @@ func (w *wizard) manageServers() { } // If the user selected an existing server, drop it if choice <= len(w.conf.Servers) { - server := w.conf.Servers[choice-1] + server := servers[choice-1] client := w.servers[server] delete(w.servers, server) if client != nil { client.Close() } - w.conf.Servers = append(w.conf.Servers[:choice-1], w.conf.Servers[choice:]...) + delete(w.conf.Servers, server) w.conf.flush() log.Info("Disconnected existing server", "server", server) @@ -73,14 +75,14 @@ func (w *wizard) makeServer() string { // Read and fial the server to ensure docker is present input := w.readString() - client, err := dial(input) + client, err := dial(input, nil) if err != nil { log.Error("Server not ready for puppeth", "err", err) return "" } // All checks passed, start tracking the server w.servers[input] = client - w.conf.Servers = append(w.conf.Servers, input) + w.conf.Servers[input] = client.pubkey w.conf.flush() return input @@ -93,7 +95,9 @@ func (w *wizard) selectServer() string { // List the available server to the user and wait for a choice fmt.Println() fmt.Println("Which server do you want to interact with?") - for i, server := range w.conf.Servers { + + servers := w.conf.servers() + for i, server := range servers { fmt.Printf(" %d. %s\n", i+1, server) } fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1) @@ -105,7 +109,7 @@ func (w *wizard) selectServer() string { } // If the user requested connecting to a new server, go for it if choice <= len(w.conf.Servers) { - return w.conf.Servers[choice-1] + return servers[choice-1] } return w.makeServer() } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index af9585bd0..9e80bba60 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -52,7 +52,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/params" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv2" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" "gopkg.in/urfave/cli.v1" ) @@ -148,7 +148,7 @@ var ( Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)", Value: eth.DefaultConfig.EthashDatasetsOnDisk, } - NetworkIdFlag = cli.IntFlag{ + NetworkIdFlag = cli.Uint64Flag{ Name: "networkid", Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten)", Value: eth.DefaultConfig.NetworkId, @@ -647,7 +647,7 @@ func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) { } } -// MakePasswordList reads password lines from the file specified by --password. +// MakePasswordList reads password lines from the file specified by the global --password flag. func MakePasswordList(ctx *cli.Context) []string { path := ctx.GlobalString(PasswordFileFlag.Name) if path == "" { @@ -806,7 +806,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { cfg.LightPeers = ctx.GlobalInt(LightPeersFlag.Name) } if ctx.GlobalIsSet(NetworkIdFlag.Name) { - cfg.NetworkId = ctx.GlobalInt(NetworkIdFlag.Name) + cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name) } // Ethereum needs to know maxPeers to calculate the light server peer ratio. @@ -979,3 +979,27 @@ func MakeConsolePreloads(ctx *cli.Context) []string { } return preloads } + +// MigrateFlags sets the global flag from a local flag when it's set. +// This is a temporary function used for migrating old command/flags to the +// new format. +// +// e.g. geth account new --keystore /tmp/mykeystore --lightkdf +// +// is equivalent after calling this method with: +// +// geth --keystore /tmp/mykeystore --lightkdf account new +// +// This allows the use of the existing configuration functionality. +// When all flags are migrated this function can be removed and the existing +// configuration functionality must be changed that is uses local flags +func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error { + return func(ctx *cli.Context) error { + for _, name := range ctx.FlagNames() { + if ctx.IsSet(name) { + ctx.GlobalSet(name, ctx.String(name)) + } + } + return action(ctx) + } +} diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go index 23b180487..f18025dff 100644 --- a/cmd/wnode/main.go +++ b/cmd/wnode/main.go @@ -65,7 +65,7 @@ var ( pub *ecdsa.PublicKey asymKey *ecdsa.PrivateKey nodeid *ecdsa.PrivateKey - topic []byte + topic whisper.TopicType asymKeyID string filterID string symPass string @@ -84,7 +84,7 @@ var ( testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics") echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics") - argVerbosity = flag.Int("verbosity", int(log.LvlWarn), "log verbosity level") + argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level") argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds") argWorkTime = flag.Uint("work", 5, "work time in seconds") argMaxSize = flag.Int("maxsize", whisper.DefaultMaxMessageLength, "max size of message") @@ -129,7 +129,7 @@ func processArgs() { if err != nil { utils.Fatalf("Failed to parse the topic: %s", err) } - topic = x + topic = whisper.BytesToTopic(x) } if *asymmetricMode && len(*argPub) > 0 { @@ -183,7 +183,7 @@ func initialize() { if *testMode { symPass = "wwww" // ascii code: 0x77777777 - msPassword = "mail server test password" + msPassword = "wwww" } if *bootstrapMode { @@ -307,7 +307,11 @@ func configureNode() { if *asymmetricMode { if len(*argPub) == 0 { s := scanLine("Please enter the peer's public key: ") - pub = crypto.ToECDSAPub(common.FromHex(s)) + b := common.FromHex(s) + if b == nil { + utils.Fatalf("Error: can not convert hexadecimal string") + } + pub = crypto.ToECDSAPub(b) if !isKeyValid(pub) { utils.Fatalf("Error: invalid public key") } @@ -326,7 +330,7 @@ func configureNode() { if !*asymmetricMode && !*forwarderMode { if len(symPass) == 0 { - symPass, err = console.Stdin.PromptPassword("Please enter the password: ") + symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ") if err != nil { utils.Fatalf("Failed to read passphrase: %v", err) } @@ -343,6 +347,8 @@ func configureNode() { if len(*argTopic) == 0 { generateTopic([]byte(symPass)) } + + fmt.Printf("Filter is configured for the topic: %x \n", topic) } if *mailServerMode { @@ -354,18 +360,17 @@ func configureNode() { filter := whisper.Filter{ KeySym: symKey, KeyAsym: asymKey, - Topics: [][]byte{topic}, + Topics: [][]byte{topic[:]}, AllowP2P: p2pAccept, } filterID, err = shh.Subscribe(&filter) if err != nil { utils.Fatalf("Failed to install filter: %s", err) } - fmt.Printf("Filter is configured for the topic: %x \n", topic) } func generateTopic(password []byte) { - x := pbkdf2.Key(password, password, 8196, 128, sha512.New) + x := pbkdf2.Key(password, password, 4096, 128, sha512.New) for i := 0; i < len(x); i++ { topic[i%whisper.TopicLength] ^= x[i] } @@ -485,16 +490,15 @@ func sendMsg(payload []byte) common.Hash { Dst: pub, KeySym: symKey, Payload: payload, - Topic: whisper.BytesToTopic(topic), + Topic: topic, TTL: uint32(*argTTL), PoW: *argPoW, WorkTime: uint32(*argWorkTime), } - msg := whisper.NewSentMessage(¶ms) - if msg == nil { - fmt.Printf("failed to create new message (OS level error)") - os.Exit(0) + msg, err := whisper.NewSentMessage(¶ms) + if err != nil { + utils.Fatalf("failed to create new message: %s", err) } envelope, err := msg.Wrap(¶ms) if err != nil { @@ -624,9 +628,9 @@ func requestExpiredMessagesLoop() { params.Src = nodeid params.WorkTime = 5 - msg := whisper.NewSentMessage(¶ms) - if msg == nil { - utils.Fatalf("failed to create new message (OS level error)") + msg, err := whisper.NewSentMessage(¶ms) + if err != nil { + utils.Fatalf("failed to create new message: %s", err) } env, err := msg.Wrap(¶ms) if err != nil { |