blob: bd8fde3403e8bf4726cb7c03f8d76d03902d66ee [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
Todd Wang8123b5e2015-05-14 18:44:43 -070016 "v.io/x/ref"
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 (
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700131 outputDir = t.NewTempDir("")
132 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
133 aliceDir = filepath.Join(outputDir, "alice")
134 aliceExpiredDir = filepath.Join(outputDir, "alice-expired")
James Ring5721f3d2015-02-12 19:53:20 -0800135 )
136
137 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
138
Asim Shankar59b8b692015-03-30 01:23:36 -0700139 blessEnv := credEnv(aliceDir)
140 got := removePublicKeys(bin.WithEnv(blessEnv).Start("dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800141 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700142Default Blessings : alice
James Ring5721f3d2015-02-12 19:53:20 -0800143---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700144Default Blessings alice
145Peer pattern Blessings
146... alice
James Ring5721f3d2015-02-12 19:53:20 -0800147---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700148Public key Pattern
149XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
150`
151 if want != got {
152 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
153 }
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700154
155 got = bin.WithEnv(blessEnv).Start("dump", "-s").Output()
156 want = "alice\n"
157 if want != got {
158 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
159 }
160
161 bin.Start("--v23.credentials="+aliceDir, "fork", "--for", "-1h", aliceExpiredDir, "expired").WaitOrDie(os.Stdout, os.Stderr)
162 blessEnv = credEnv(aliceExpiredDir)
163 got = removePublicKeys(bin.WithEnv(blessEnv).Start("dump").Output())
164 want = `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
165Default Blessings : alice/expired [EXPIRED]
166---------------- BlessingStore ----------------
167Default Blessings alice/expired
168Peer pattern Blessings
169... alice/expired
170---------------- BlessingRoots ----------------
171Public key Pattern
172XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
173`
174 if want != got {
175 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
176 }
177
178 got = bin.WithEnv(blessEnv).Start("dump", "-s").Output()
179 want = "alice/expired [EXPIRED]\n"
180 if want != got {
181 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
182 }
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700183}
184
185func V23TestGetRecognizedRoots(t *v23tests.T) {
186 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700187 outputDir = t.NewTempDir("")
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700188 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
189 aliceDir = filepath.Join(outputDir, "alice")
190 )
191
192 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
193
194 blessEnv := credEnv(aliceDir)
195 got := removePublicKeys(bin.WithEnv(blessEnv).Start("get", "recognizedroots").Output())
196 want := `Public key Pattern
197XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
198`
199 if want != got {
200 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
201 }
202}
203
204func V23TestGetPeermap(t *v23tests.T) {
205 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700206 outputDir = t.NewTempDir("")
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700207 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
208 aliceDir = filepath.Join(outputDir, "alice")
209 )
210
211 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
212
213 blessEnv := credEnv(aliceDir)
Suharsh Sivakumar2b22fc12015-04-15 19:38:04 -0700214 got := bin.WithEnv(blessEnv).Start("get", "peermap").Output()
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700215 want := `Default Blessings alice
216Peer pattern Blessings
217... alice
James Ring5721f3d2015-02-12 19:53:20 -0800218`
219 if want != got {
220 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
221 }
222}
223
Asim Shankara0bba462015-02-20 22:50:51 -0800224// Given an invocation of "principal recvblessings", this function returns the
225// arguments to provide to "principal bless" provided by the "recvblessings"
226// invocation.
227//
228// For example,
229// principal recvblessings
230// would typically print something like:
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700231// principal bless --remote-key=<some_public_key> --remote-token=<some_token> extensionfoo
Asim Shankara0bba462015-02-20 22:50:51 -0800232// as an example of command line to use to send the blessings over.
233//
234// In that case, this method would return:
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700235// { "--remote-key=<some_public_key>", "--remote-token=<some_token>", "extensionfoo"}
Asim Shankara0bba462015-02-20 22:50:51 -0800236func blessArgsFromRecvBlessings(inv *v23tests.Invocation) []string {
237 cmd := inv.ExpectSetEventuallyRE("(^principal bless .*$)")[0][0]
238 return strings.Split(cmd, " ")[2:]
239}
240
James Ring5721f3d2015-02-12 19:53:20 -0800241func V23TestRecvBlessings(t *v23tests.T) {
242 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700243 outputDir = t.NewTempDir("")
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700244 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
245 aliceDir = filepath.Join(outputDir, "alice")
246 bobDir = filepath.Join(outputDir, "bob")
247 carolDir = filepath.Join(outputDir, "carol")
248 bobBlessFile = filepath.Join(outputDir, "bobBlessInfo")
James Ring5721f3d2015-02-12 19:53:20 -0800249 )
250
251 // Generate principals for alice and carol.
252 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700253 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800254 bin.Start("create", carolDir, "carol").WaitOrDie(os.Stdout, os.Stderr)
255
256 // Run recvblessings on carol, and have alice send blessings over
257 // (blessings received must be set as default and shareable with all peers).
258 var args []string
259 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700260 inv := bin.Start("--v23.credentials="+carolDir, "--v23.tcp.address=127.0.0.1:0", "recvblessings")
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700261 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Asim Shankara0bba462015-02-20 22:50:51 -0800262 // Replace the random extension suggested by recvblessings with "friend/carol"
263 args[len(args)-1] = "friend/carol"
James Ring5721f3d2015-02-12 19:53:20 -0800264 }
Asim Shankar59b8b692015-03-30 01:23:36 -0700265 bin.WithEnv(credEnv(aliceDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800266
267 // Run recvblessings on carol, and have alice send blessings over
268 // (blessings received must be set as shareable with peers matching 'alice/...'.)
269 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700270 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 -0800271 // recvblessings suggests a random extension, find the extension and replace it with friend/carol/foralice.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700272 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Asim Shankara0bba462015-02-20 22:50:51 -0800273 args[len(args)-1] = "friend/carol/foralice"
James Ring5721f3d2015-02-12 19:53:20 -0800274 }
Asim Shankar59b8b692015-03-30 01:23:36 -0700275 bin.WithEnv(credEnv(aliceDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800276
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700277 // 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 -0700278 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700279 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 -0700280 // recvblessings suggests a random extension, use friend/carol/forbob instead.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700281 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(inv)...)
Suharsh Sivakumarab21eb02015-04-01 12:58:20 -0700282 args[len(args)-1] = "friend/carol/forbob"
283 }
284 bin.WithEnv(credEnv(bobDir)).Start(args...).WaitOrDie(os.Stdout, os.Stderr)
285
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700286 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 -0800287
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700288 args = append([]string{"bless", "--require-caveats=false"}, blessArgsFromRecvBlessings(listenerInv)...)
James Ring5721f3d2015-02-12 19:53:20 -0800289
290 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700291 // Mucking around with remote-key should fail.
292 cpy := strings.Split(regexp.MustCompile("remote-key=").ReplaceAllString(strings.Join(args, " "), "remote-key=BAD"), " ")
James Ring5721f3d2015-02-12 19:53:20 -0800293 var buf bytes.Buffer
Asim Shankar59b8b692015-03-30 01:23:36 -0700294 if bin.WithEnv(credEnv(aliceDir)).Start(cpy...).Wait(os.Stdout, &buf) == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800295 t.Fatalf("%v should have failed, but did not", cpy)
James Ring5721f3d2015-02-12 19:53:20 -0800296 }
297
298 if want, got := "key mismatch", buf.String(); !strings.Contains(got, want) {
299 t.Fatalf("expected %q to be contained within\n%s\n, but was not", want, got)
300 }
301 }
302
303 {
304 var buf bytes.Buffer
305 // Mucking around with the token should fail.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700306 cpy := strings.Split(regexp.MustCompile("remote-token=").ReplaceAllString(strings.Join(args, " "), "remote-token=BAD"), " ")
Asim Shankar59b8b692015-03-30 01:23:36 -0700307 if bin.WithEnv(credEnv(aliceDir)).Start(cpy...).Wait(os.Stdout, &buf) == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800308 t.Fatalf("%v should have failed, but did not", cpy)
James Ring5721f3d2015-02-12 19:53:20 -0800309 }
310
311 if want, got := "blessings received from unexpected sender", buf.String(); !strings.Contains(got, want) {
312 t.Fatalf("expected %q to be contained within\n%s\n, but was not", want, got)
313 }
314 }
315
Asim Shankarf32d24d2015-04-01 16:34:26 -0700316 // Dump carol out, the only blessing that survives should be from the
317 // first "bless" command. (alice/friend/carol).
318 got := removePublicKeys(bin.Start("--v23.credentials="+carolDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800319 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700320Default Blessings : alice/friend/carol
James Ring5721f3d2015-02-12 19:53:20 -0800321---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700322Default Blessings alice/friend/carol
323Peer pattern Blessings
324... alice/friend/carol
325alice alice/friend/carol/foralice
326bob bob/friend/carol/forbob
James Ring5721f3d2015-02-12 19:53:20 -0800327---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700328Public key Pattern
329XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
330XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [bob]
331XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [carol]
James Ring5721f3d2015-02-12 19:53:20 -0800332`
333 if want != got {
334 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
335 }
336}
337
338func V23TestFork(t *v23tests.T) {
339 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700340 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800341 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -0800342 aliceDir = filepath.Join(outputDir, "alice")
343 alicePhoneDir = filepath.Join(outputDir, "alice-phone")
344 alicePhoneCalendarDir = filepath.Join(outputDir, "alice-phone-calendar")
Asim Shankara0bba462015-02-20 22:50:51 -0800345 tmpfile = filepath.Join(outputDir, "tmpfile")
James Ring5721f3d2015-02-12 19:53:20 -0800346 )
347
348 // Generate principals for alice.
349 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
350
351 // Run fork to setup up credentials for alice/phone that are
352 // blessed by alice under the extension "phone".
Asim Shankarf32d24d2015-04-01 16:34:26 -0700353 bin.Start("--v23.credentials="+aliceDir, "fork", "--for", "1h", alicePhoneDir, "phone").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800354
355 // Dump alice-phone out, the only blessings it has must be from alice (alice/phone).
356 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700357 got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800358 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700359Default Blessings : alice/phone
James Ring5721f3d2015-02-12 19:53:20 -0800360---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700361Default Blessings alice/phone
362Peer pattern Blessings
363... alice/phone
James Ring5721f3d2015-02-12 19:53:20 -0800364---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700365Public key Pattern
366XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
James Ring5721f3d2015-02-12 19:53:20 -0800367`
368 if want != got {
369 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
370 }
371 }
Asim Shankara0bba462015-02-20 22:50:51 -0800372 // And it should have an expiry caveat
373 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700374 redirect(t, bin.Start("--v23.credentials", alicePhoneDir, "get", "default"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800375 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
376 want := `Blessings : alice/phone
377PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
378Certificate chains : 1
379Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
380 Certificate #0: alice with 0 caveats
381 Certificate #1: phone with 1 caveat
382 (0) ExpiryCaveat
383`
384 if want != got {
385 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
386 }
387 }
James Ring5721f3d2015-02-12 19:53:20 -0800388
389 // Run fork to setup up credentials for alice/phone/calendar that are
390 // blessed by alice/phone under the extension "calendar".
Asim Shankarf32d24d2015-04-01 16:34:26 -0700391 bin.Start("--v23.credentials="+alicePhoneDir, "fork", "--for", "1h", alicePhoneCalendarDir, "calendar").WaitOrDie(os.Stdout, os.Stderr)
James Ring5721f3d2015-02-12 19:53:20 -0800392 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700393 got := removePublicKeys(bin.Start("--v23.credentials="+alicePhoneCalendarDir, "dump").Output())
James Ring5721f3d2015-02-12 19:53:20 -0800394 want := `Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Bogdan Caprita4ab95412015-05-13 13:37:46 -0700395Default Blessings : alice/phone/calendar
James Ring5721f3d2015-02-12 19:53:20 -0800396---------------- BlessingStore ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700397Default Blessings alice/phone/calendar
398Peer pattern Blessings
399... alice/phone/calendar
James Ring5721f3d2015-02-12 19:53:20 -0800400---------------- BlessingRoots ----------------
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700401Public key Pattern
402XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX [alice]
James Ring5721f3d2015-02-12 19:53:20 -0800403`
404 if want != got {
405 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
406 }
407 }
Asim Shankara0bba462015-02-20 22:50:51 -0800408 {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700409 redirect(t, bin.Start("--v23.credentials", alicePhoneCalendarDir, "get", "default"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800410 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
411 want := `Blessings : alice/phone/calendar
412PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
413Certificate chains : 1
414Chain #0 (3 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
415 Certificate #0: alice with 0 caveats
416 Certificate #1: phone with 1 caveat
417 (0) ExpiryCaveat
418 Certificate #2: calendar with 1 caveat
419 (0) ExpiryCaveat
420`
421 if want != got {
422 t.Fatalf("unexpected output, got\n%s, wanted\n%s", got, want)
423 }
424 }
James Ring5721f3d2015-02-12 19:53:20 -0800425}
426
427func V23TestCreate(t *v23tests.T) {
428 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700429 outputDir = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800430 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
James Ring5721f3d2015-02-12 19:53:20 -0800431 aliceDir = filepath.Join(outputDir, "alice")
432 )
433
434 // Creating a principal should succeed the first time.
435 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
436
437 // The second time should fail (the create command won't override an existing principal).
438 if bin.Start("create", aliceDir, "alice").Wait(os.Stdout, os.Stderr) == nil {
439 t.Fatalf("principal creation should have failed, but did not")
440 }
441
442 // If we specify -overwrite, it will.
443 bin.Start("create", "--overwrite", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
444}
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800445
446func V23TestCaveats(t *v23tests.T) {
447 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700448 outputDir = t.NewTempDir("")
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800449 aliceDir = filepath.Join(outputDir, "alice")
450 aliceBlessingFile = filepath.Join(outputDir, "aliceself")
451 )
452
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800453 bin := t.BuildGoPkg("v.io/x/ref/cmd/principal")
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800454 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
455
Asim Shankar59b8b692015-03-30 01:23:36 -0700456 bin = bin.WithEnv(credEnv(aliceDir))
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800457 args := []string{
458 "blessself",
Suharsh Sivakumar60b78e92015-04-23 21:36:49 -0700459 "--caveat=\"v.io/v23/security\".MethodCaveat={\"method\"}",
Suharsh Sivakumar1d61f642015-02-17 20:56:14 -0800460 "--caveat={{0x54,0xa6,0x76,0x39,0x81,0x37,0x18,0x7e,0xcd,0xb2,0x6d,0x2d,0x69,0xba,0x0,0x3},typeobject([]string)}={\"method\"}",
461 "alicereborn",
462 }
463 redirect(t, bin.Start(args...), aliceBlessingFile)
464 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", aliceBlessingFile).Output()))
465 want := `Blessings : alicereborn
466PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
467Certificate chains : 1
468Chain #0 (1 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
469 Certificate #0: alicereborn with 2 caveats
470 (0) MethodCaveat
471 (1) MethodCaveat
472`
473 if want != got {
474 t.Fatalf("unexpected output, wanted \n%s, got\n%s", want, got)
475 }
476}
Asim Shankar918190d2015-02-18 17:12:43 -0800477
478func V23TestForkWithoutVDLPATH(t *v23tests.T) {
479 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700480 parent = t.NewTempDir("")
Jiri Simsa32f76fb2015-04-07 15:39:23 -0700481 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal").WithEnv("V23_ROOT=''", "VDLPATH=''")
Asim Shankar918190d2015-02-18 17:12:43 -0800482 )
483 if err := bin.Start("create", parent, "parent").Wait(os.Stdout, os.Stderr); err != nil {
484 t.Fatalf("create %q failed: %v", parent, err)
485 }
Robert Kroeger02714b72015-04-14 18:02:38 -0700486 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 -0800487 t.Errorf("fork failed: %v", err)
488 }
489}
Asim Shankara0bba462015-02-20 22:50:51 -0800490
491func V23TestForkWithoutCaveats(t *v23tests.T) {
492 var (
Robert Kroeger02714b72015-04-14 18:02:38 -0700493 parent = t.NewTempDir("")
494 child = t.NewTempDir("")
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800495 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Asim Shankara0bba462015-02-20 22:50:51 -0800496 buf bytes.Buffer
497 )
498 if err := bin.Start("create", parent, "parent").Wait(os.Stdout, os.Stderr); err != nil {
499 t.Fatalf("create %q failed: %v", parent, err)
500 }
Asim Shankarf32d24d2015-04-01 16:34:26 -0700501 if err := bin.Start("--v23.credentials", parent, "fork", child, "child").Wait(os.Stdout, &buf); err == nil {
Asim Shankara0bba462015-02-20 22:50:51 -0800502 t.Errorf("fork should have failed without any caveats, but did not")
503 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
504 t.Errorf("fork returned error: %q, expected error to contain %q", got, want)
505 }
Asim Shankarf32d24d2015-04-01 16:34:26 -0700506 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 -0800507 t.Errorf("fork should have failed without any caveats, but did not")
508 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
509 t.Errorf("fork returned error: %q, expected error to contain %q", got, want)
510 }
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700511 if err := bin.Start("--v23.credentials", parent, "fork", "--require-caveats=false", child, "child").Wait(os.Stdout, os.Stderr); err != nil {
512 t.Errorf("fork --require-caveats=false failed with: %v", err)
Asim Shankara0bba462015-02-20 22:50:51 -0800513 }
514}
515
516func V23TestBless(t *v23tests.T) {
517 var (
Matt Rosencrantzbca49812015-03-01 21:32:54 -0800518 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Robert Kroeger02714b72015-04-14 18:02:38 -0700519 dir = t.NewTempDir("")
Asim Shankara0bba462015-02-20 22:50:51 -0800520 aliceDir = filepath.Join(dir, "alice")
521 bobDir = filepath.Join(dir, "bob")
522 tmpfile = filepath.Join(dir, "tmpfile")
523 )
524 // Create two principals: alice and bob
525 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
526 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
527
528 // All blessings will be done by "alice"
Asim Shankar59b8b692015-03-30 01:23:36 -0700529 bin = bin.WithEnv(credEnv(aliceDir))
Asim Shankara0bba462015-02-20 22:50:51 -0800530
531 {
532 // "alice" should fail to bless "bob" without any caveats
533 var buf bytes.Buffer
534 if err := bin.Start("bless", bobDir, "friend").Wait(os.Stdout, &buf); err == nil {
535 t.Errorf("bless should have failed when no caveats are specified")
536 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
537 t.Errorf("got error %q, expected to match %q", got, want)
538 }
539 }
540 {
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700541 // But succeed if --require-caveats=false is specified
542 redirect(t, bin.Start("bless", "--require-caveats=false", bobDir, "friend"), tmpfile)
Asim Shankara0bba462015-02-20 22:50:51 -0800543 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
544 want := `Blessings : alice/friend
545PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
546Certificate chains : 1
547Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
548 Certificate #0: alice with 0 caveats
549 Certificate #1: friend with 1 caveat
550 (0) Unconstrained
551`
552 if got != want {
553 t.Errorf("Got\n%vWant\n%v", got, want)
554 }
555 }
556 {
557 // And succeed if --for is specified
558 redirect(t, bin.Start("bless", "--for=1m", bobDir, "friend"), tmpfile)
559 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
560 want := `Blessings : alice/friend
561PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
562Certificate chains : 1
563Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
564 Certificate #0: alice with 0 caveats
565 Certificate #1: friend with 1 caveat
566 (0) ExpiryCaveat
567`
568 if got != want {
569 t.Errorf("Got\n%vWant\n%v", got, want)
570 }
571 }
572 {
Suharsh Sivakumar7e80c862015-05-11 15:33:55 -0700573 // If the Blessings are expired, dumpBlessings should print so.
574 redirect(t, bin.Start("bless", "--for=-1s", bobDir, "friend"), tmpfile)
575 got := removeCaveats(removePublicKeys(bin.Start("dumpblessings", tmpfile).Output()))
576 want := `Blessings : alice/friend [EXPIRED]
577PublicKey : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
578Certificate chains : 1
579Chain #0 (2 certificates). Root certificate public key: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
580 Certificate #0: alice with 0 caveats
581 Certificate #1: friend with 1 caveat
582 (0) ExpiryCaveat
583`
584 if got != want {
585 t.Errorf("Got\n%vWant\n%v", got, want)
586 }
587 }
588 {
Asim Shankara0bba462015-02-20 22:50:51 -0800589 // But not if --for=0
590 var buf bytes.Buffer
591 if err := bin.Start("bless", "--for=0", bobDir, "friend").Wait(os.Stdout, &buf); err == nil {
592 t.Errorf("bless should have failed when no caveats are specified")
593 } else if got, want := buf.String(), "ERROR: no caveats provided"; !strings.Contains(got, want) {
594 t.Errorf("got error %q, expected to match %q", got, want)
595 }
596 }
597}
Asim Shankar5fbe3262015-03-11 23:03:51 -0700598
Asim Shankar80277d02015-03-31 12:57:06 -0700599func V23TestAddBlessingsToRoots(t *v23tests.T) {
Asim Shankar5fbe3262015-03-11 23:03:51 -0700600 var (
601 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
Robert Kroeger02714b72015-04-14 18:02:38 -0700602 aliceDir = t.NewTempDir("")
603 bobDir = t.NewTempDir("")
604 blessingFile = filepath.Join(t.NewTempDir(""), "bobfile")
Asim Shankar5fbe3262015-03-11 23:03:51 -0700605
606 // Extract the public key from the first line of output from
607 // "principal dump", which is formatted as:
608 // Public key : <the public key>
609 publicKey = func(dir string) string {
Asim Shankarf32d24d2015-04-01 16:34:26 -0700610 output := bin.Start("--v23.credentials="+dir, "dump").Output()
Asim Shankar5fbe3262015-03-11 23:03:51 -0700611 line := strings.SplitN(output, "\n", 2)[0]
612 fields := strings.Split(line, " ")
613 return fields[len(fields)-1]
614 }
615 )
616 // Create two principals, "alice" and "bob"
617 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
618 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
619 // Have bob create a "bob/friend" blessing and have alice recognize that.
Suharsh Sivakumared5be1d2015-04-01 17:45:35 -0700620 redirect(t, bin.Start("--v23.credentials="+bobDir, "bless", "--require-caveats=false", aliceDir, "friend"), blessingFile)
Asim Shankar562b2302015-04-27 13:52:43 -0700621 bin.Start("--v23.credentials="+aliceDir, "recognize", blessingFile).WaitOrDie(os.Stdout, os.Stderr)
Asim Shankar5fbe3262015-03-11 23:03:51 -0700622
Suharsh Sivakumar4bbe8ed2015-04-09 14:21:44 -0700623 want := fmt.Sprintf(`Public key Pattern
624%v [alice]
625%v [bob]
626`, publicKey(aliceDir), publicKey(bobDir))
627
628 // Finally view alice's recognized roots, it should have lines corresponding to aliceLine and bobLine.
629 got := bin.Start("--v23.credentials="+aliceDir, "get", "recognizedroots").Output()
630 if got != want {
631 t.Fatalf("Got:\n%v\n\nWant:\n%v", got, want)
Asim Shankar5fbe3262015-03-11 23:03:51 -0700632 }
633}
Asim Shankar59b8b692015-03-30 01:23:36 -0700634
Asim Shankar80277d02015-03-31 12:57:06 -0700635func V23TestAddKeyToRoots(t *v23tests.T) {
636 var (
Asim Shankarde6fda52015-04-22 21:20:24 -0700637 bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
638 outputDir = t.NewTempDir("")
639 aliceDir = filepath.Join(outputDir, "alice")
640 bobDir = filepath.Join(outputDir, "bob")
Asim Shankar80277d02015-03-31 12:57:06 -0700641 )
642 bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
Asim Shankarde6fda52015-04-22 21:20:24 -0700643 bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
644 // Get bob's public key and add it to roots for alice
645 bobKey := strings.TrimSpace(bin.Start("--v23.credentials="+bobDir, "get", "publickey").Output())
646 bobPrettyKey := strings.TrimSpace(bin.Start("--v23.credentials="+bobDir, "get", "publickey", "--pretty").Output())
Asim Shankar562b2302015-04-27 13:52:43 -0700647 bin.Start("--v23.credentials="+aliceDir, "recognize", "bob", bobKey).WaitOrDie(os.Stdout, os.Stderr)
Asim Shankarde6fda52015-04-22 21:20:24 -0700648
649 // Verify that it has been added
Asim Shankarf32d24d2015-04-01 16:34:26 -0700650 output := bin.Start("--v23.credentials="+aliceDir, "dump").Output()
Asim Shankarde6fda52015-04-22 21:20:24 -0700651 want := fmt.Sprintf("%v [bob]", bobPrettyKey)
Asim Shankar80277d02015-03-31 12:57:06 -0700652 for _, line := range strings.Split(output, "\n") {
653 if line == want {
654 return
655 }
656 }
657 t.Errorf("Could not find line:\n%v\nin output:\n%v\n", want, output)
658}
659
Asim Shankar59b8b692015-03-30 01:23:36 -0700660func credEnv(dir string) string {
Todd Wang8123b5e2015-05-14 18:44:43 -0700661 return fmt.Sprintf("%s=%s", ref.EnvCredentials, dir)
Asim Shankar59b8b692015-03-30 01:23:36 -0700662}