Skip to content

Commit

Permalink
add keyctl read&describe to remove auth from keyring
Browse files Browse the repository at this point in the history
Add method removeAllAuthFromKeyring.
Get key describes from keyring using KEYCTL_READ and KEYCTL_DESCRIBE, and remove them from keyring if the decription has prefix 'container-registry-login:'.

Signed-off-by: Qi Wang <qiwan@redhat.com>
  • Loading branch information
QiWang19 committed Sep 11, 2019
1 parent 6617860 commit 8e1c9e9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
10 changes: 9 additions & 1 deletion pkg/docker/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,17 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error {
})
}

// RemoveAllAuthentication deletes all the credentials stored in auth.json
// RemoveAllAuthentication deletes all the credentials stored in auth.json and kernel keyring
func RemoveAllAuthentication(sys *types.SystemContext) error {
return modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if enableKeyring {
err := removeAllAuthFromKernelKeyring()
if err == nil {
logrus.Debugf("removing all credentials from kernel keyring")
return false, nil
}
logrus.Debugf("error removing credentials from kernel keyring")
}
auths.CredHelpers = make(map[string]string)
auths.AuthConfigs = make(map[string]dockerAuthConfig)
return true, nil
Expand Down
76 changes: 75 additions & 1 deletion pkg/docker/config/config_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package config
import (
"fmt"
"strings"
"unsafe"

"github.com/containers/image/pkg/keyctl"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

const keyDescribePrefix = "container-registry-login:"

func getAuthFromKernelKeyring(registry string) (string, string, error) {
userkeyring, err := keyctl.UserKeyring()
if err != nil {
Expand Down Expand Up @@ -41,6 +46,34 @@ func deleteAuthFromKernelKeyring(registry string) error {
return key.Unlink()
}

func removeAllAuthFromKernelKeyring() error {
keyIDs, err := readUserKeyring()
if err != nil {
return err
}

for _, kID := range keyIDs {
keyAttr, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(kID))
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 avaliable", kID)
}
keyDescribe := keyAttrs[4]
if strings.HasPrefix(keyDescribe, keyDescribePrefix) {
_, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, int(kID), int(unix.KEY_SPEC_USER_KEYRING), 0, 0)
if err != nil {
return errors.Wrapf(err, "error unlinking key %d", kID)
}
logrus.Debugf("unlink key %d:%s", kID, keyAttr)
}
}
return nil
}

func setAuthToKernelKeyring(registry, username, password string) error {
keyring, err := keyctl.SessionKeyring()
if err != nil {
Expand Down Expand Up @@ -75,5 +108,46 @@ func setAuthToKernelKeyring(registry, username, password string) error {
}

func genDescription(registry string) string {
return fmt.Sprintf("container-registry-login:%s", registry)
return fmt.Sprintf("%s%s", keyDescribePrefix, registry)
}

// readUserKeyring reads user keyring and returns slice of key id(key_serial_t) representing the IDs of all the keys that are linked to it
func readUserKeyring() ([]int32, 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) []int32 {
idSize := 4
var keyIDs []int32
for idx := 0; idx+idSize <= len(byteKeyIDs); idx = idx + idSize {
tempID := *(*int32)(unsafe.Pointer(&byteKeyIDs[idx]))
keyIDs = append(keyIDs, tempID)
}
return keyIDs
}
4 changes: 4 additions & 0 deletions pkg/docker/config/config_unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ func deleteAuthFromKernelKeyring(registry string) error {
func setAuthToKernelKeyring(registry, username, password string) error {
return ErrNotSupported
}

func removeAllAuthFromKernelKeyring() error {
return ErrNotSupported
}

0 comments on commit 8e1c9e9

Please sign in to comment.