]> Cypherpunks repositories - gostls13.git/commitdiff
misc/ios: read codesign info from environment variables
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 13 Apr 2015 18:31:41 +0000 (11:31 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 15 Apr 2015 00:00:10 +0000 (00:00 +0000)
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 <crawshaw@golang.org>
misc/ios/detect.go [new file with mode: 0644]
misc/ios/go_darwin_arm_exec.go

diff --git a/misc/ios/detect.go b/misc/ios/detect.go
new file mode 100644 (file)
index 0000000..54493e0
--- /dev/null
@@ -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)
+}
index 5b044f2a931e0349d65dfa28558927b0304663a2..917d9a3e078fe9cef9b0026fd7e2887c4e64d4b1 100644 (file)
 // 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 = `<?xml version="1.0" encoding="UTF-8"?>
 </plist>
 `
 
-const devID = `YE84DJ86AZ`
-
-const entitlementsPlist = `<?xml version="1.0" encoding="UTF-8"?>
+func entitlementsPlist() string {
+       return `<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
        <key>keychain-access-groups</key>
-       <array><string>` + devID + `.golang.gotest</string></array>
+       <array><string>` + teamID + `.golang.gotest</string></array>
        <key>get-task-allow</key>
        <true/>
        <key>application-identifier</key>
-       <string>` + devID + `.golang.gotest</string>
+       <string>` + teamID + `.golang.gotest</string>
        <key>com.apple.developer.team-identifier</key>
-       <string>` + devID + `</string>
+       <string>` + teamID + `</string>
 </dict>
 </plist>`
+}
 
 const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">