diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 85c6ae1a3df..bd3146ca57c 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -12,11 +12,13 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" config "github.com/ipfs/go-ipfs-config" + keystore "github.com/ipfs/go-ipfs-keystore" oldcmds "github.com/ipfs/go-ipfs/commands" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" "github.com/ipfs/go-ipfs/core/commands/e" ke "github.com/ipfs/go-ipfs/core/commands/keyencode" fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" + migrations "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" options "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-core/crypto" peer "github.com/libp2p/go-libp2p-core/peer" @@ -150,7 +152,6 @@ path can be specified with '--output=' or '-o='. cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."), }, NoRemote: true, - PreRun: DaemonNotRunning, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { name := req.Arguments[0] @@ -163,13 +164,24 @@ path can be specified with '--output=' or '-o='. return err } - r, err := fsrepo.Open(cfgRoot) + // Check repo version, and error out if not matching + ver, err := migrations.RepoVersion(cfgRoot) + if err != nil { + return err + } + if ver != fsrepo.RepoVersion { + return fmt.Errorf("key export expects repo version (%d) but found (%d)", fsrepo.RepoVersion, ver) + } + + // Export is read-only: safe to read it without acquiring repo lock + // (this makes export work when ipfs daemon is already running) + ksp := filepath.Join(cfgRoot, "keystore") + ks, err := keystore.NewFSKeystore(ksp) if err != nil { return err } - defer r.Close() - sk, err := r.Keystore().Get(name) + sk, err := ks.Get(name) if err != nil { return fmt.Errorf("key with name '%s' doesn't exist", name) } diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index b3ae12fefd7..ad4b6a6c7c7 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -175,14 +175,25 @@ ipfs key rm key_ed25519 test_cmp rsa_key_id roundtrip_rsa_key_id ' - test_expect_success "online export rsa key" ' - test_must_fail ipfs key export generated_rsa_key + # export works directly on the keystore present in IPFS_PATH + test_expect_success "export and import ed25519 key while daemon is running" ' + edhash=$(ipfs key gen exported_ed25519_key --type=ed25519) + echo $edhash > ed25519_key_id + ipfs key export exported_ed25519_key && + ipfs key rm exported_ed25519_key && + ipfs key import exported_ed25519_key exported_ed25519_key.key > roundtrip_ed25519_key_id && + test_cmp ed25519_key_id roundtrip_ed25519_key_id + ' + + test_expect_success "key export over HTTP /api/v0/key/export is not possible" ' + ipfs key gen nohttpexporttest_key --type=ed25519 && + curl -X POST -sI "http://$API_ADDR/api/v0/key/export&arg=nohttpexporttest_key" | grep -q "^HTTP/1.1 404 Not Found" ' test_expect_success "online rotate rsa key" ' test_must_fail ipfs key rotate ' - + test_kill_ipfs_daemon }