// Update configuration based on command-line options. Does very little sanity checking. func configureFromOptions(cfg *tao.LinuxHostConfig) { if *options.Bool["root"] && *options.Bool["stacked"] { options.Usage("Can supply only one of -root and -stacked") } else if *options.Bool["root"] { cfg.Type = proto.String("root") } else if *options.Bool["stacked"] { cfg.Type = proto.String("stacked") } cfg.Hosting = append(cfg.Hosting, options.Strings["hosting"]...) if s := *options.String["parent_type"]; s != "" { cfg.ParentType = proto.String(s) } if s := *options.String["parent_spec"]; s != "" { cfg.ParentSpec = proto.String(s) } if s := *options.String["socket_dir"]; s != "" { cfg.SocketDir = proto.String(s) } if s := *options.String["kvm_coreos_img"]; s != "" { cfg.KvmCoreosImg = proto.String(s) } if i := *options.Int["kvm_coreos_vm_memory"]; i != 0 { cfg.KvmCoreosVmMemory = proto.Int32(int32(i)) } if s := *options.String["kvm_coreos_ssh_auth_keys"]; s != "" { cfg.KvmCoreosSshAuthKeys = proto.String(s) } }
func loadHost(domain *tao.Domain, cfg *tao.LinuxHostConfig) (*tao.LinuxHost, error) { var tc tao.Config // Sanity check host type var stacked bool switch cfg.GetType() { case "root": stacked = false case "stacked": stacked = true case "": options.Usage("Must supply -root or -stacked flag") default: options.Usage("Invalid host type: %s", cfg.GetType()) } // Sanity check hosting type hosting := make(map[string]bool) for _, h := range cfg.GetHosting() { switch h { case "process", "docker", "kvm_coreos", "kvm_coreos_linuxhost": hosting[h] = true default: options.Usage("Invalid hosting type: %s", cfg.GetHosting()) } } if len(hosting) == 0 { options.Usage("Must supply -hosting flag") } // For stacked hosts, figure out the channel type: TPM, pipe, file, or unix if 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 "": // leave channel type blank, tao may find it in env vars tc.HostChannelType = "" default: options.Usage("Invalid parent type: %s", cfg.GetParentType()) } // For stacked hosts, we may also have a parent spec from command line tc.HostSpec = cfg.GetParentSpec() // For stacked hosts on a TPM, we may also have tpm info from domain config if domain.Config.TpmInfo != nil { tc.TPMAIKPath = path.Join(apps.TaoDomainPath(), 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(apps.TaoDomainPath(), 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 // NewLinuxKVMCoreOSHostFactory need to be modified to support the new // CachedGuard? They probably don't. childFactory := make(map[string]tao.HostedProgramFactory) if hosting["process"] { childFactory["process"] = tao.NewLinuxProcessFactory("pipe", socketPath) } if hosting["docker"] { childFactory["docker"] = tao.NewLinuxDockerContainerFactory(socketPath, rulesPath) } if hosting["kvm_coreos"] { // TODO(kwalsh) re-enable this code path in new kvm factory // sshFile := cfg.GetKvmCoreosSshAuthKeys() // if sshFile != "" { // if !path.IsAbs(sshFile) { // sshFile = path.Join(apps.TaoDomainPath(), sshFile) // } // sshKeysCfg, err := io.ReadFile(sshFile) // options.FailIf(err, "Can't read ssh authorized 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(apps.TaoDomainPath(), coreOSImage) } // TODO(kwalsh) re-enable this code path in new kvm factory // vmMemory := cfg.GetKvmCoreosVmMemory() // if vmMemory == 0 { // vmMemory = 1024 // } var err error childFactory["kvm_coreos"], err = tao.NewKVMCoreOSFactory(coreOSImage, false) options.FailIf(err, "Can't create KVM CoreOS factory") } if hosting["kvm_coreos_linuxhost"] { 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(apps.TaoDomainPath(), 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(apps.TaoDomainPath(), coreOSImage) } vmMemory := cfg.GetKvmCoreosVmMemory() if vmMemory == 0 { vmMemory = 1024 } cfg := &tao.CoreOSLinuxhostConfig{ ImageFile: coreOSImage, Memory: int(vmMemory), RulesPath: rulesPath, SSHKeysCfg: sshKeysCfg, } childFactory["kvm_coreos_linuxhost"], err = tao.NewLinuxKVMCoreOSHostFactory(socketPath, cfg) options.FailIf(err, "Can't create KVM CoreOS LinuxHost factory") } if !stacked { pwd := options.Password("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) and associated variables\n", tao.HostChannelTypeEnvVar) } return tao.NewStackedLinuxHost(hostPath(), domain.Guard, parent, childFactory) } }
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) } }