diff --git a/keyring.go b/keyring.go index 8c635f7..c9eb286 100644 --- a/keyring.go +++ b/keyring.go @@ -23,6 +23,7 @@ type Keyring interface { Search(string) (*Key, error) SearchType(string, string) (*Key, error) SetDefaultTimeout(uint) + AttachPersistent() (Keyring, error) } // Named keyrings are user-created keyrings linked to a parent keyring. The @@ -103,6 +104,13 @@ func (kr *keyring) SearchType(name string, keyType string) (*Key, error) { return nil, err } +// AttachPersistent attaches the current executing context's persistent +// keyring to this keyring. See persistent-keyring(7) for more info. +// It returns either an error, or the persistent Keyring. +func (kr *keyring) AttachPersistent() (Keyring, error) { + return attachPersistent(kr.id) +} + // Return the current login session keyring func SessionKeyring() (Keyring, error) { return newKeyring(keySpecSessionKeyring) diff --git a/keyring_test.go b/keyring_test.go index 2f33721..6d19a26 100644 --- a/keyring_test.go +++ b/keyring_test.go @@ -112,6 +112,18 @@ func TestCreateKeyring(t *testing.T) { } } +func TestAttachPersistentKeyring(t *testing.T) { + kr, err := SessionKeyring() + if err != nil { + t.Fatalf("unexpected test failure: could not create session keyring: %v", err) + } + pkr, err := kr.AttachPersistent() + if err != nil { + t.Fatalf("unexpected test failure: could not attach persistent keyring: %v", err) + } + t.Logf("found persistent keyring %d", pkr.Id()) +} + func TestCreateNestedKeyring(t *testing.T) { ring := helperTestCreateKeyring(nil, "", t) diff --git a/sys_linux.go b/sys_linux.go index 6c6bc2c..dd6f389 100644 --- a/sys_linux.go +++ b/sys_linux.go @@ -354,3 +354,12 @@ func keyctl_Move(id, from_ring keyId, to_ring keyId, flags uint) error { } return nil } + +func attachPersistent(id keyId) (*keyring, error) { + uid := int32(-1) + r1, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlGetPersistent), uintptr(uid), uintptr(id)) + if errno != 0 { + return nil, errno + } + return &keyring{id: keyId(r1)}, nil +}