aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/faucet/faucet.go4
-rw-r--r--cmd/geth/accountcmd.go123
-rw-r--r--cmd/geth/accountcmd_test.go16
-rw-r--r--cmd/puppeth/ssh.go49
-rw-r--r--cmd/puppeth/wizard.go14
-rw-r--r--cmd/puppeth/wizard_genesis.go2
-rw-r--r--cmd/puppeth/wizard_intro.go9
-rw-r--r--cmd/puppeth/wizard_netstats.go4
-rw-r--r--cmd/puppeth/wizard_network.go18
-rw-r--r--cmd/utils/flags.go32
-rw-r--r--cmd/wnode/main.go38
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(&params)
- if msg == nil {
- fmt.Printf("failed to create new message (OS level error)")
- os.Exit(0)
+ msg, err := whisper.NewSentMessage(&params)
+ if err != nil {
+ utils.Fatalf("failed to create new message: %s", err)
}
envelope, err := msg.Wrap(&params)
if err != nil {
@@ -624,9 +628,9 @@ func requestExpiredMessagesLoop() {
params.Src = nodeid
params.WorkTime = 5
- msg := whisper.NewSentMessage(&params)
- if msg == nil {
- utils.Fatalf("failed to create new message (OS level error)")
+ msg, err := whisper.NewSentMessage(&params)
+ if err != nil {
+ utils.Fatalf("failed to create new message: %s", err)
}
env, err := msg.Wrap(&params)
if err != nil {