blob: e6c59dd80f47652e2f382a735b3c858bbda26ffb [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -08005package main_test
6
7import (
James Ring5721f3d2015-02-12 19:53:20 -08008 "bytes"
Asim Shankar5fbe3262015-03-11 23:03:51 -07009 "fmt"
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080010 "io/ioutil"
11 "os"
12 "path/filepath"
13 "regexp"
James Ring5721f3d2015-02-12 19:53:20 -080014 "strings"
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080015
Asim Shankar59b8b692015-03-30 01:23:36 -070016 "v.io/x/ref/envvar"
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070017 "v.io/x/ref/test/v23tests"
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080018)
19
Cosmos Nicolaoua866f262015-02-10 14:56:06 -080020//go:generate v23 test generate
Suharsh Sivakumar6d70f9e2015-02-20 16:35:33 -080021
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080022// redirect redirects the stdout of the given invocation to the file at the
23// given path.
Cosmos Nicolaou01007a02015-02-11 15:38:38 -080024func redirect(t *v23tests.T, inv *v23tests.Invocation, path string) {
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080025 if err := ioutil.WriteFile(path, []byte(inv.Output()), 0600); err != nil {
26 t.Fatalf("WriteFile(%q) failed: %v\n", path, err)
27 }
28}
29
James Ring5721f3d2015-02-12 19:53:20 -080030// removePublicKeys replaces public keys (16 hex bytes, :-separated) with
31// XX:.... This substitution enables comparison with golden output even when
32// keys are freshly minted by the "principal create" command.
33func removePublicKeys(input string) string {
34 return regexp.MustCompile("([0-9a-f]{2}:){15}[0-9a-f]{2}").ReplaceAllString(input, "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX")
35}
36
37func removeCaveats(input string) string {
Suharsh Sivakumarf3eafa22015-02-24 12:58:51 -080038 input = regexp.MustCompile(`0xa64c2d0119fba3348071feeb2f308000\(time\.Time=.*\)`).ReplaceAllString(input, "ExpiryCaveat")
Asim Shankara0bba462015-02-20 22:50:51 -080039 input = regexp.MustCompile(`0x54a676398137187ecdb26d2d69ba0003\(\[]string=.*\)`).ReplaceAllString(input, "MethodCaveat")
40 input = regexp.MustCompile(`0x00000000000000000000000000000000\(bool=true\)`).ReplaceAllString(input, "Unconstrained")
41 return input
James Ring5721f3d2015-02-12 19:53:20 -080042}
43
Cosmos Nicolaou01007a02015-02-11 15:38:38 -080044func V23TestBlessSelf(t *v23tests.T) {
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080045 var (
Robert Kroeger02714b72015-04-14 18:02:38 -070046 outputDir = t.NewTempDir("")
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080047 aliceDir = filepath.Join(outputDir, "alice")
48 aliceBlessingFile = filepath.Join(outputDir, "aliceself")
49 )
50
Matt Rosencrantzbca49812015-03-01 21:32:54 -080051 bin := t.BuildGoPkg("v.io/x/ref/cmd/principal")
Cosmos Nicolaou42a17362015-03-10 16:40:18 -070052 bin.Run("create", aliceDir, "alice")
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080053
Asim Shankar59b8b692015-03-30 01:23:36 -070054 bin = bin.WithEnv(credEnv(aliceDir))
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080055 redirect(t, bin.Start("blessself", "alicereborn"), aliceBlessingFile)
James Ring5721f3d2015-02-12 19:53:20 -080056 got := removePublicKeys(bin.Start("dumpblessings", aliceBlessingFile).Output())
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080057 want := `Blessings : alicereborn
James Ring5721f3d2015-02-12 19:53:20 -080058PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080059Certificate chains : 1
James Ring5721f3d2015-02-12 19:53:20 -080060Chain #0 (1 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
61 Certificate #0: alicereborn with 0 caveats
62`
63 if want != got {
64 t.Fatalf("unexpected output, wanted \n%s, got\n%s", want, got)
Cosmos Nicolaou728a57e2015-02-05 13:04:08 -080065 }
66}
James Ring5721f3d2015-02-12 19:53:20 -080067
68func V23TestStore(t *v23tests.T) {
69 var (
Robert Kroeger02714b72015-04-14 18:02:38 -070070 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -080071 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -080072 aliceDir = filepath.Join(outputDir, "alice")
73 aliceFriend = filepath.Join(outputDir, "alice.bless")
74 bobDir = filepath.Join(outputDir, "bob")
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -070075 bobForPeer = filepath.Join(outputDir, "bob.get.forpeer")
James Ring5721f3d2015-02-12 19:53:20 -080076 )
77
78 // Create two principals: alice and bob.
79 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
80 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
81
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -070082 // Bless Bob with Alice's principal.
Asim Shankar59b8b692015-03-30 01:23:36 -070083 blessEnv := credEnv(aliceDir)
84 redirect(t, bin.WithEnv(blessEnv).Start("bless", "--for=1m", bobDir, "friend"), aliceFriend)
James Ring5721f3d2015-02-12 19:53:20 -080085
86 // Run store forpeer on bob.
Asim Shankarf32d24d2015-04-01 16:34:26 -070087 bin.Start("--v23.credentials="+bobDir, "set", "forpeer", aliceFriend, "alice").WaitOrDie(os.Stdout, os.Stderr)
88 redirect(t, bin.WithEnv(blessEnv).Start("--v23.credentials="+bobDir, "get", "forpeer", "alice/server"), bobForPeer)
James Ring5721f3d2015-02-12 19:53:20 -080089
90 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", bobForPeer).Output()))
Asim Shankarb3c8d662015-03-31 23:48:02 -070091 want := `Blessings : bob,alice/friend
James Ring5721f3d2015-02-12 19:53:20 -080092PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
93Certificate chains : 2
94Chain #0 (1 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
95 Certificate #0: bob with 0 caveats
96Chain #1 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
97 Certificate #0: alice with 0 caveats
98 Certificate #1: friend with 1 caveat
99 (0) ExpiryCaveat
100`
101 if want != got {
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -0700102 t.Errorf("unexpected output, got\n%s, wanted\n%s", got, want)
103 }
104
105 // Test the names flag.
106 got = bin.WithEnv(blessEnv).Start("--v23.credentials="+bobDir, "get", "forpeer", "--names", "alice/server").Output()
107 want = `bob
108alice/friend
109`
110 if got != want {
111 t.Errorf("unexpected output, got %s, want %s", got, want)
112 }
113
114 // Test the rootkey flag. In particular alice/friend's rootkey should be equal to alice's publickey.
115 got = bin.WithEnv(blessEnv).Start("--v23.credentials="+bobDir, "get", "forpeer", "--rootkey", "alice/friend", "alice/server").Output()
Asim Shankarde6fda52015-04-22 21:20:24 -0700116 want = bin.WithEnv(blessEnv).Start("get", "publickey", "--pretty").Output()
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -0700117 if got != want {
118 t.Errorf("unexpected output, got %s, want %s", got, want)
119 }
120
121 // Test the caveats flag.
122 got = bin.WithEnv(blessEnv).Start("--v23.credentials="+bobDir, "get", "forpeer", "--caveats", "alice/friend", "alice/server").Output()
123 want = "Expires at"
124 if !strings.HasPrefix(got, want) {
125 t.Errorf("unexpected output, got %s, want %s", got, want)
James Ring5721f3d2015-02-12 19:53:20 -0800126 }
127}
128
129func V23TestDump(t *v23tests.T) {
130 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700131 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800132 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -0800133 aliceDir = filepath.Join(outputDir, "alice")
134 )
135
136 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
137
Asim Shankar59b8b692015-03-30 01:23:36 -0700138 blessEnv := credEnv(aliceDir)
139 got := removePublicKeys(bin.WithEnv(blessEnv).Start("dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800140 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
141---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700142Default Blessings alice
143Peer pattern Blessings
144... alice
James Ring5721f3d2015-02-12 19:53:20 -0800145---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700146Public key Pattern
147XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
148`
149 if want != got {
150 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
151 }
152}
153
154func V23TestGetRecognizedRoots(t *v23tests.T) {
155 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700156 outputDir = t.NewTempDir("")
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700157 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
158 aliceDir = filepath.Join(outputDir, "alice")
159 )
160
161 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
162
163 blessEnv := credEnv(aliceDir)
164 got := removePublicKeys(bin.WithEnv(blessEnv).Start("get", "recognizedroots").Output())
165 want := `Public key Pattern
166XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
167`
168 if want != got {
169 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
170 }
171}
172
173func V23TestGetPeermap(t *v23tests.T) {
174 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700175 outputDir = t.NewTempDir("")
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700176 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
177 aliceDir = filepath.Join(outputDir, "alice")
178 )
179
180 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
181
182 blessEnv := credEnv(aliceDir)
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -0700183 got := bin.WithEnv(blessEnv).Start("get", "peermap").Output()
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700184 want := `Default Blessings alice
185Peer pattern Blessings
186... alice
James Ring5721f3d2015-02-12 19:53:20 -0800187`
188 if want != got {
189 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
190 }
191}
192
Asim Shankara0bba462015-02-20 22:50:51 -0800193// Given an invocation of "principal recvblessings", this function returns the
194// arguments to provide to "principal bless" provided by the "recvblessings"
195// invocation.
196//
197// For example,
198// principal recvblessings
199// would typically print something like:
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700200// principal bless --remote-key=<some_public_key> --remote-token=<some_token> extensionfoo
Asim Shankara0bba462015-02-20 22:50:51 -0800201// as an example of command line to use to send the blessings over.
202//
203// In that case, this method would return:
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700204// { "--remote-key=<some_public_key>", "--remote-token=<some_token>", "extensionfoo"}
Asim Shankara0bba462015-02-20 22:50:51 -0800205func blessArgsFromRecvBlessings(inv *v23tests.Invocation) []string {
206 cmd := inv.ExpectSetEventuallyRE("(^principal bless .*$)")[0][0]
207 return strings.Split(cmd, " ")[2:]
208}
209
James Ring5721f3d2015-02-12 19:53:20 -0800210func V23TestRecvBlessings(t *v23tests.T) {
211 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700212 outputDir = t.NewTempDir("")
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700213 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
214 aliceDir = filepath.Join(outputDir, "alice")
215 bobDir = filepath.Join(outputDir, "bob")
216 carolDir = filepath.Join(outputDir, "carol")
217 bobBlessFile = filepath.Join(outputDir, "bobBlessInfo")
James Ring5721f3d2015-02-12 19:53:20 -0800218 )
219
220 // Generate principals for alice and carol.
221 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700222 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800223 bin.Start("create", carolDir, "carol").WaitOrDie(os.Stdout, os.Stderr)
224
225 // Run recvblessings on carol, and have alice send blessings over
226 // (blessings received must be set as default and shareable with all peers).
227 var args []string
228 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700229 inv := bin.Start("--v23.credentials="+carolDir, "--v23.tcp.address=127.0.0.1:0", "recvblessings")
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700230 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Asim Shankara0bba462015-02-20 22:50:51 -0800231 // Replace the random extension suggested by recvblessings with "friend/carol"
232 args[len(args)-1] = "friend/carol"
James Ring5721f3d2015-02-12 19:53:20 -0800233 }
Asim Shankar59b8b692015-03-30 01:23:36 -0700234 bin.WithEnv(credEnv(aliceDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800235
236 // Run recvblessings on carol, and have alice send blessings over
237 // (blessings received must be set as shareable with peers matching 'alice/...'.)
238 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700239 inv := bin.Start("--v23.credentials="+carolDir, "--v23.tcp.address=127.0.0.1:0", "recvblessings", "--for-peer=alice", "--set-default=false")
James Ring5721f3d2015-02-12 19:53:20 -0800240 // recvblessings suggests a random extension, find the extension and replace it with friend/carol/foralice.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700241 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Asim Shankara0bba462015-02-20 22:50:51 -0800242 args[len(args)-1] = "friend/carol/foralice"
James Ring5721f3d2015-02-12 19:53:20 -0800243 }
Asim Shankar59b8b692015-03-30 01:23:36 -0700244 bin.WithEnv(credEnv(aliceDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800245
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700246 // Run recvblessings on carol with the --remote-arg-file flag, and have bob send blessings over with the --remote-arg-file flag.
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700247 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700248 inv := bin.Start("--v23.credentials="+carolDir, "--v23.tcp.address=127.0.0.1:0", "recvblessings", "--for-peer=bob", "--set-default=false", "--remote-arg-file="+bobBlessFile)
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700249 // recvblessings suggests a random extension, use friend/carol/forbob instead.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700250 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700251 args[len(args)-1] = "friend/carol/forbob"
252 }
253 bin.WithEnv(credEnv(bobDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
254
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700255 listenerInv := bin.Start("--v23.credentials="+carolDir, "--v23.tcp.address=127.0.0.1:0", "recvblessings", "--for-peer=alice/...", "--set-default=false", "--vmodule=*=2", "--logtostderr")
James Ring5721f3d2015-02-12 19:53:20 -0800256
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700257 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(listenerInv)...)
James Ring5721f3d2015-02-12 19:53:20 -0800258
259 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700260 // Mucking around with remote-key should fail.
261 cpy := strings.Split(regexp.MustCompile("remote-key=").ReplaceAllString(strings.Join(args, " "), "remote-key=BAD"), " ")
James Ring5721f3d2015-02-12 19:53:20 -0800262 var buf bytes.Buffer
Asim Shankar59b8b692015-03-30 01:23:36 -0700263 if bin.WithEnv(credEnv(aliceDir)).Start(cpy...).Wait(os.Stdout, &buf) == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800264 t.Fatalf("%v should have failed, but did not", cpy)
James Ring5721f3d2015-02-12 19:53:20 -0800265 }
266
267 if want, got := "key mismatch", buf.String(); !strings.Contains(got, want) {
268 t.Fatalf("expected %q to be contained within\n%s\n, but was not", want, got)
269 }
270 }
271
272 {
273 var buf bytes.Buffer
274 // Mucking around with the token should fail.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700275 cpy := strings.Split(regexp.MustCompile("remote-token=").ReplaceAllString(strings.Join(args, " "), "remote-token=BAD"), " ")
Asim Shankar59b8b692015-03-30 01:23:36 -0700276 if bin.WithEnv(credEnv(aliceDir)).Start(cpy...).Wait(os.Stdout, &buf) == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800277 t.Fatalf("%v should have failed, but did not", cpy)
James Ring5721f3d2015-02-12 19:53:20 -0800278 }
279
280 if want, got := "blessings received from unexpected sender", buf.String(); !strings.Contains(got, want) {
281 t.Fatalf("expected %q to be contained within\n%s\n, but was not", want, got)
282 }
283 }
284
Asim Shankarf32d24d2015-04-01 16:34:26 -0700285 // Dump carol out, the only blessing that survives should be from the
286 // first "bless" command. (alice/friend/carol).
287 got := removePublicKeys(bin.Start("--v23.credentials="+carolDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800288 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
289---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700290Default Blessings alice/friend/carol
291Peer pattern Blessings
292... alice/friend/carol
293alice alice/friend/carol/foralice
294bob bob/friend/carol/forbob
James Ring5721f3d2015-02-12 19:53:20 -0800295---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700296Public key Pattern
297XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
298XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [bob]
299XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [carol]
James Ring5721f3d2015-02-12 19:53:20 -0800300`
301 if want != got {
302 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
303 }
304}
305
306func V23TestFork(t *v23tests.T) {
307 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700308 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800309 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -0800310 aliceDir = filepath.Join(outputDir, "alice")
311 alicePhoneDir = filepath.Join(outputDir, "alice-phone")
312 alicePhoneCalendarDir = filepath.Join(outputDir, "alice-phone-calendar")
Asim Shankara0bba462015-02-20 22:50:51 -0800313 tmpfile = filepath.Join(outputDir, "tmpfile")
James Ring5721f3d2015-02-12 19:53:20 -0800314 )
315
316 // Generate principals for alice.
317 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
318
319 // Run fork to setup up credentials for alice/phone that are
320 // blessed by alice under the extension "phone".
Asim Shankarf32d24d2015-04-01 16:34:26 -0700321 bin.Start("--v23.credentials="+aliceDir, "fork", "--for", "1h", alicePhoneDir, "phone").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800322
323 // Dump alice-phone out, the only blessings it has must be from alice (alice/phone).
324 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700325 got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800326 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
327---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700328Default Blessings alice/phone
329Peer pattern Blessings
330... alice/phone
James Ring5721f3d2015-02-12 19:53:20 -0800331---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700332Public key Pattern
333XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
James Ring5721f3d2015-02-12 19:53:20 -0800334`
335 if want != got {
336 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
337 }
338 }
Asim Shankara0bba462015-02-20 22:50:51 -0800339 // And it should have an expiry caveat
340 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700341 redirect(t, bin.Start("--v23.credentials", alicePhoneDir, "get", "default"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800342 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
343 want := `Blessings : alice/phone
344PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
345Certificate chains : 1
346Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
347 Certificate #0: alice with 0 caveats
348 Certificate #1: phone with 1 caveat
349 (0) ExpiryCaveat
350`
351 if want != got {
352 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
353 }
354 }
James Ring5721f3d2015-02-12 19:53:20 -0800355
356 // Run fork to setup up credentials for alice/phone/calendar that are
357 // blessed by alice/phone under the extension "calendar".
Asim Shankarf32d24d2015-04-01 16:34:26 -0700358 bin.Start("--v23.credentials="+alicePhoneDir, "fork", "--for", "1h", alicePhoneCalendarDir, "calendar").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800359 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700360 got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneCalendarDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800361 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
362---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700363Default Blessings alice/phone/calendar
364Peer pattern Blessings
365... alice/phone/calendar
James Ring5721f3d2015-02-12 19:53:20 -0800366---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700367Public key Pattern
368XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
James Ring5721f3d2015-02-12 19:53:20 -0800369`
370 if want != got {
371 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
372 }
373 }
Asim Shankara0bba462015-02-20 22:50:51 -0800374 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700375 redirect(t, bin.Start("--v23.credentials", alicePhoneCalendarDir, "get", "default"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800376 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
377 want := `Blessings : alice/phone/calendar
378PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
379Certificate chains : 1
380Chain #0 (3 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
381 Certificate #0: alice with 0 caveats
382 Certificate #1: phone with 1 caveat
383 (0) ExpiryCaveat
384 Certificate #2: calendar with 1 caveat
385 (0) ExpiryCaveat
386`
387 if want != got {
388 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
389 }
390 }
James Ring5721f3d2015-02-12 19:53:20 -0800391}
392
393func V23TestCreate(t *v23tests.T) {
394 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700395 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800396 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -0800397 aliceDir = filepath.Join(outputDir, "alice")
398 )
399
400 // Creating a principal should succeed the first time.
401 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
402
403 // The second time should fail (the create command won't override an existing principal).
404 if bin.Start("create", aliceDir, "alice").Wait(os.Stdout, os.Stderr) == nil {
405 t.Fatalf("principal creation should have failed, but did not")
406 }
407
408 // If we specify -overwrite, it will.
409 bin.Start("create", "--overwrite", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
410}
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800411
412func V23TestCaveats(t *v23tests.T) {
413 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700414 outputDir = t.NewTempDir("")
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800415 aliceDir = filepath.Join(outputDir, "alice")
416 aliceBlessingFile = filepath.Join(outputDir, "aliceself")
417 )
418
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800419 bin := t.BuildGoPkg("v.io/x/ref/cmd/principal")
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800420 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
421
Asim Shankar59b8b692015-03-30 01:23:36 -0700422 bin = bin.WithEnv(credEnv(aliceDir))
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800423 args := []string{
424 "blessself",
Suharsh Sivakumar60b78e92015-04-23 21:36:49 -0700425 "--caveat=\"v.io/v23/security\".MethodCaveat={\"method\"}",
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800426 "--caveat={{0x54,0xa6,0x76,0x39,0x81,0x37,0x18,0x7e,0xcd,0xb2,0x6d,0x2d,0x69,0xba,0x0,0x3},typeobject([]string)}={\"method\"}",
427 "alicereborn",
428 }
429 redirect(t, bin.Start(args...), aliceBlessingFile)
430 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", aliceBlessingFile).Output()))
431 want := `Blessings : alicereborn
432PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
433Certificate chains : 1
434Chain #0 (1 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
435 Certificate #0: alicereborn with 2 caveats
436 (0) MethodCaveat
437 (1) MethodCaveat
438`
439 if want != got {
440 t.Fatalf("unexpected output, wanted \n%s, got\n%s", want, got)
441 }
442}
Asim Shankar918190d2015-02-18 17:12:43 -0800443
444func V23TestForkWithoutVDLPATH(t *v23tests.T) {
445 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700446 parent = t.NewTempDir("")
Jiri Simsa32f76fb2015-04-07 15:39:23 -0700447 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal").WithEnv("V23_ROOT=''", "VDLPATH=''")
Asim Shankar918190d2015-02-18 17:12:43 -0800448 )
449 if err := bin.Start("create", parent, "parent").Wait(os.Stdout, os.Stderr); err != nil {
450 t.Fatalf("create %q failed: %v", parent, err)
451 }
Robert Kroeger02714b72015-04-14 18:02:38 -0700452 if err := bin.Start("--v23.credentials="+parent, "fork", "--for=1s", t.NewTempDir(""), "child").Wait(os.Stdout, os.Stderr); err != nil {
Asim Shankar918190d2015-02-18 17:12:43 -0800453 t.Errorf("fork failed: %v", err)
454 }
455}
Asim Shankara0bba462015-02-20 22:50:51 -0800456
457func V23TestForkWithoutCaveats(t *v23tests.T) {
458 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700459 parent = t.NewTempDir("")
460 child = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800461 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Asim Shankara0bba462015-02-20 22:50:51 -0800462 buf bytes.Buffer
463 )
464 if err := bin.Start("create", parent, "parent").Wait(os.Stdout, os.Stderr); err != nil {
465 t.Fatalf("create %q failed: %v", parent, err)
466 }
Asim Shankarf32d24d2015-04-01 16:34:26 -0700467 if err := bin.Start("--v23.credentials", parent, "fork", child, "child").Wait(os.Stdout, &buf); err == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800468 t.Errorf("fork should have failed without any caveats, but did not")
469 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
470 t.Errorf("fork returned error: %q, expected error to contain %q", got, want)
471 }
Asim Shankarf32d24d2015-04-01 16:34:26 -0700472 if err := bin.Start("--v23.credentials", parent, "fork", "--for=0", child, "child").Wait(os.Stdout, &buf); err == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800473 t.Errorf("fork should have failed without any caveats, but did not")
474 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
475 t.Errorf("fork returned error: %q, expected error to contain %q", got, want)
476 }
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700477 if err := bin.Start("--v23.credentials", parent, "fork", "--require-caveats=false", child, "child").Wait(os.Stdout, os.Stderr); err != nil {
478 t.Errorf("fork --require-caveats=false failed with: %v", err)
Asim Shankara0bba462015-02-20 22:50:51 -0800479 }
480}
481
482func V23TestBless(t *v23tests.T) {
483 var (
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800484 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Robert Kroeger02714b72015-04-14 18:02:38 -0700485 dir = t.NewTempDir("")
Asim Shankara0bba462015-02-20 22:50:51 -0800486 aliceDir = filepath.Join(dir, "alice")
487 bobDir = filepath.Join(dir, "bob")
488 tmpfile = filepath.Join(dir, "tmpfile")
489 )
490 // Create two principals: alice and bob
491 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
492 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
493
494 // All blessings will be done by "alice"
Asim Shankar59b8b692015-03-30 01:23:36 -0700495 bin = bin.WithEnv(credEnv(aliceDir))
Asim Shankara0bba462015-02-20 22:50:51 -0800496
497 {
498 // "alice" should fail to bless "bob" without any caveats
499 var buf bytes.Buffer
500 if err := bin.Start("bless", bobDir, "friend").Wait(os.Stdout, &buf); err == nil {
501 t.Errorf("bless should have failed when no caveats are specified")
502 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
503 t.Errorf("got error %q, expected to match %q", got, want)
504 }
505 }
506 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700507 // But succeed if --require-caveats=false is specified
508 redirect(t, bin.Start("bless", "--require-caveats=false", bobDir, "friend"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800509 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
510 want := `Blessings : alice/friend
511PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
512Certificate chains : 1
513Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
514 Certificate #0: alice with 0 caveats
515 Certificate #1: friend with 1 caveat
516 (0) Unconstrained
517`
518 if got != want {
519 t.Errorf("Got\n%vWant\n%v", got, want)
520 }
521 }
522 {
523 // And succeed if --for is specified
524 redirect(t, bin.Start("bless", "--for=1m", bobDir, "friend"), tmpfile)
525 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
526 want := `Blessings : alice/friend
527PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
528Certificate chains : 1
529Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
530 Certificate #0: alice with 0 caveats
531 Certificate #1: friend with 1 caveat
532 (0) ExpiryCaveat
533`
534 if got != want {
535 t.Errorf("Got\n%vWant\n%v", got, want)
536 }
537 }
538 {
539 // But not if --for=0
540 var buf bytes.Buffer
541 if err := bin.Start("bless", "--for=0", bobDir, "friend").Wait(os.Stdout, &buf); err == nil {
542 t.Errorf("bless should have failed when no caveats are specified")
543 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
544 t.Errorf("got error %q, expected to match %q", got, want)
545 }
546 }
547}
Asim Shankar5fbe3262015-03-11 23:03:51 -0700548
Asim Shankar80277d02015-03-31 12:57:06 -0700549func V23TestAddBlessingsToRoots(t *v23tests.T) {
Asim Shankar5fbe3262015-03-11 23:03:51 -0700550 var (
551 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Robert Kroeger02714b72015-04-14 18:02:38 -0700552 aliceDir = t.NewTempDir("")
553 bobDir = t.NewTempDir("")
554 blessingFile = filepath.Join(t.NewTempDir(""), "bobfile")
Asim Shankar5fbe3262015-03-11 23:03:51 -0700555
556 // Extract the public key from the first line of output from
557 // "principal dump", which is formatted as:
558 // Public key : <the public key>
559 publicKey = func(dir string) string {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700560 output := bin.Start("--v23.credentials="+dir, "dump").Output()
Asim Shankar5fbe3262015-03-11 23:03:51 -0700561 line := strings.SplitN(output, "\n", 2)[0]
562 fields := strings.Split(line, " ")
563 return fields[len(fields)-1]
564 }
565 )
566 // Create two principals, "alice" and "bob"
567 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
568 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
569 // Have bob create a "bob/friend" blessing and have alice recognize that.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700570 redirect(t, bin.Start("--v23.credentials="+bobDir, "bless", "--require-caveats=false", aliceDir, "friend"), blessingFile)
Asim Shankarf32d24d2015-04-01 16:34:26 -0700571 bin.Start("--v23.credentials="+aliceDir, "addtoroots", blessingFile).WaitOrDie(os.Stdout, os.Stderr)
Asim Shankar5fbe3262015-03-11 23:03:51 -0700572
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700573 want := fmt.Sprintf(`Public key Pattern
574%v [alice]
575%v [bob]
576`, publicKey(aliceDir), publicKey(bobDir))
577
578 // Finally view alice's recognized roots, it should have lines corresponding to aliceLine and bobLine.
579 got := bin.Start("--v23.credentials="+aliceDir, "get", "recognizedroots").Output()
580 if got != want {
581 t.Fatalf("Got:\n%v\n\nWant:\n%v", got, want)
Asim Shankar5fbe3262015-03-11 23:03:51 -0700582 }
583}
Asim Shankar59b8b692015-03-30 01:23:36 -0700584
Asim Shankar80277d02015-03-31 12:57:06 -0700585func V23TestAddKeyToRoots(t *v23tests.T) {
586 var (
Asim Shankarde6fda52015-04-22 21:20:24 -0700587 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
588 outputDir = t.NewTempDir("")
589 aliceDir = filepath.Join(outputDir, "alice")
590 bobDir = filepath.Join(outputDir, "bob")
Asim Shankar80277d02015-03-31 12:57:06 -0700591 )
592 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
Asim Shankarde6fda52015-04-22 21:20:24 -0700593 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
594 // Get bob's public key and add it to roots for alice
595 bobKey := strings.TrimSpace(bin.Start("--v23.credentials="+bobDir, "get", "publickey").Output())
596 bobPrettyKey := strings.TrimSpace(bin.Start("--v23.credentials="+bobDir, "get", "publickey", "--pretty").Output())
597 bin.Start("--v23.credentials="+aliceDir, "addtoroots", bobKey, "bob").WaitOrDie(os.Stdout, os.Stderr)
598
599 // Verify that it has been added
Asim Shankarf32d24d2015-04-01 16:34:26 -0700600 output := bin.Start("--v23.credentials="+aliceDir, "dump").Output()
Asim Shankarde6fda52015-04-22 21:20:24 -0700601 want := fmt.Sprintf("%v [bob]", bobPrettyKey)
Asim Shankar80277d02015-03-31 12:57:06 -0700602 for _, line := range strings.Split(output, "\n") {
603 if line == want {
604 return
605 }
606 }
607 t.Errorf("Could not find line:\n%v\nin output:\n%v\n", want, output)
608}
609
Asim Shankar59b8b692015-03-30 01:23:36 -0700610func credEnv(dir string) string {
611 return fmt.Sprintf("%s=%s", envvar.Credentials, dir)
612}