mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 18:37:45 +08:00
config: guard against privkey being overwritten in fsrepo setConfig
License: MIT Signed-off-by: Jeromy <why@ipfs.io>
This commit is contained in:
parent
671425ea33
commit
91dd044d55
@ -163,28 +163,12 @@ included in the output of this command.
|
||||
return
|
||||
}
|
||||
|
||||
idmap, ok := cfg["Identity"].(map[string]interface{})
|
||||
if !ok {
|
||||
res.SetError(errors.New("config has no identity"), cmds.ErrNormal)
|
||||
err = scrubValue(cfg, []string{config.IdentityTag, config.PrivKeyTag})
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
privKeyKey := "" // make sure we both find the name of privkey and we delete it
|
||||
for key, _ := range idmap {
|
||||
if strings.ToLower(key) == "privkey" {
|
||||
if privKeyKey != "" {
|
||||
res.SetError(errors.New("found multiple PrivKey keys"), cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
privKeyKey = key
|
||||
}
|
||||
}
|
||||
if privKeyKey == "" {
|
||||
res.SetError(errors.New("haven't found PriveKey key"), cmds.ErrNormal)
|
||||
}
|
||||
|
||||
delete(idmap, privKeyKey)
|
||||
|
||||
output, err := config.HumanOutput(cfg)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
@ -195,6 +179,47 @@ included in the output of this command.
|
||||
},
|
||||
}
|
||||
|
||||
func scrubValue(m map[string]interface{}, key []string) error {
|
||||
find := func(m map[string]interface{}, k string) (string, interface{}, bool) {
|
||||
lckey := strings.ToLower(k)
|
||||
for mkey, val := range m {
|
||||
lcmkey := strings.ToLower(mkey)
|
||||
if lckey == lcmkey {
|
||||
return mkey, val, true
|
||||
}
|
||||
}
|
||||
return "", nil, false
|
||||
}
|
||||
|
||||
cur := m
|
||||
for _, k := range key[:len(key)-1] {
|
||||
foundk, val, ok := find(cur, k)
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to find specified key")
|
||||
}
|
||||
|
||||
if foundk != k {
|
||||
// case mismatch, calling this an error
|
||||
return fmt.Errorf("case mismatch in config, expected %q but got %q", k, foundk)
|
||||
}
|
||||
|
||||
mval, mok := val.(map[string]interface{})
|
||||
if !mok {
|
||||
return fmt.Errorf("%s was not a map", foundk)
|
||||
}
|
||||
|
||||
cur = mval
|
||||
}
|
||||
|
||||
todel, _, ok := find(cur, key[len(key)-1])
|
||||
if !ok {
|
||||
return fmt.Errorf("%s, not found", strings.Join(key, "."))
|
||||
}
|
||||
|
||||
delete(cur, todel)
|
||||
return nil
|
||||
}
|
||||
|
||||
var configEditCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Opens the config file for editing in $EDITOR.",
|
||||
@ -265,19 +290,10 @@ func getConfig(r repo.Repo, key string) (*ConfigField, error) {
|
||||
}
|
||||
|
||||
func setConfig(r repo.Repo, key string, value interface{}) (*ConfigField, error) {
|
||||
keyF, err := getConfig(r, "Identity.PrivKey")
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to get PrivKey")
|
||||
}
|
||||
privkey := keyF.Value
|
||||
err = r.SetConfigKey(key, value)
|
||||
err := r.SetConfigKey(key, value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set config value: %s (maybe use --json?)", err)
|
||||
}
|
||||
err = r.SetConfigKey("Identity.PrivKey", privkey)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to set PrivKey")
|
||||
}
|
||||
return getConfig(r, key)
|
||||
}
|
||||
|
||||
@ -301,7 +317,7 @@ func replaceConfig(r repo.Repo, file io.Reader) error {
|
||||
return errors.New("setting private key with API is not supported")
|
||||
}
|
||||
|
||||
keyF, err := getConfig(r, "Identity.PrivKey")
|
||||
keyF, err := getConfig(r, config.PrivKeySelector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get PrivKey")
|
||||
}
|
||||
|
||||
@ -5,6 +5,10 @@ import (
|
||||
ic "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
|
||||
)
|
||||
|
||||
const IdentityTag = "Identity"
|
||||
const PrivKeyTag = "PrivKey"
|
||||
const PrivKeySelector = IdentityTag + "." + PrivKeyTag
|
||||
|
||||
// Identity tracks the configuration of the local node's identity.
|
||||
type Identity struct {
|
||||
PeerID string
|
||||
|
||||
@ -482,6 +482,14 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Load private key to guard against it being overwritten.
|
||||
// NOTE: this is a temporary measure to secure this field until we move
|
||||
// keys out of the config file.
|
||||
pkval, err := common.MapGetKV(mapconf, config.PrivKeySelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the type of the value associated with the key
|
||||
oldValue, err := common.MapGetKV(mapconf, key)
|
||||
ok := true
|
||||
@ -523,6 +531,11 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// replace private key, in case it was overwritten.
|
||||
if err := common.MapSetKV(mapconf, "Identity.PrivKey", pkval); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This step doubles as to validate the map against the struct
|
||||
// before serialization
|
||||
conf, err := config.FromMap(mapconf)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user