diff --git a/daemon/access.go b/daemon/access.go index ca537ac1ee9..4021d7d2ef0 100644 --- a/daemon/access.go +++ b/daemon/access.go @@ -201,6 +201,9 @@ func requireInterfaceApiAccessImpl(d *Daemon, r *http.Request, ucred *ucrednet, } if connRef.PlugRef.Snap == snapName { r.RemoteAddr = ucrednetAttachInterface(r.RemoteAddr, connState.Interface) + // Do not return here, but keep processing connections for the side + // effect of attaching all connected interfaces we asked for to the + // remote address. foundMatchingInterface = true } } diff --git a/daemon/access_test.go b/daemon/access_test.go index 6d978f714f8..701f2e8702f 100644 --- a/daemon/access_test.go +++ b/daemon/access_test.go @@ -235,12 +235,14 @@ type: os version: 1 slots: snap-themes-control: + snap-refresh-control: `) s.mockSnap(c, ` name: some-snap version: 1 plugs: snap-themes-control: + snap-refresh-control: `) restore := daemon.MockCgroupSnapNameFromPid(func(pid int) (string, error) { @@ -251,7 +253,7 @@ plugs: }) defer restore() - var ac daemon.AccessChecker = daemon.InterfaceOpenAccess{Interfaces: []string{"snap-themes-control"}} + var ac daemon.AccessChecker = daemon.InterfaceOpenAccess{Interfaces: []string{"snap-themes-control", "snap-refresh-control"}} // Access with no ucred data is forbidden c.Check(ac.CheckAccess(d, nil, nil, nil), DeepEquals, errForbidden) @@ -290,6 +292,23 @@ plugs: // Interface is attached to RemoteAddr c.Check(req.RemoteAddr, Equals, fmt.Sprintf("%siface=snap-themes-control;", ucred)) + // Now connect both interfaces + st.Lock() + st.Set("conns", map[string]interface{}{ + "some-snap:snap-themes-control core:snap-themes-control": map[string]interface{}{ + "interface": "snap-themes-control", + }, + "some-snap:snap-refresh-control core:snap-refresh-control": map[string]interface{}{ + "interface": "snap-refresh-control", + }, + }) + st.Unlock() + req = http.Request{RemoteAddr: ucred.String()} + c.Check(ac.CheckAccess(s.d, &req, ucred, nil), IsNil) + // Check that both interfaces are attached to RemoteAddr. + // Since conns is a map, order is not guaranteed. + c.Check(req.RemoteAddr, Matches, fmt.Sprintf("^%siface=(snap-themes-control&snap-refresh-control|snap-refresh-control&snap-themes-control);$", ucred)) + // A left over "undesired" connection does not grant access st.Lock() st.Set("conns", map[string]interface{}{