blob: 7bba065052808a4ee63dd87542c9e21c3b46b072 [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
Robert Kroeger6e4ed122015-03-06 13:03:54 -08005package impl_test
6
7import (
Robert Kroeger066ac712015-03-20 16:28:48 -07008 "io/ioutil"
Robert Kroeger6e4ed122015-03-06 13:03:54 -08009 "syscall"
10 "testing"
11
12 "v.io/v23/context"
Robert Kroeger16ee22b2015-03-12 14:57:09 -070013 "v.io/v23/naming"
Robert Kroeger6e4ed122015-03-06 13:03:54 -080014 "v.io/v23/security"
Todd Wang387d8a42015-03-30 17:09:05 -070015 "v.io/v23/security/access"
Todd Wang30192a22015-03-31 13:24:41 -070016 "v.io/v23/services/permissions"
Robert Kroeger8f914be2015-03-14 16:32:37 -070017 "v.io/v23/verror"
Robert Kroeger6e4ed122015-03-06 13:03:54 -080018
Robert Kroeger22fcb032015-04-30 07:40:11 -070019 "v.io/x/ref/services/device/internal/impl/utiltest"
Todd Wang5fc36442015-04-07 15:15:27 -070020 "v.io/x/ref/services/internal/servicetest"
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070021 "v.io/x/ref/test/testutil"
Robert Kroeger6e4ed122015-03-06 13:03:54 -080022)
23
Benjamin Prosnitzb60efb92015-03-11 17:47:43 -070024func updateAccessList(t *testing.T, ctx *context.T, blessing, right string, name ...string) {
Todd Wang30192a22015-03-31 13:24:41 -070025 accessStub := permissions.ObjectClient(naming.Join(name...))
Adam Sadovskya4d4a692015-04-20 11:36:49 -070026 perms, version, err := accessStub.GetPermissions(ctx)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080027 if err != nil {
Robert Kroeger066ac712015-03-20 16:28:48 -070028 t.Fatalf(testutil.FormatLogLine(2, "GetPermissions(%v) failed %v", name, err))
Robert Kroeger6e4ed122015-03-06 13:03:54 -080029 }
Adam Sadovskya4d4a692015-04-20 11:36:49 -070030 perms.Add(security.BlessingPattern(blessing), right)
31 if err = accessStub.SetPermissions(ctx, perms, version); err != nil {
Robert Kroeger8f914be2015-03-14 16:32:37 -070032 t.Fatalf(testutil.FormatLogLine(2, "SetPermissions(%v, %v, %v) failed: %v", name, blessing, right, err))
Robert Kroeger6e4ed122015-03-06 13:03:54 -080033 }
34}
35
Robert Kroeger8f914be2015-03-14 16:32:37 -070036func testAccessFail(t *testing.T, expected verror.ID, ctx *context.T, who string, name ...string) {
Robert Kroeger22fcb032015-04-30 07:40:11 -070037 if _, err := utiltest.StatsStub(name...).Value(ctx); verror.ErrorID(err) != expected {
Robert Kroeger8f914be2015-03-14 16:32:37 -070038 t.Fatalf(testutil.FormatLogLine(2, "%s got error %v but expected %v", who, err, expected))
39 }
40}
41
42func TestDebugPermissionsPropagation(t *testing.T) {
Robert Kroeger22fcb032015-04-30 07:40:11 -070043 cleanup, ctx, sh, envelope, root, helperPath, idp := utiltest.StartupHelper(t)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080044 defer cleanup()
45
46 // Set up the device manager.
Todd Wang5fc36442015-04-07 15:15:27 -070047 dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
48 servicetest.ReadPID(t, dmh)
Robert Kroeger22fcb032015-04-30 07:40:11 -070049 utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", noPairingToken)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080050
51 // Create the local server that the app uses to let us know it's ready.
Robert Kroeger658e0912015-04-30 10:30:57 -070052 pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080053 defer cleanup()
Robert Kroeger22fcb032015-04-30 07:40:11 -070054 utiltest.Resolve(t, ctx, "pingserver", 1)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080055
56 // Make some users.
57 selfCtx := ctx
Robert Kroeger22fcb032015-04-30 07:40:11 -070058 bobCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "bob")
59 hjCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "hackerjoe")
60 aliceCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "alice")
Robert Kroeger6e4ed122015-03-06 13:03:54 -080061
Benjamin Prosnitzb60efb92015-03-11 17:47:43 -070062 // TODO(rjkroege): Set AccessLists here that conflict with the one provided by the device
Robert Kroeger6e4ed122015-03-06 13:03:54 -080063 // manager and show that the one set here is overridden.
64 // Create the envelope for the first version of the app.
Robert Kroeger22fcb032015-04-30 07:40:11 -070065 *envelope = utiltest.EnvelopeFromShell(sh, nil, appCmd, "google naps", "appV1")
Robert Kroeger6e4ed122015-03-06 13:03:54 -080066
67 // Install the app.
Robert Kroeger22fcb032015-04-30 07:40:11 -070068 appID := utiltest.InstallApp(t, ctx)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080069
70 // Give bob rights to start an app.
Robert Kroeger066ac712015-03-20 16:28:48 -070071 updateAccessList(t, selfCtx, "root/bob/$", string(access.Read), "dm/apps", appID)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080072
73 // Bob starts an instance of the app.
Robert Kroeger22fcb032015-04-30 07:40:11 -070074 bobApp := utiltest.LaunchApp(t, bobCtx, appID)
Robert Kroeger658e0912015-04-30 10:30:57 -070075 pingCh.VerifyPingArgs(t, userName(t), "default", "")
Robert Kroeger6e4ed122015-03-06 13:03:54 -080076
77 // Bob permits Alice to read from his app.
Robert Kroeger066ac712015-03-20 16:28:48 -070078 updateAccessList(t, bobCtx, "root/alice/$", string(access.Read), "dm/apps", appID, bobApp)
Robert Kroeger6e4ed122015-03-06 13:03:54 -080079
Robert Kroeger8f914be2015-03-14 16:32:37 -070080 // Create some globbing test vectors.
Robert Kroeger22fcb032015-04-30 07:40:11 -070081 globtests := []utiltest.GlobTestVector{
Robert Kroeger8f914be2015-03-14 16:32:37 -070082 {naming.Join("dm", "apps", appID, bobApp), "*",
83 []string{"logs", "pprof", "stats"},
84 },
85 {naming.Join("dm", "apps", appID, bobApp, "stats", "system"),
86 "start-time*",
87 []string{"start-time-rfc1123", "start-time-unix"},
88 },
89 {naming.Join("dm", "apps", appID, bobApp, "logs"),
90 "*",
91 []string{
92 "STDERR-<timestamp>",
93 "STDOUT-<timestamp>",
94 "app.INFO",
95 "app.<*>.INFO.<timestamp>",
96 },
97 },
Robert Kroeger6e4ed122015-03-06 13:03:54 -080098 }
Robert Kroeger22fcb032015-04-30 07:40:11 -070099 appGlobtests := []utiltest.GlobTestVector{
Robert Kroegerbc226062015-03-16 17:24:07 -0700100 {naming.Join("appV1", "__debug"), "*",
101 []string{"logs", "pprof", "stats", "vtrace"},
102 },
103 {naming.Join("appV1", "__debug", "stats", "system"),
104 "start-time*",
105 []string{"start-time-rfc1123", "start-time-unix"},
106 },
107 {naming.Join("appV1", "__debug", "logs"),
108 "*",
109 []string{
110 "STDERR-<timestamp>",
111 "STDOUT-<timestamp>",
112 "app.INFO",
113 "app.<*>.INFO.<timestamp>",
114 },
115 },
116 }
Robert Kroeger8f914be2015-03-14 16:32:37 -0700117 globtestminus := globtests[1:]
Robert Kroeger22fcb032015-04-30 07:40:11 -0700118 res := utiltest.NewGlobTestRegexHelper("app")
Robert Kroeger8f914be2015-03-14 16:32:37 -0700119
120 // Confirm that self can access __debug names.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700121 utiltest.VerifyGlob(t, selfCtx, "app", globtests, res)
122 utiltest.VerifyStatsValues(t, selfCtx, "dm", "apps", appID, bobApp, "stats/system/start-time*")
123 utiltest.VerifyLog(t, selfCtx, "dm", "apps", appID, bobApp, "logs", "*")
124 utiltest.VerifyPProfCmdLine(t, selfCtx, "app", "dm", "apps", appID, bobApp, "pprof")
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800125
Robert Kroegerbc226062015-03-16 17:24:07 -0700126 // Bob started the app so selfCtx can't connect to the app.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700127 utiltest.VerifyFailGlob(t, selfCtx, appGlobtests)
Robert Kroegerbc226062015-03-16 17:24:07 -0700128 testAccessFail(t, verror.ErrNoAccess.ID, selfCtx, "self", "appV1", "__debug", "stats/system/pid")
129
130 // hackerjoe (for example) can't either.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700131 utiltest.VerifyFailGlob(t, hjCtx, appGlobtests)
Robert Kroegerbc226062015-03-16 17:24:07 -0700132 testAccessFail(t, verror.ErrNoAccess.ID, hjCtx, "hackerjoe", "appV1", "__debug", "stats/system/pid")
133
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800134 // Bob has an issue with his app and tries to use the debug output to figure it out.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700135 utiltest.VerifyGlob(t, bobCtx, "app", globtests, res)
136 utiltest.VerifyStatsValues(t, bobCtx, "dm", "apps", appID, bobApp, "stats/system/start-time*")
137 utiltest.VerifyLog(t, bobCtx, "dm", "apps", appID, bobApp, "logs", "*")
138 utiltest.VerifyPProfCmdLine(t, bobCtx, "app", "dm", "apps", appID, bobApp, "pprof")
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800139
Robert Kroegerbc226062015-03-16 17:24:07 -0700140 // Bob can also connect directly to his app.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700141 utiltest.VerifyGlob(t, bobCtx, "app", appGlobtests, res)
142 utiltest.VerifyStatsValues(t, bobCtx, "appV1", "__debug", "stats/system/start-time*")
Robert Kroegerbc226062015-03-16 17:24:07 -0700143
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800144 // But Bob can't figure it out and hopes that hackerjoe can debug it.
Robert Kroeger066ac712015-03-20 16:28:48 -0700145 updateAccessList(t, bobCtx, "root/hackerjoe/$", string(access.Debug), "dm/apps", appID, bobApp)
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800146
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700147 // Fortunately the device manager permits hackerjoe to access the stats.
148 // But hackerjoe can't solve Bob's problem.
Robert Kroegerbc226062015-03-16 17:24:07 -0700149 // Because hackerjoe has Debug, hackerjoe can glob the __debug resources
Robert Kroeger8f914be2015-03-14 16:32:37 -0700150 // of Bob's app but can't glob Bob's app.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700151 utiltest.VerifyGlob(t, hjCtx, "app", globtestminus, res)
152 utiltest.VerifyFailGlob(t, hjCtx, globtests[0:1])
153 utiltest.VerifyStatsValues(t, hjCtx, "dm", "apps", appID, bobApp, "stats", "system/start-time*")
154 utiltest.VerifyLog(t, hjCtx, "dm", "apps", appID, bobApp, "logs", "*")
155 utiltest.VerifyPProfCmdLine(t, hjCtx, "app", "dm", "apps", appID, bobApp, "pprof")
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700156
Robert Kroeger9732f012015-03-16 13:41:25 -0700157 // Permissions are propagated to the app so hackerjoe can connect
158 // directly to the app too.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700159 utiltest.VerifyGlob(t, hjCtx, "app", globtestminus, res)
160 utiltest.VerifyStatsValues(t, hjCtx, "appV1", "__debug", "stats/system/start-time*")
Robert Kroegerbc226062015-03-16 17:24:07 -0700161
Adam Sadovskya4d4a692015-04-20 11:36:49 -0700162 // Alice might be able to help but Bob didn't give Alice access to the debug Permissionss.
Robert Kroegerbc226062015-03-16 17:24:07 -0700163 testAccessFail(t, verror.ErrNoAccess.ID, aliceCtx, "Alice", "dm", "apps", appID, bobApp, "stats/system/pid")
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800164
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700165 // Bob forgets that Alice can't read the stats when he can.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700166 utiltest.VerifyGlob(t, bobCtx, "app", globtests, res)
167 utiltest.VerifyStatsValues(t, bobCtx, "dm", "apps", appID, bobApp, "stats/system/start-time*")
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800168
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700169 // So Bob changes the permissions so that Alice can help debug too.
Robert Kroeger066ac712015-03-20 16:28:48 -0700170 updateAccessList(t, bobCtx, "root/alice/$", string(access.Debug), "dm/apps", appID, bobApp)
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700171
172 // Alice can access __debug content.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700173 utiltest.VerifyGlob(t, aliceCtx, "app", globtestminus, res)
174 utiltest.VerifyFailGlob(t, aliceCtx, globtests[0:1])
175 utiltest.VerifyStatsValues(t, aliceCtx, "dm", "apps", appID, bobApp, "stats", "system/start-time*")
176 utiltest.VerifyLog(t, aliceCtx, "dm", "apps", appID, bobApp, "logs", "*")
177 utiltest.VerifyPProfCmdLine(t, aliceCtx, "app", "dm", "apps", appID, bobApp, "pprof")
Robert Kroeger16ee22b2015-03-12 14:57:09 -0700178
Robert Kroeger9732f012015-03-16 13:41:25 -0700179 // Alice can also now connect directly to the app.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700180 utiltest.VerifyGlob(t, aliceCtx, "app", globtestminus, res)
181 utiltest.VerifyStatsValues(t, aliceCtx, "appV1", "__debug", "stats/system/start-time*")
Robert Kroegerbc226062015-03-16 17:24:07 -0700182
Bogdan Caprita2b050322015-04-17 09:04:03 -0700183 // Bob is glum because no one can help him fix his app so he terminates
184 // it.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700185 utiltest.TerminateApp(t, bobCtx, appID, bobApp)
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800186
187 // Cleanly shut down the device manager.
188 syscall.Kill(dmh.Pid(), syscall.SIGINT)
Robert Kroeger5358ddf2015-03-11 10:15:43 -0700189 dmh.Expect("dm terminated")
190 dmh.ExpectEOF()
Robert Kroeger6e4ed122015-03-06 13:03:54 -0800191}
Robert Kroeger066ac712015-03-20 16:28:48 -0700192
193func TestClaimSetsDebugPermissions(t *testing.T) {
Robert Kroeger22fcb032015-04-30 07:40:11 -0700194 cleanup, ctx, sh, _, root, helperPath, idp := utiltest.StartupHelper(t)
Robert Kroeger066ac712015-03-20 16:28:48 -0700195 defer cleanup()
196
197 extraLogDir, err := ioutil.TempDir(root, "testlogs")
198 if err != nil {
199 t.Fatalf("ioutil.TempDir failed: %v", err)
200 }
201
202 // Set up the device manager.
Todd Wang5fc36442015-04-07 15:15:27 -0700203 dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "--log_dir="+extraLogDir, "dm", root, helperPath, "unused", "unused_curr_link")
204 servicetest.ReadPID(t, dmh)
Robert Kroeger066ac712015-03-20 16:28:48 -0700205
206 // Make some users.
207 selfCtx := ctx
Robert Kroeger22fcb032015-04-30 07:40:11 -0700208 bobCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "bob")
209 aliceCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "alice")
210 hjCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "hackerjoe")
Robert Kroeger066ac712015-03-20 16:28:48 -0700211
212 // Bob claims the device manager.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700213 utiltest.ClaimDevice(t, bobCtx, "claimable", "dm", "mydevice", noPairingToken)
Robert Kroeger066ac712015-03-20 16:28:48 -0700214
215 // Create some globbing test vectors.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700216 dmGlobtests := []utiltest.GlobTestVector{
Robert Kroeger066ac712015-03-20 16:28:48 -0700217 {naming.Join("dm", "__debug"), "*",
218 []string{"logs", "pprof", "stats", "vtrace"},
219 },
220 {naming.Join("dm", "__debug", "stats", "system"),
221 "start-time*",
222 []string{"start-time-rfc1123", "start-time-unix"},
223 },
224 {naming.Join("dm", "__debug", "logs"),
225 "*",
226 []string{
227 // STDERR and STDOUT are not handled through the log package so
228 // are not included here.
229 "impl.test.INFO",
230 "impl.test.<*>.INFO.<timestamp>",
231 },
232 },
233 }
Robert Kroeger22fcb032015-04-30 07:40:11 -0700234 res := utiltest.NewGlobTestRegexHelper(`impl\.test`)
Robert Kroeger066ac712015-03-20 16:28:48 -0700235
236 // Bob claimed the DM so can access it.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700237 utiltest.VerifyGlob(t, bobCtx, "impl.test", dmGlobtests, res)
238 utiltest.VerifyStatsValues(t, bobCtx, "dm", "__debug", "stats/system/start-time*")
Robert Kroeger066ac712015-03-20 16:28:48 -0700239
240 // Without permissions, hackerjoe can't access the device manager.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700241 utiltest.VerifyFailGlob(t, hjCtx, dmGlobtests)
Robert Kroeger066ac712015-03-20 16:28:48 -0700242 testAccessFail(t, verror.ErrNoAccess.ID, hjCtx, "hackerjoe", "dm", "__debug", "stats/system/pid")
243
244 // Bob gives system administrator Alice admin access to the dm and hence Alice
245 // can access the __debug space.
246 updateAccessList(t, bobCtx, "root/alice/$", string(access.Admin), "dm", "device")
247
Robert Kroeger3bbf3c72015-03-25 13:04:55 -0700248 // Alice is an adminstrator and so can can access device manager __debug
249 // values.
Robert Kroeger22fcb032015-04-30 07:40:11 -0700250 utiltest.VerifyGlob(t, aliceCtx, "impl.test", dmGlobtests, res)
251 utiltest.VerifyStatsValues(t, aliceCtx, "dm", "__debug", "stats/system/start-time*")
Robert Kroeger066ac712015-03-20 16:28:48 -0700252
253 // Bob gives debug access to the device manager to hackerjoe
254 updateAccessList(t, bobCtx, "root/hackerjoe/$", string(access.Debug), "dm", "device")
255
Robert Kroeger3bbf3c72015-03-25 13:04:55 -0700256 // hackerjoe can now access the device manager
Robert Kroeger22fcb032015-04-30 07:40:11 -0700257 utiltest.VerifyGlob(t, hjCtx, "impl.test", dmGlobtests, res)
258 utiltest.VerifyStatsValues(t, hjCtx, "dm", "__debug", "stats/system/start-time*")
Robert Kroeger066ac712015-03-20 16:28:48 -0700259
260 // Cleanly shut down the device manager.
261 syscall.Kill(dmh.Pid(), syscall.SIGINT)
262 dmh.Expect("dm terminated")
263 dmh.ExpectEOF()
264}