1
0
mirror of https://github.com/rancher/os.git synced 2025-06-20 04:01:55 +00:00
os/cmd/cloudinitexecute/authorize_ssh_keys.go

109 lines
2.2 KiB
Go
Raw Normal View History

package cloudinitexecute
2015-02-23 18:58:43 +00:00
import (
2016-11-16 21:02:35 +00:00
"io/ioutil"
2015-02-23 18:58:43 +00:00
"os"
2016-11-16 21:02:35 +00:00
"path"
"strconv"
"strings"
"github.com/rancher/os/log"
2016-11-16 21:02:35 +00:00
"github.com/rancher/os/util"
)
2016-11-17 07:29:33 +00:00
const (
sshDirName = ".ssh"
authorizedKeysFileName = "authorized_keys"
2016-11-16 21:02:35 +00:00
)
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]
}
}
2016-11-17 07:29:33 +00:00
sshDir := path.Join(homeDir, sshDirName)
authorizedKeysFile := path.Join(sshDir, authorizedKeysFileName)
2016-11-16 21:02:35 +00:00
if _, err := os.Stat(sshDir); os.IsNotExist(err) {
if err = os.Mkdir(sshDir, 0700); err != nil {
return err
}
} else if err != nil {
return err
}
2016-11-17 07:29:33 +00:00
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 {
2016-11-16 21:02:35 +00:00
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 {
2016-11-16 21:02:35 +00:00
return err
}
2016-11-16 21:02:35 +00:00
} else if err != nil {
return err
}
bytes, err := ioutil.ReadFile(authorizedKeysFile)
if err != nil {
return err
}
2016-11-16 21:02:35 +00:00
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
}
2016-11-17 07:29:33 +00:00
return os.Chown(authorizedKeysFile, uid, gid)
}