blob: 81f93d50e48d338e53478f9ea3bd5115bc4b6267 [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
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005package rt_test
6
7import (
8 "fmt"
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -08009 "io/ioutil"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070010 "os"
11 "regexp"
12 "testing"
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070013 "time"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070014
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070015 "v.io/v23"
Matt Rosencrantz250558f2015-03-17 11:37:31 -070016 "v.io/v23/context"
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070017 "v.io/v23/security"
Cosmos Nicolaou0e4e3922015-06-10 16:30:09 -070018
Todd Wang8123b5e2015-05-14 18:44:43 -070019 "v.io/x/ref"
Cosmos Nicolaoue9c622d2015-07-10 11:09:42 -070020 "v.io/x/ref/internal/logger"
Todd Wangb3511492015-04-07 23:32:34 -070021 vsecurity "v.io/x/ref/lib/security"
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070022 "v.io/x/ref/test"
23 "v.io/x/ref/test/expect"
24 "v.io/x/ref/test/modules"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070025)
26
Suharsh Sivakumard19c95d2015-02-19 14:44:50 -080027//go:generate v23 test generate
Jiri Simsa5293dcb2014-05-10 09:56:38 -070028
29func TestInit(t *testing.T) {
Todd Wang8123b5e2015-05-14 18:44:43 -070030 ref.EnvClearCredentials()
Jiri Simsa6ac95222015-02-23 16:11:49 -080031 ctx, shutdown := v23.Init()
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -080032 defer shutdown()
Matt Rosencrantzf1c3b442015-01-12 17:53:08 -080033
Cosmos Nicolaoue9c622d2015-07-10 11:09:42 -070034 mgr := logger.Manager(ctx)
35 fmt.Println(mgr)
36 args := fmt.Sprintf("%s", mgr)
37 expected := regexp.MustCompile("name=vanadium logdirs=\\[/tmp\\] logtostderr=true|false alsologtostderr=false|true max_stack_buf_size=4292608 v=[0-9] stderrthreshold=2 vmodule= vfilepath= log_backtrace_at=:0")
38
Jiri Simsa5293dcb2014-05-10 09:56:38 -070039 if !expected.MatchString(args) {
Cosmos Nicolaou0e4e3922015-06-10 16:30:09 -070040 t.Errorf("unexpected default args: %s, want %s", args, expected)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070041 }
Jiri Simsa6ac95222015-02-23 16:11:49 -080042 p := v23.GetPrincipal(ctx)
Asim Shankar220a0152014-10-30 21:21:09 -070043 if p == nil {
44 t.Fatalf("A new principal should have been created")
45 }
46 if p.BlessingStore() == nil {
47 t.Fatalf("The principal must have a BlessingStore")
48 }
Asim Shankar2bf7b1e2015-02-27 00:45:12 -080049 if p.BlessingStore().Default().IsZero() {
50 t.Errorf("Principal().BlessingStore().Default() should not be the zero value")
Asim Shankar220a0152014-10-30 21:21:09 -070051 }
Asim Shankar2bf7b1e2015-02-27 00:45:12 -080052 if p.BlessingStore().ForPeer().IsZero() {
53 t.Errorf("Principal().BlessingStore().ForPeer() should not be the zero value")
Jiri Simsa5293dcb2014-05-10 09:56:38 -070054 }
55}
56
Todd Wang95873902015-05-22 14:21:30 -070057var child = modules.Register(func(env *modules.Env, args ...string) error {
Cosmos Nicolaoue9c622d2015-07-10 11:09:42 -070058 ctx, shutdown := test.V23Init()
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -080059 defer shutdown()
Matt Rosencrantz0610a232014-12-04 10:26:39 -080060
Cosmos Nicolaoue9c622d2015-07-10 11:09:42 -070061 mgr := logger.Manager(ctx)
62 ctx.Infof("%s\n", mgr)
63 fmt.Fprintf(env.Stdout, "%s\n", mgr)
Todd Wang95873902015-05-22 14:21:30 -070064 modules.WaitForEOF(env.Stdin)
65 fmt.Fprintf(env.Stdout, "done\n")
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070066 return nil
Todd Wang95873902015-05-22 14:21:30 -070067}, "child")
Jiri Simsa5293dcb2014-05-10 09:56:38 -070068
69func TestInitArgs(t *testing.T) {
Cosmos Nicolaou9e909842015-03-17 11:58:59 -070070 sh, err := modules.NewShell(nil, nil, testing.Verbose(), t)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -080071 if err != nil {
72 t.Fatalf("unexpected error: %s", err)
73 }
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070074 defer sh.Cleanup(os.Stderr, os.Stderr)
Todd Wang95873902015-05-22 14:21:30 -070075 h, err := sh.Start(nil, child, "--logtostderr=true", "--vmodule=*=3", "--", "foobar")
Jiri Simsa5293dcb2014-05-10 09:56:38 -070076 if err != nil {
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070077 t.Fatalf("unexpected error: %s", err)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070078 }
Cosmos Nicolaou0e4e3922015-06-10 16:30:09 -070079 h.Expect(fmt.Sprintf("name=vlog "+
Jiri Simsa5293dcb2014-05-10 09:56:38 -070080 "logdirs=[%s] "+
81 "logtostderr=true "+
82 "alsologtostderr=true "+
83 "max_stack_buf_size=4292608 "+
Cosmos Nicolaoud83b90b2014-11-30 15:01:31 -080084 "v=0 "+
Jiri Simsa5293dcb2014-05-10 09:56:38 -070085 "stderrthreshold=2 "+
Cosmos Nicolaoud83b90b2014-11-30 15:01:31 -080086 "vmodule=*=3 "+
Cosmos Nicolaou616c8e82015-06-11 15:16:42 -070087 "vfilepath= "+
Jiri Simsa5293dcb2014-05-10 09:56:38 -070088 "log_backtrace_at=:0",
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070089 os.TempDir()))
90 h.CloseStdin()
Cosmos Nicolaou9e909842015-03-17 11:58:59 -070091 h.Expect("done")
92 h.ExpectEOF()
Cosmos Nicolaou59496fe2014-10-14 11:21:05 -070093 h.Shutdown(os.Stderr, os.Stderr)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070094}
Ankur7c890592014-10-02 11:36:28 -070095
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -080096func validatePrincipal(p security.Principal) error {
97 if p == nil {
98 return fmt.Errorf("nil principal")
Matt Rosencrantz0610a232014-12-04 10:26:39 -080099 }
Ankurd8646812015-03-12 10:48:41 -0700100 call := security.NewCall(&security.CallParams{LocalPrincipal: p, RemoteBlessings: p.BlessingStore().Default()})
Matt Rosencrantz250558f2015-03-17 11:37:31 -0700101 ctx, cancel := context.RootContext()
102 defer cancel()
Todd Wang4264e4b2015-04-16 22:43:40 -0700103 blessings, rejected := security.RemoteBlessingNames(ctx, call)
Asim Shankar2bf7b1e2015-02-27 00:45:12 -0800104 if n := len(blessings); n != 1 {
105 return fmt.Errorf("rt.Principal().BlessingStore().Default() return blessings:%v (rejected:%v), want exactly one recognized blessing", blessings, rejected)
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -0800106 }
107 return nil
108}
109
110func defaultBlessing(p security.Principal) string {
Ankurd8646812015-03-12 10:48:41 -0700111 call := security.NewCall(&security.CallParams{LocalPrincipal: p, RemoteBlessings: p.BlessingStore().Default()})
Matt Rosencrantz250558f2015-03-17 11:37:31 -0700112 ctx, cancel := context.RootContext()
113 defer cancel()
Todd Wang4264e4b2015-04-16 22:43:40 -0700114 b, _ := security.RemoteBlessingNames(ctx, call)
Ryan Brown41093a92015-02-10 10:59:14 -0800115 return b[0]
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -0800116}
117
118func tmpDir(t *testing.T) string {
119 dir, err := ioutil.TempDir("", "rt_test_dir")
120 if err != nil {
121 t.Fatalf("unexpected error: %s", err)
122 }
123 return dir
124}
125
Todd Wang95873902015-05-22 14:21:30 -0700126var principal = modules.Register(func(env *modules.Env, args ...string) error {
Todd Wang60052d82015-05-22 15:00:10 -0700127 ctx, shutdown := test.V23Init()
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -0800128 defer shutdown()
Matt Rosencrantz0610a232014-12-04 10:26:39 -0800129
Jiri Simsa6ac95222015-02-23 16:11:49 -0800130 p := v23.GetPrincipal(ctx)
Matt Rosencrantzf1c3b442015-01-12 17:53:08 -0800131 if err := validatePrincipal(p); err != nil {
Ankur9f957942014-11-24 16:34:18 -0800132 return err
133 }
Todd Wang95873902015-05-22 14:21:30 -0700134 fmt.Fprintf(env.Stdout, "DEFAULT_BLESSING=%s\n", defaultBlessing(p))
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700135 return nil
Todd Wang95873902015-05-22 14:21:30 -0700136}, "principal")
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700137
138// Runner runs a principal as a subprocess and reports back with its
139// own security info and it's childs.
Todd Wang95873902015-05-22 14:21:30 -0700140var runner = modules.Register(func(env *modules.Env, args ...string) error {
Todd Wang60052d82015-05-22 15:00:10 -0700141 ctx, shutdown := test.V23Init()
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -0800142 defer shutdown()
143
Jiri Simsa6ac95222015-02-23 16:11:49 -0800144 p := v23.GetPrincipal(ctx)
Matt Rosencrantzf1c3b442015-01-12 17:53:08 -0800145 if err := validatePrincipal(p); err != nil {
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700146 return err
Ankur7c890592014-10-02 11:36:28 -0700147 }
Todd Wang95873902015-05-22 14:21:30 -0700148 fmt.Fprintf(env.Stdout, "RUNNER_DEFAULT_BLESSING=%v\n", defaultBlessing(p))
Cosmos Nicolaou9e909842015-03-17 11:58:59 -0700149 sh, err := modules.NewShell(ctx, p, false, nil)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -0800150 if err != nil {
151 return err
152 }
Todd Wang95873902015-05-22 14:21:30 -0700153 if _, err := sh.Start(nil, principal, args...); err != nil {
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700154 return err
155 }
Suharsh Sivakumard02ac222014-11-18 14:02:15 -0800156 // Cleanup copies the output of sh to these Writers.
Todd Wang95873902015-05-22 14:21:30 -0700157 sh.Cleanup(env.Stdout, env.Stderr)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700158 return nil
Todd Wang95873902015-05-22 14:21:30 -0700159}, "runner")
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700160
Suharsh Sivakumar4d36f812015-01-15 13:58:00 -0800161func createCredentialsInDir(t *testing.T, dir string, blessing string) {
162 principal, err := vsecurity.CreatePersistentPrincipal(dir, nil)
163 if err != nil {
164 t.Fatalf("unexpected error: %s", err)
165 }
166 if err := vsecurity.InitDefaultBlessings(principal, blessing); err != nil {
167 t.Fatalf("unexpected error: %s", err)
168 }
169}
170
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700171func TestPrincipalInheritance(t *testing.T) {
Cosmos Nicolaou9e909842015-03-17 11:58:59 -0700172 sh, err := modules.NewShell(nil, nil, testing.Verbose(), t)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -0800173 if err != nil {
174 t.Fatalf("unexpected error: %s", err)
175 }
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700176 defer func() {
177 sh.Cleanup(os.Stdout, os.Stderr)
178 }()
179
Ankur9f957942014-11-24 16:34:18 -0800180 // Test that the child inherits from the parent's credentials correctly.
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700181 // The running test process may or may not have a credentials directory set
182 // up so we have to use a 'runner' process to ensure the correct setup.
183 cdir := tmpDir(t)
184 defer os.RemoveAll(cdir)
185
Ankur9f957942014-11-24 16:34:18 -0800186 createCredentialsInDir(t, cdir, "test")
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700187
188 // directory supplied by the environment.
Todd Wang8123b5e2015-05-14 18:44:43 -0700189 credEnv := []string{ref.EnvCredentials + "=" + cdir}
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700190
Todd Wang95873902015-05-22 14:21:30 -0700191 h, err := sh.Start(credEnv, runner)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700192 if err != nil {
193 t.Fatalf("unexpected error: %s", err)
194 }
Ankur9f957942014-11-24 16:34:18 -0800195
Cosmos Nicolaou9e909842015-03-17 11:58:59 -0700196 runnerBlessing := h.ExpectVar("RUNNER_DEFAULT_BLESSING")
197 principalBlessing := h.ExpectVar("DEFAULT_BLESSING")
198 if err := h.Error(); err != nil {
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700199 t.Fatalf("failed to read input from children: %s", err)
200 }
201 h.Shutdown(os.Stdout, os.Stderr)
Ankur9f957942014-11-24 16:34:18 -0800202
203 wantRunnerBlessing := "test"
204 wantPrincipalBlessing := "test/child"
205 if runnerBlessing != wantRunnerBlessing || principalBlessing != wantPrincipalBlessing {
206 t.Fatalf("unexpected default blessing: got runner %s, principal %s, want runner %s, principal %s", runnerBlessing, principalBlessing, wantRunnerBlessing, wantPrincipalBlessing)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700207 }
208
209}
210
211func TestPrincipalInit(t *testing.T) {
Ankur9f957942014-11-24 16:34:18 -0800212 // Collect the process' public key and error status
213 collect := func(sh *modules.Shell, env []string, args ...string) string {
Todd Wang95873902015-05-22 14:21:30 -0700214 h, err := sh.Start(env, principal, args...)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700215 if err != nil {
216 t.Fatalf("unexpected error: %s", err)
217 }
218 s := expect.NewSession(t, h.Stdout(), time.Minute)
219 s.SetVerbosity(testing.Verbose())
Ankur9f957942014-11-24 16:34:18 -0800220 return s.ExpectVar("DEFAULT_BLESSING")
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700221 }
222
223 // A credentials directory may, or may, not have been already specified.
224 // Either way, we want to use our own, so we set it aside and use our own.
Todd Wang8123b5e2015-05-14 18:44:43 -0700225 origCredentialsDir := os.Getenv(ref.EnvCredentials)
226 defer os.Setenv(ref.EnvCredentials, origCredentialsDir)
227 if err := os.Setenv(ref.EnvCredentials, ""); err != nil {
Ankur7c890592014-10-02 11:36:28 -0700228 t.Fatal(err)
229 }
230
Ankura4b7c4a2015-02-02 11:41:24 -0800231 // We create two shells -- one initializing the principal for a child process
232 // via a credentials directory and the other via an agent.
Cosmos Nicolaou9e909842015-03-17 11:58:59 -0700233 sh, err := modules.NewShell(nil, nil, testing.Verbose(), t)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -0800234 if err != nil {
235 t.Fatalf("unexpected error: %s", err)
236 }
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700237 defer sh.Cleanup(os.Stderr, os.Stderr)
238
Todd Wang60052d82015-05-22 15:00:10 -0700239 ctx, shutdown := test.V23Init()
Ankura4b7c4a2015-02-02 11:41:24 -0800240 defer shutdown()
241
Cosmos Nicolaou9e909842015-03-17 11:58:59 -0700242 agentSh, err := modules.NewShell(ctx, v23.GetPrincipal(ctx), testing.Verbose(), t)
Ankura4b7c4a2015-02-02 11:41:24 -0800243 if err != nil {
244 t.Fatalf("unexpected error: %s", err)
245 }
246 defer agentSh.Cleanup(os.Stderr, os.Stderr)
247
Todd Wang8123b5e2015-05-14 18:44:43 -0700248 // Test that with ref.EnvCredentials unset the runtime's Principal
Ankura4b7c4a2015-02-02 11:41:24 -0800249 // is correctly initialized for both shells.
250 if len(collect(sh, nil)) == 0 {
251 t.Fatalf("Without agent: child returned an empty default blessings set")
252 }
Cosmos Nicolaoua18a1eb2015-03-12 13:15:01 -0700253 if got, want := collect(agentSh, nil), test.TestBlessing+security.ChainSeparator+"child"; got != want {
Ankura4b7c4a2015-02-02 11:41:24 -0800254 t.Fatalf("With agent: got %q, want %q", got, want)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700255 }
256
Todd Wang8123b5e2015-05-14 18:44:43 -0700257 // Test that credentials specified via the ref.EnvCredentials
Asim Shankar59b8b692015-03-30 01:23:36 -0700258 // environment variable take precedence over an agent.
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700259 cdir1 := tmpDir(t)
260 defer os.RemoveAll(cdir1)
Ankur9f957942014-11-24 16:34:18 -0800261 createCredentialsInDir(t, cdir1, "test_env")
Todd Wang8123b5e2015-05-14 18:44:43 -0700262 credEnv := []string{ref.EnvCredentials + "=" + cdir1}
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700263
Ankura4b7c4a2015-02-02 11:41:24 -0800264 if got, want := collect(sh, credEnv), "test_env"; got != want {
265 t.Errorf("Without agent: got default blessings: %q, want %q", got, want)
266 }
267 if got, want := collect(agentSh, credEnv), "test_env"; got != want {
268 t.Errorf("With agent: got default blessings: %q, want %q", got, want)
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700269 }
270
Ankura4b7c4a2015-02-02 11:41:24 -0800271 // Test that credentials specified via the command line take precedence over the
Todd Wang8123b5e2015-05-14 18:44:43 -0700272 // ref.EnvCredentials environment variable and also the agent.
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700273 cdir2 := tmpDir(t)
274 defer os.RemoveAll(cdir2)
Ankur9f957942014-11-24 16:34:18 -0800275 createCredentialsInDir(t, cdir2, "test_cmd")
Cosmos Nicolaoue5b41502014-10-29 22:55:09 -0700276
Asim Shankarf32d24d2015-04-01 16:34:26 -0700277 if got, want := collect(sh, credEnv, "--v23.credentials="+cdir2), "test_cmd"; got != want {
Ankura4b7c4a2015-02-02 11:41:24 -0800278 t.Errorf("Without agent: got %q, want %q", got, want)
279 }
Asim Shankarf32d24d2015-04-01 16:34:26 -0700280 if got, want := collect(agentSh, credEnv, "--v23.credentials="+cdir2), "test_cmd"; got != want {
Ankura4b7c4a2015-02-02 11:41:24 -0800281 t.Errorf("With agent: got %q, want %q", got, want)
Ankur7c890592014-10-02 11:36:28 -0700282 }
283}