// CheckInterfaces checks whether plugs and slots of snap are allowed for installation. func CheckInterfaces(st *state.State, snapInfo *snap.Info) error { // XXX: AddImplicitSlots is really a brittle interface snap.AddImplicitSlots(snapInfo) baseDecl, err := assertstate.BaseDeclaration(st) if err != nil { return fmt.Errorf("internal error: cannot find base declaration: %v", err) } var snapDecl *asserts.SnapDeclaration if snapInfo.SnapID != "" { var err error snapDecl, err = assertstate.SnapDeclaration(st, snapInfo.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", snapInfo.Name(), err) } } ic := policy.InstallCandidate{ Snap: snapInfo, SnapDeclaration: snapDecl, BaseDeclaration: baseDecl, } return ic.Check() }
func (s *assertMgrSuite) TestSnapDeclaration(c *C) { s.state.Lock() defer s.state.Unlock() // have a declaration in the system db err := assertstate.Add(s.state, s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(s.state, s.dev1Acct) c.Assert(err, IsNil) snapDeclFoo := s.snapDecl(c, "foo", nil) err = assertstate.Add(s.state, snapDeclFoo) c.Assert(err, IsNil) _, err = assertstate.SnapDeclaration(s.state, "snap-id-other") c.Check(err, Equals, asserts.ErrNotFound) snapDecl, err := assertstate.SnapDeclaration(s.state, "foo-id") c.Assert(err, IsNil) c.Check(snapDecl.SnapName(), Equals, "foo") }
func (c *autoConnectChecker) snapDeclaration(snapID string) (*asserts.SnapDeclaration, error) { snapDecl := c.cache[snapID] if snapDecl != nil { return snapDecl, nil } snapDecl, err := assertstate.SnapDeclaration(c.st, snapID) if err != nil { return nil, err } c.cache[snapID] = snapDecl return snapDecl, nil }
func (m *InterfaceManager) doConnect(task *state.Task, _ *tomb.Tomb) error { st := task.State() st.Lock() defer st.Unlock() plugRef, slotRef, err := getPlugAndSlotRefs(task) if err != nil { return err } conns, err := getConns(st) if err != nil { return err } connRef, err := m.repo.ResolveConnect(plugRef.Snap, plugRef.Name, slotRef.Snap, slotRef.Name) if err != nil { return err } plug := m.repo.Plug(connRef.PlugRef.Snap, connRef.PlugRef.Name) if plug == nil { return fmt.Errorf("snap %q has no %q plug", connRef.PlugRef.Snap, connRef.PlugRef.Name) } var plugDecl *asserts.SnapDeclaration if plug.Snap.SnapID != "" { var err error plugDecl, err = assertstate.SnapDeclaration(st, plug.Snap.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", plug.Snap.Name(), err) } } slot := m.repo.Slot(connRef.SlotRef.Snap, connRef.SlotRef.Name) if slot == nil { return fmt.Errorf("snap %q has no %q slot", connRef.SlotRef.Snap, connRef.SlotRef.Name) } var slotDecl *asserts.SnapDeclaration if slot.Snap.SnapID != "" { var err error slotDecl, err = assertstate.SnapDeclaration(st, slot.Snap.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", slot.Snap.Name(), err) } } baseDecl, err := assertstate.BaseDeclaration(st) if err != nil { return fmt.Errorf("internal error: cannot find base declaration: %v", err) } // check the connection against the declarations' rules ic := policy.ConnectCandidate{ Plug: plug.PlugInfo, PlugSnapDeclaration: plugDecl, Slot: slot.SlotInfo, SlotSnapDeclaration: slotDecl, BaseDeclaration: baseDecl, } err = ic.Check() if err != nil { return err } err = m.repo.Connect(connRef) if err != nil { return err } var plugSnapst snapstate.SnapState if err := snapstate.Get(st, connRef.PlugRef.Snap, &plugSnapst); err != nil { return err } var slotSnapst snapstate.SnapState if err := snapstate.Get(st, connRef.SlotRef.Snap, &slotSnapst); err != nil { return err } if err := setupSnapSecurity(task, slot.Snap, slotSnapst.DevModeAllowed(), m.repo); err != nil { return err } if err := setupSnapSecurity(task, plug.Snap, plugSnapst.DevModeAllowed(), m.repo); err != nil { return err } conns[connRef.ID()] = connState{Interface: plug.Interface} setConns(st, conns) return nil }
func (m *InterfaceManager) doConnect(task *state.Task, _ *tomb.Tomb) error { st := task.State() st.Lock() defer st.Unlock() plugRef, slotRef, err := getPlugAndSlotRefs(task) if err != nil { return err } conns, err := getConns(st) if err != nil { return err } connRef, err := m.repo.ResolveConnect(plugRef.Snap, plugRef.Name, slotRef.Snap, slotRef.Name) if err != nil { return err } plug := m.repo.Plug(connRef.PlugRef.Snap, connRef.PlugRef.Name) if plug == nil { return fmt.Errorf("snap %q has no %q plug", connRef.PlugRef.Snap, connRef.PlugRef.Name) } var plugDecl *asserts.SnapDeclaration if plug.Snap.SnapID != "" { var err error plugDecl, err = assertstate.SnapDeclaration(st, plug.Snap.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", plug.Snap.Name(), err) } } slot := m.repo.Slot(connRef.SlotRef.Snap, connRef.SlotRef.Name) if slot == nil { return fmt.Errorf("snap %q has no %q slot", connRef.SlotRef.Snap, connRef.SlotRef.Name) } var slotDecl *asserts.SnapDeclaration if slot.Snap.SnapID != "" { var err error slotDecl, err = assertstate.SnapDeclaration(st, slot.Snap.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", slot.Snap.Name(), err) } } baseDecl, err := assertstate.BaseDeclaration(st) if err != nil { return fmt.Errorf("internal error: cannot find base declaration: %v", err) } // check the connection against the declarations' rules ic := policy.ConnectCandidate{ Plug: plug.PlugInfo, PlugSnapDeclaration: plugDecl, Slot: slot.SlotInfo, SlotSnapDeclaration: slotDecl, BaseDeclaration: baseDecl, } // if either of plug or slot snaps don't have a declaration it // means they were installed with "dangerous", so the security // check should be skipped at this point. if plugDecl != nil && slotDecl != nil { err = ic.Check() if err != nil { return err } } err = m.repo.Connect(connRef) if err != nil { return err } var plugSnapst snapstate.SnapState if err := snapstate.Get(st, connRef.PlugRef.Snap, &plugSnapst); err != nil { return err } var slotSnapst snapstate.SnapState if err := snapstate.Get(st, connRef.SlotRef.Snap, &slotSnapst); err != nil { return err } slotOpts := confinementOptions(slotSnapst.Flags) if err := setupSnapSecurity(task, slot.Snap, slotOpts, m.repo); err != nil { return err } plugOpts := confinementOptions(plugSnapst.Flags) if err := setupSnapSecurity(task, plug.Snap, plugOpts, m.repo); err != nil { return err } conns[connRef.ID()] = connState{Interface: plug.Interface} setConns(st, conns) return nil }