in cmd/core_plugin/metadatasshkey/metadatasshkey_linux.go [90:161]
func updateSSHKeys(ctx context.Context, user *accounts.User, keys []string) error {
gComment := "# Added by Google"
if user.HomeDir == "" {
return fmt.Errorf("user %s has no homedir set", user.Username)
}
if user.Shell == "/sbin/nologin" {
return nil
}
galog.V(2).Debugf("Updating keys for user %s to %v", user.Username, keys)
sshPath := filepath.Join(user.HomeDir, ".ssh")
if !file.Exists(sshPath, file.TypeDir) {
if err := os.Mkdir(sshPath, 0700); err != nil {
return err
}
if err := os.Chown(sshPath, user.UnixUID(), user.UnixGID()); err != nil {
return err
}
}
authorizedKeysPath := filepath.Join(sshPath, "authorized_keys")
// Remove empty file.
if len(keys) == 0 {
os.Remove(authorizedKeysPath)
return nil
}
authorizedKeysContents, err := os.ReadFile(authorizedKeysPath)
if err != nil && !os.IsNotExist(err) {
return err
}
var isGoogle bool
var userKeys []string
for _, key := range strings.Split(string(authorizedKeysContents), "\n") {
if key == "" {
continue
}
if isGoogle {
isGoogle = false
continue
}
if key == gComment {
isGoogle = true
continue
}
userKeys = append(userKeys, key)
}
authorizedKeysOutput := strings.Join(userKeys, "\n")
if len(userKeys) > 0 {
authorizedKeysOutput += "\n"
}
for _, k := range keys {
authorizedKeysOutput += fmt.Sprintf("%s\n%s\n", gComment, k)
}
writeOpts := file.Options{
Perm: 0600,
Owner: &file.GUID{
UID: user.UnixUID(),
GID: user.UnixGID(),
},
}
if err := file.SaferWriteFile(ctx, []byte(authorizedKeysOutput), authorizedKeysPath, writeOpts); err != nil {
return fmt.Errorf("failed to write authorized_keys file: %w", err)
}
return selinuxRestoreCon(ctx, authorizedKeysPath)
}