func createDomain() { dt := template() if dt.Config.DomainInfo.GetPolicyKeysPath() == "" { options.Usage("Must supply a policy_keys_path in the domain configuration") } pwd := getKey("domain policy key password", "pass") domain, err := tao.CreateDomain(*dt.Config, configPath(), pwd) options.FailIf(err, "Can't create domain") if domain.Config.DomainInfo.GetGuardType() == "Datalog" { // Add any rules specified in the domain template. for _, rule := range dt.DatalogRules { err := domain.Guard.AddRule(rule) options.FailIf(err, "Can't add rule to domain") } } else if domain.Config.DomainInfo.GetGuardType() == "ACLs" { for _, rule := range dt.AclRules { err := domain.Guard.AddRule(rule) options.FailIf(err, "Can't add rule to domain") } } err = domain.Save() options.FailIf(err, "Can't save domain") // Optionally, create a public cached domain. if addr := *options.String["pub_domain_address"]; addr != "" { net := *options.String["pub_domain_network"] ttl := *options.Duration["pub_domain_ttl"] _, err = domain.CreatePublicCachedDomain(net, addr, int64(ttl)) options.FailIf(err, "Can't create public cached domain") } }
func main() { options.Help = "Usage: %s [options] (get|post ...)" options.Parse() srv := netlog.DefaultServer if *options.String["addr"] != "" { srv = &netlog.Server{Addr: *options.String["addr"]} } fmt.Printf("# connecting to netlog server %s using tao authentication.\n", srv.Addr) err := srv.Connect() options.FailIf(err, "couldn't connect to netlog server") args := options.Args() if len(args) == 1 && args[0] == "get" { log, err := srv.Entries() options.FailIf(err, "couldn't get netlog entries") fmt.Printf("# %d entries\n", len(log)) for i, e := range log { fmt.Printf("%d %q %s\n", i, e.Prin, e.Msg) } } else if len(args) > 1 && args[0] == "post" { msg := strings.Join(args[1:], " ") err := srv.Log(msg) options.FailIf(err, "couldn't post netlog entry") } else { options.Usage("Unrecognized command: %s\n", args[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") }
func doClient(domain *tao.Domain) { network := "tcp" keys, err := tao.NewTemporaryTaoDelegatedKeys(tao.Signing, nil, tao.Parent()) options.FailIf(err, "client: couldn't generate temporary Tao keys") g := domain.Guard if *ca != "" { na, err := tao.RequestTruncatedAttestation(network, *ca, keys, domain.Keys.VerifyingKey) options.FailIf(err, "client: couldn't get a truncated attestation from %s: %s\n", *ca) keys.Delegation = na // If we're using a CA, then use a custom guard that accepts only // programs that have talked to the CA. g, err = newTempCAGuard(domain.Keys.VerifyingKey) options.FailIf(err, "client: couldn't set up a new guard") } pingGood := 0 pingFail := 0 for i := 0; i < *pingCount || *pingCount < 0; i++ { // negative means forever if doRequest(g, domain, keys) { pingGood++ } else { pingFail++ } fmt.Printf("client: made %d connections, finished %d ok, %d bad pings\n", i+1, pingGood, pingFail) } }
func outputPrincipal() { if path := *options.String["program"]; path != "" { subprin, err := makeProgramSubPrin(path) options.FailIf(err, "Can't create program principal") pt := auth.PrinTail{Ext: subprin} fmt.Println(pt) } if path := *options.String["container"]; path != "" { subprin, err := makeContainerSubPrin(path) options.FailIf(err, "Can't create container principal") pt := auth.PrinTail{Ext: subprin} fmt.Println(pt) } if *options.Bool["tpm"] { tpmPath, aikFile, pcrVals := getTPMConfig() prin := makeTPMPrin(tpmPath, aikFile, pcrVals) // In the domain template the host name is in quotes. We need to escape // quote strings in the Principal string so that domain_template.pb gets // parsed correctly. name := strings.Replace(prin.String(), "\"", "\\\"", -1) fmt.Println(name) } if lhpath := *options.String["soft"]; lhpath != "" { if !path.IsAbs(lhpath) { lhpath = path.Join(domainPath(), lhpath) } k, err := tao.NewOnDiskPBEKeys(tao.Signing, nil, lhpath, nil) options.FailIf(err, "Can't create soft tao keys") fmt.Println(k.VerifyingKey.ToPrincipal()) } }
func SubmitAndInstall(keys *tao.Keys, csr *CSR) { verbose.Printf("Obtaining certificate from CA (may take a while)\n") resp, err := Submit(keys, csr) options.FailIf(err, "can't obtain X509 certificate from CA") if len(resp) == 0 { options.Fail(nil, "no x509 certificates returned from CA") } // Add the certs to our keys... keys.Cert["default"] = resp[0] for i, c := range resp { name := "ca" if i > 0 { name = fmt.Sprintf("ca-%d", i) } keys.Cert[name] = c } if keys.X509Path("default") != "" { err = keys.SaveCerts() } options.FailIf(err, "can't save X509 certificates") chain := keys.CertChain("default") verbose.Printf("Obtained certfificate chain of length %d:\n", len(chain)) for i, cert := range chain { verbose.Printf(" Cert[%d] Subject: %s\n", i, x509txt.RDNString(cert.Subject)) } if Warn { fmt.Println("Note: You may need to install root CA's key into the browser.") } }
func (mh ManifestHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { q := req.URL.Query() name, ok := q["p"] if !ok || len(name) != 1 { w.Header().Set("Content-Type", "text/html") t, err := template.New("show").Parse(ManifestIndexTemplate) options.FailIf(err, "can't parse template") err = t.Execute(w, mh) options.FailIf(err, "can't execute template") return } fmt.Printf("request for: %s\n", name[0]) var p auth.Prin if _, err := fmt.Sscanf("("+name[0]+")", "%v", &p); err != nil { http.NotFound(w, req) return } m := tao.DeriveManifest(&p) var b bytes.Buffer Dump(indent.NewHtmlWriter(&b, "h2"), tao.Manifest{"Principal Manifest": m}) s := b.String() w.Header().Set("Content-Type", "text/html") t, err := template.New("show").Parse(ManifestTemplate) options.FailIf(err, "can't parse template") err = t.Execute(w, template.HTML(s)) options.FailIf(err, "can't execute template") }
func addACLPrograms(host string, domain *tao.Domain) { if host == "" { return } dt := template() prin := makeHostPrin(host) for _, p := range dt.ProgramPaths { subprin, err := makeProgramSubPrin(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") } for _, vm := range dt.VmPaths { vmPrin, err := makeVMSubPrin(vm) if err != nil { continue } for _, lh := range dt.LinuxHostPaths { lhPrin, err := makeLinuxHostSubPrin(lh) if err != nil { continue } var lsp auth.SubPrin lsp = append(lsp, vmPrin...) lsp = append(lsp, lhPrin...) lprog := prin.MakeSubprincipal(lsp) err = domain.Guard.Authorize(lprog, "Execute", nil) options.FailIf(err, "Can't authorize program in domain") for _, p := range dt.ProgramPaths { subprin, err := makeProgramSubPrin(p) if err != nil { continue } var sp auth.SubPrin sp = append(sp, vmPrin...) sp = append(sp, lhPrin...) sp = append(sp, subprin...) prog := prin.MakeSubprincipal(sp) err = domain.Guard.Authorize(prog, "Execute", nil) options.FailIf(err, "Can't authorize program in domain") var gsp auth.SubPrin gsp = append(gsp, vmPrin...) gsp = append(gsp, lhPrin...) gsp = append(gsp, domain.Guard.Subprincipal()...) gsp = append(gsp, subprin...) gprog := prin.MakeSubprincipal(gsp) err = domain.Guard.Authorize(gprog, "Execute", nil) options.FailIf(err, "Can't authorize program in domain") } } } }
func main() { options.Parse() if *options.String["config"] != "" && !*options.Bool["init"] { err := options.Load(*options.String["config"]) options.FailIf(err, "Can't load configuration") } fmt.Println("Cloudproxy HTTPS Server") if tao.Parent() == nil { options.Fail(nil, "can't continue: no host Tao available") } self, err := tao.Parent().GetTaoName() options.FailIf(err, "Can't get Tao name") // TODO(kwalsh) extend tao name with operating mode and policy addr := net.JoinHostPort(*options.String["host"], *options.String["port"]) cpath := *options.String["config"] kdir := *options.String["keys"] if kdir == "" && cpath != "" { kdir = path.Dir(cpath) } else if kdir == "" { options.Fail(nil, "Option -keys or -config is required") } docs := *options.String["docs"] if docs == "" && cpath != "" { docs = path.Join(path.Dir(cpath), "docs") } else if docs == "" { options.Fail(nil, "Option -keys or -config is required") } var keys *tao.Keys if *options.Bool["init"] { keys = taoca.GenerateKeys(name, addr, kdir) } else { keys = taoca.LoadKeys(kdir) } fmt.Printf("Configuration file: %s\n", cpath) if *options.Bool["init"] && cpath != "" { err := options.Save(cpath, "HTTPS server configuration", "persistent") options.FailIf(err, "Can't save configuration") } http.Handle("/cert/", https.CertificateHandler{keys.CertificatePool}) http.Handle("/prin/", https.ManifestHandler{"/prin/", self.String()}) http.Handle("/", http.FileServer(https.LoggingFilesystem{http.Dir(docs)})) fmt.Printf("Listening at %s using HTTPS\n", addr) err = tao.ListenAndServeTLS(addr, keys) options.FailIf(err, "can't listen and serve") fmt.Println("Server Done") }
func startHost(domain *tao.Domain) { if *options.Bool["daemon"] && *options.Bool["foreground"] { options.Usage("Can supply only one of -daemon and -foreground") } if *options.Bool["daemon"] { daemonize() } cfg := configureFromFile() configureFromOptions(cfg) host, err := loadHost(domain, cfg) options.FailIf(err, "Can't create host") sockPath := path.Join(hostPath(), "admin_socket") // Set the socketPath directory go+rx so tao_launch can access sockPath and // connect to this linux host, even when tao_launch is run as non-root. err = os.Chmod(path.Dir(sockPath), 0755) options.FailIf(err, "Can't change permissions") uaddr, err := net.ResolveUnixAddr("unix", sockPath) options.FailIf(err, "Can't resolve unix socket") sock, err := net.ListenUnix("unix", uaddr) options.FailIf(err, "Can't create admin socket") defer sock.Close() err = os.Chmod(sockPath, 0666) if err != nil { sock.Close() options.Fail(err, "Can't change permissions on admin socket") } go func() { verbose.Printf("Linux Tao Service (%s) started and waiting for requests\n", host.HostName()) err = tao.NewLinuxHostAdminServer(host).Serve(sock) verbose.Printf("Linux Tao Service finished\n") sock.Close() options.FailIf(err, "Error serving admin requests") os.Exit(0) }() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGTERM) <-c verbose.Printf("Linux Tao Service shutting down\n") err = shutdown() if err != nil { sock.Close() options.Fail(err, "Can't shut down admin socket") } // The above goroutine will normally end by calling os.Exit(), so we // can block here indefinitely. But if we get a second kill signal, // let's abort. verbose.Printf("Waiting for shutdown....\n") <-c options.Fail(nil, "Could not shut down linux_host") }
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") }
func queryGuard(query string) { domain, err := tao.LoadDomain(configPath(), nil) options.FailIf(err, "Can't load domain") ok, err := domain.Guard.Query(query) options.FailIf(err, "Can't process query") if ok { fmt.Println("The policy implies the statement.") } else { fmt.Println("The policy does not imply the statement") } }
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") }
func template() *tao.DomainTemplate { if savedTemplate == nil { configTemplate := *options.String["config_template"] if configTemplate == "" { options.Usage("Must supply -config_template") } savedTemplate = new(tao.DomainTemplate) pbtext, err := ioutil.ReadFile(configTemplate) options.FailIf(err, "Can't read config template") err = proto.UnmarshalText(string(pbtext), savedTemplate) options.FailIf(err, "Can't parse config template: %s", configTemplate) } return savedTemplate }
func template() *tao.DomainTemplate { if savedTemplate == nil { configTemplate := *options.String["config_template"] if configTemplate == "" { configTemplate = path.Join(apps.TaoDomainPath(), "domain_template.pb") } savedTemplate = new(tao.DomainTemplate) pbtext, err := ioutil.ReadFile(configTemplate) options.FailIf(err, "Can't read config template. Try -config_template instead?") err = proto.UnmarshalText(string(pbtext), savedTemplate) options.FailIf(err, "Can't parse config template: %s", configTemplate) } return savedTemplate }
func initHost(domain *tao.Domain) { var cfg tao.LinuxHostConfig configureFromOptions(&cfg) _, err := loadHost(domain, &cfg) options.FailIf(err, "Can't create host") // If we get here, keys were created and flags must be ok. file, err := util.CreatePath(hostConfigPath(), 0777, 0666) options.FailIf(err, "Can't create host configuration") cs := proto.MarshalTextString(&cfg) fmt.Fprint(file, cs) file.Close() }
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") } }
func main() { options.Parse() if *options.String["config"] != "" && !*options.Bool["init"] { err := options.Load(*options.String["config"]) options.FailIf(err, "Can't load configuration") } fmt.Println("Cloudproxy HTTPS Netlog Viewer") if tao.Parent() == nil { options.Fail(nil, "can't continue: no host Tao available") } // TODO(kwalsh) extend tao name with operating mode and policy addr := net.JoinHostPort(*options.String["host"], *options.String["port"]) cpath := *options.String["config"] kdir := *options.String["keys"] if kdir == "" && cpath != "" { kdir = path.Dir(cpath) } else if kdir == "" { options.Fail(nil, "Option -keys or -config is required") } var keys *tao.Keys if *options.Bool["init"] { keys = taoca.GenerateKeys(name, addr, kdir) } else { keys = taoca.LoadKeys(kdir) } fmt.Printf("Configuration file: %s\n", cpath) if *options.Bool["init"] && cpath != "" { err := options.Save(cpath, "Cloudproxy HTTPS netlog viewer configuration", "persistent") options.FailIf(err, "Can't save configuration") } http.Handle("/cert/", https.CertificateHandler{keys.CertificatePool}) http.Handle("/index.html", http.RedirectHandler("/", 301)) http.HandleFunc("/", netlog_show) fmt.Printf("Listening at %s using HTTPS\n", addr) err := tao.ListenAndServeTLS(addr, keys) options.FailIf(err, "can't listen and serve") fmt.Println("Server Done") }
func showHost(domain *tao.Domain) { cfg := configureFromFile() configureFromOptions(cfg) host, err := loadHost(domain, cfg) options.FailIf(err, "Can't create host") fmt.Printf("%v\n", host.HostName()) }
func getTPMConfig() (string, string, []int) { domain, err := tao.LoadDomain(configPath(), nil) options.FailIf(err, "Can't load domain") tpmPath := domain.Config.GetTpmInfo().GetTpmPath() aikFile := domain.Config.GetTpmInfo().GetAikPath() pcrVals := domain.Config.GetTpmInfo().GetPcrs() var pcrNums []int for _, s := range strings.Split(pcrVals, ",") { v, err := strconv.ParseInt(s, 10, 32) options.FailIf(err, "Can't parse TPM PCR spec") pcrNums = append(pcrNums, int(v)) } return tpmPath, aikFile, pcrNums }
func main() { flag.Parse() // Check to see if we are running in Docker mode with linked containers. // If so, then there will be an environment variable SERVER_PORT that // will contain a value of the form tcp://<ip>:<port> serverEnvVar := os.Getenv("SERVER_PORT") if serverEnvVar == "" { serverAddr = net.JoinHostPort(*serverHost, *serverPort) } else { serverAddr = strings.TrimPrefix(serverEnvVar, "tcp://") if serverAddr == serverEnvVar { options.Usage("client: invalid SERVER_PORT environment variable value '%s'\n", serverEnvVar) } } switch *demoAuth { case "tcp", "tls", "tao": default: options.Usage("unrecognized authentication mode: %s\n", *demoAuth) } fmt.Println("Go Tao Demo Client") if tao.Parent() == nil { options.Fail(nil, "can't continue: No host Tao available") } domain, err := tao.LoadDomain(configPath(), nil) options.FailIf(err, "error: couldn't load the tao domain from %s\n", configPath()) doClient(domain) fmt.Println("Client Done") }
func netlog_show(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") e, err := netlog.Entries() if err != nil { t, _ := template.New("error").Parse(err_tpl) err = t.Execute(w, err) if err != nil { fmt.Printf("error showing netlog: %s\n", err) } return } s := compress(e) t, err := template.New("show").Parse(show_tpl) options.FailIf(err, "can't parse template") err = t.Execute(w, s) options.FailIf(err, "can't execute template") }
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") }
func makeHostPrin(host string) auth.Prin { if host == "" { options.Usage("The domain template must contain a Tao host in host_name") } var prin auth.Prin _, err := fmt.Sscanf(host, "%v", &prin) options.FailIf(err, "Can't create host principal") return prin }
func UrlBasename(loc string) string { u, err := url.ParseRequestURI(loc) options.FailIf(err, "can't parse url in certificate: %s", u) s := strings.Split(u.Path, "/") if len(s) < 2 { options.Fail(nil, "can't parse url in certificate: %s", u) } return s[len(s)-1] }
// TODO(tmroeder): The keys for the TPM2 have to already be created here so // that we can produce the name of the TPM2 key. For now, this just returns a // dummy key. func makeTPM2Prin(tpmPath string, pcrNums []int) auth.Prin { // TODO(tmroeder): The following key is generated on the spot. This should // instead be the key read from a file. privKey, err := rsa.GenerateKey(rand.Reader, 2048) options.FailIf(err, "Can't generate a temp RSA key") // Open a connection to the TPM. tpmFile, err := os.OpenFile(tpmPath, os.O_RDWR, 0) options.FailIf(err, "Can't access TPM") pcrVals, err := tao.ReadTPM2PCRs(tpmFile, pcrNums) tpmFile.Close() options.FailIf(err, "Can't get the PCRs from a TPM 2.0") prin, err := tao.MakeTPM2Prin(&privKey.PublicKey, pcrNums, pcrVals) options.FailIf(err, "Can't create a TPM2 principal") return prin }
func main() { verbose.Set(true) options.Parse() if *options.String["config"] != "" && !*options.Bool["init"] { err := options.Load(*options.String["config"]) options.FailIf(err, "Can't load configuration") } if *options.Bool["init"] { cpath := *options.String["config"] if cpath == "" { options.Fail(nil, "Option -init requires option -config") } fmt.Println("Initializing configuration file: " + cpath) err := options.Save(cpath, "Tao rendezvous configuration", "persistent") options.FailIf(err, "Can't save configuration") } fmt.Println("Cloudproxy Rendezvous Service") if tao.Parent() == nil { options.Fail(nil, "can't continue: no host Tao available") } allowAnon = *options.Bool["anon"] manualMode = *options.Bool["manual"] fcfsMode = *options.Bool["fcfs"] addr := *options.String["addr"] netlog.Log("rendezvous: init") netlog.Log("rendezvous: allow anon? %v", allowAnon) netlog.Log("rendezvous: manual? %v", manualMode) netlog.Log("rendezvous: fcfs? %v", fcfsMode) netlog.Log("rendezvous: addr = %v", addr) // TODO(kwalsh) extend tao name with operating mode and policy err := tao.NewOpenServer(tao.ConnHandlerFunc(doResponses)).ListenAndServe(addr) options.FailIf(err, "server died") netlog.Log("rendezvous: done") }
func getTPM2Config() (string, []int) { domain, err := tao.LoadDomain(configPath(), nil) options.FailIf(err, "Can't load domain") // TODO(tmroeder): This ignores the info path, since it ignores the cert // files. tpmPath := domain.Config.GetTpm2Info().GetTpm2Device() pcrVals := domain.Config.GetTpm2Info().GetTpm2Pcrs() // TODO(tmroeder): This currently ignores the paths to the ek_cert and // quote_cert, since it creates its own keys. var pcrNums []int for _, s := range strings.Split(pcrVals, ",") { v, err := strconv.ParseInt(s, 10, 32) options.FailIf(err, "Can't parse TPM PCR spec") pcrNums = append(pcrNums, int(v)) } return tpmPath, pcrNums }
// Main provides the main functionality of linux_host. This is provided as a // separate function to allow other code to register other Tao implementations // (with tao.Register) before starting the code. func Main() { flag.Usage = help // Get options before the command verb flag.Parse() // Get command verb cmd := "help" if flag.NArg() > 0 { cmd = flag.Arg(0) } // Get options after the command verb if flag.NArg() > 1 { flag.CommandLine.Parse(flag.Args()[1:]) } if !*options.Bool["quiet"] { noise = os.Stdout } // Load the domain. domain, err := tao.LoadDomain(domainConfigPath(), nil) options.FailIf(err, "Can't load domain") // Set $TAO_DOMAIN so it will be inherited by hosted programs os.Unsetenv("TAO_DOMAIN") err = os.Setenv("TAO_DOMAIN", domainPath()) options.FailIf(err, "Can't set $TAO_DOMAIN") switch cmd { case "help": help() case "init": initHost(domain) case "show": showHost(domain) case "start": startHost(domain) case "stop", "shutdown": stopHost(domain) default: options.Usage("Unrecognized command: %s", cmd) } }
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") }