Commit 2d0c962b authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

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/8910Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent e7fe9f56
// 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)
}
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
// the remote lldb session. This flag is appended to the end of the // the remote lldb session. This flag is appended to the end of the
// script's arguments and is not passed through to the underlying // script's arguments and is not passed through to the underlying
// binary. // 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 package main
import ( import (
...@@ -37,6 +43,12 @@ var errRetry = errors.New("failed to start test harness (retry attempted)") ...@@ -37,6 +43,12 @@ var errRetry = errors.New("failed to start test harness (retry attempted)")
var tmpdir string var tmpdir string
var (
devID string
appID string
teamID string
)
func main() { func main() {
log.SetFlags(0) log.SetFlags(0)
log.SetPrefix("go_darwin_arm_exec: ") log.SetPrefix("go_darwin_arm_exec: ")
...@@ -47,6 +59,10 @@ func main() { ...@@ -47,6 +59,10 @@ func main() {
log.Fatal("usage: go_darwin_arm_exec a.out") 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 var err error
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_") tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
if err != nil { if err != nil {
...@@ -77,6 +93,14 @@ func main() { ...@@ -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) { func run(bin string, args []string) (err error) {
appdir := filepath.Join(tmpdir, "gotest.app") appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir) os.RemoveAll(appdir)
...@@ -89,7 +113,7 @@ func run(bin string, args []string) (err error) { ...@@ -89,7 +113,7 @@ func run(bin string, args []string) (err error) {
} }
entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist") 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 return err
} }
if err := ioutil.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist), 0744); err != nil { 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) { ...@@ -107,7 +131,7 @@ func run(bin string, args []string) (err error) {
cmd := exec.Command( cmd := exec.Command(
"codesign", "codesign",
"-f", "-f",
"-s", "E8BMC3FE2Z", // certificate associated with golang.org "-s", devID,
"--entitlements", entitlementsPath, "--entitlements", entitlementsPath,
appdir, appdir,
) )
...@@ -592,22 +616,22 @@ const infoPlist = `<?xml version="1.0" encoding="UTF-8"?> ...@@ -592,22 +616,22 @@ const infoPlist = `<?xml version="1.0" encoding="UTF-8"?>
</plist> </plist>
` `
const devID = `YE84DJ86AZ` func entitlementsPlist() string {
return `<?xml version="1.0" encoding="UTF-8"?>
const entitlementsPlist = `<?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"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array><string>` + devID + `.golang.gotest</string></array> <array><string>` + teamID + `.golang.gotest</string></array>
<key>get-task-allow</key> <key>get-task-allow</key>
<true/> <true/>
<key>application-identifier</key> <key>application-identifier</key>
<string>` + devID + `.golang.gotest</string> <string>` + teamID + `.golang.gotest</string>
<key>com.apple.developer.team-identifier</key> <key>com.apple.developer.team-identifier</key>
<string>` + devID + `</string> <string>` + teamID + `</string>
</dict> </dict>
</plist>` </plist>`
}
const resourceRules = `<?xml version="1.0" encoding="UTF-8"?> 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"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment