image/pkg/docker/config/config_linux.go

116 lines
2.8 KiB
Go

package config
import (
"fmt"
"strings"
"github.com/containers/image/v5/internal/pkg/keyctl"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
const keyDescribePrefix = "container-registry-login:"
func getAuthFromKernelKeyring(registry string) (string, string, error) {
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 {
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 {
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, "error unlinking key %d", k.ID())
}
logrus.Debugf("unlinked key %d:%s", k.ID(), keyAttr)
}
}
return nil
}
func setAuthToKernelKeyring(registry, username, password string) error {
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, "error getting user keyring")
}
err = keyctl.Link(userKeyring, id)
if err != nil {
return errors.Wrapf(err, "error linking the key to user keyring")
}
// unlink the key from session keyring
err = keyctl.Unlink(keyring, id)
if err != nil {
return errors.Wrapf(err, "error unlinking the key from session keyring")
}
return nil
}
func genDescription(registry string) string {
return fmt.Sprintf("%s%s", keyDescribePrefix, registry)
}