Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework of CLI + Cobra #69

Merged
merged 39 commits into from
Jun 5, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1b7f188
Added new print module
Foxboron May 16, 2021
955c547
Added more fidelity to the logging methods
Foxboron May 16, 2021
0d249b2
Added bundle cli format
Foxboron May 16, 2021
7a4defc
Added deps
Foxboron May 16, 2021
431363f
Added list-files new WIP for commands
Foxboron May 16, 2021
62d653d
Added status new format
Foxboron May 16, 2021
2a53d52
Added list-bundles setup
Foxboron May 16, 2021
a05e6c8
Fixed commands with colors off
Foxboron May 16, 2021
bb78cf9
Remove previous logging, improve error bubling
Foxboron May 16, 2021
b82e17e
Return errors when generating bundles
Foxboron May 16, 2021
3568e9d
sbctl: Buble up errors from the "library"
Foxboron May 16, 2021
1508b29
Moved json out function
Foxboron May 17, 2021
23381e0
Added NotOK instead of "Error". Makes more sense semantically
Foxboron May 17, 2021
3d7f094
Added an iter function
Foxboron May 17, 2021
fb9b3c7
🤷
Foxboron May 17, 2021
30e16f5
Catch for unknown command
Foxboron May 17, 2021
70b00f3
Added new error
Foxboron May 18, 2021
d0022cb
Added BundleIter
Foxboron May 18, 2021
877ab49
Implement GetGUID
Foxboron May 18, 2021
adadb52
Give status the ability to display owner GUID
Foxboron May 18, 2021
3505f1b
New structure
Foxboron May 18, 2021
a5e0551
GUID package
Foxboron May 18, 2021
342ba34
Fixup
Foxboron May 18, 2021
235238c
Fixed lint issues
Foxboron May 18, 2021
f01453a
Change immutable error a little bit
Foxboron May 18, 2021
97435cc
More internal restructuring
Foxboron May 18, 2021
3454841
Moved create-keys top-level
Foxboron May 18, 2021
a318695
Moved generate-bundles top-level
Foxboron May 18, 2021
3f05d1d
Propegate errors better
Foxboron May 18, 2021
6dfc186
enroll changes
Foxboron May 19, 2021
b49ebbb
Added CanVerifyFiles
Foxboron May 19, 2021
8b4fc40
Added internal functions for checked paths, and CheckMSDos
Foxboron May 19, 2021
0d12167
Move verify to top-level
Foxboron May 19, 2021
fe514e1
Added errors to WriteFileDatabase
Foxboron May 19, 2021
6b0242c
Added print layout for key syncing
Foxboron May 19, 2021
57a1c93
Remove last of the log.* stuff
Foxboron May 19, 2021
ba0cee8
Make lint happy
Foxboron May 19, 2021
550b4e6
Move global flags to persistent
Foxboron May 22, 2021
ae1aec1
sbctl: Ensure all commands inherit stdout turning off
Foxboron May 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
New structure
Signed-off-by: Morten Linderud <morten@linderud.pw>
  • Loading branch information
Foxboron committed May 30, 2021
commit 3505f1b57174243a685f161f88795fb71701a557
29 changes: 0 additions & 29 deletions bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/foxboron/sbctl/logging"
)
Expand Down Expand Up @@ -126,31 +125,3 @@ func GenerateBundle(bundle *Bundle) (bool, error) {
logging.Print("Wrote EFI bundle %s\n", bundle.Output)
return true, nil
}

func FormatBundle(name string, bundle *Bundle) {
logging.Println(name)
logging.Print("\tSigned:\t\t")
if ok, _ := VerifyFile(DBCert, name); ok {
logging.Ok("Signed")
} else {
logging.NotOk("Not Signed")
}
esp := GetESP()
logging.Print("\tESP Location:\t%s\n", esp)
logging.Print("\tOutput:\t\t└─%s\n", strings.TrimPrefix(bundle.Output, esp))
logging.Print("\tEFI Stub Image:\t └─%s\n", bundle.EFIStub)
if bundle.Splash != "" {
logging.Print("\tSplash Image:\t ├─%s\n", bundle.Splash)
}
logging.Print("\tCmdline:\t ├─%s\n", bundle.Cmdline)
logging.Print("\tOS Release:\t ├─%s\n", bundle.OSRelease)
logging.Print("\tKernel Image:\t ├─%s\n", bundle.KernelImage)
logging.Print("\tInitramfs Image: └─%s\n", bundle.Initramfs)
if bundle.AMDMicrocode != "" {
logging.Print("\tAMD Microcode: └─%s\n", bundle.AMDMicrocode)
}
if bundle.IntelMicrocode != "" {
logging.Print("\tIntel Microcode: └─%s\n", bundle.IntelMicrocode)
}
logging.Println("")
}
99 changes: 99 additions & 0 deletions cmd/sbctl/bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import (
"os"
"path/filepath"

"github.com/foxboron/sbctl"
"github.com/foxboron/sbctl/logging"
"github.com/spf13/cobra"
)

var (
amducode string
intelucode string
splashImg string
osRelease string
efiStub string
kernelImg string
cmdline string
initramfs string
espPath string
saveBundle bool
)

var bundleCmd = &cobra.Command{
Use: "bundle",
Short: "Bundle the needed files for an EFI stub image",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
logging.Print("Requires a file to sign...\n")
os.Exit(1)
}
checkFiles := []string{amducode, intelucode, splashImg, osRelease, efiStub, kernelImg, cmdline, initramfs}
for _, path := range checkFiles {
if path == "" {
continue
}
if _, err := os.Stat(path); os.IsNotExist(err) {
logging.Print("%s does not exist!\n", path)
os.Exit(1)
}
}
bundle := sbctl.NewBundle()
output, err := filepath.Abs(args[0])
if err != nil {
return err
}
// Fail early if user wants to save bundle but doesn't have permissions
var bundles sbctl.Bundles
if saveBundle {
// "err" needs to have been declared before this, otherwise it's necessary
// to use ":=", which shadows the "bundles" variable
bundles, err = sbctl.ReadBundleDatabase(sbctl.BundleDBPath)
if err != nil {
return err
}
}
bundle.Output = output
bundle.IntelMicrocode = intelucode
bundle.AMDMicrocode = amducode
bundle.KernelImage = kernelImg
bundle.Initramfs = initramfs
bundle.Cmdline = cmdline
bundle.Splash = splashImg
bundle.OSRelease = osRelease
bundle.EFIStub = efiStub
bundle.ESP = espPath
if err = sbctl.CreateBundle(*bundle); err != nil {
return err
}
if saveBundle {
bundles[bundle.Output] = bundle
sbctl.WriteBundleDatabase(sbctl.BundleDBPath, bundles)
}
return nil
},
}

func bundleCmdFlags(cmd *cobra.Command) {
esp := sbctl.GetESP()
f := cmd.Flags()
f.StringVarP(&amducode, "amducode", "a", "", "AMD microcode location")
f.StringVarP(&intelucode, "intelucode", "i", "", "Intel microcode location")
f.StringVarP(&splashImg, "splash-img", "l", "", "Boot splash image location")
f.StringVarP(&osRelease, "os-release", "o", "/usr/lib/os-release", "OS Release file location")
f.StringVarP(&efiStub, "efi-stub", "e", "/usr/lib/systemd/boot/efi/linuxx64.efi.stub", "EFI Stub location")
f.StringVarP(&kernelImg, "kernel-img", "k", "/boot/vmlinuz-linux", "Kernel image location")
f.StringVarP(&cmdline, "cmdline", "c", "/etc/kernel/cmdline", "Cmdline location")
f.StringVarP(&initramfs, "initramfs", "f", "/boot/initramfs-linux.img", "Initramfs location")
f.StringVarP(&espPath, "esp", "p", esp, "ESP location")
f.BoolVarP(&saveBundle, "save", "s", false, "save bundle to the database")
}

func init() {
bundleCmdFlags(bundleCmd)
CliCommands = append(CliCommands, cliCommand{
Cmd: bundleCmd,
})
}
51 changes: 51 additions & 0 deletions cmd/sbctl/completions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"os"

"github.com/spf13/cobra"
)

var completionCmd = &cobra.Command{Use: "completion"}

func completionBashCmd() *cobra.Command {
var completionCmd = &cobra.Command{
Use: "bash",
Hidden: true,
Run: func(cmd *cobra.Command, args []string) {
rootCmd.GenBashCompletion(os.Stdout)
},
}
return completionCmd
}

func completionZshCmd() *cobra.Command {
var completionCmd = &cobra.Command{
Use: "zsh",
Hidden: true,
Run: func(cmd *cobra.Command, args []string) {
rootCmd.GenZshCompletion(os.Stdout)
},
}
return completionCmd
}

func completionFishCmd() *cobra.Command {
var completionCmd = &cobra.Command{
Use: "fish",
Hidden: true,
Run: func(cmd *cobra.Command, args []string) {
rootCmd.GenFishCompletion(os.Stdout, true)
},
}
return completionCmd
}

func init() {
completionCmd.AddCommand(completionBashCmd())
completionCmd.AddCommand(completionZshCmd())
completionCmd.AddCommand(completionFishCmd())
CliCommands = append(CliCommands, cliCommand{
Cmd: completionCmd,
})
}
20 changes: 20 additions & 0 deletions cmd/sbctl/create-keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"github.com/foxboron/sbctl"
"github.com/spf13/cobra"
)

var createKeysCmd = &cobra.Command{
Use: "create-keys",
Short: "Create a set of secure boot signing keys",
RunE: func(cmd *cobra.Command, args []string) error {
return sbctl.CreateKeys()
},
}

func init() {
CliCommands = append(CliCommands, cliCommand{
Cmd: createKeysCmd,
})
}
20 changes: 20 additions & 0 deletions cmd/sbctl/enroll-keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"github.com/foxboron/sbctl"
"github.com/spf13/cobra"
)

var enrollKeysCmd = &cobra.Command{
Use: "enroll-keys",
Short: "Enroll the current keys to EFI",
RunE: func(cmd *cobra.Command, args []string) error {
return sbctl.SyncKeys()
},
}

func init() {
CliCommands = append(CliCommands, cliCommand{
Cmd: enrollKeysCmd,
})
}
30 changes: 30 additions & 0 deletions cmd/sbctl/generate-bundles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"github.com/foxboron/sbctl"
"github.com/spf13/cobra"
)

var (
sign bool
)

var generateBundlesCmd = &cobra.Command{
Use: "generate-bundles",
Short: "Generate all EFI stub bundles",
RunE: func(cmd *cobra.Command, args []string) error {
return sbctl.GenerateAllBundles(sign)
},
}

func generateBundlesCmdFlags(cmd *cobra.Command) {
f := cmd.Flags()
f.BoolVarP(&sign, "sign", "s", false, "Sign all the generated bundles")
}

func init() {
generateBundlesCmdFlags(generateBundlesCmd)
CliCommands = append(CliCommands, cliCommand{
Cmd: generateBundlesCmd,
})
}
73 changes: 73 additions & 0 deletions cmd/sbctl/list-bundles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"strings"

"github.com/foxboron/sbctl"
"github.com/foxboron/sbctl/logging"
"github.com/spf13/cobra"
)

type JsonBundle struct {
sbctl.Bundle
IsSigned bool `json:"is_signed"`
}

var listBundlesCmd = &cobra.Command{
Use: "list-bundles",
Short: "List stored bundles",
RunE: func(cmd *cobra.Command, args []string) error {
bundles := []JsonBundle{}
var isSigned bool
err := sbctl.BundleIter(
func(s *sbctl.Bundle) error {
ok, err := sbctl.VerifyFile(sbctl.DBCert, s.Output)
if err != nil {
return err
}
logging.Println("Enrolled bundles:\n")
logging.Println(s.Output)
logging.Print("\tSigned:\t\t")
if ok {
isSigned = true
logging.Ok("Signed")
} else {
isSigned = false
logging.NotOk("Not Signed")
}
esp := sbctl.GetESP()
logging.Print("\tESP Location:\t%s\n", esp)
logging.Print("\tOutput:\t\t└─%s\n", strings.TrimPrefix(s.Output, esp))
logging.Print("\tEFI Stub Image:\t └─%s\n", s.EFIStub)
if s.Splash != "" {
logging.Print("\tSplash Image:\t ├─%s\n", s.Splash)
}
logging.Print("\tCmdline:\t ├─%s\n", s.Cmdline)
logging.Print("\tOS Release:\t ├─%s\n", s.OSRelease)
logging.Print("\tKernel Image:\t ├─%s\n", s.KernelImage)
logging.Print("\tInitramfs Image: └─%s\n", s.Initramfs)
if s.AMDMicrocode != "" {
logging.Print("\tAMD Microcode: └─%s\n", s.AMDMicrocode)
}
if s.IntelMicrocode != "" {
logging.Print("\tIntel Microcode: └─%s\n", s.IntelMicrocode)
}
bundles = append(bundles, JsonBundle{*s, isSigned})
logging.Println("")
return nil
})
if err != nil {
return err
}
if cmdOptions.JsonOutput {
JsonOut(bundles)
}
return nil
},
}

func init() {
CliCommands = append(CliCommands, cliCommand{
Cmd: listBundlesCmd,
})
}
Loading