diff --git a/internal/pkg/keyctl/key.go b/internal/pkg/keyctl/key.go deleted file mode 100644 index bf6cc87d4..000000000 --- a/internal/pkg/keyctl/key.go +++ /dev/null @@ -1,74 +0,0 @@ -// 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. - -//go:build linux -// +build linux - -package keyctl - -import ( - "golang.org/x/sys/unix" -) - -// Key represents a single key linked to one or more kernel keyrings. -type Key struct { - Name string - - id, ring keyID - size int -} - -// ID returns the 32-bit kernel identifier for a specific key -func (k *Key) ID() int32 { - return int32(k.id) -} - -// Get the key's value as a byte slice -func (k *Key) Get() ([]byte, error) { - var ( - b []byte - err error - sizeRead int - ) - - if k.size == 0 { - k.size = 512 - } - - size := k.size - - b = make([]byte, int(size)) - sizeRead = size + 1 - for sizeRead > size { - r1, err := unix.KeyctlBuffer(unix.KEYCTL_READ, int(k.id), b, size) - if err != nil { - return nil, err - } - - if sizeRead = int(r1); sizeRead > size { - b = make([]byte, sizeRead) - size = sizeRead - sizeRead = size + 1 - } else { - k.size = sizeRead - } - } - return b[:k.size], err -} - -// 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 { - _, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, int(k.id), int(k.ring), 0, 0) - return err -} - -// Describe returns a string describing the attributes of a specified key -func (k *Key) Describe() (string, error) { - keyAttr, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(k.id)) - if err != nil { - return "", err - } - return keyAttr, nil -} diff --git a/internal/pkg/keyctl/keyring.go b/internal/pkg/keyctl/keyring.go deleted file mode 100644 index 5eaad615c..000000000 --- a/internal/pkg/keyctl/keyring.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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. - -//go:build linux -// +build linux - -// Package keyctl is a Go interface to linux kernel keyrings (keyctl interface) -package keyctl - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -// Keyring is the basic interface to a linux keyctl keyring. -type Keyring interface { - ID - Add(string, []byte) (*Key, error) - Search(string) (*Key, error) -} - -type keyring struct { - id keyID -} - -// ID is unique 32-bit serial number identifiers for all Keys and Keyrings have. -type ID interface { - ID() int32 -} - -// 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 := unix.AddKey("user", name, key, int(kr.id)) - if err == nil { - key := &Key{Name: name, id: keyID(r), ring: kr.id} - return key, nil - } - return nil, err -} - -// Search for a key by name, this also searches child keyrings linked to this -// one. The key, if found, is linked to the top keyring that Search() was called -// from. -func (kr *keyring) Search(name string) (*Key, error) { - id, err := unix.KeyctlSearch(int(kr.id), "user", name, 0) - if err == nil { - return &Key{Name: name, id: keyID(id), ring: kr.id}, nil - } - return nil, err -} - -// ID returns the 32-bit kernel identifier of a keyring -func (kr *keyring) ID() int32 { - return int32(kr.id) -} - -// SessionKeyring returns the current login session keyring -func SessionKeyring() (Keyring, error) { - return newKeyring(unix.KEY_SPEC_SESSION_KEYRING) -} - -// UserKeyring returns the keyring specific to the current user. -func UserKeyring() (Keyring, error) { - return newKeyring(unix.KEY_SPEC_USER_KEYRING) -} - -// Unlink an object from a keyring -func Unlink(parent Keyring, child ID) error { - _, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, int(child.ID()), int(parent.ID()), 0, 0) - return err -} - -// Link a key into a keyring -func Link(parent Keyring, child ID) error { - _, err := unix.KeyctlInt(unix.KEYCTL_LINK, int(child.ID()), int(parent.ID()), 0, 0) - return err -} - -// ReadUserKeyring reads user keyring and returns slice of key with id(key_serial_t) representing the IDs of all the keys that are linked to it -func ReadUserKeyring() ([]*Key, error) { - var ( - b []byte - err error - sizeRead int - ) - krSize := 4 - size := krSize - b = make([]byte, size) - sizeRead = size + 1 - for sizeRead > size { - r1, err := unix.KeyctlBuffer(unix.KEYCTL_READ, unix.KEY_SPEC_USER_KEYRING, b, size) - if err != nil { - return nil, err - } - - if sizeRead = int(r1); sizeRead > size { - b = make([]byte, sizeRead) - size = sizeRead - sizeRead = size + 1 - } else { - krSize = sizeRead - } - } - keyIDs := getKeyIDsFromByte(b[:krSize]) - return keyIDs, err -} - -func getKeyIDsFromByte(byteKeyIDs []byte) []*Key { - idSize := 4 - var keys []*Key - for idx := 0; idx+idSize <= len(byteKeyIDs); idx = idx + idSize { - tempID := *(*int32)(unsafe.Pointer(&byteKeyIDs[idx])) - keys = append(keys, &Key{id: keyID(tempID)}) - } - return keys -} diff --git a/internal/pkg/keyctl/keyring_test.go b/internal/pkg/keyctl/keyring_test.go deleted file mode 100644 index 3a1c27449..000000000 --- a/internal/pkg/keyctl/keyring_test.go +++ /dev/null @@ -1,222 +0,0 @@ -//go:build linux -// +build linux - -package keyctl - -import ( - "crypto/rand" - "strings" - "testing" -) - -func TestSessionKeyring(t *testing.T) { - - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testname" - keyring, err := SessionKeyring() - if err != nil { - t.Fatal(err) - } - _, err = keyring.Add(testname, token) - if err != nil { - t.Fatal(err) - } - key, err := keyring.Search(testname) - if err != nil { - t.Fatal(err) - } - data, err := key.Get() - if err != nil { - t.Fatal(err) - } - if string(data) != string(token) { - t.Errorf("Expected data %v, but get %v", token, data) - } - err = key.Unlink() - if err != nil { - t.Fatal(err) - } -} - -func TestUserKeyring(t *testing.T) { - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testuser" - - userKeyring, err := UserKeyring() - if err != nil { - t.Fatal(err) - } - - userKey, err := userKeyring.Add(testname, token) - if err != nil { - t.Fatal(err, userKey) - } - - searchRet, err := userKeyring.Search(testname) - if err != nil { - t.Fatal(err) - } - if searchRet.Name != testname { - t.Errorf("Expected data %v, but get %v", testname, searchRet.Name) - } - - err = userKey.Unlink() - if err != nil { - t.Fatal(err) - } -} - -func TestLink(t *testing.T) { - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testlink" - - userKeyring, err := UserKeyring() - if err != nil { - t.Fatal(err) - } - - sessionKeyring, err := SessionKeyring() - if err != nil { - t.Fatal(err) - } - - key, err := sessionKeyring.Add(testname, token) - if err != nil { - t.Fatal(err) - } - - _, err = userKeyring.Search(testname) - if err == nil { - t.Fatalf("Expected error, but got key %v", testname) - } - ExpectedError := "required key not available" - if err.Error() != ExpectedError { - t.Fatal(err) - } - - err = Link(userKeyring, key) - if err != nil { - t.Fatal(err) - } - _, err = userKeyring.Search(testname) - if err != nil { - t.Fatal(err) - } - - err = key.Unlink() - if err != nil { - t.Fatal(err) - } - - err = Unlink(userKeyring, key) - if err != nil { - t.Fatal(err) - } -} - -func TestUnlink(t *testing.T) { - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testunlink" - keyring, err := SessionKeyring() - if err != nil { - t.Fatal(err) - } - key, err := keyring.Add(testname, token) - if err != nil { - t.Fatal(err) - } - - err = Unlink(keyring, key) - if err != nil { - t.Fatal(err) - } - - _, err = keyring.Search(testname) - ExpectedError := "required key not available" - if err.Error() != ExpectedError { - t.Fatal(err) - } -} - -func TestReadKeyring(t *testing.T) { - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testuser" - - userKeyring, err := UserKeyring() - if err != nil { - t.Fatal(err) - } - - userKey, err := userKeyring.Add(testname, token) - if err != nil { - t.Fatal(err, userKey) - } - keys, err := ReadUserKeyring() - if err != nil { - t.Fatal(err) - } - expectedKeyLen := 1 - if len(keys) != 1 { - t.Errorf("expected to read %d userkeyring, but get %d", expectedKeyLen, len(keys)) - } - err = Unlink(userKeyring, userKey) - if err != nil { - t.Fatal(err) - } -} - -func TestDescribe(t *testing.T) { - token := make([]byte, 20) - _, err := rand.Read(token) - if err != nil { - t.Fatal(err) - } - - testname := "testuser" - - userKeyring, err := UserKeyring() - if err != nil { - t.Fatal(err) - } - - userKey, err := userKeyring.Add(testname, token) - if err != nil { - t.Fatal(err, userKey) - } - keyAttr, err := userKey.Describe() - if err != nil { - t.Fatal(err) - } - if !strings.Contains(keyAttr, testname) { - t.Errorf("expect description contains %s, but get %s", testname, keyAttr) - } - err = Unlink(userKeyring, userKey) - if err != nil { - t.Fatal(err) - } -} diff --git a/internal/pkg/keyctl/perm.go b/internal/pkg/keyctl/perm.go deleted file mode 100644 index 5f4d2157a..000000000 --- a/internal/pkg/keyctl/perm.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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. - -//go:build linux -// +build linux - -package keyctl - -import ( - "golang.org/x/sys/unix" -) - -// 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. -type KeyPerm uint32 - -const ( - // PermOtherAll sets all permission for Other - PermOtherAll KeyPerm = 0x3f << (8 * iota) - // PermGroupAll sets all permission for Group - PermGroupAll - // PermUserAll sets all permission for User - PermUserAll - // PermProcessAll sets all permission for Processor - PermProcessAll -) - -// SetPerm sets the permissions on a key or keyring. -func SetPerm(k ID, p KeyPerm) error { - err := unix.KeyctlSetperm(int(k.ID()), uint32(p)) - return err -} diff --git a/internal/pkg/keyctl/sys_linux.go b/internal/pkg/keyctl/sys_linux.go deleted file mode 100644 index f61666e42..000000000 --- a/internal/pkg/keyctl/sys_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -//go:build linux -// +build linux - -package keyctl - -import ( - "golang.org/x/sys/unix" -) - -type keyID int32 - -func newKeyring(id keyID) (*keyring, error) { - r1, err := unix.KeyctlGetKeyringID(int(id), true) - if err != nil { - return nil, err - } - - if id < 0 { - r1 = int(id) - } - return &keyring{id: keyID(r1)}, nil -} diff --git a/pkg/docker/config/config_linux.go b/pkg/docker/config/config_linux.go deleted file mode 100644 index 0bf161259..000000000 --- a/pkg/docker/config/config_linux.go +++ /dev/null @@ -1,119 +0,0 @@ -package config - -import ( - "fmt" - "strings" - - "github.com/containers/image/v5/internal/pkg/keyctl" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// NOTE: none of the functions here are currently used. If we ever want to -// re-enable keyring support, we should introduce a similar built-in credential -// helpers as for `sysregistriesv2.AuthenticationFileHelper`. - -const keyDescribePrefix = "container-registry-login:" //nolint:deadcode,unused - -func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused - userkeyring, err := keyctl.UserKeyring() - if err != nil { - return "", "", err - } - key, err := userkeyring.Search(genDescription(registry)) - if err != nil { - return "", "", err - } - authData, err := key.Get() - if err != nil { - return "", "", err - } - parts := strings.SplitN(string(authData), "\x00", 2) - if len(parts) != 2 { - return "", "", nil - } - return parts[0], parts[1], nil -} - -func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused - userkeyring, err := keyctl.UserKeyring() - - if err != nil { - return err - } - key, err := userkeyring.Search(genDescription(registry)) - if err != nil { - return err - } - return key.Unlink() -} - -func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused - keys, err := keyctl.ReadUserKeyring() - if err != nil { - return err - } - - userkeyring, err := keyctl.UserKeyring() - if err != nil { - return err - } - - for _, k := range keys { - keyAttr, err := k.Describe() - if err != nil { - return err - } - // split string "type;uid;gid;perm;description" - keyAttrs := strings.SplitN(keyAttr, ";", 5) - if len(keyAttrs) < 5 { - return errors.Errorf("Key attributes of %d are not available", k.ID()) - } - keyDescribe := keyAttrs[4] - if strings.HasPrefix(keyDescribe, keyDescribePrefix) { - err := keyctl.Unlink(userkeyring, k) - if err != nil { - return errors.Wrapf(err, "unlinking key %d", k.ID()) - } - logrus.Debugf("unlinked key %d:%s", k.ID(), keyAttr) - } - } - return nil -} - -func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused - keyring, err := keyctl.SessionKeyring() - if err != nil { - return err - } - id, err := keyring.Add(genDescription(registry), []byte(fmt.Sprintf("%s\x00%s", username, password))) - if err != nil { - return err - } - - // sets all permission(view,read,write,search,link,set attribute) for current user - // it enables the user to search the key after it linked to user keyring and unlinked from session keyring - err = keyctl.SetPerm(id, keyctl.PermUserAll) - if err != nil { - return err - } - // link the key to userKeyring - userKeyring, err := keyctl.UserKeyring() - if err != nil { - return errors.Wrapf(err, "getting user keyring") - } - err = keyctl.Link(userKeyring, id) - if err != nil { - return errors.Wrapf(err, "linking the key to user keyring") - } - // unlink the key from session keyring - err = keyctl.Unlink(keyring, id) - if err != nil { - return errors.Wrapf(err, "unlinking the key from session keyring") - } - return nil -} - -func genDescription(registry string) string { //nolint:deadcode,unused - return fmt.Sprintf("%s%s", keyDescribePrefix, registry) -} diff --git a/pkg/docker/config/config_unsupported.go b/pkg/docker/config/config_unsupported.go deleted file mode 100644 index d9827d8ed..000000000 --- a/pkg/docker/config/config_unsupported.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build !linux && (!386 || !amd64) -// +build !linux -// +build !386 !amd64 - -package config - -func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused - return "", "", ErrNotSupported -} - -func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused - return ErrNotSupported -} - -func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused - return ErrNotSupported -} - -func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused - return ErrNotSupported -}