Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}
Example #5
0
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
}