diff --git a/keyring.go b/keyring.go index 6761087..981ef1d 100644 --- a/keyring.go +++ b/keyring.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build linux // +build linux // A Go interface to linux kernel keyrings (keyctl interface) @@ -21,6 +22,7 @@ type Keyring interface { Add(string, []byte) (*Key, error) Search(string) (*Key, error) SetDefaultTimeout(uint) + AttachPersistent() (Keyring, error) } // Named keyrings are user-created keyrings linked to a parent keyring. The @@ -93,6 +95,13 @@ func (kr *keyring) Search(name 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 a78d43c..5513fc1 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 0c4c194..9e8abbb 100644 --- a/sys_linux.go +++ b/sys_linux.go @@ -37,6 +37,12 @@ const ( keyctlSetReqKeyKeyring keyctlSetTimeout keyctlAssumeAuthority + keyctlGetSecurity + keyctlSessionToParent + keyctlReject + keyctlInstantiateIOV + keyctlInvalidate + keyctlGetPersistent ) var debugSyscalls bool @@ -81,6 +87,8 @@ func (cmd keyctlCommand) String() string { return "keyctlSetTimeout" case keyctlAssumeAuthority: return "keyctlAssumeAuthority" + case keyctlGetPersistent: + return "keyctlGetPersistent" } panic("bad arg") } @@ -294,3 +302,12 @@ func updateKey(id keyId, payload []byte) 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 +}