mgmt,identity: Use a security setup more representative of what will
happen in practice in the integration tests.
Specifically:
(a) Clients and servers run as different principals
(b) Avoid use of the VEYRON_CREDENTIALS environment variable,
(and utilize the implicit agent in the v23tests framework)
The most notable change is in the DeviceManager test (renamed from
NodeManager in this change). An unclaimed device manager now starts
with self-signed blessings and gains useful ones only when being
"claimed".
Change-Id: I20b901392dd013d0e3aa6f5c6c840656f426b71b
diff --git a/cmd/mgmt/mgmt_v23_test.go b/cmd/mgmt/mgmt_v23_test.go
index 9e00043..8063f95 100644
--- a/cmd/mgmt/mgmt_v23_test.go
+++ b/cmd/mgmt/mgmt_v23_test.go
@@ -54,7 +54,7 @@
hostname = name
}
-func V23TestNodeManager(i *v23tests.T) {
+func V23TestDeviceManager(i *v23tests.T) {
defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")
userFlag := "--single_user"
withSuid := false
@@ -64,49 +64,53 @@
}
i.Logf("user flag: %q", userFlag)
+ var (
+ workDir = i.NewTempDir()
+ binStagingDir = mkSubdir(i, workDir, "bin")
+ dmInstallDir = filepath.Join(workDir, "dm")
+
+ // All vanadium command-line utitilities will be run by a
+ // principal that has "root/alice" as its blessing.
+ // (Where "root" comes from i.Principal().BlessingStore().Default()).
+ // Create those credentials and options to use to setup the
+ // binaries with them.
+ aliceCreds, _ = i.Shell().NewChildCredentials("alice")
+ aliceOpts = i.Shell().DefaultStartOpts().ExternalCommand().WithCustomCredentials(aliceCreds)
+
+ // Build all the command-line tools and set them up to run as alice.
+ // applicationd/binaryd servers will be run by alice too.
+ namespaceBin = i.BuildV23Pkg("v.io/x/ref/cmd/namespace").WithStartOpts(aliceOpts)
+ debugBin = i.BuildV23Pkg("v.io/x/ref/cmd/debug").WithStartOpts(aliceOpts)
+ deviceBin = i.BuildV23Pkg("v.io/x/ref/cmd/mgmt/device").WithStartOpts(aliceOpts)
+ binaryBin = i.BuildV23Pkg("v.io/x/ref/cmd/binary").WithStartOpts(aliceOpts)
+ applicationBin = i.BuildV23Pkg("v.io/x/ref/cmd/application").WithStartOpts(aliceOpts)
+ binarydBin = i.BuildV23Pkg("v.io/x/ref/services/mgmt/binary/binaryd").WithStartOpts(aliceOpts)
+ applicationdBin = i.BuildV23Pkg("v.io/x/ref/services/mgmt/application/applicationd").WithStartOpts(aliceOpts)
+
+ // The devicex script is not provided with any credentials, it
+ // will generate its own. This means that on "devicex start"
+ // the device will have no useful credentials and until "device
+ // claim" is invoked (as alice), it will just sit around
+ // waiting to be claimed.
+ //
+ // Other binaries, like applicationd and binaryd will be run by alice.
+ deviceScript = i.BinaryFromPath("device/devicex").WithEnv("VANADIUM_DEVICE_DIR=" + dmInstallDir)
+
+ mtName = "devices/" + hostname // Name under which the device manager will publish itself.
+ )
+
v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
- workDir := i.NewTempDir()
-
- mkSubdir := func(sub string) string {
- n := filepath.Join(workDir, sub)
- if err := os.Mkdir(n, 0755); err != nil {
- i.Fatalf("failed to create %q: %v", n, err)
- }
- return n
- }
-
- binStagingDir := mkSubdir("bin")
- agentServerBin := i.BuildGoPkg("v.io/x/ref/security/agent/agentd")
- suidHelperBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/suidhelper")
- initHelperBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/inithelper")
-
- // Device manager and principal use their own set of credentials.
- // The credentials directory will be populated with Start an application
- // server under the blessing "alice/myworkstation/applicationd" so that
- // the device ("alice/myworkstation") can talk to it. ALl of the binaries
- // that communicate with each other must share this credentials directory.
- credentials := "VEYRON_CREDENTIALS=" + i.NewTempDir()
- namespaceBin := i.BuildGoPkg("v.io/x/ref/cmd/namespace").WithEnv(credentials)
- debugBin := i.BuildGoPkg("v.io/x/ref/cmd/debug").WithEnv(credentials)
- deviceBin := i.BuildGoPkg("v.io/x/ref/cmd/mgmt/device").WithEnv(credentials)
- devicedBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/device/deviced").WithEnv(credentials)
- deviceScript := i.BinaryFromPath("device/devicex").WithEnv(credentials)
- principalBin := i.BuildGoPkg("v.io/x/ref/cmd/principal").WithEnv(credentials)
- binarydBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/binary/binaryd").WithEnv(credentials)
- binaryBin := i.BuildGoPkg("v.io/x/ref/cmd/binary").WithEnv(credentials)
- applicationdBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/application/applicationd").WithEnv(credentials)
- applicationBin := i.BuildGoPkg("v.io/x/ref/cmd/application").WithEnv(credentials)
+ buildAndCopyBinaries(
+ i,
+ binStagingDir,
+ "v.io/x/ref/services/mgmt/device/deviced",
+ "v.io/x/ref/security/agent/agentd",
+ "v.io/x/ref/services/mgmt/suidhelper",
+ "v.io/x/ref/services/mgmt/inithelper")
appDName := "applicationd"
devicedAppName := filepath.Join(appDName, "deviced", "test")
- i.BinaryFromPath("/bin/cp").Start(agentServerBin.Path(), suidHelperBin.Path(), initHelperBin.Path(), devicedBin.Path(), binStagingDir).WaitOrDie(os.Stdout, os.Stderr)
-
- dmInstallDir := filepath.Join(workDir, "dm")
- i.SetVar("VANADIUM_DEVICE_DIR", dmInstallDir)
-
- neighborhoodName := fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int())
-
deviceScript.Start(
"install",
binStagingDir,
@@ -114,16 +118,13 @@
"--origin="+devicedAppName,
"--",
"--veyron.tcp.address=127.0.0.1:0",
- "--neighborhood_name="+neighborhoodName).
+ "--neighborhood_name="+fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int())).
WaitOrDie(os.Stdout, os.Stderr)
-
deviceScript.Start("start").WaitOrDie(os.Stdout, os.Stderr)
- mtName := "devices/" + hostname
-
resolve := func(name string) string {
resolver := func() (interface{}, error) {
- // Use Start, rather than Run, sinde it's ok for 'namespace resolve'
+ // Use Start, rather than Run, since it's ok for 'namespace resolve'
// to fail with 'name doesn't exist'
inv := namespaceBin.Start("resolve", name)
// Cleanup after ourselves to avoid leaving a ton of invocations
@@ -144,25 +145,7 @@
i.Fatalf("glob failed for %q", mtName)
}
- // Create a self-signed blessing with name "alice" and set it as default
- // and shareable with all peers on the principal that the device manager
- // and principal are sharing (via the .WithEnv method) above. This
- // blessing will be used by all commands run by the device manager that
- // specify the same credentials.
- // TODO - update these commands
- // that except those
- // run with a different which gets a principal forked from the
- // process principal.
- blessingFilename := filepath.Join(workDir, "alice.bless")
- blessing := principalBin.Run("blessself", "alice")
- if err := ioutil.WriteFile(blessingFilename, []byte(blessing), 0755); err != nil {
- i.Fatal(err)
- }
- principalBin.Run("store", "setdefault", blessingFilename)
- principalBin.Run("store", "set", blessingFilename, "...")
- defer os.Remove(blessingFilename)
-
- // Claim the device as "alice/myworkstation".
+ // Claim the device as "root/alice/myworkstation".
deviceBin.Start("claim", mtName+"/devmgr/device", "myworkstation")
resolveChange := func(name, old string) string {
@@ -190,7 +173,7 @@
// Verify the device's default blessing is as expected.
inv := debugBin.Start("stats", "read", mtName+"/devmgr/__debug/stats/security/principal/*/blessingstore")
- inv.ExpectRE(".*Default blessings: alice/myworkstation$", -1)
+ inv.ExpectRE(".*Default blessings: root/alice/myworkstation$", -1)
// Get the device's profile, which should be set to non-empty string
inv = deviceBin.Start("describe", mtName+"/devmgr/device")
@@ -208,34 +191,27 @@
i.Fatalf("failed to get profile")
}
+ // Start a binaryd server that will serve the binary for the test
+ // application to be installed on the device.
binarydName := "binaryd"
- // Start an application server under the blessing
- // "alice/myworkstation/applicationd" so that
- // the device ("alice/myworkstation") can talk to it.
binarydBin.Start(
"--name="+binarydName,
"--root_dir="+filepath.Join(workDir, "binstore"),
"--veyron.tcp.address=127.0.0.1:0",
"--http=127.0.0.1:0")
-
sampleAppBinName := binarydName + "/testapp"
binaryBin.Run("upload", sampleAppBinName, binarydBin.Path())
-
- // Verify that the binary we uploaded is shown by glob, we need to run
- // with the same blessed credentials as binaryd in order to be able to
- // glob its names pace.
- if got := namespaceBin.WithEnv(credentials).Run("glob", sampleAppBinName); len(got) == 0 {
+ if got := namespaceBin.Run("glob", sampleAppBinName); len(got) == 0 {
i.Fatalf("glob failed for %q", sampleAppBinName)
}
- appstoreDir := mkSubdir("apptstore")
-
+ // Start an applicationd server that will serve the application
+ // envelope for the test application to be installed on the device.
applicationdBin.Start(
"--name="+appDName,
- "--store="+appstoreDir,
+ "--store="+mkSubdir(i, workDir, "appstore"),
"--veyron.tcp.address=127.0.0.1:0",
)
-
sampleAppName := appDName + "/testapp/v0"
appPubName := "testbinaryd"
appEnvelopeFilename := filepath.Join(workDir, "app.envelope")
@@ -306,13 +282,11 @@
// Upload a deviced binary
devicedAppBinName := binarydName + "/deviced"
- binaryBin.Run("upload", devicedAppBinName, devicedBin.Path())
+ binaryBin.Run("upload", devicedAppBinName, i.BuildGoPkg("v.io/x/ref/services/mgmt/device/deviced").Path())
- // Upload a device manager envelope, make sure that we set
- // VEYRON_CREDENTIALS in the enevelope, otherwise the updated device
- // manager will use new credentials.
+ // Upload a device manager envelope.
devicedEnvelopeFilename := filepath.Join(workDir, "deviced.envelope")
- devicedEnvelope := fmt.Sprintf("{\"Title\":\"device manager\", \"Binary\":{\"File\":%q}, \"Env\":[%q]}", devicedAppBinName, credentials)
+ devicedEnvelope := fmt.Sprintf("{\"Title\":\"device manager\", \"Binary\":{\"File\":%q}}", devicedAppBinName)
ioutil.WriteFile(devicedEnvelopeFilename, []byte(devicedEnvelope), 0666)
defer os.Remove(devicedEnvelopeFilename)
applicationBin.Run("put", devicedAppName, deviceProfile, devicedEnvelopeFilename)
@@ -353,7 +327,7 @@
// also be from some VAR or something. For now, hardcoded, but this
// should be fixed along with
// https://github.com/veyron/release-issues/issues/98
- if got, want := namespaceBin.Run("resolve", n), security.JoinPatternName(security.BlessingPattern("alice/myworkstation"), namespaceRoot); got != want {
+ if got, want := namespaceBin.Run("resolve", n), security.JoinPatternName(security.BlessingPattern("root/alice/myworkstation"), namespaceRoot); got != want {
i.Fatalf("got %q, want %q", got, want)
}
@@ -393,3 +367,20 @@
i.Fatalf("wrong error: %v", err)
}
}
+
+func buildAndCopyBinaries(i *v23tests.T, destinationDir string, packages ...string) {
+ var args []string
+ for _, pkg := range packages {
+ args = append(args, i.BuildGoPkg(pkg).Path())
+ }
+ args = append(args, destinationDir)
+ i.BinaryFromPath("/bin/cp").Start(args...).WaitOrDie(os.Stdout, os.Stderr)
+}
+
+func mkSubdir(i *v23tests.T, parent, child string) string {
+ dir := filepath.Join(parent, child)
+ if err := os.Mkdir(dir, 0755); err != nil {
+ i.Fatalf("failed to create %q: %v", dir, err)
+ }
+ return dir
+}
diff --git a/cmd/mgmt/v23_test.go b/cmd/mgmt/v23_test.go
index 720176d..eca31e6 100644
--- a/cmd/mgmt/v23_test.go
+++ b/cmd/mgmt/v23_test.go
@@ -20,6 +20,6 @@
os.Exit(r)
}
-func TestV23NodeManager(t *testing.T) {
- v23tests.RunTest(t, V23TestNodeManager)
+func TestV23DeviceManager(t *testing.T) {
+ v23tests.RunTest(t, V23TestDeviceManager)
}
diff --git a/security/agent/agent_v23_test.go b/security/agent/agent_v23_test.go
index e068999..5c46db9 100644
--- a/security/agent/agent_v23_test.go
+++ b/security/agent/agent_v23_test.go
@@ -90,7 +90,7 @@
pingpongClient.ExpectRE(".*Pinging...", -1)
pingpongClient.Expect("pong")
- // Make sure that the agent does not pass VEYRON_CREDENTIALs on to its children
+ // Make sure that the agent does not pass VEYRON_CREDENTIALS on to its children
agent := agentBin.WithEnv(credentials).Start("bash", "-c", "echo", "$VEYRON_CREDENTIALS")
fmt.Fprintln(agent.Stdin())
all, err := agent.ReadAll()
diff --git a/services/identity/identityd/identityd_v23_test.go b/services/identity/identityd/identityd_v23_test.go
index 5f3e11e..4cc612c 100644
--- a/services/identity/identityd/identityd_v23_test.go
+++ b/services/identity/identityd/identityd_v23_test.go
@@ -14,9 +14,7 @@
//go:generate v23 test generate .
-var (
- urlRE = "^(https://.*)$"
-)
+const urlRE = "^(https://.*)$"
func seekBlessings(i *v23tests.T, principal *v23tests.Binary, httpaddr string) {
args := []string{
@@ -61,21 +59,32 @@
func V23TestIdentityServer(i *v23tests.T) {
v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
-
- args := []string{
+ // Start identityd:
+ //
+ // identityd must have credentials that recognize the root mounttable.
+ // In production, the two share a common root certificate and thus
+ // recognize each other. The same is done here, i.Principal()
+ // wields the root key.
+ identityd := i.BuildV23Pkg("v.io/x/ref/services/identity/identityd_test")
+ creds, err := i.Shell().NewChildCredentials("identityd")
+ if err != nil {
+ i.Fatal(err)
+ }
+ identityd = identityd.WithStartOpts(identityd.StartOpts().WithCustomCredentials(creds))
+ httpaddr := identityd.Start(
"-host=localhost",
"-veyron.tcp.address=127.0.0.1:0",
- "--httpaddr=127.0.0.1:0",
- }
-
- httpaddr := i.BuildGoPkg("v.io/x/ref/services/identity/identityd_test").Start(args...).ExpectVar("HTTP_ADDR")
+ "-httpaddr=127.0.0.1:0").ExpectVar("HTTP_ADDR")
// Use the principal tool to seekblessings.
+ // This tool will not run with any credentials: Its whole purpose is to "seek" them!
principal := i.BuildGoPkg("v.io/x/ref/cmd/principal")
// Test an initial seekblessings call.
seekBlessings(i, principal, httpaddr)
// Test that a subsequent call succeeds with the same
// credentials. This means that the blessings and principal from the
// first call works correctly.
+ // TODO(ashankar): Does anyone recall what was the intent here? Running
+ // the tool twice doesn't seem to help?
seekBlessings(i, principal, httpaddr)
}
diff --git a/services/mgmt/application/applicationd/applicationd_v23_test.go b/services/mgmt/application/applicationd/applicationd_v23_test.go
index b17e5ca..7c3902f 100644
--- a/services/mgmt/application/applicationd/applicationd_v23_test.go
+++ b/services/mgmt/application/applicationd/applicationd_v23_test.go
@@ -7,15 +7,13 @@
"v.io/v23/naming"
"v.io/v23/security"
- vsecurity "v.io/x/ref/security"
- libsecurity "v.io/x/ref/test/security"
"v.io/x/ref/test/v23tests"
)
//go:generate v23 test generate
-func helper(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, credentials, cmd string, args ...string) string {
- args = append([]string{"-veyron.credentials=" + credentials, cmd}, args...)
+func helper(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, cmd string, args ...string) string {
+ args = append([]string{cmd}, args...)
inv := clientBin.Start(args...)
out := inv.Output()
err := inv.Wait(os.Stdout, os.Stderr)
@@ -29,53 +27,48 @@
}
-func matchEnvelope(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, credentials, name, suffix string) string {
- return helper(i, clientBin, expectError, credentials, "match", naming.Join(name, suffix), "test-profile")
+func matchEnvelope(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, name, suffix string) string {
+ return helper(i, clientBin, expectError, "match", naming.Join(name, suffix), "test-profile")
}
-func putEnvelope(i *v23tests.T, clientBin *v23tests.Binary, credentials, name, suffix, envelope string) string {
- return helper(i, clientBin, false, credentials, "put", naming.Join(name, suffix), "test-profile", envelope)
+func putEnvelope(i *v23tests.T, clientBin *v23tests.Binary, name, suffix, envelope string) string {
+ return helper(i, clientBin, false, "put", naming.Join(name, suffix), "test-profile", envelope)
}
-func removeEnvelope(i *v23tests.T, clientBin *v23tests.Binary, credentials, name, suffix string) string {
- return helper(i, clientBin, false, credentials, "remove", naming.Join(name, suffix), "test-profile")
+func removeEnvelope(i *v23tests.T, clientBin *v23tests.Binary, name, suffix string) string {
+ return helper(i, clientBin, false, "remove", naming.Join(name, suffix), "test-profile")
+}
+
+func binaryWithCredentials(i *v23tests.T, extension, pkgpath string) *v23tests.Binary {
+ creds, err := i.Shell().NewChildCredentials(extension)
+ if err != nil {
+ i.Fatalf("NewCustomCredentials (for %q) failed: %v", pkgpath, err)
+ }
+ b := i.BuildV23Pkg(pkgpath)
+ return b.WithStartOpts(b.StartOpts().WithCustomCredentials(creds))
}
func V23TestApplicationRepository(i *v23tests.T) {
v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
- // TODO(sjr): talk to caprita about the necessity/correctness of these.
- // Generate credentials.
- serverCred, serverPrin := libsecurity.NewCredentials("server")
- defer os.RemoveAll(serverCred)
- clientCred, _ := libsecurity.ForkCredentials(serverPrin, "client")
- defer os.RemoveAll(clientCred)
-
// Start the application repository.
appRepoName := "test-app-repo"
- appRepoStore := i.NewTempDir()
- args := []string{
- "-name=" + appRepoName,
- "-store=" + appRepoStore,
+ binaryWithCredentials(i, "applicationd", "v.io/x/ref/services/mgmt/application/applicationd").Start(
+ "-name="+appRepoName,
+ "-store="+i.NewTempDir(),
"-v=2",
- "-veyron.tcp.address=127.0.0.1:0",
- "-veyron.credentials=" + serverCred,
- }
- i.BuildGoPkg("v.io/x/ref/services/mgmt/application/applicationd").Start(args...)
+ "-veyron.tcp.address=127.0.0.1:0")
- // Build the client binary.
- clientBin := i.BuildGoPkg("v.io/x/ref/cmd/application")
+ // Build the client binary (must be a delegate of the server to pass
+ // the default authorization policy).
+ clientBin := binaryWithCredentials(i, "applicationd/client", "v.io/x/ref/cmd/application")
// Generate publisher blessings
- principal, err := vsecurity.NewPrincipal()
+ publisher, err := i.Shell().NewChildCredentials("publisher")
if err != nil {
i.Fatal(err)
}
- blessings, err := principal.BlessSelf("self")
- if err != nil {
- i.Fatal(err)
- }
- sig, err := principal.Sign([]byte("binarycontents"))
+ sig, err := publisher.Principal().Sign([]byte("binarycontents"))
if err != nil {
i.Fatal(err)
}
@@ -83,7 +76,7 @@
if err != nil {
i.Fatal(err)
}
- pubJSON, err := json.MarshalIndent(security.MarshalBlessings(blessings), " ", " ")
+ pubJSON, err := json.MarshalIndent(security.MarshalBlessings(publisher.Principal().BlessingStore().Default()), " ", " ")
if err != nil {
i.Fatal(err)
}
@@ -105,17 +98,17 @@
if _, err := appEnvelopeFile.Write([]byte(wantEnvelope)); err != nil {
i.Fatalf("Write() failed: %v", err)
}
- putEnvelope(i, clientBin, clientCred, appRepoName, appRepoSuffix, appEnvelopeFile.Name())
+ putEnvelope(i, clientBin, appRepoName, appRepoSuffix, appEnvelopeFile.Name())
// Match the application envelope.
- gotEnvelope := matchEnvelope(i, clientBin, false, clientCred, appRepoName, appRepoSuffix)
+ gotEnvelope := matchEnvelope(i, clientBin, false, appRepoName, appRepoSuffix)
if gotEnvelope != wantEnvelope {
i.Fatalf("unexpected output: got %v, want %v", gotEnvelope, wantEnvelope)
}
// Remove the application envelope.
- removeEnvelope(i, clientBin, clientCred, appRepoName, appRepoSuffix)
+ removeEnvelope(i, clientBin, appRepoName, appRepoSuffix)
// Check that the application envelope no longer exists.
- matchEnvelope(i, clientBin, true, clientCred, appRepoName, appRepoSuffix)
+ matchEnvelope(i, clientBin, true, appRepoName, appRepoSuffix)
}
diff --git a/services/mgmt/binary/binaryd/binaryd_v23_test.go b/services/mgmt/binary/binaryd/binaryd_v23_test.go
index 079f90f..acc4923 100644
--- a/services/mgmt/binary/binaryd/binaryd_v23_test.go
+++ b/services/mgmt/binary/binaryd/binaryd_v23_test.go
@@ -10,7 +10,6 @@
"strings"
"v.io/v23/naming"
- "v.io/x/ref/test/security"
"v.io/x/ref/test/testutil"
"v.io/x/ref/test/v23tests"
)
@@ -44,25 +43,18 @@
}
}
-func deleteFile(i *v23tests.T, clientBin *v23tests.Binary, credentials, name, suffix string) {
- deleteArgs := []string{
- "-veyron.credentials=" + credentials,
- "delete", naming.Join(name, suffix),
- }
- clientBin.Start(deleteArgs...).WaitOrDie(nil, nil)
+func deleteFile(i *v23tests.T, clientBin *v23tests.Binary, name, suffix string) {
+ clientBin.Start("delete", naming.Join(name, suffix)).WaitOrDie(os.Stdout, os.Stderr)
}
-func downloadFile(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, credentials, name, path, suffix string) {
- downloadArgs := []string{
- "-veyron.credentials=" + credentials,
- "download", naming.Join(name, suffix), path,
- }
- err := clientBin.Start(downloadArgs...).Wait(os.Stdout, os.Stderr)
+func downloadFile(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, name, path, suffix string) {
+ args := []string{"download", naming.Join(name, suffix), path}
+ err := clientBin.Start(args...).Wait(os.Stdout, os.Stderr)
if expectError && err == nil {
- i.Fatalf("%s %q did not fail when it should", clientBin.Path(), strings.Join(downloadArgs, " "))
+ i.Fatalf("%s %v: did not fail when it should", clientBin.Path(), args)
}
if !expectError && err != nil {
- i.Fatalf("%s %q failed: %v", clientBin.Path(), strings.Join(downloadArgs, " "), err)
+ i.Fatalf("%s %v: failed: %v", clientBin.Path(), args, err)
}
}
@@ -82,45 +74,40 @@
}
}
-func rootURL(i *v23tests.T, clientBin *v23tests.Binary, credentials, name string) string {
- rootArgs := []string{
- "-veyron.credentials=" + credentials,
- "url", name,
- }
- return strings.TrimSpace(clientBin.Start(rootArgs...).Output())
+func rootURL(i *v23tests.T, clientBin *v23tests.Binary, name string) string {
+ return strings.TrimSpace(clientBin.Start("url", name).Output())
}
-func uploadFile(i *v23tests.T, clientBin *v23tests.Binary, credentials, name, path, suffix string) {
- uploadArgs := []string{
- "-veyron.credentials=" + credentials,
- "upload", naming.Join(name, suffix), path,
+func uploadFile(i *v23tests.T, clientBin *v23tests.Binary, name, path, suffix string) {
+ clientBin.Start("upload", naming.Join(name, suffix), path).WaitOrDie(os.Stdout, os.Stderr)
+}
+
+func binaryWithCredentials(i *v23tests.T, extension, pkgpath string) *v23tests.Binary {
+ creds, err := i.Shell().NewChildCredentials(extension)
+ if err != nil {
+ i.Fatalf("NewCustomCredentials (for %q) failed: %v", pkgpath, err)
}
- clientBin.Start(uploadArgs...).WaitOrDie(os.Stdout, os.Stderr)
+ b := i.BuildV23Pkg(pkgpath)
+ return b.WithStartOpts(b.StartOpts().WithCustomCredentials(creds))
}
func V23TestBinaryRepositoryIntegration(i *v23tests.T) {
v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
// Build the required binaries.
- binaryRepoBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/binary/binaryd")
- clientBin := i.BuildGoPkg("v.io/x/ref/cmd/binary")
-
- // Generate credentials.
- serverCred, serverPrin := security.NewCredentials("server")
- defer os.RemoveAll(serverCred)
- clientCred, _ := security.ForkCredentials(serverPrin, "client")
- defer os.RemoveAll(clientCred)
+ // The client must run as a "delegate" of the server in order to pass
+ // the default authorization checks on the server.
+ var (
+ binaryRepoBin = binaryWithCredentials(i, "binaryd", "v.io/x/ref/services/mgmt/binary/binaryd")
+ clientBin = binaryWithCredentials(i, "binaryd/client", "v.io/x/ref/cmd/binary")
+ )
// Start the build server.
binaryRepoName := "test-binary-repository"
- args := []string{
- "-name=" + binaryRepoName,
+ binaryRepoBin.Start(
+ "-name="+binaryRepoName,
"-http=127.0.0.1:0",
- "-veyron.tcp.address=127.0.0.1:0",
- "-veyron.credentials=" + serverCred,
- }
-
- binaryRepoBin.Start(args...)
+ "-veyron.tcp.address=127.0.0.1:0")
// Upload a random binary file.
binFile := i.NewTempFile()
@@ -128,7 +115,7 @@
i.Fatalf("Write() failed: %v", err)
}
binSuffix := "test-binary"
- uploadFile(i, clientBin, clientCred, binaryRepoName, binFile.Name(), binSuffix)
+ uploadFile(i, clientBin, binaryRepoName, binFile.Name(), binSuffix)
// Upload a compressed version of the binary file.
tarFile := binFile.Name() + ".tar.gz"
@@ -141,13 +128,13 @@
}
defer os.Remove(tarFile)
tarSuffix := "test-compressed-file"
- uploadFile(i, clientBin, clientCred, binaryRepoName, tarFile, tarSuffix)
+ uploadFile(i, clientBin, binaryRepoName, tarFile, tarSuffix)
// Download the binary file and check that it matches the
// original one and that it has the right file type.
downloadedBinFile := binFile.Name() + "-downloaded"
defer os.Remove(downloadedBinFile)
- downloadFile(i, clientBin, false, clientCred, binaryRepoName, downloadedBinFile, binSuffix)
+ downloadFile(i, clientBin, false, binaryRepoName, downloadedBinFile, binSuffix)
compareFiles(i, binFile.Name(), downloadedBinFile)
checkFileType(i, downloadedBinFile, `{"Type":"application/octet-stream","Encoding":""}`)
@@ -156,13 +143,13 @@
// right file type.
downloadedTarFile := binFile.Name() + "-downloaded.tar.gz"
defer os.Remove(downloadedTarFile)
- downloadFile(i, clientBin, false, clientCred, binaryRepoName, downloadedTarFile, tarSuffix)
+ downloadFile(i, clientBin, false, binaryRepoName, downloadedTarFile, tarSuffix)
compareFiles(i, tarFile, downloadedTarFile)
checkFileType(i, downloadedTarFile, `{"Type":"application/x-tar","Encoding":"gzip"}`)
// Fetch the root URL of the HTTP server used by the binary
// repository to serve URLs.
- root := rootURL(i, clientBin, clientCred, binaryRepoName)
+ root := rootURL(i, clientBin, binaryRepoName)
// Download the binary file using the HTTP protocol and check
// that it matches the original one.
@@ -180,10 +167,10 @@
compareFiles(i, downloadedTarFile, downloadedTarFileURL)
// Delete the files.
- deleteFile(i, clientBin, clientCred, binaryRepoName, binSuffix)
- deleteFile(i, clientBin, clientCred, binaryRepoName, tarSuffix)
+ deleteFile(i, clientBin, binaryRepoName, binSuffix)
+ deleteFile(i, clientBin, binaryRepoName, tarSuffix)
// Check the files no longer exist.
- downloadFile(i, clientBin, true, clientCred, binaryRepoName, downloadedBinFile, binSuffix)
- downloadFile(i, clientBin, true, clientCred, binaryRepoName, downloadedTarFile, tarSuffix)
+ downloadFile(i, clientBin, true, binaryRepoName, downloadedBinFile, binSuffix)
+ downloadFile(i, clientBin, true, binaryRepoName, downloadedTarFile, tarSuffix)
}
diff --git a/services/mgmt/binary/impl/acl_test.go b/services/mgmt/binary/impl/acl_test.go
index e498592..6a70bf4 100644
--- a/services/mgmt/binary/impl/acl_test.go
+++ b/services/mgmt/binary/impl/acl_test.go
@@ -79,9 +79,7 @@
if err != nil {
t.Fatalf("SetPrincipal failed: %v", err)
}
- dir, childPrincipal := tsecurity.ForkCredentials(selfPrincipal, "child")
- defer os.RemoveAll(dir)
- childCtx, err := v23.SetPrincipal(ctx, childPrincipal)
+ childCtx, err := v23.SetPrincipal(ctx, tsecurity.ForkCredentials(selfPrincipal, "child"))
if err != nil {
t.Fatalf("SetPrincipal failed: %v", err)
}
diff --git a/services/mgmt/build/buildd/buildd_v23_test.go b/services/mgmt/build/buildd/buildd_v23_test.go
index bcbc423..f8d4671 100644
--- a/services/mgmt/build/buildd/buildd_v23_test.go
+++ b/services/mgmt/build/buildd/buildd_v23_test.go
@@ -9,7 +9,6 @@
"runtime"
"strings"
- "v.io/x/ref/test/security"
"v.io/x/ref/test/v23tests"
)
@@ -23,28 +22,30 @@
`
func V23TestBuildServerIntegration(i *v23tests.T) {
- v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
-
- // Generate credentials.
- serverCred, serverPrin := security.NewCredentials("server")
- defer os.RemoveAll(serverCred)
- clientCred, _ := security.ForkCredentials(serverPrin, "client")
- defer os.RemoveAll(clientCred)
-
- // Start the build server.
- buildServerBin := i.BuildGoPkg("v.io/x/ref/services/mgmt/build/buildd")
- buildServerName := "test-build-server"
goBin, err := exec.LookPath("go")
if err != nil {
i.Fatalf("%v", err)
}
goRoot := runtime.GOROOT()
- args := []string{
- "-name=" + buildServerName, "-gobin=" + goBin, "-goroot=" + goRoot,
- "-veyron.tcp.address=127.0.0.1:0",
- "-veyron.credentials=" + serverCred,
- }
- buildServerBin.Start(args...)
+
+ v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0")
+
+ // Build binaries for the client and server.
+ // Since ACLs are not setup on the server, the client must pass the
+ // default authorization policy, i.e., must be a "delegate" of the
+ // server.
+ var (
+ buildServerBin = binaryWithCredentials(i, "buildd", "v.io/x/ref/services/mgmt/build/buildd")
+ buildBin = binaryWithCredentials(i, "buildd/client", "v.io/x/ref/cmd/build")
+ )
+
+ // Start the build server.
+ buildServerName := "test-build-server"
+ buildServerBin.Start(
+ "-name="+buildServerName,
+ "-gobin="+goBin,
+ "-goroot="+goRoot,
+ "-veyron.tcp.address=127.0.0.1:0")
// Create and build a test source file.
testGoPath := i.NewTempDir()
@@ -61,13 +62,13 @@
if err := ioutil.WriteFile(testSrcFile, []byte(testProgram), os.FileMode(0600)); err != nil {
i.Fatalf("WriteFile(%v) failed: %v", testSrcFile, err)
}
- buildArgs := []string{
- "-veyron.credentials=" + clientCred,
- "build", buildServerName, "test",
- }
- buildEnv := []string{"GOPATH=" + testGoPath, "GOROOT=" + goRoot, "TMPDIR=" + testBinDir}
- buildBin := i.BuildGoPkg("v.io/x/ref/cmd/build")
- buildBin.WithEnv(buildEnv...).Start(buildArgs...).WaitOrDie(os.Stdout, os.Stderr)
+ buildBin.WithEnv(
+ "GOPATH="+testGoPath,
+ "GOROOT="+goRoot,
+ "TMPDIR="+testBinDir).Start(
+ "build",
+ buildServerName,
+ "test").WaitOrDie(os.Stdout, os.Stderr)
var testOut bytes.Buffer
testCmd := exec.Command(testBinFile)
testCmd.Stdout = &testOut
@@ -79,3 +80,12 @@
i.Fatalf("unexpected output: got %v, want %v", got, want)
}
}
+
+func binaryWithCredentials(i *v23tests.T, extension, pkgpath string) *v23tests.Binary {
+ creds, err := i.Shell().NewChildCredentials(extension)
+ if err != nil {
+ i.Fatalf("NewCustomCredentials (for %q) failed: %v", pkgpath, err)
+ }
+ b := i.BuildV23Pkg(pkgpath)
+ return b.WithStartOpts(b.StartOpts().WithCustomCredentials(creds))
+}
diff --git a/services/mounttable/mounttabled/mounttabled_v23_test.go b/services/mounttable/mounttabled/mounttabled_v23_test.go
index 9537309..ce596a2 100644
--- a/services/mounttable/mounttabled/mounttabled_v23_test.go
+++ b/services/mounttable/mounttabled/mounttabled_v23_test.go
@@ -19,13 +19,21 @@
}
}
+func binaryWithCredentials(i *v23tests.T, extension, pkgpath string) *v23tests.Binary {
+ creds, err := i.Shell().NewChildCredentials(extension)
+ if err != nil {
+ i.Fatalf("NewCustomCredentials (for %q) failed: %v", pkgpath, err)
+ }
+ b := i.BuildV23Pkg(pkgpath)
+ return b.WithStartOpts(b.StartOpts().WithCustomCredentials(creds))
+}
+
func V23TestMount(i *v23tests.T) {
neighborhood := fmt.Sprintf("test-%s-%d", getHostname(i), os.Getpid())
v23tests.RunRootMT(i, "--veyron.tcp.address=127.0.0.1:0", "--neighborhood_name="+neighborhood)
name, _ := i.GetVar("NAMESPACE_ROOT")
-
- clientBin := i.BuildGoPkg("v.io/x/ref/cmd/mounttable")
+ clientBin := binaryWithCredentials(i, "cmd", "v.io/x/ref/cmd/mounttable")
// Get the neighborhood endpoint from the mounttable.
neighborhoodEndpoint := clientBin.Start("glob", name, "nh").ExpectSetEventuallyRE(`^nh (.*) \(TTL .*\)$`)[0][1]
diff --git a/test/security/util.go b/test/security/util.go
index 696859f..eecbb44 100644
--- a/test/security/util.go
+++ b/test/security/util.go
@@ -9,17 +9,12 @@
// Create a new in-memory principal with self-signed blessing for "alice".
// p := NewPrincipal("alice")
//
-// Create a VeyronCredentials directory with a new persistent principal that has a
-// self-signed blessing for "alice" -- this directory can be set as the value
-// of the VEYRON_CREDENTIALS environment variable or the --veyron.credentials flag
-// used to initialize a runtime. All updates to the principal's state get subsequently
-// persisted to the directory. Both the directory and a handle to the created principal
-// are returned.
-// dir, p := NewCredentials("alice") // principal p has blessing "alice"
-//
-// Create a VeyronCredentials directory with a new persistent principal that is
-// blessed by the principal p under the extension "friend"
-// forkdir, forkp := ForkCredentials(p, "friend") // principal forkp has blessing "alice/friend"
+// Use a common "identity" provider that blesses other principals allowing
+// them to share a single root of trust:
+// idp := NewIDProvider("identity_provider")
+// p1, p2 := NewPrincipal(), NewPrincipal()
+// idp.Bless(p1, "alice") // Providing the blessing "identity_provider/alice" to p1
+// idp.Bless(p2, "bob) // Providing the blessing "identity_provider/bob" to p2.
package security
import (
@@ -76,23 +71,14 @@
return dir, p
}
-// ForkCredentials generates a directory with a new principal whose
-// blessings are provided by the 'parent'.
+// ForkCredentials creates a new Principal with blessings extended
+// from those of the parent.
//
// In particular, the principal is initialized with blessings from
// 'parent' under the provided 'extensions', and marked as default and
// shareable with all peers on the principal's blessing store.
-//
-// It returns the path to the directory created and the principal.
-// The directory can be used as a value for the VEYRON_CREDENTIALS
-// environment variable (or the --veyron.credentials flag) used to
-// initialize a Runtime.
-func ForkCredentials(parent security.Principal, requiredExtension string, otherExtensions ...string) (string, security.Principal) {
- dir, err := ioutil.TempDir("", "veyron_credentials")
- if err != nil {
- panic(err)
- }
- p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
+func ForkCredentials(parent security.Principal, requiredExtension string, otherExtensions ...string) security.Principal {
+ p, err := vsecurity.NewPrincipal()
if err != nil {
panic(err)
}
@@ -107,7 +93,7 @@
}
}
SetDefaultBlessings(p, def)
- return dir, p
+ return p
}
// NewPrincipal creates a new security.Principal.
diff --git a/test/security/util_test.go b/test/security/util_test.go
index 49d18ab..eb76380 100644
--- a/test/security/util_test.go
+++ b/test/security/util_test.go
@@ -27,38 +27,35 @@
return
}
-func testCredentials(cred string, wantPrincipal security.Principal, wantBlessings []string) error {
- pFromCred, err := vsecurity.LoadPersistentPrincipal(cred, nil)
- if err != nil {
- return fmt.Errorf("LoadPersistentPrincipal(%q, nil) failed: %v", cred, err)
- }
- if !reflect.DeepEqual(pFromCred, wantPrincipal) {
- fmt.Errorf("got principal from directory: %v, want: %v", pFromCred, wantPrincipal)
- }
-
- bs := pFromCred.BlessingStore()
- if got := namesForBlessings(pFromCred, bs.ForPeer("foo")); !unsortedEquals(got, wantBlessings) {
+func testBlessings(principal security.Principal, wantBlessings ...string) error {
+ bs := principal.BlessingStore()
+ if got := namesForBlessings(principal, bs.ForPeer("foo")); !unsortedEquals(got, wantBlessings) {
return fmt.Errorf("got peer blessings: %v, want: %v", got, wantBlessings)
}
- if got := namesForBlessings(pFromCred, bs.Default()); !unsortedEquals(got, wantBlessings) {
+ if got := namesForBlessings(principal, bs.Default()); !unsortedEquals(got, wantBlessings) {
return fmt.Errorf("got default blessings: %v, want: %v", got, wantBlessings)
}
return nil
}
-func TestCredentials(t *testing.T) {
- dir, p := NewCredentials("ali", "alice")
- if err := testCredentials(dir, p, []string{"ali", "alice"}); err != nil {
+func TestForkCredentials(t *testing.T) {
+ dir, origp := NewCredentials("ali", "alice")
+ p, err := vsecurity.LoadPersistentPrincipal(dir, nil)
+ if err != nil {
+ t.Fatalf("LoadPersistentPrincipal(%q, nil) failed: %v", dir, err)
+ }
+ if !reflect.DeepEqual(p, origp) {
+ t.Errorf("LoadPersistentPrincipal(%q) returned %v, want %v", dir, p, origp)
+ }
+ if err := testBlessings(p, "ali", "alice"); err != nil {
t.Fatal(err)
}
-
- forkdir, forkp := ForkCredentials(p, "friend", "enemy")
- if err := testCredentials(forkdir, forkp, []string{"ali/friend", "alice/friend", "ali/enemy", "alice/enemy"}); err != nil {
+ forkp := ForkCredentials(p, "friend", "enemy")
+ if err := testBlessings(forkp, "ali/friend", "alice/friend", "ali/enemy", "alice/enemy"); err != nil {
t.Fatal(err)
}
-
- forkforkdir, forkforkp := ForkCredentials(forkp, "spouse")
- if err := testCredentials(forkforkdir, forkforkp, []string{"ali/friend/spouse", "alice/friend/spouse", "ali/enemy/spouse", "alice/enemy/spouse"}); err != nil {
+ forkforkp := ForkCredentials(forkp, "spouse")
+ if err := testBlessings(forkforkp, "ali/friend/spouse", "alice/friend/spouse", "ali/enemy/spouse", "alice/enemy/spouse"); err != nil {
t.Fatal(err)
}
}
diff --git a/test/v23tests/v23tests.go b/test/v23tests/v23tests.go
index 9c0df9c..c56737b 100644
--- a/test/v23tests/v23tests.go
+++ b/test/v23tests/v23tests.go
@@ -452,8 +452,9 @@
writeStringOrDie(t, file, fmt.Sprintf("<< Exited shell: %s\n", state.String()))
}
-// BinaryFromPath returns a new Binary that, when started, will
-// execute the executable or script at the given path.
+// BinaryFromPath returns a new Binary that, when started, will execute the
+// executable or script at the given path. The binary is assumed to not
+// implement the exec protocol defined in v.io/x/ref/lib/exec.
//
// E.g. env.BinaryFromPath("/bin/bash").Start("-c", "echo hello world").Output() -> "hello world"
func (t *T) BinaryFromPath(path string) *Binary {
@@ -465,11 +466,10 @@
}
}
-// BuildGoPkg expects a Go package path that identifies a "main"
-// package and returns a Binary representing the newly built
-// binary. This binary does not use the exec protocol defined
-// in v.io/x/ref/lib/exec. Use this for command line tools and non
-// Vanadium servers.
+// BuildGoPkg expects a Go package path that identifies a "main" package and
+// returns a Binary representing the newly built binary. This binary does not
+// use the exec protocol defined in v.io/x/ref/lib/exec. Use this for
+// non-Vanadium command-line tools and servers.
func (t *T) BuildGoPkg(pkg string) *Binary {
return t.buildPkg(pkg)
}