github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/hookstate/ctlcmd/fde_setup_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package ctlcmd_test 21 22 import ( 23 "encoding/base64" 24 "fmt" 25 26 . "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/dirs" 29 "github.com/snapcore/snapd/kernel/fde" 30 "github.com/snapcore/snapd/overlord/hookstate" 31 "github.com/snapcore/snapd/overlord/hookstate/ctlcmd" 32 "github.com/snapcore/snapd/overlord/hookstate/hooktest" 33 "github.com/snapcore/snapd/overlord/state" 34 "github.com/snapcore/snapd/secboot" 35 "github.com/snapcore/snapd/snap" 36 "github.com/snapcore/snapd/testutil" 37 ) 38 39 type fdeSetupSuite struct { 40 testutil.BaseTest 41 42 st *state.State 43 mockHandler *hooktest.MockHandler 44 mockTask *state.Task 45 mockContext *hookstate.Context 46 } 47 48 var _ = Suite(&fdeSetupSuite{}) 49 50 var mockFdeSetupKernelYaml = `name: pc-kernel 51 version: 1.0 52 type: kernel 53 hooks: 54 fde-setup: 55 ` 56 57 func (s *fdeSetupSuite) SetUpTest(c *C) { 58 s.BaseTest.SetUpTest(c) 59 dirs.SetRootDir(c.MkDir()) 60 s.AddCleanup(func() { dirs.SetRootDir("/") }) 61 62 s.st = state.New(nil) 63 s.mockHandler = hooktest.NewMockHandler() 64 s.st.Lock() 65 defer s.st.Unlock() 66 67 mockInstalledSnap(c, s.st, mockFdeSetupKernelYaml) 68 s.mockTask = s.st.NewTask("test-task", "my test task") 69 hooksup := &hookstate.HookSetup{ 70 Snap: "pc-kernel", 71 Revision: snap.R(1), 72 Hook: "fde-setup", 73 } 74 context, err := hookstate.NewContext(s.mockTask, s.st, hooksup, s.mockHandler, "") 75 c.Assert(err, IsNil) 76 s.mockContext = context 77 } 78 79 func (s *fdeSetupSuite) TestFdeSetupRequestOpInvalid(c *C) { 80 fdeSetup := &fde.SetupRequest{ 81 Op: "invalid-and-unknown", 82 } 83 s.mockContext.Lock() 84 s.mockContext.Set("fde-setup-request", fdeSetup) 85 s.mockContext.Unlock() 86 87 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"fde-setup-request"}, 0) 88 c.Check(err, ErrorMatches, `unknown fde-setup-request op "invalid-and-unknown"`) 89 c.Check(string(stdout), Equals, "") 90 c.Check(string(stderr), Equals, "") 91 } 92 93 func (s *fdeSetupSuite) TestFdeSetupRequestNoFdeSetupOpData(c *C) { 94 hooksup := &hookstate.HookSetup{ 95 Snap: "pc-kernel", 96 Revision: snap.R(1), 97 Hook: "other-hook", 98 } 99 context, err := hookstate.NewContext(nil, s.st, hooksup, s.mockHandler, "") 100 c.Assert(err, IsNil) 101 102 // check "fde-setup-request" error 103 stdout, stderr, err := ctlcmd.Run(context, []string{"fde-setup-request"}, 0) 104 c.Check(err, ErrorMatches, `cannot use fde-setup-request outside of the fde-setup hook`) 105 c.Check(string(stdout), Equals, "") 106 c.Check(string(stderr), Equals, "") 107 108 // check "fde-setup-result" error 109 stdout, stderr, err = ctlcmd.Run(context, []string{"fde-setup-result"}, 0) 110 c.Check(err, ErrorMatches, `cannot use fde-setup-result outside of the fde-setup hook`) 111 c.Check(string(stdout), Equals, "") 112 c.Check(string(stderr), Equals, "") 113 } 114 115 func (s *fdeSetupSuite) TestFdeSetupRequestOpFeatures(c *C) { 116 fdeSetup := &fde.SetupRequest{ 117 Op: "features", 118 } 119 s.mockContext.Lock() 120 s.mockContext.Set("fde-setup-request", fdeSetup) 121 s.mockContext.Unlock() 122 123 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"fde-setup-request"}, 0) 124 c.Assert(err, IsNil) 125 c.Check(string(stdout), Equals, `{"op":"features"}`+"\n") 126 c.Check(string(stderr), Equals, "") 127 } 128 129 func (s *fdeSetupSuite) TestFdeSetupRequestOpInitialSetup(c *C) { 130 mockKey := secboot.EncryptionKey{1, 2, 3, 4} 131 fdeSetup := &fde.SetupRequest{ 132 Op: "initial-setup", 133 Key: mockKey[:], 134 KeyName: "the-key-name", 135 } 136 s.mockContext.Lock() 137 s.mockContext.Set("fde-setup-request", fdeSetup) 138 s.mockContext.Unlock() 139 140 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"fde-setup-request"}, 0) 141 c.Assert(err, IsNil) 142 143 // the encryption key should be base64 encoded 144 encodedBase64Key := base64.StdEncoding.EncodeToString(mockKey[:]) 145 146 c.Check(string(stdout), Equals, fmt.Sprintf(`{"op":"initial-setup","key":%q,"key-name":"the-key-name"}`+"\n", encodedBase64Key)) 147 c.Check(string(stderr), Equals, "") 148 } 149 150 func (s *fdeSetupSuite) TestFdeSetupResult(c *C) { 151 mockStdin := []byte("sealed-key-data-from-stdin-as-set-by-daemon:runSnapctl") 152 153 s.mockContext.Lock() 154 s.mockContext.Set("stdin", mockStdin) 155 s.mockContext.Unlock() 156 157 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"fde-setup-result"}, 0) 158 c.Assert(err, IsNil) 159 c.Check(string(stdout), Equals, "") 160 c.Check(string(stderr), Equals, "") 161 162 // check that the task got the key that was passed via stdin 163 var fdeSetupResult []byte 164 s.mockContext.Lock() 165 s.mockContext.Get("fde-setup-result", &fdeSetupResult) 166 s.mockContext.Unlock() 167 c.Check(fdeSetupResult, DeepEquals, mockStdin) 168 }