check / check (push) Failing after 2s
Keychain and Secure Enclave unlocker IDs were the creation time to the minute plus the host name, and passphrase unlocker IDs the time to the minute, so two created within one minute shared an ID, and `unlocker select`, `unlocker remove` and the selection after `unlocker add` acted on the older one. Every unlocker's ID is now its directory name, unique in its vault. `vault.ListUnlockers` returns each unlocker's metadata keyed by that name, so `unlocker list` and shell completion no longer find IDs by matching metadata. PGP unlocker IDs were `pgp-<fingerprint>`; a second PGP unlocker for one key is refused by comparing fingerprints in metadata. Model: opus-5-5
85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
//go:build !darwin
|
|
|
|
package secret
|
|
|
|
import (
|
|
"errors"
|
|
"path/filepath"
|
|
|
|
"filippo.io/age"
|
|
"github.com/awnumar/memguard"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
// KeychainUnlockerMetadata is a stub for non-Darwin platforms
|
|
type KeychainUnlockerMetadata struct {
|
|
UnlockerMetadata
|
|
|
|
KeychainItemName string `json:"keychainItemName"`
|
|
}
|
|
|
|
// KeychainUnlocker is a stub for non-Darwin platforms
|
|
type KeychainUnlocker struct {
|
|
Directory string
|
|
Metadata UnlockerMetadata
|
|
fs afero.Fs
|
|
}
|
|
|
|
var errKeychainNotSupported = errors.New(
|
|
"keychain unlockers are only supported on macOS")
|
|
|
|
// NewKeychainUnlocker creates a stub KeychainUnlocker on non-Darwin
|
|
// platforms. The returned instance's methods that require macOS
|
|
// functionality will return errors.
|
|
func NewKeychainUnlocker(
|
|
fs afero.Fs, directory string, metadata UnlockerMetadata,
|
|
) *KeychainUnlocker {
|
|
return &KeychainUnlocker{
|
|
Directory: directory,
|
|
Metadata: metadata,
|
|
fs: fs,
|
|
}
|
|
}
|
|
|
|
// GetIdentity returns an error on non-Darwin platforms
|
|
func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|
return nil, errKeychainNotSupported
|
|
}
|
|
|
|
// GetType returns the unlocker type
|
|
func (k *KeychainUnlocker) GetType() string {
|
|
return "keychain"
|
|
}
|
|
|
|
// GetMetadata returns the unlocker metadata
|
|
func (k *KeychainUnlocker) GetMetadata() UnlockerMetadata {
|
|
return k.Metadata
|
|
}
|
|
|
|
// GetDirectory returns the unlocker directory
|
|
func (k *KeychainUnlocker) GetDirectory() string {
|
|
return k.Directory
|
|
}
|
|
|
|
// GetID returns the unlocker ID, the name of the unlocker's directory
|
|
func (k *KeychainUnlocker) GetID() string {
|
|
return filepath.Base(k.Directory)
|
|
}
|
|
|
|
// GetKeychainItemName returns an error on non-Darwin platforms
|
|
func (k *KeychainUnlocker) GetKeychainItemName() (string, error) {
|
|
return "", errKeychainNotSupported
|
|
}
|
|
|
|
// Remove returns an error on non-Darwin platforms
|
|
func (k *KeychainUnlocker) Remove() error {
|
|
return errKeychainNotSupported
|
|
}
|
|
|
|
// CreateKeychainUnlocker returns an error on non-Darwin platforms
|
|
func CreateKeychainUnlocker(
|
|
_ afero.Fs, _ string, _, _ *memguard.LockedBuffer,
|
|
) (*KeychainUnlocker, error) {
|
|
return nil, errKeychainNotSupported
|
|
}
|