예제 #1
0
func addContainerRules(host string, domain *tao.Domain) {
	dt := template()
	if domain.Config.DomainInfo.GetGuardType() == "Datalog" {
		for _, c := range dt.ContainerPaths {
			prin, err := makeContainerSubPrin(c)
			if err != nil {
				continue
			}
			pt := auth.PrinTail{Ext: prin}
			pred := auth.MakePredicate(dt.GetContainerPredicateName(), pt)
			err = domain.Guard.AddRule(fmt.Sprint(pred))
			options.FailIf(err, "Can't add rule to domain")
		}
	} else if domain.Config.DomainInfo.GetGuardType() == "ACLs" && host != "" {
		prin := makeHostPrin(host)
		for _, p := range dt.ContainerPaths {
			subprin, err := makeContainerSubPrin(p)
			if err != nil {
				continue
			}
			prog := prin.MakeSubprincipal(subprin)
			err = domain.Guard.Authorize(prog, "Execute", nil)
			options.FailIf(err, "Can't authorize program in domain")
		}
	}
	err := domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #2
0
func generateDomain(t *testing.T) *tao.Domain {
	domain := tao.Domain{}
	domain.Keys, domain.Keys.Cert = generatePolicyKey(t)
	domain.Guard = *generateGuard(t)
	domain.Config = tao.DomainConfig{X509Info: x509Info}
	return &domain
}
예제 #3
0
// This function reads in trusted entities from a file at trustedEntitiesPath. In particular,
// this file contains the text representation of a trusted_entities proto message, which contains
// the Tao names of trusted programs and hosts, information about trusted machines and trusted
// machine certificates.
// For each such trusted entity, this function adds ACL rules to the domain guard, and saves
// the changes before returning.
func InitAcls(domain *tao.Domain, trustedEntitiesPath string) error {
	text, err := ioutil.ReadFile(trustedEntitiesPath)
	if err != nil {
		log.Printf("Can't open trusted entities file: %s", trustedEntitiesPath)
		return err
	}
	trustedEntities := TrustedEntities{}
	err = proto.UnmarshalText(string(text), &trustedEntities)
	if err != nil {
		log.Printf("Can't parse trusted entities file: %s", trustedEntitiesPath)
		return err
	}
	for _, programTaoName := range trustedEntities.GetTrustedProgramTaoNames() {
		var programPrin auth.Prin
		_, err := fmt.Sscanf(programTaoName, "%v", &programPrin)
		if err != nil {
			log.Printf("Can't create program principal from: %s\nError: %s",
				programTaoName, err)
			return err
		}
		err = domain.Guard.Authorize(programPrin, "Execute", []string{})
		if err != nil {
			log.Printf("Can't authorize principal: %s\nError: %s", programPrin, err)
			return err
		}
	}
	for _, hostTaoName := range trustedEntities.GetTrustedHostTaoNames() {
		var hostPrin auth.Prin
		_, err := fmt.Sscanf(hostTaoName, "%v", &hostPrin)
		if err != nil {
			log.Printf("Can't create host principal from: %s\nError: %s",
				hostTaoName, err)
			return err
		}
		err = domain.Guard.Authorize(hostPrin, "Host", []string{})
		if err != nil {
			log.Printf("Can't authorize principal: %s\nError: %s", hostPrin, err)
			return err
		}
	}
	for _, machineInfo := range trustedEntities.GetTrustedMachineInfos() {
		machinePrin := auth.Prin{
			Type:    "MachineInfo",
			KeyHash: auth.Str(machineInfo),
		}
		err = domain.Guard.Authorize(machinePrin, "Root", []string{})
		if err != nil {
			log.Printf("Can't authorize principal: %s\nError: %s", machinePrin, err)
			return err
		}
	}
	err = domain.Save()
	if err != nil {
		log.Println("Can't save domain.", err)
	}
	return err
}
예제 #4
0
func addHostRules(host string, domain *tao.Domain) {
	if host == "" {
		return
	}
	dt := template()
	prin := makeHostPrin(host)
	pred := auth.MakePredicate(dt.GetHostPredicateName(), prin)
	err := domain.Guard.AddRule(fmt.Sprint(pred))
	options.FailIf(err, "Can't add rule to domain")
	err = domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #5
0
func addGuardRules(domain *tao.Domain) {
	dt := template()
	subprin := domain.Guard.Subprincipal()
	pt := auth.PrinTail{Ext: subprin}
	pred := auth.Pred{
		Name: dt.GetGuardPredicateName(),
		Arg:  []auth.Term{pt},
	}
	err := domain.Guard.AddRule(fmt.Sprint(pred))
	options.FailIf(err, "Can't add rule to domain")
	err = domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #6
0
func addExecute(path, host string, domain *tao.Domain) {
	prin := makeHostPrin(host)
	subprin, err := makeProgramSubPrin(path)
	if err == nil {
		prog := prin.MakeSubprincipal(subprin)
		fmt.Fprintf(noise, "Authorizing program to execute:\n"+
			"  path: %s\n"+
			"  host: %s\n"+
			"  name: %s\n", path, prin, subprin)
		err := domain.Guard.Authorize(prog, "Execute", nil)
		options.FailIf(err, "Can't authorize program in domain")
		err = domain.Save()
		options.FailIf(err, "Can't save domain")
	}
}
예제 #7
0
func addLinuxHostRules(domain *tao.Domain) {
	dt := template()
	for _, c := range dt.LinuxHostPaths {
		prin, err := makeLinuxHostSubPrin(c)
		if err != nil {
			continue
		}
		pt := auth.PrinTail{Ext: prin}
		pred := auth.MakePredicate(dt.GetLinuxHostPredicateName(), pt)
		err = domain.Guard.AddRule(fmt.Sprint(pred))
		options.FailIf(err, "Can't add rule to domain")
	}
	// The ACLs need the full name, so that only happens for containers and
	// programs.
	err := domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #8
0
func addTPM2Rules(domain *tao.Domain) {
	dt := template()
	tpmPath, pcrNums := getTPM2Config()
	prin := makeTPM2Prin(tpmPath, pcrNums)

	// TrustedOS predicate from PCR principal tail.
	prinPCRs := auth.PrinTail{Ext: prin.Ext}
	predTrustedOS := auth.MakePredicate(dt.GetOsPredicateName(), prinPCRs)
	err := domain.Guard.AddRule(fmt.Sprint(predTrustedOS))
	options.FailIf(err, "Can't add rule to domain")

	// TrustedTPM predicate from TPM principal.
	prin.Ext = nil
	predTrustedTPM2 := auth.MakePredicate(dt.GetTpm2PredicateName(), prin)
	err = domain.Guard.AddRule(fmt.Sprint(predTrustedTPM2))
	options.FailIf(err, "Can't add rule to domain")

	err = domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #9
0
func addProgramRules(host string, domain *tao.Domain) {
	dt := template()
	if domain.Config.DomainInfo.GetGuardType() == "Datalog" {
		// Add the hashes of any programs given in the template.
		for _, p := range dt.ProgramPaths {
			prin, err := makeProgramSubPrin(p)
			if err != nil {
				continue
			}
			pt := auth.PrinTail{Ext: prin}
			pred := auth.MakePredicate(dt.GetProgramPredicateName(), pt)
			err = domain.Guard.AddRule(fmt.Sprint(pred))
			options.FailIf(err, "Can't add rule to domain")
		}
	} else if domain.Config.DomainInfo.GetGuardType() == "ACLs" {
		addACLPrograms(host, domain)
	}
	err := domain.Save()
	options.FailIf(err, "Can't save domain")
}
예제 #10
0
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)
	}
}
예제 #11
0
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)
	}
}