func verifyDataPaths() error { for _, path := range []string{ config.ContainerBasePath(), filepath.Join(config.ContainerBasePath(), "home"), filepath.Join(config.ContainerBasePath(), "git"), filepath.Join(config.ContainerBasePath(), "units"), filepath.Join(config.ContainerBasePath(), "access", "git"), filepath.Join(config.ContainerBasePath(), "access", "containers", "ssh"), filepath.Join(config.ContainerBasePath(), "keys", "public"), } { if err := checkPath(path, os.FileMode(0755), true); err != nil { return err } if err := selinux.RestoreCon(path, false); err != nil { return err } } for _, path := range []string{ filepath.Join(config.ContainerBasePath(), "targets"), filepath.Join(config.ContainerBasePath(), "slices"), filepath.Join(config.ContainerBasePath(), "env", "contents"), filepath.Join(config.ContainerBasePath(), "ports", "descriptions"), filepath.Join(config.ContainerBasePath(), "ports", "interfaces"), } { if err := checkPath(path, os.FileMode(0750), true); err != nil { return err } if err := selinux.RestoreCon(path, false); err != nil { return err } } return nil }
func createUser(id containers.Identifier) error { cmd := exec.Command("/usr/sbin/useradd", id.LoginFor(), "-m", "-d", id.HomePath(), "-c", "Container user") if out, err := cmd.CombinedOutput(); err != nil { log.Println(out) return err } selinux.RestoreCon(id.HomePath(), true) return nil }
func createUser(repositoryId git.RepoIdentifier) error { cmd := exec.Command("/usr/sbin/useradd", repositoryId.LoginFor(), "-m", "-d", repositoryId.HomePath(), "-c", "Repository user") if out, err := cmd.CombinedOutput(); err != nil { fmt.Println(out) return err } selinux.RestoreCon(repositoryId.HomePath(), true) return nil }
func InitializeRepository(repositoryId git.RepoIdentifier, repositoryURL string) error { var err error if _, err = user.Lookup(repositoryId.LoginFor()); err != nil { if _, ok := err.(user.UnknownUserError); !ok { return err } if err = createUser(repositoryId); err != nil { return err } } if err := os.MkdirAll(repositoryId.HomePath(), 0700); err != nil { return err } if err := os.MkdirAll(repositoryId.RepositoryPathFor(), 0700); err != nil { return err } var u *user.User if u, err = user.Lookup(repositoryId.LoginFor()); err != nil { return err } uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) if err = os.Chown(repositoryId.HomePath(), uid, gid); err != nil { return err } if err = os.Chown(repositoryId.RepositoryPathFor(), uid, gid); err != nil { return err } switchns := filepath.Join("/", "usr", "bin", "switchns") cmd := exec.Command(switchns, "--container=geard-githost", "--", "/git/init-repo", repositoryId.RepositoryPathFor(), u.Uid, u.Gid, repositoryURL) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return err } if err := selinux.RestoreCon(repositoryId.RepositoryPathFor(), true); err != nil { return err } return nil }
func checkPath(path string, mode os.FileMode, dir bool) error { stat, err := os.Lstat(path) if os.IsNotExist(err) && dir { err = os.MkdirAll(path, mode) stat, _ = os.Lstat(path) } if err != nil { return errors.New("init: path (" + path + ") could not be created: " + err.Error()) } if stat.IsDir() != dir { return errors.New("init: path (" + path + ") must be a directory instead of a file") } if err := selinux.RestoreCon(path, false); err != nil { return err } return nil }
// FIXME: Refactor into separate responsibilities for file creation, templating, and disk access func generateAuthorizedKeys(id containers.Identifier, u *user.User, forceCreate, printToStdOut bool) error { var ( err error sshKeys []string destFile *os.File srcFile *os.File w *bufio.Writer ) var authorizedKeysPortSpec string ports, err := containers.GetExistingPorts(id) if err != nil { fmt.Errorf("container init pre-start: Unable to retrieve port mapping") return err } for _, port := range ports { authorizedKeysPortSpec += fmt.Sprintf("permitopen=\"127.0.0.1:%v\",", port.External) } sshKeys, err = filepath.Glob(path.Join(SshAccessBasePath(id), "*")) if !printToStdOut { os.MkdirAll(id.HomePath(), 0700) os.Mkdir(path.Join(id.HomePath(), ".ssh"), 0700) authKeysPath := id.AuthKeysPathFor() if _, err = os.Stat(authKeysPath); err != nil { if !os.IsNotExist(err) { return err } } else { if forceCreate { os.Remove(authKeysPath) } else { return nil } } if destFile, err = os.Create(authKeysPath); err != nil { return err } defer destFile.Close() w = bufio.NewWriter(destFile) } else { w = bufio.NewWriter(os.Stdout) } for _, keyFile := range sshKeys { s, err := os.Stat(keyFile) if err != nil { continue } if s.IsDir() { continue } srcFile, err = os.Open(keyFile) defer srcFile.Close() w.WriteString(fmt.Sprintf("command=\"/usr/bin/switchns\",%vno-agent-forwarding,no-X11-forwarding ", authorizedKeysPortSpec)) io.Copy(w, srcFile) w.WriteString("\n") } w.Flush() if !printToStdOut { uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) for _, path := range []string{ id.HomePath(), filepath.Join(id.HomePath(), ".ssh"), filepath.Join(id.HomePath(), ".ssh", "authorized_keys"), } { if err := os.Chown(path, uid, gid); err != nil { return err } } if err := selinux.RestoreCon(id.BaseHomePath(), true); err != nil { return err } } return nil }
// FIXME: I do 99% of the same thing as ssh/generate_authorized_keys func generateAuthorizedKeys(repoId RepoIdentifier, u *user.User, forceCreate, printToStdOut bool) error { var err error var sshKeys []string var destFile *os.File var srcFile *os.File var w *bufio.Writer sshKeys, err = filepath.Glob(path.Join(repoId.SshAccessBasePath(), "*")) if err != nil { return err } if !printToStdOut { os.MkdirAll(repoId.HomePath(), 0700) os.Mkdir(path.Join(repoId.HomePath(), ".ssh"), 0700) authKeysPath := repoId.AuthKeysPathFor() if _, err = os.Stat(authKeysPath); err != nil { if !os.IsNotExist(err) { return err } } else { if forceCreate { os.Remove(authKeysPath) } else { return nil } } if destFile, err = os.Create(authKeysPath); err != nil { return err } defer destFile.Close() destFile.Chmod(0400) w = bufio.NewWriter(destFile) } else { w = bufio.NewWriter(os.Stdout) } for _, keyFile := range sshKeys { s, err := os.Stat(keyFile) if err != nil { continue } if s.IsDir() { continue } srcFile, err = os.Open(keyFile) defer srcFile.Close() readwriteRepo := strings.HasSuffix(keyFile, ".write") if readwriteRepo { w.WriteString("command=\"/usr/bin/switchns --git\",no-agent-forwarding,no-X11-forwarding,no-port-forwarding ") } else { w.WriteString("command=\"/usr/bin/switchns --git-ro\",no-agent-forwarding,no-X11-forwarding,no-port-forwarding ") } io.Copy(w, srcFile) w.WriteString("\n") } w.Flush() if !printToStdOut { uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) for _, path := range []string{ repoId.HomePath(), filepath.Join(repoId.HomePath(), ".ssh"), filepath.Join(repoId.HomePath(), ".ssh", "authorized_keys"), } { if err := os.Chown(path, uid, gid); err != nil { return err } } if err := selinux.RestoreCon(repoId.BaseHomePath(), true); err != nil { return err } } return nil }