From 2d0c962b1c13e451d0cce79032c92551c607b1bd Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 13 Apr 2015 11:31:41 -0700 Subject: [PATCH] misc/ios: read codesign info from environment variables Use environment variables to allow set-and-forget. Add a script to attempt to autodetect codesign info. Change-Id: Ic56b9c5f097b1a4117ebb89c408bc333d91f581d Reviewed-on: https://go-review.googlesource.com/8910 Reviewed-by: David Crawshaw --- misc/ios/detect.go | 132 +++++++++++++++++++++++++++++++++ misc/ios/go_darwin_arm_exec.go | 40 ++++++++-- 2 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 misc/ios/detect.go diff --git a/misc/ios/detect.go b/misc/ios/detect.go new file mode 100644 index 0000000000..54493e0abc --- /dev/null +++ b/misc/ios/detect.go @@ -0,0 +1,132 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// detect attempts to autodetect the correct +// values of the environment variables +// used by go_darwin_arm_exec. +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "strings" +) + +func main() { + devID := detectDevID() + fmt.Printf("export GOIOS_DEV_ID=%s\n", devID) + + udid := detectUDID() + mp := detectMobileProvisionFile(udid) + + f, err := ioutil.TempFile("", "go_ios_detect_") + check(err) + fname := f.Name() + defer os.Remove(fname) + + out := combinedOutput(parseMobileProvision(mp)) + _, err = f.Write(out) + check(err) + check(f.Close()) + + appID, err := plistExtract(fname, "ApplicationIdentifierPrefix:0") + check(err) + fmt.Printf("export GOIOS_APP_ID=%s\n", appID) + + teamID, err := plistExtract(fname, "Entitlements:com.apple.developer.team-identifier") + check(err) + fmt.Printf("export GOIOS_TEAM_ID=%s\n", teamID) +} + +func detectDevID() string { + cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v") + lines := getLines(cmd) + + for _, line := range lines { + if !bytes.Contains(line, []byte("iPhone Developer")) { + continue + } + fields := bytes.Fields(line) + return string(fields[1]) + } + fail("no code signing identity found") + panic("unreachable") +} + +var udidPrefix = []byte("UniqueDeviceID: ") + +func detectUDID() []byte { + cmd := exec.Command("ideviceinfo") + lines := getLines(cmd) + for _, line := range lines { + if bytes.HasPrefix(line, udidPrefix) { + return bytes.TrimPrefix(line, udidPrefix) + } + } + fail("udid not found; is the device connected?") + panic("unreachable") +} + +func detectMobileProvisionFile(udid []byte) string { + cmd := exec.Command("mdfind", "-name", ".mobileprovision") + lines := getLines(cmd) + + for _, line := range lines { + if len(line) == 0 { + continue + } + xmlLines := getLines(parseMobileProvision(string(line))) + for _, xmlLine := range xmlLines { + if bytes.Contains(xmlLine, udid) { + return string(line) + } + } + } + fail("did not find mobile provision matching device udid %s", udid) + panic("ureachable") +} + +func parseMobileProvision(fname string) *exec.Cmd { + return exec.Command("security", "cms", "-D", "-i", string(fname)) +} + +func plistExtract(fname string, path string) ([]byte, error) { + out, err := exec.Command("/usr/libexec/PlistBuddy", "-c", "Print "+path, fname).CombinedOutput() + if err != nil { + return nil, err + } + return bytes.TrimSpace(out), nil +} + +func getLines(cmd *exec.Cmd) [][]byte { + out := combinedOutput(cmd) + return bytes.Split(out, []byte("\n")) +} + +func combinedOutput(cmd *exec.Cmd) []byte { + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Println(strings.Join(cmd.Args, "\n")) + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + return out +} + +func check(err error) { + if err != nil { + fail(err.Error()) + } +} + +func fail(msg string, v ...interface{}) { + fmt.Fprintf(os.Stderr, msg, v...) + fmt.Fprintln(os.Stderr) + os.Exit(1) +} diff --git a/misc/ios/go_darwin_arm_exec.go b/misc/ios/go_darwin_arm_exec.go index 5b044f2a93..917d9a3e07 100644 --- a/misc/ios/go_darwin_arm_exec.go +++ b/misc/ios/go_darwin_arm_exec.go @@ -11,6 +11,12 @@ // the remote lldb session. This flag is appended to the end of the // script's arguments and is not passed through to the underlying // binary. +// +// This script requires that three environment variables be set: +// GOIOS_DEV_ID: The codesigning developer id or certificate identifier +// GOIOS_APP_ID: The provisioning app id prefix. Must support wildcard app ids. +// GOIOS_TEAM_ID: The team id that owns the app id prefix. +// $GOROOT/misc/ios contains a script, detect.go, that attempts to autodetect these. package main import ( @@ -37,6 +43,12 @@ var errRetry = errors.New("failed to start test harness (retry attempted)") var tmpdir string +var ( + devID string + appID string + teamID string +) + func main() { log.SetFlags(0) log.SetPrefix("go_darwin_arm_exec: ") @@ -47,6 +59,10 @@ func main() { log.Fatal("usage: go_darwin_arm_exec a.out") } + devID = getenv("GOIOS_DEV_ID") + appID = getenv("GOIOS_APP_ID") + teamID = getenv("GOIOS_TEAM_ID") + var err error tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_") if err != nil { @@ -77,6 +93,14 @@ func main() { } } +func getenv(envvar string) string { + s := os.Getenv(envvar) + if s == "" { + log.Fatalf("%s not set\nrun $GOROOT/misc/ios/detect.go to attempt to autodetect", s) + } + return s +} + func run(bin string, args []string) (err error) { appdir := filepath.Join(tmpdir, "gotest.app") os.RemoveAll(appdir) @@ -89,7 +113,7 @@ func run(bin string, args []string) (err error) { } entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist") - if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist), 0744); err != nil { + if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist()), 0744); err != nil { return err } if err := ioutil.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist), 0744); err != nil { @@ -107,7 +131,7 @@ func run(bin string, args []string) (err error) { cmd := exec.Command( "codesign", "-f", - "-s", "E8BMC3FE2Z", // certificate associated with golang.org + "-s", devID, "--entitlements", entitlementsPath, appdir, ) @@ -592,22 +616,22 @@ const infoPlist = ` ` -const devID = `YE84DJ86AZ` - -const entitlementsPlist = ` +func entitlementsPlist() string { + return ` keychain-access-groups - ` + devID + `.golang.gotest + ` + teamID + `.golang.gotest get-task-allow application-identifier - ` + devID + `.golang.gotest + ` + teamID + `.golang.gotest com.apple.developer.team-identifier - ` + devID + ` + ` + teamID + ` ` +} const resourceRules = ` -- 2.50.0