123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package cloudinitexecute
- import (
- "io/ioutil"
- "os"
- "path"
- "strconv"
- "strings"
- "github.com/rancher/os/pkg/log"
- "github.com/rancher/os/pkg/util"
- )
- const (
- sshDirName = ".ssh"
- authorizedKeysFileName = "authorized_keys"
- )
- func authorizeSSHKeys(username string, authorizedKeys []string, name string) error {
- var uid int
- var gid int
- var homeDir string
- bytes, err := ioutil.ReadFile("/etc/passwd")
- if err != nil {
- return err
- }
- for _, line := range strings.Split(string(bytes), "\n") {
- if strings.HasPrefix(line, username) {
- split := strings.Split(line, ":")
- if len(split) < 6 {
- break
- }
- uid, err = strconv.Atoi(split[2])
- if err != nil {
- return err
- }
- gid, err = strconv.Atoi(split[3])
- if err != nil {
- return err
- }
- homeDir = split[5]
- }
- }
- sshDir := path.Join(homeDir, sshDirName)
- authorizedKeysFile := path.Join(sshDir, authorizedKeysFileName)
- if _, err := os.Stat(sshDir); os.IsNotExist(err) {
- if err = os.Mkdir(sshDir, 0700); err != nil {
- return err
- }
- } else if err != nil {
- return err
- }
- if err = os.Chown(sshDir, uid, gid); err != nil {
- return err
- }
- for _, authorizedKey := range authorizedKeys {
- if err = authorizeSSHKey(authorizedKey, authorizedKeysFile, uid, gid); err != nil {
- log.Errorf("Failed to authorize SSH key %s: %v", authorizedKey, err)
- }
- }
- return nil
- }
- func authorizeSSHKey(authorizedKey, authorizedKeysFile string, uid, gid int) error {
- authorizedKeysFileInfo, err := os.Stat(authorizedKeysFile)
- if os.IsNotExist(err) {
- keysFile, err := os.Create(authorizedKeysFile)
- if err != nil {
- return err
- }
- if err = keysFile.Chmod(0600); err != nil {
- return err
- }
- if err = keysFile.Close(); err != nil {
- return err
- }
- authorizedKeysFileInfo, err = os.Stat(authorizedKeysFile)
- if err != nil {
- return err
- }
- } else if err != nil {
- return err
- }
- bytes, err := ioutil.ReadFile(authorizedKeysFile)
- if err != nil {
- return err
- }
- if !strings.Contains(string(bytes), authorizedKey) {
- bytes = append(bytes, []byte(authorizedKey)...)
- bytes = append(bytes, '\n')
- }
- perm := authorizedKeysFileInfo.Mode().Perm()
- if err = util.WriteFileAtomic(authorizedKeysFile, bytes, perm); err != nil {
- return err
- }
- return os.Chown(authorizedKeysFile, uid, gid)
- }
|