From c0d87b1e44bab002b5dc6ce46e210d419cb32011 Mon Sep 17 00:00:00 2001 From: Anatolij Ostroumov Date: Sun, 17 Oct 2021 00:09:00 +0300 Subject: [PATCH 1/2] 1. upgrade comments to make golint happier 2. typos fixed 3. Processor changed to Possessor, like they explain in man documentation 4. Backported ARM uniptr's from https://github.com/jsipprell/keyctl/pull/8 5. Generate better documentation for https://pkg.go.dev/github.com/jsipprell/keyctl 6. UPD travis config to include newer golang versions --- .gitignore | 2 + .travis.yml | 14 ++++--- Makefile | 17 ++++++++ README.md | 57 ++++++++++++++++++--------- doc.go | 6 +++ go.mod | 8 ++++ go.sum | 14 +++++++ key.go | 20 +++++----- key_test.go | 6 +-- keyring.go | 96 +++++++++++++++++++++------------------------- keyring_test.go | 20 +++++----- perms.go | 79 ++++++++++++++++++++++++++------------ pgp/doc.go | 12 ++++++ pgp/passphrase.go | 15 ++------ pgp/prompt.go | 5 +++ reader.go | 4 +- reader_test.go | 4 +- ref.go | 67 ++++++++++++++++---------------- ref_test.go | 2 +- sys_linux.go | 88 +++++++++++++++++++++--------------------- sys_linux_386.go | 8 ++-- sys_linux_amd64.go | 8 ++-- sys_linux_arm.go | 11 ++++++ sys_test.go | 2 +- writer.go | 11 +++--- 25 files changed, 346 insertions(+), 230 deletions(-) create mode 100644 Makefile create mode 100644 doc.go create mode 100644 go.sum create mode 100644 pgp/doc.go create mode 100644 sys_linux_arm.go diff --git a/.gitignore b/.gitignore index 7605460..f817923 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ c.out coverage.html +.idea/ +cover.out \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 911fc44..bf6ae39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,15 @@ branches: - master language: go go: - - 1.11 + - "1.11" + - "1.15" + - "1.16" - tip install: - - go get golang.org/x/crypto/openpgp - - go get golang.org/x/crypto/cast5 - - go get golang.org/x/crypto/ssh/terminal - - go get golang.org/x/tools/cmd/cover + - go get -u golang.org/x/tools/cmd/cover + - go get -u golang.org/x/lint/golint + - make -v + - make deps - go build -v ./... script: - - go test -v -cover + - make check diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e279166 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +deps: + go mod download + go mod verify + go mod tidy + +lint: +# format code + gofmt -w=true -s=true -l=true . +# run basic code quality and sanity check + golint ./... + go vet ./... + +check: lint +# ran unit tests with coverage report + go test -v -coverprofile=cover.out ./... + +test: check diff --git a/README.md b/README.md index 4604039..b520b15 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -[![GoDoc](https://godoc.org/github.com/jsipprell/keyctl?status.svg)](https://godoc.org/github.com/jsipprell/keyctl) -[![Build Status](https://travis-ci.org/jsipprell/keyctl.svg?branch=master)](https://travis-ci.org/jsipprell/keyctl) - # keyctl +[![GoDoc](https://pkg.go.dev/github.com/jsipprell/keyctl?status.svg)](https://pkg.go.dev/github.com/jsipprell/keyctl) +[![Build Status](https://travis-ci.org/jsipprell/keyctl.svg?branch=master)](https://travis-ci.org/jsipprell/keyctl) +[![Go Report Card](https://goreportcard.com/badge/github.com/jsipprell/keyctl)](https://goreportcard.com/report/github.com/jsipprell/keyctl) + A native Go API for the security key management system (aka "keyrings") found in Linux 2.6+ The keyctl interface is nominally provided by three or so Linux-specific syscalls, however it is almost always wrapped @@ -47,24 +48,42 @@ To search for an existing key by name: package main import ( - "log" - "github.com/jsipprell/keyctl" + "log" + + "github.com/jsipprell/keyctl" ) func main() { - keyring, err := keyctl.SessionKeyring() - if err != nil { - log.Fatal(err) - } - key, err := keyring.Search("some-data") - if err != nil { - log.Fatal(err) - } - - data, err := key.Get() - if err != nil { - log.Fatal(err) - } - log.Printf("secure data: %v\n", data) + keyring, err := keyctl.SessionKeyring() + if err != nil { + log.Fatal(err) + } + key, err := keyring.Search("some-data") + if err != nil { + log.Fatal(err) + } + + data, err := key.Get() + if err != nil { + log.Fatal(err) + } + log.Printf("secure data: %v\n", data) } ``` + +Running tests +=================== + +Ensure you have [GNU make](https://www.gnu.org/software/make/) installed. + +```shell + + $ make check + +``` + + +Copyright: 2015 Jesse Sipprell. All rights reserved. +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file. + diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..cb3304b --- /dev/null +++ b/doc.go @@ -0,0 +1,6 @@ +// Package keyctl is a Go interface to linux kernel keyrings (keyctl interface) described here https://man7.org/linux/man-pages/man7/keyrings.7.html +package keyctl + +// Copyright 2015 Jesse Sipprell. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. diff --git a/go.mod b/go.mod index 0b6e906..5c48a29 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,9 @@ module github.com/jsipprell/keyctl + +go 1.15 + +require ( + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..87c67d1 --- /dev/null +++ b/go.sum @@ -0,0 +1,14 @@ +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/key.go b/key.go index 7d03c0c..a83a7bd 100644 --- a/key.go +++ b/key.go @@ -4,30 +4,30 @@ import ( "time" ) -// Represents a single key linked to one or more kernel keyrings. +// Key represents a single key linked to one or more kernel keyrings. type Key struct { Name string - id, ring keyId + id, ring keyID size int ttl time.Duration } func (k *Key) private() {} -// Returns the 32-bit kernel identifier for a specific key -func (k *Key) Id() int32 { +// ID returns the 32-bit kernel identifier for a specific key +func (k *Key) ID() int32 { return int32(k.id) } -// To expire a key automatically after some period of time call this method. +// ExpireAfter makes key expire automatically after some period of time call this method. func (k *Key) ExpireAfter(nsecs uint) error { k.ttl = time.Duration(nsecs) * time.Second - return keyctl_SetTimeout(k.id, nsecs) + return keyctlSetTimeoutFunc(k.id, nsecs) } -// Return information about a key. +// Info return information about a key. func (k *Key) Info() (Info, error) { return getInfo(k.id) } @@ -46,10 +46,10 @@ func (k *Key) Get() ([]byte, error) { size := k.size - b = make([]byte, int(size)) + b = make([]byte, size) sizeRead = size + 1 for sizeRead > size { - r1, err := keyctl_Read(k.id, &b[0], size) + r1, err := keyctlReadFunc(k.id, &b[0], size) if err != nil { return nil, err } @@ -77,5 +77,5 @@ func (k *Key) Set(b []byte) error { // Unlink a key from the keyring it was loaded from (or added to). If the key // is not linked to any other keyrings, it is destroyed. func (k *Key) Unlink() error { - return keyctl_Unlink(k.id, k.ring) + return keyctlUnlinkFunc(k.id, k.ring) } diff --git a/key_test.go b/key_test.go index 43d73f9..2bb7b2e 100644 --- a/key_test.go +++ b/key_test.go @@ -73,7 +73,7 @@ func TestRandomKey256(t *testing.T) { t.Fatal(err) } - t.Logf("added %d byte random value key as: %v (%v)\n", len(r256), id.Id(), r256) + t.Logf("added %d byte random value key as: %v (%v)\n", len(r256), id.ID(), r256) helperCompareBlock(t, "rand256", r256, nil) } @@ -89,12 +89,12 @@ func TestRandomKey700(t *testing.T) { t.Fatal(err) } - t.Logf("added %d byte random value key as: %v (%v)\n", len(r700), id.Id(), r700) + t.Logf("added %d byte random value key as: %v (%v)\n", len(r700), id.ID(), r700) helperCompareBlock(t, "rand700", r700, nil) time.Sleep(time.Duration(5)*time.Second + time.Duration(250000)) if _, err = ring.Search("rand700"); err == nil { t.Fatal("'rand700' key did not expire in five seconds") } - t.Logf("key %v expired after five seconds", id.Id()) + t.Logf("key %v expired after five seconds", id.ID()) } diff --git a/keyring.go b/keyring.go index 5c5a9b9..696b83e 100644 --- a/keyring.go +++ b/keyring.go @@ -1,31 +1,24 @@ -// Copyright 2015 Jesse Sipprell. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux - -// A Go interface to linux kernel keyrings (keyctl interface) package keyctl -// All Keys and Keyrings have unique 32-bit serial number identifiers. -type Id interface { - Id() int32 +// ID is interface for all Keys and Keyrings that have unique 32-bit serial number identifiers. +type ID interface { + ID() int32 Info() (Info, error) private() } -// Basic interface to a linux keyctl keyring. +// Keyring is a basic interface to a linux keyctl keyring. type Keyring interface { - Id + ID Add(string, []byte) (*Key, error) Search(string) (*Key, error) SetDefaultTimeout(uint) } -// Named keyrings are user-created keyrings linked to a parent keyring. The +// NamedKeyring are user-created keyrings linked to a parent keyring. The // parent can be either named or one of the in-built keyrings (session, group -// etc). The in-built keyrings have no parents. Keyring searching is performed +// etc.). The in-built keyrings have no parents. Keyring searching is performed // hierarchically. type NamedKeyring interface { Keyring @@ -33,48 +26,47 @@ type NamedKeyring interface { } type keyring struct { - id keyId - defaultTtl uint + id keyID + defaultTTL uint } type namedKeyring struct { *keyring - parent keyId + parent keyID name string // for non-anonymous keyrings ttl uint } func (kr *keyring) private() {} -// Returns the 32-bit kernel identifier of a keyring -func (kr *keyring) Id() int32 { +// ID returns the 32-bit kernel identifier of a keyring +func (kr *keyring) ID() int32 { return int32(kr.id) } -// Returns information about a keyring. +// Info returns information about a keyring. func (kr *keyring) Info() (Info, error) { return getInfo(kr.id) } -// Return the name of a NamedKeyring that was set when the keyring was created +// Name return the name of a NamedKeyring that was set when the keyring was created // or opened. func (kr *namedKeyring) Name() string { return kr.name } -// Set a default timeout, in seconds, after which newly added keys will be -// destroyed. +// SetDefaultTimeout in seconds, after which newly added keys will be destroyed. func (kr *keyring) SetDefaultTimeout(nsecs uint) { - kr.defaultTtl = nsecs + kr.defaultTTL = nsecs } // Add a new key to a keyring. The key can be searched for later by name. func (kr *keyring) Add(name string, key []byte) (*Key, error) { - r, err := add_key("user", name, key, int32(kr.id)) + r, err := addKeyFunc("user", name, key, int32(kr.id)) if err == nil { - key := &Key{Name: name, id: keyId(r), ring: kr.id} - if kr.defaultTtl != 0 { - err = key.ExpireAfter(kr.defaultTtl) + key := &Key{Name: name, id: keyID(r), ring: kr.id} + if kr.defaultTTL != 0 { + err = key.ExpireAfter(kr.defaultTTL) } return key, err } @@ -93,34 +85,34 @@ func (kr *keyring) Search(name string) (*Key, error) { return nil, err } -// Return the current login session keyring +// SessionKeyring return the current login session keyring func SessionKeyring() (Keyring, error) { return newKeyring(keySpecSessionKeyring) } -// Return the current user-session keyring (part of session, but private to +// UserSessionKeyring return the current user-session keyring (part of session, but private to // current user) func UserSessionKeyring() (Keyring, error) { return newKeyring(keySpecUserSessionKeyring) } -// Return the current group keyring. +// GroupKeyring return the current group keyring. func GroupKeyring() (Keyring, error) { return newKeyring(keySpecGroupKeyring) } -// Return the keyring specific to the current executing thread. +// ThreadKeyring return the keyring specific to the current executing thread. func ThreadKeyring() (Keyring, error) { return newKeyring(keySpecThreadKeyring) } -// Return the keyring specific to the current executing process. +// ProcessKeyring returns the keyring specific to the current executing process. func ProcessKeyring() (Keyring, error) { return newKeyring(keySpecProcessKeyring) } -// Creates a new named-keyring linked to a parent keyring. The parent may be -// one of those returned by SessionKeyring(), UserSessionKeyring() and friends +// CreateKeyring creates a new named-keyring linked to a parent keyring. The parent may be +// one of those returned by SessionKeyring(), UserSessionKeyring() and friends, // or it may be an existing named-keyring. When searching is performed, all // keyrings form a hierarchy and are searched top-down. If the keyring already // exists it will be destroyed and a new one with the same name created. Named @@ -129,8 +121,8 @@ func ProcessKeyring() (Keyring, error) { func CreateKeyring(parent Keyring, name string) (NamedKeyring, error) { var ttl uint - parentId := keyId(parent.Id()) - kr, err := createKeyring(parentId, name) + parentID := keyID(parent.ID()) + kr, err := createKeyring(parentID, name) if err != nil { return nil, err } @@ -140,39 +132,39 @@ func CreateKeyring(parent Keyring, name string) (NamedKeyring, error) { } ring := &namedKeyring{ keyring: kr, - parent: parentId, + parent: parentID, name: name, ttl: ttl, } if ttl > 0 { - err = keyctl_SetTimeout(ring.id, ttl) + err = keyctlSetTimeoutFunc(ring.id, ttl) } return ring, nil } -// Search for and open an existing keyring with the given name linked to a +// OpenKeyring search for and open an existing keyring with the given name linked to a // parent keyring (at any depth). func OpenKeyring(parent Keyring, name string) (NamedKeyring, error) { - parentId := keyId(parent.Id()) - id, err := searchKeyring(parentId, name, "keyring") + parentID := keyID(parent.ID()) + id, err := searchKeyring(parentID, name, "keyring") if err != nil { return nil, err } return &namedKeyring{ keyring: &keyring{id: id}, - parent: parentId, + parent: parentID, name: name, }, nil } -// Set the time to live in seconds for an entire keyring and all of its keys. +// SetKeyringTTL set the time to live in seconds for an entire keyring and all of its keys. // Only named keyrings can have their time-to-live set, the in-built keyrings -// cannot (Session, UserSession, etc). +// cannot (Session, UserSession, etc.). func SetKeyringTTL(kr NamedKeyring, nsecs uint) error { - err := keyctl_SetTimeout(keyId(kr.Id()), nsecs) + err := keyctlSetTimeoutFunc(keyID(kr.ID()), nsecs) if err == nil { kr.(*namedKeyring).ttl = nsecs } @@ -180,16 +172,16 @@ func SetKeyringTTL(kr NamedKeyring, nsecs uint) error { } // Link an object to a keyring -func Link(parent Keyring, child Id) error { - return keyctl_Link(keyId(child.Id()), keyId(parent.Id())) +func Link(parent Keyring, child ID) error { + return keyctlLinkFunc(keyID(child.ID()), keyID(parent.ID())) } // Unlink an object from a keyring -func Unlink(parent Keyring, child Id) error { - return keyctl_Unlink(keyId(child.Id()), keyId(parent.Id())) +func Unlink(parent Keyring, child ID) error { + return keyctlUnlinkFunc(keyID(child.ID()), keyID(parent.ID())) } -// Unlink a named keyring from its parent. +// UnlinkKeyring a named keyring from its parent. func UnlinkKeyring(kr NamedKeyring) error { - return keyctl_Unlink(keyId(kr.Id()), kr.(*namedKeyring).parent) + return keyctlUnlinkFunc(keyID(kr.ID()), kr.(*namedKeyring).parent) } diff --git a/keyring_test.go b/keyring_test.go index a78d43c..5cd27c3 100644 --- a/keyring_test.go +++ b/keyring_test.go @@ -14,7 +14,7 @@ func TestAdd100BytesToSessionKeyring(t *testing.T) { t.Fatal(err) } - t.Logf("added 100 byte empty key as: %v\n", key.Id()) + t.Logf("added 100 byte empty key as: %v\n", key.ID()) buf, err := key.Get() if err != nil { @@ -34,7 +34,7 @@ func TestAdd128BytesToSessionExpireAfter10Seconds(t *testing.T) { if err != nil { t.Fatal(err) } - t.Logf("added 128 byte empty key as: %v\n", key.Id()) + t.Logf("added 128 byte empty key as: %v\n", key.ID()) } func TestFetchKey(t *testing.T) { @@ -99,7 +99,7 @@ func helperTestCreateKeyring(ring Keyring, name string, t *testing.T) NamedKeyri t.Fatal(err) } - t.Logf("created keyring %v named %q", ring.Id(), ring.(NamedKeyring).Name()) + t.Logf("created keyring %v named %q", ring.ID(), ring.(NamedKeyring).Name()) return ring.(NamedKeyring) } @@ -121,9 +121,9 @@ func TestCreateNestedKeyring(t *testing.T) { } ring = helperTestCreateKeyring(ring, "testring2", t) - t.Logf("created nested keyring %v named %q", ring.Id(), ring.Name()) + t.Logf("created nested keyring %v named %q", ring.ID(), ring.Name()) ring = helperTestCreateKeyring(ring, "testring3", t) - t.Logf("created nested keyring %v named %q", ring.Id(), ring.Name()) + t.Logf("created nested keyring %v named %q", ring.ID(), ring.Name()) } func TestOpenNestedKeyring(t *testing.T) { @@ -139,15 +139,15 @@ func TestOpenNestedKeyring(t *testing.T) { } ring = helperTestCreateKeyring(ring, "testring2", t) - t.Logf("created nested keyring %v named %q", ring.Id(), ring.Name()) + t.Logf("created nested keyring %v named %q", ring.ID(), ring.Name()) ring = helperTestCreateKeyring(ring, "testring3", t) - t.Logf("created nested keyring %v named %q", ring.Id(), ring.Name()) + t.Logf("created nested keyring %v named %q", ring.ID(), ring.Name()) ring, err = OpenKeyring(us, "testring3") if err != nil { t.Fatal(err) } - t.Logf("successfully reopened keyring %v named %q", ring.Id(), ring.Name()) + t.Logf("successfully reopened keyring %v named %q", ring.ID(), ring.Name()) } func TestUnlinkKeyring(t *testing.T) { @@ -161,12 +161,12 @@ func TestUnlinkKeyring(t *testing.T) { t.Fatal(err) } - t.Logf("created keyring %v named %q", nring.Id(), nring.Name()) + t.Logf("created keyring %v named %q", nring.ID(), nring.Name()) err = UnlinkKeyring(nring) if err != nil { t.Fatal(err) } - t.Logf("unlinked keyring %v [%s]", nring.Id(), nring.Name()) + t.Logf("unlinked keyring %v [%s]", nring.ID(), nring.Name()) } diff --git a/perms.go b/perms.go index 4113820..14c9e3a 100644 --- a/perms.go +++ b/perms.go @@ -1,51 +1,81 @@ package keyctl +// Good read - https://man7.org/linux/man-pages/man7/keyrings.7.html + // KeyPerm represents in-kernel access control permission to keys and keyrings // as a 32-bit integer broken up into four permission sets, one per byte. -// In MSB order, the perms are: Processor, User, Group, Other. +// In MSB order, the perms are: Possessor, User, Group, Other. type KeyPerm uint32 const ( + // PermOtherView shows other can view this key PermOtherView KeyPerm = 1 << iota + // PermOtherRead shows other can read this key PermOtherRead + // PermOtherWrite shows other can write this key PermOtherWrite + // PermOtherSearch shows other can search this key PermOtherSearch + // PermOtherLink shows other can link this key PermOtherLink + // PermOtherSetattr shows other can set attributes to this key PermOtherSetattr ) const ( + // PermGroupView shows group can view this key PermGroupView KeyPerm = 1 << (8 + iota) + // PermGroupRead shows group can read this key PermGroupRead + // PermGroupWrite shows group can write this key PermGroupWrite + // PermGroupSearch shows group can search this key PermGroupSearch + // PermGroupLink shows group can link this key PermGroupLink + // PermGroupSetattr shows group can set attributes to this key PermGroupSetattr ) const ( + // PermUserView shows user can viewthis key PermUserView KeyPerm = 1 << (16 + iota) + // PermUserRead shows user can read this key PermUserRead + // PermUserWrite shows user can write this key PermUserWrite + // PermUserSearch shows user can search this key PermUserSearch + // PermUserLink shows user can link this key PermUserLink + // PermUserSetattr shows user can sett attributes to this key PermUserSetattr ) const ( - PermProcessView KeyPerm = 1 << (24 + iota) - PermProcessRead - PermProcessWrite - PermProcessSearch - PermProcessLink - PermProcessSetattr + // PermPossessorView shows processors can view this key + PermPossessorView KeyPerm = 1 << (24 + iota) + // PermPossessorRead shows processors can read this key + PermPossessorRead + // PermPossessorWrite shows processors can write this key + PermPossessorWrite + // PermPossessorSearch shows processors can search this key + PermPossessorSearch + // PermPossessorLink shows processors can link this key + PermPossessorLink + // PermPossessorSetattr shows process can set attributes to this key + PermPossessorSetattr ) const ( + // PermOtherAll shows others can do everything to this key PermOtherAll KeyPerm = 0x3f << (8 * iota) + // PermGroupAll shows group can do everything to this key PermGroupAll + // PermUserAll shows user can do everything to this key PermUserAll - PermProcessAll + // PermPossessorAll shows process can do everything to this key + PermPossessorAll ) var permsChars = []byte("--alswrv") @@ -66,45 +96,44 @@ func encodePerms(p uint8) string { return string(out) } -// Returns processor permissions in symbolic form -func (p KeyPerm) Process() string { +// Possess returns possess permissions in symbolic form +func (p KeyPerm) Possess() string { return encodePerms(uint8(uint(p) >> 24)) } -// Returns the group permissions in symbolic form +// Group returns the group permissions in symbolic form func (p KeyPerm) Group() string { return encodePerms(uint8(uint(p) >> 8)) } -// Returns the user permissions in symbolic form +// User returns the user permissions in symbolic form func (p KeyPerm) User() string { return encodePerms(uint8(uint(p) >> 16)) } -// Returns other (default) permissions in symbolic form +// Other returns other (default) permissions in symbolic form func (p KeyPerm) Other() string { return encodePerms(uint8(p)) } +// String returns string representation of key permissions func (p KeyPerm) String() string { - return p.Process()[2:] + p.User()[2:] + p.Group()[2:] + p.Other()[2:] + return p.Possess()[2:] + p.User()[2:] + p.Group()[2:] + p.Other()[2:] } -// Change user ownership on a key or keyring. -func Chown(k Id, user int) error { +// Chown change user ownership on a key or keyring. +func Chown(k ID, user int) error { group := -1 - - return keyctl_Chown(keyId(k.Id()), user, group) + return keyctlChownFunc(keyID(k.ID()), user, group) } -// Change group ownership on a key or keyring. -func Chgrp(k Id, group int) error { +// Chgrp change group ownership on a key or keyring. +func Chgrp(k ID, group int) error { user := -1 - - return keyctl_Chown(keyId(k.Id()), user, group) + return keyctlChownFunc(keyID(k.ID()), user, group) } -// Set permissions on a key or keyring. -func SetPerm(k Id, p KeyPerm) error { - return keyctl_SetPerm(keyId(k.Id()), uint32(p)) +// SetPerm set permissions on a key or keyring. +func SetPerm(k ID, p KeyPerm) error { + return keyctlSetPermFunc(keyID(k.ID()), uint32(p)) } diff --git a/pgp/doc.go b/pgp/doc.go new file mode 100644 index 0000000..6a94875 --- /dev/null +++ b/pgp/doc.go @@ -0,0 +1,12 @@ +// Package pgp provides a keyring with an openpgp.ReadMessage wrapper +// method that when called will automatically attempt +// private key decryption and save the passphrase in the +// private session kernel keyring for a configurable +// amount of time. If an encrypted private key is seen again +// before it expires, the original PromptFunction will not +// be called (unless decryption fails) +package pgp + +// Copyright 2015 Jesse Sipprell. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. diff --git a/pgp/passphrase.go b/pgp/passphrase.go index 96bdc9b..df77af3 100644 --- a/pgp/passphrase.go +++ b/pgp/passphrase.go @@ -2,13 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Provides a keyring with an openpgp.ReadMessage wrapper -// method that when called will automatically attempt -// private key decryption and save the passphrase in the -// private session kernel keyring for a configurable -// amount of time. If an encrypted private key is seen again -// before it expires, the original PromptFunction will not -// be called (unless decryption fails) package pgp import ( @@ -19,12 +12,12 @@ import ( "golang.org/x/crypto/openpgp/packet" ) -// A standard passphrase prompting interface +// Prompter is a standard passphrase prompting interface type Prompter interface { Prompt([]openpgp.Key, bool) ([]byte, error) } -// A wrapper keyring that can automatically decrypt openpgp secret keys if the +// PassphraseKeyring is a wrapper keyring that can automatically decrypt openpgp secret keys if the // passphrase was previously used by the keyring (and the ttl has not expired) // Such caching lives beyond the lifetime of the current process unless the // process or thread keyring is used. @@ -41,7 +34,7 @@ type passphrase struct { type prompter openpgp.PromptFunction -// Create a new Prompter from an openpgp prompting function +// NewPrompter creates a new Prompter from an openpgp prompting function func NewPrompter(prompt openpgp.PromptFunction) Prompter { return prompter(prompt) } @@ -50,7 +43,7 @@ func (fn prompter) Prompt(keys []openpgp.Key, symmetric bool) ([]byte, error) { return fn(keys, symmetric) } -// A look-alike to "golang.org/x/crypto/opengpg".ReadMessage. When called it +// ReadMessage is analog to "golang.org/x/crypto/opengpg".ReadMessage. When called it // calls the openpgp.ReadMessage function, passing the io.Reader and // openpgp.Keyring verbatim but in func (pkr PassphraseKeyring) ReadMessage(r io.Reader, keyring openpgp.KeyRing, diff --git a/pgp/prompt.go b/pgp/prompt.go index a412e31..23f94b6 100644 --- a/pgp/prompt.go +++ b/pgp/prompt.go @@ -1,3 +1,7 @@ +// Copyright 2015 Jesse Sipprell. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package pgp import ( @@ -8,6 +12,7 @@ import ( "golang.org/x/crypto/ssh/terminal" ) +// PassphrasePrompt asks for password in secure way via terminal func PassphrasePrompt(keys []openpgp.Key, symmetric bool) ([]byte, error) { if len(keys) == 0 && !symmetric { return nil, io.EOF diff --git a/reader.go b/reader.go index c4213d1..d17b775 100644 --- a/reader.go +++ b/reader.go @@ -29,13 +29,13 @@ func (r *reader) Read(b []byte) (int, error) { return r.Buffer.Read(b) } -// Returns an io.Reader interface object which will read the key's data from +// NewReader returns an io.Reader interface object which will read the key's data from // the kernel. func NewReader(key *Key) io.Reader { return &reader{key: key} } -// Open an existing key on a keyring given its name +// OpenReader opens an existing key on a keyring given its name func OpenReader(name string, ring Keyring) (io.Reader, error) { key, err := ring.Search(name) if err == nil { diff --git a/reader_test.go b/reader_test.go index bbfdf1f..89ceeb1 100644 --- a/reader_test.go +++ b/reader_test.go @@ -5,7 +5,7 @@ import ( "testing" ) -func helperSetRandBlock(name string, sz int) (key Id, ring Keyring, blk []byte, err error) { +func helperSetRandBlock(name string, sz int) (key ID, ring Keyring, blk []byte, err error) { if ring, err = SessionKeyring(); err != nil { return } @@ -36,7 +36,7 @@ func TestStreamReader(t *testing.T) { buf := make([]byte, 128) for i, err = r.Read(buf); err == nil; i, err = r.Read(buf) { helperCmp(t, blk[:i], buf[:i]) - t.Logf("compared key %v %d bytes: %v", key.Id(), i, blk[:i]) + t.Logf("compared key %v %d bytes: %v", key.ID(), i, blk[:i]) blk = blk[i:] } diff --git a/ref.go b/ref.go index ea82f76..acc42f3 100644 --- a/ref.go +++ b/ref.go @@ -8,37 +8,35 @@ import ( ) var ( - // Error returned if the Get() method is called on a Reference that doesn't + // ErrUnsupportedKeyType error is returned if the Get() method is called on a Reference that doesn't // represent a key or keychain. ErrUnsupportedKeyType = errors.New("unsupported keyctl key type") - // Error returned if a reference is stale when Info() or Get() is called on - // it. + // ErrInvalidReference error is returned if a reference is stale when Info() or Get() is called on it. ErrInvalidReference = errors.New("invalid keyctl reference") ) // Reference is a reference to an unloaded keyctl Key or Keychain. It can be // dereferenced by calling the Get() method. type Reference struct { - // Id is the kernel key or keychain identifier referenced. - Id int32 - + // ID is the kernel key or keychain identifier referenced. + ID int32 info *Info - parent keyId + parent keyID } -// Information about a keyctl reference as returned by ref.Info() +// Info depicts information about a keyctl reference as returned by ref.Info() type Info struct { Type, Name string - Uid, Gid int + UID, Gid int Perm KeyPerm valid bool } -func getInfo(id keyId) (i Info, err error) { +func getInfo(id keyID) (i Info, err error) { var desc []byte - if desc, err = describeKeyId(id); err != nil { + if desc, err = describeKeyID(id); err != nil { i.Name = err.Error() return } @@ -56,7 +54,7 @@ func getInfo(id keyId) (i Info, err error) { i.Gid, _ = strconv.Atoi(string(fields[2])) fallthrough case 2: - i.Uid, _ = strconv.Atoi(string(fields[1])) + i.UID, _ = strconv.Atoi(string(fields[1])) fallthrough case 1: if i.Type = string(fields[0]); i.Type == "user" { @@ -69,23 +67,22 @@ func getInfo(id keyId) (i Info, err error) { return } -// Returns permissions in symbolic format. +// Permissions returns permissions in symbolic format. func (i Info) Permissions() string { - if i.Uid == os.Geteuid() { + if i.UID == os.Geteuid() { return encodePerms(uint8(i.Perm >> KeyPerm(16))) - } else { - fsgid, err := getfsgid() - if (err == nil && i.Gid == int(fsgid)) || i.Gid == os.Getegid() { - return encodePerms(uint8(i.Perm >> KeyPerm(8))) - } + } + fsgid, err := getfsgid() + if (err == nil && i.Gid == int(fsgid)) || i.Gid == os.Getegid() { + return encodePerms(uint8(i.Perm >> KeyPerm(8))) } return encodePerms(uint8(i.Perm)) } -// Return Information about a keyctl reference. +// Info returns Information about a keyctl reference. func (r *Reference) Info() (i Info, err error) { if r.info == nil { - i, err = getInfo(keyId(r.Id)) + i, err = getInfo(keyID(r.ID)) r.info = &i return } @@ -93,23 +90,27 @@ func (r *Reference) Info() (i Info, err error) { return *r.info, err } -// Returns true if the Info fetched by ref.Info() is valid. +// Valid returns true if the Info fetched by ref.Info() is valid. func (i Info) Valid() bool { return i.valid } -// Returns true if the keyctl reference is valid. Refererences can become +// Valid returns true if the keyctl reference is valid. References can become // invalid if they have expired since the reference was created. func (r *Reference) Valid() bool { if r.info == nil { - r.Info() + i, err := r.Info() + if err != nil { + return false + } + return i.valid } return r.info.valid } -// Loads the referenced keyctl object, which must either be a key or a +// Get loads the referenced keyctl object, which must either be a key or a // keyring otherwise ErrUnsupportedKeyType will be returned. -func (r *Reference) Get() (Id, error) { +func (r *Reference) Get() (ID, error) { if r.info == nil { _, err := r.Info() if err != nil { @@ -123,10 +124,10 @@ func (r *Reference) Get() (Id, error) { switch r.info.Type { case "key", "big_key": - return &Key{Name: r.info.Name, id: keyId(r.Id), ring: r.parent}, nil + return &Key{Name: r.info.Name, id: keyID(r.ID), ring: r.parent}, nil case "keyring": - ring := &keyring{id: keyId(r.Id)} - if r.Id > 0 && r.info.Name != "" { + ring := &keyring{id: keyID(r.ID)} + if r.ID > 0 && r.info.Name != "" { return &namedKeyring{ keyring: ring, parent: r.parent, @@ -139,12 +140,12 @@ func (r *Reference) Get() (Id, error) { } } -// List the contents of a keyring. Each contained object is represented by a -// Reference struct. Addl information is available by calling ref.Info(), and +// ListKeyring shows the contents of a keyring. Each contained object is represented by a +// Reference struct. Address information is available by calling ref.Info(), and // contained objects which are keys or subordinate keyrings can be fetched by // calling ref.Get() func ListKeyring(kr Keyring) ([]Reference, error) { - id := keyId(kr.Id()) + id := keyID(kr.ID()) keys, err := listKeys(id) if err != nil { return nil, err @@ -153,7 +154,7 @@ func ListKeyring(kr Keyring) ([]Reference, error) { refs := make([]Reference, len(keys)) for i, k := range keys { - refs[i].Id, refs[i].parent = int32(k), id + refs[i].ID, refs[i].parent = int32(k), id } return refs, nil diff --git a/ref_test.go b/ref_test.go index 80e7f7a..dc17663 100644 --- a/ref_test.go +++ b/ref_test.go @@ -30,7 +30,7 @@ func helperTestKeyRefs(ring Keyring, t *testing.T) []Reference { } for _, r := range refs { - t.Logf("%d: %+v [%s]\n", r.Id, mustInfo(r), mustInfo(r).Permissions()) + t.Logf("%d: %+v [%s]\n", r.ID, mustInfo(r), mustInfo(r).Permissions()) } return refs diff --git a/sys_linux.go b/sys_linux.go index 0c4c194..bf5f795 100644 --- a/sys_linux.go +++ b/sys_linux.go @@ -7,20 +7,20 @@ import ( type keyctlCommand int -type keyId int32 +type keyID int32 const ( - keySpecThreadKeyring keyId = -1 - keySpecProcessKeyring keyId = -2 - keySpecSessionKeyring keyId = -3 - keySpecUserKeyring keyId = -4 - keySpecUserSessionKeyring keyId = -5 - keySpecGroupKeyring keyId = -6 - keySpecReqKeyAuthKey keyId = -7 + keySpecThreadKeyring keyID = -1 + keySpecProcessKeyring keyID = -2 + keySpecSessionKeyring keyID = -3 + keySpecUserKeyring keyID = -4 + keySpecUserSessionKeyring keyID = -5 + keySpecGroupKeyring keyID = -6 + keySpecReqKeyAuthKey keyID = -7 ) const ( - keyctlGetKeyringId keyctlCommand = iota + keyctlGetKeyringID keyctlCommand = iota keyctlJoinSessionKeyring keyctlUpdate keyctlRevoke @@ -41,14 +41,14 @@ const ( var debugSyscalls bool -func (id keyId) Id() int32 { +func (id keyID) ID() int32 { return int32(id) } func (cmd keyctlCommand) String() string { switch cmd { - case keyctlGetKeyringId: - return "keyctlGetKeyringId" + case keyctlGetKeyringID: + return "keyctlGetKeyringID" case keyctlJoinSessionKeyring: return "keyctlJoinSessionKeyring" case keyctlUpdate: @@ -85,16 +85,16 @@ func (cmd keyctlCommand) String() string { panic("bad arg") } -func keyctl_SetTimeout(id keyId, nsecs uint) error { - _, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlSetTimeout), uintptr(id), uintptr(nsecs)) +func keyctlSetTimeoutFunc(id keyID, nsecs uint) error { + _, _, errno := syscall.Syscall(syscallKeyctlPTR, uintptr(keyctlSetTimeout), uintptr(id), uintptr(nsecs)) if errno != 0 { return errno } return nil } -func keyctl_Read(id keyId, b *byte, size int) (int32, error) { - v1, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlRead), uintptr(id), uintptr(unsafe.Pointer(b)), uintptr(size), 0, 0) +func keyctlReadFunc(id keyID, b *byte, size int) (int32, error) { + v1, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlRead), uintptr(id), uintptr(unsafe.Pointer(b)), uintptr(size), 0, 0) if errno != 0 { return -1, errno } @@ -102,39 +102,39 @@ func keyctl_Read(id keyId, b *byte, size int) (int32, error) { return int32(v1), nil } -func keyctl_Link(id, ring keyId) error { - _, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlLink), uintptr(id), uintptr(ring)) +func keyctlLinkFunc(id, ring keyID) error { + _, _, errno := syscall.Syscall(syscallKeyctlPTR, uintptr(keyctlLink), uintptr(id), uintptr(ring)) if errno != 0 { return errno } return nil } -func keyctl_Unlink(id, ring keyId) error { - _, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlUnlink), uintptr(id), uintptr(ring)) +func keyctlUnlinkFunc(id, ring keyID) error { + _, _, errno := syscall.Syscall(syscallKeyctlPTR, uintptr(keyctlUnlink), uintptr(id), uintptr(ring)) if errno != 0 { return errno } return nil } -func keyctl_Chown(id keyId, user, group int) error { - _, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlChown), uintptr(id), uintptr(user), uintptr(group), 0, 0) +func keyctlChownFunc(id keyID, user, group int) error { + _, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlChown), uintptr(id), uintptr(user), uintptr(group), 0, 0) if errno != 0 { return errno } return nil } -func keyctl_SetPerm(id keyId, perm uint32) error { - _, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlSetPerm), uintptr(id), uintptr(perm)) +func keyctlSetPermFunc(id keyID, perm uint32) error { + _, _, errno := syscall.Syscall(syscallKeyctlPTR, uintptr(keyctlSetPerm), uintptr(id), uintptr(perm)) if errno != 0 { return errno } return nil } -func add_key(keyType, keyDesc string, payload []byte, id int32) (int32, error) { +func addKeyFunc(keyType, keyDesc string, payload []byte, id int32) (int32, error) { var ( err error errno syscall.Errno @@ -154,7 +154,7 @@ func add_key(keyType, keyDesc string, payload []byte, id int32) (int32, error) { if len(payload) > 0 { pptr = unsafe.Pointer(&payload[0]) } - r1, _, errno = syscall.Syscall6(syscall_add_key, + r1, _, errno = syscall.Syscall6(syscallAddKeyPTR, uintptr(unsafe.Pointer(b1)), uintptr(unsafe.Pointer(b2)), uintptr(pptr), @@ -178,35 +178,35 @@ func getfsgid() (int32, error) { ) a1 = -1 - if r1, _, errno = syscall.Syscall(syscall_setfsgid, uintptr(a1), 0, 0); errno != 0 { + if r1, _, errno = syscall.Syscall(syscallSetFSGIDPTR, uintptr(a1), 0, 0); errno != 0 { err = errno return int32(-1), err } return int32(r1), nil } -func newKeyring(id keyId) (*keyring, error) { - r1, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlGetKeyringId), uintptr(id), uintptr(1)) +func newKeyring(id keyID) (*keyring, error) { + r1, _, errno := syscall.Syscall(syscallKeyctlPTR, uintptr(keyctlGetKeyringID), uintptr(id), uintptr(1)) if errno != 0 { return nil, errno } if id >= 0 { - id = keyId(r1) + id = keyID(r1) } return &keyring{id: id}, nil } -func createKeyring(parent keyId, name string) (*keyring, error) { - id, err := add_key("keyring", name, nil, int32(parent)) +func createKeyring(parent keyID, name string) (*keyring, error) { + id, err := addKeyFunc("keyring", name, nil, int32(parent)) if err != nil { return nil, err } - return &keyring{id: keyId(id)}, nil + return &keyring{id: keyID(id)}, nil } -func searchKeyring(id keyId, name, keyType string) (keyId, error) { +func searchKeyring(id keyID, name, keyType string) (keyID, error) { var ( b1, b2 *byte err error @@ -218,14 +218,14 @@ func searchKeyring(id keyId, name, keyType string) (keyId, error) { if b2, err = syscall.BytePtrFromString(name); err != nil { return 0, err } - r1, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlSearch), uintptr(id), uintptr(unsafe.Pointer(b1)), uintptr(unsafe.Pointer(b2)), 0, 0) + r1, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlSearch), uintptr(id), uintptr(unsafe.Pointer(b1)), uintptr(unsafe.Pointer(b2)), 0, 0) if errno != 0 { err = errno } - return keyId(r1), err + return keyID(r1), err } -func describeKeyId(id keyId) ([]byte, error) { +func describeKeyID(id keyID) ([]byte, error) { var ( b1 []byte size, sizeRead int @@ -235,7 +235,7 @@ func describeKeyId(id keyId) ([]byte, error) { size = len(b1) sizeRead = size + 1 for sizeRead > size { - r1, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlDescribe), uintptr(id), uintptr(unsafe.Pointer(&b1[0])), uintptr(size), 0, 0) + r1, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlDescribe), uintptr(id), uintptr(unsafe.Pointer(&b1[0])), uintptr(size), 0, 0) if errno != 0 { return nil, errno } @@ -251,7 +251,7 @@ func describeKeyId(id keyId) ([]byte, error) { return b1[:size-1], nil } -func listKeys(id keyId) ([]keyId, error) { +func listKeys(id keyID) ([]keyID, error) { var ( b1 []byte size, sizeRead int @@ -262,7 +262,7 @@ func listKeys(id keyId) ([]keyId, error) { size = len(b1) sizeRead = size + 1 for sizeRead > size { - r1, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlRead), uintptr(id), uintptr(unsafe.Pointer(&b1[0])), uintptr(size), 0, 0) + r1, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlRead), uintptr(id), uintptr(unsafe.Pointer(&b1[0])), uintptr(size), 0, 0) if errno != 0 { return nil, errno } @@ -275,20 +275,20 @@ func listKeys(id keyId) ([]keyId, error) { size = sizeRead } } - keys := make([]keyId, size/bsz) + keys := make([]keyID, size/bsz) for i := range keys { - keys[i] = *((*keyId)(unsafe.Pointer(&b1[i*bsz]))) + keys[i] = *((*keyID)(unsafe.Pointer(&b1[i*bsz]))) } return keys, nil } -func updateKey(id keyId, payload []byte) error { +func updateKey(id keyID, payload []byte) error { size := len(payload) if size == 0 { payload = make([]byte, 1) } - _, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlUpdate), uintptr(id), uintptr(unsafe.Pointer(&payload[0])), uintptr(size), 0, 0) + _, _, errno := syscall.Syscall6(syscallKeyctlPTR, uintptr(keyctlUpdate), uintptr(id), uintptr(unsafe.Pointer(&payload[0])), uintptr(size), 0, 0) if errno != 0 { return errno } diff --git a/sys_linux_386.go b/sys_linux_386.go index 0442bee..8bccb05 100644 --- a/sys_linux_386.go +++ b/sys_linux_386.go @@ -1,7 +1,9 @@ package keyctl +// these constants apply only for 386 architecture + const ( - syscall_keyctl uintptr = 288 - syscall_add_key uintptr = 286 - syscall_setfsgid uintptr = 139 + syscallKeyctlPTR uintptr = 288 + syscallAddKeyPTR uintptr = 286 + syscallSetFSGIDPTR uintptr = 139 ) diff --git a/sys_linux_amd64.go b/sys_linux_amd64.go index f36f316..fac37ab 100644 --- a/sys_linux_amd64.go +++ b/sys_linux_amd64.go @@ -1,7 +1,9 @@ package keyctl +// these constants apply only for AMD64 architecture + const ( - syscall_keyctl uintptr = 250 - syscall_add_key uintptr = 248 - syscall_setfsgid uintptr = 123 + syscallKeyctlPTR uintptr = 250 + syscallAddKeyPTR uintptr = 248 + syscallSetFSGIDPTR uintptr = 123 ) diff --git a/sys_linux_arm.go b/sys_linux_arm.go new file mode 100644 index 0000000..8b773b7 --- /dev/null +++ b/sys_linux_arm.go @@ -0,0 +1,11 @@ +package keyctl + +// these constants apply only for ARM architecture +// Code is borrowed from +// https://github.com/nonoo/keyctl/commit/b6b7469de4a9f9515154d0799aceed891dc3104d + +const ( + syscallKeyctlPTR uintptr = 311 + syscallAddKeyPTR uintptr = 309 + syscallSetFSGIDPTR uintptr = 139 +) diff --git a/sys_test.go b/sys_test.go index b531368..19754cd 100644 --- a/sys_test.go +++ b/sys_test.go @@ -11,7 +11,7 @@ func TestListKeyring(t *testing.T) { t.Fatal(err) } - keys, err := listKeys(keyId(ring.Id())) + keys, err := listKeys(keyID(ring.ID())) if err != nil { t.Fatal(err) } diff --git a/writer.go b/writer.go index 3573688..6ce318f 100644 --- a/writer.go +++ b/writer.go @@ -6,18 +6,19 @@ import ( "io" ) +// Flusher is interface implementing io.Writer, io.Closer and `Flush` function type Flusher interface { io.Writer io.Closer Flush() error } -// Error returned when attempting to close or flush an already closed stream +// ErrStreamClosed error is returned when attempting to close or flush an already closed stream var ErrStreamClosed = errors.New("keyctl write stream closed") type writer struct { *bytes.Buffer - key Id + key ID name string closed bool } @@ -38,7 +39,7 @@ func (w *writer) Flush() (err error) { if !w.closed { switch t := w.key.(type) { case Keyring: - var key Id + var key ID key, err = t.Add(w.name, w.Bytes()) if err == nil { w.key = key @@ -58,13 +59,13 @@ func setClosed(w *writer) { w.closed = true } -// Create a new stream writer to write key data to. The writer MUST Close() or +// NewWriter creates a new stream writer to write key data to. The writer MUST Close() or // Flush() the stream before the data will be flushed to the kernel. func NewWriter(key *Key) Flusher { return &writer{Buffer: bytes.NewBuffer(make([]byte, 0, 1024)), key: key} } -// Create a new key and stream writer with a given name on an open keyring. +// CreateWriter makes a new key and stream writer with a given name on an open keyring. func CreateWriter(name string, ring Keyring) (Flusher, error) { return &writer{Buffer: bytes.NewBuffer(make([]byte, 0, 1024)), key: ring, name: name}, nil } From 0bb104d75a758eb10e27f711005a51ddb1ed45e8 Mon Sep 17 00:00:00 2001 From: Anatolij Ostroumov Date: Tue, 4 Jan 2022 13:10:57 +0300 Subject: [PATCH 2/2] backported https://github.com/jsipprell/keyctl/commit/36ca02672b6c5fd75fd60a02dd624f36d2c82971 --- keyring.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/keyring.go b/keyring.go index 696b83e..0333d98 100644 --- a/keyring.go +++ b/keyring.go @@ -96,6 +96,11 @@ func UserSessionKeyring() (Keyring, error) { return newKeyring(keySpecUserSessionKeyring) } +// UserKeyring returns users keyring +func UserKeyring() (Keyring, error) { + return newKeyring(keySpecUserKeyring) +} + // GroupKeyring return the current group keyring. func GroupKeyring() (Keyring, error) { return newKeyring(keySpecGroupKeyring)