mirror of
https://github.com/rancher/os.git
synced 2025-05-01 21:03:20 +00:00
109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
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)
|
|
}
|