Ask for the mnemonic and passphrase before taking the state directory lock (closes #152)
check / check (push) Waiting to run
check / check (push) Waiting to run
init, vault create, unlocker add, and add, import and generate secret with --force asked for the mnemonic or passphrase, or unlocked the vault, while holding the state directory lock, so every other command that changes anything waited at the prompt. They now ask and unlock first and lock after. What they checked before asking is checked again under the lock: unlocker add fails if the vault was removed meanwhile and refuses a GPG key added meanwhile, and a forced add fails if another command created the secret meanwhile, rather than ask under the lock. secret.CreatePGPUnlocker now takes the vault, already unlocked. Not done: secret move between vaults still unlocks both under the lock; the issue does not name it. Model: opus-5-5
This commit is contained in:
+33
-27
@@ -67,36 +67,15 @@ func (cli *Instance) promptMnemonic() (*memguard.LockedBuffer, func(), error) {
|
||||
return mnemonicBuffer, mnemonicBuffer.Destroy, nil
|
||||
}
|
||||
|
||||
// Init initializes the secret manager, holding the state directory lock
|
||||
// while initialize runs
|
||||
// Init initializes the secret manager. It asks for the mnemonic and the
|
||||
// passphrase before it takes the state directory lock, so that no other
|
||||
// command waits while the user answers, and holds the lock while
|
||||
// initialize runs.
|
||||
func (cli *Instance) Init(cmd *cobra.Command) error {
|
||||
release, err := vault.LockStateDir(cli.fs, cli.stateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
return cli.initialize(cmd)
|
||||
}
|
||||
|
||||
// initialize creates the state directory, the default vault and its first
|
||||
// unlocker
|
||||
func (cli *Instance) initialize(cmd *cobra.Command) error {
|
||||
secret.Debug("Starting secret manager initialization")
|
||||
|
||||
// Create state directory
|
||||
stateDir := cli.GetStateDir()
|
||||
secret.DebugWith("Creating state directory", slog.String("path", stateDir))
|
||||
|
||||
err := cli.fs.MkdirAll(stateDir, secret.DirPerms)
|
||||
if err != nil {
|
||||
secret.Debug("Failed to create state directory", "error", err)
|
||||
|
||||
return fmt.Errorf("failed to create state directory: %w", err)
|
||||
}
|
||||
|
||||
// Refuse an existing default vault before asking for anything
|
||||
err = vault.CheckNewVaultName(cli.fs, cli.stateDir, defaultVaultName)
|
||||
err := vault.CheckNewVaultName(cli.fs, cli.stateDir, defaultVaultName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create default vault: %w", err)
|
||||
}
|
||||
@@ -135,11 +114,38 @@ func (cli *Instance) initialize(cmd *cobra.Command) error {
|
||||
}
|
||||
defer cleanupPassphrase()
|
||||
|
||||
release, err := vault.LockStateDir(cli.fs, cli.stateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer release()
|
||||
|
||||
return cli.initialize(cmd, mnemonic, passphraseBuffer)
|
||||
}
|
||||
|
||||
// initialize creates the state directory, and the default vault from
|
||||
// mnemonic with a passphrase unlocker protected by passphrase. Another
|
||||
// command may have created the vault since Init checked: vault.CreateVault
|
||||
// checks again.
|
||||
func (cli *Instance) initialize(
|
||||
cmd *cobra.Command, mnemonic, passphrase *memguard.LockedBuffer,
|
||||
) error {
|
||||
// Create state directory
|
||||
stateDir := cli.GetStateDir()
|
||||
secret.DebugWith("Creating state directory", slog.String("path", stateDir))
|
||||
|
||||
err := cli.fs.MkdirAll(stateDir, secret.DirPerms)
|
||||
if err != nil {
|
||||
secret.Debug("Failed to create state directory", "error", err)
|
||||
|
||||
return fmt.Errorf("failed to create state directory: %w", err)
|
||||
}
|
||||
|
||||
// Create the default vault with its passphrase unlocker
|
||||
secret.Debug("Creating default vault")
|
||||
|
||||
vlt, err := vault.CreateVault(cli.fs, cli.stateDir, defaultVaultName,
|
||||
mnemonic, passphraseBuffer)
|
||||
mnemonic, passphrase)
|
||||
if err != nil {
|
||||
secret.Debug("Failed to create default vault", "error", err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user