func loadHost(domain *tao.Domain, cfg *tao.LinuxHostConfig) (*tao.LinuxHost, error) { var tc tao.Config // Decide host type switch cfg.GetType() { case "root": tc.HostType = tao.Root case "stacked": tc.HostType = tao.Stacked case "": options.Usage("Must supply -hosting flag") default: options.Usage("Invalid host type: %s", cfg.GetType()) } // Decide hosting type switch cfg.GetHosting() { case "process": tc.HostedType = tao.ProcessPipe case "docker": tc.HostedType = tao.DockerUnix case "kvm_coreos": tc.HostedType = tao.KVMCoreOSFile case "": options.Usage("Must supply -hosting flag") default: options.Usage("Invalid hosting type: %s", cfg.GetHosting()) } // For stacked hosts, figure out the channel type: TPM, pipe, file, or unix if tc.HostType == tao.Stacked { switch cfg.GetParentType() { case "TPM": tc.HostChannelType = "tpm" case "pipe": tc.HostChannelType = "pipe" case "file": tc.HostChannelType = "file" case "unix": tc.HostChannelType = "unix" case "": options.Usage("Must supply -parent_type for stacked hosts") default: options.Usage("Invalid parent type: %s", cfg.GetParentType()) } // For stacked hosts on anything but a TPM, we also need parent spec if tc.HostChannelType != "tpm" { tc.HostSpec = cfg.GetParentSpec() if tc.HostSpec == "" { options.Usage("Must supply -parent_spec for non-TPM stacked hosts") } } else { // For stacked hosts on a TPM, we also need info from domain config if domain.Config.TpmInfo == nil { options.Usage("Must provide TPM configuration in the domain to use a TPM") } tc.TPMAIKPath = path.Join(domainPath(), domain.Config.TpmInfo.GetAikPath()) tc.TPMPCRs = domain.Config.TpmInfo.GetPcrs() tc.TPMDevice = domain.Config.TpmInfo.GetTpmPath() } } rulesPath := "" if p := domain.RulesPath(); p != "" { rulesPath = path.Join(domainPath(), p) } // Create the hosted program factory socketPath := hostPath() if subPath := cfg.GetSocketDir(); subPath != "" { if path.IsAbs(subPath) { socketPath = subPath } else { socketPath = path.Join(socketPath, subPath) } } // TODO(cjpatton) How do the NewLinuxDockerContainterFactory and the // NewLinuxKVMCoreOSFactory need to be modified to support the new // CachedGuard? They probably don't. var childFactory tao.HostedProgramFactory switch tc.HostedType { case tao.ProcessPipe: childFactory = tao.NewLinuxProcessFactory("pipe", socketPath) case tao.DockerUnix: childFactory = tao.NewLinuxDockerContainerFactory(socketPath, rulesPath) case tao.KVMCoreOSFile: sshFile := cfg.GetKvmCoreosSshAuthKeys() if sshFile == "" { options.Usage("Must specify -kvm_coreos_ssh_auth_keys for hosting QEMU/KVM CoreOS") } if !path.IsAbs(sshFile) { sshFile = path.Join(domainPath(), sshFile) } sshKeysCfg, err := tao.CloudConfigFromSSHKeys(sshFile) options.FailIf(err, "Can't read ssh keys") coreOSImage := cfg.GetKvmCoreosImg() if coreOSImage == "" { options.Usage("Must specify -kvm_coreos_image for hosting QEMU/KVM CoreOS") } if !path.IsAbs(coreOSImage) { coreOSImage = path.Join(domainPath(), coreOSImage) } vmMemory := cfg.GetKvmCoreosVmMemory() if vmMemory == 0 { vmMemory = 1024 } cfg := &tao.CoreOSConfig{ ImageFile: coreOSImage, Memory: int(vmMemory), RulesPath: rulesPath, SSHKeysCfg: sshKeysCfg, } childFactory, err = tao.NewLinuxKVMCoreOSFactory(socketPath, cfg) options.FailIf(err, "Can't create KVM CoreOS factory") } if tc.HostType == tao.Root { pwd := getKey("root host key password", "pass") return tao.NewRootLinuxHost(hostPath(), domain.Guard, pwd, childFactory) } else { parent := tao.ParentFromConfig(tc) if parent == nil { options.Usage("No host tao available, verify -parent_type or $%s\n", tao.HostChannelTypeEnvVar) } return tao.NewStackedLinuxHost(hostPath(), domain.Guard, tao.ParentFromConfig(tc), childFactory) } }