Skip to content

Commit

Permalink
Enable nilaway and fix issues
Browse files Browse the repository at this point in the history
  • Loading branch information
eikendev committed Feb 15, 2025
1 parent d99d9ad commit 38d31ed
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 75 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ test: lint_scripts
errcheck ./...
gocritic check -disable='#experimental,#opinionated' -@ifElseChain.minThreshold 3 ./...
revive -set_exit_status ./...
nilaway ./...
go test -v -cover ./...
gosec -exclude-dir=tests ./...
govulncheck ./...
Expand All @@ -42,6 +43,7 @@ setup:
go install github.com/kisielk/errcheck@latest
go install github.com/mgechev/revive@latest
go install github.com/securego/gosec/v2/cmd/gosec@latest
go install go.uber.org/nilaway/cmd/nilaway@latest
go install golang.org/x/vuln/cmd/govulncheck@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
go install mvdan.cc/gofumpt@latest
Expand Down
6 changes: 6 additions & 0 deletions internal/commands/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ func downloadImage(path, url string) error {
log.Errorf("Cannot download image file: %s\n", err)
return err
}
if resp == nil {
return fmt.Errorf("received nil response")
}
defer handling.Close(resp.Body)

if resp.StatusCode != http.StatusOK {
Expand Down Expand Up @@ -104,6 +107,9 @@ func validateChecksum(localPath, checksum string) error {
func (c *GetCommand) Run(s *options.Options) error {
image := images.GetImageDetails(s.Type)
info := image.GetDownloadInfo(true)
if info == nil {
return fmt.Errorf("failed to get download information")
}

log.Printf("Found file %s with checksum %s\n", info.Filename, info.Checksum)

Expand Down
21 changes: 16 additions & 5 deletions internal/commands/up.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package commands

import (
"errors"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -137,16 +138,19 @@ func provisionClient(_ *UpCommand, image *images.Image, guestIPAddr string) {
}
}

func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, guestIPAddr string, keymap string) {
func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, guestIPAddr string, keymap string) error {
client, err := goph.NewUnknown(image.SSHUser, guestIPAddr, goph.Password(image.SSHPassword))
if err != nil {
log.Fatal(err)
return err
}
if client == nil {
return errors.New("nil goph client")
}

publicKeyPath := paths.GetDataFilePath(constants.SSHKeypairName + ".pub")
publicKey, err := os.ReadFile(publicKeyPath) //#nosec G304
if err != nil {
log.Fatalf("Unable to read private SSH key: %s\n", err)
return fmt.Errorf("unable to read private SSH key: %s", err)
}
publicKeyStr := string(publicKey)

Expand Down Expand Up @@ -180,9 +184,11 @@ func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, gu
for _, cmd := range cmds {
_, err := client.Run(cmd)
if err != nil {
log.Fatalf("Failed to run command over SSH: %s\n", err)
return fmt.Errorf("failed to run command '%s' over SSH: %s", cmd, err)
}
}

return nil
}

func ensureSSHKeypairExists() error {
Expand Down Expand Up @@ -253,7 +259,12 @@ func (c *UpCommand) Run(s *options.Options) error {
guestIPAddr := waitBootComplete(dom, &image)
image.StartSSH(dom)

configureClient(c, dom, &image, guestIPAddr, s.Keymap)
err = configureClient(c, dom, &image, guestIPAddr, s.Keymap)
if err != nil {
log.Errorf("Cannot configure client: %s\n", err)
return err
}

log.Printf("%s is now ready to use\n", image.DisplayName)

if s.Provision {
Expand Down
4 changes: 4 additions & 0 deletions internal/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,9 @@ func GetHostKeyboardLayout() string {

line = strings.TrimSpace(line)
parts := strings.Split(line, " ")
if len(parts) < 2 {
log.Fatalf("Unable to retrieve host's keyboard layout\n")
return ""
}
return parts[len(parts)-1]
}
24 changes: 24 additions & 0 deletions internal/images/checksums.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package images

import (
"fmt"
"regexp"
"strings"
)

// parseChecksumLine extracts checksum information from a line
func parseChecksumLine(line string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
parts := strings.Fields(line)
if len(parts) < 2 {
return nil, fmt.Errorf("invalid checksum line format: %s", line)
}

checksum := parts[0]
filename := parts[len(parts)-1]

return &DownloadInfo{
Checksum: checksum,
Version: versionRegex.FindString(filename),
Filename: filename,
}, nil
}
3 changes: 2 additions & 1 deletion internal/images/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ func (vc genericVersionComparer) Lt(a, b string) bool {
aParts := strings.Split(a, ".")
bParts := strings.Split(b, ".")

if len(aParts) != len(bParts) {
if len(aParts) == 0 || len(bParts) == 0 || len(aParts) != len(bParts) {
log.Fatalf("Cannot compare versions %s and %s\n", a, b)
return false
}

for i := range aParts {
Expand Down
11 changes: 4 additions & 7 deletions internal/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ var images = map[string]Image{
ArchiveURL: "https://deb.parrot.sh/parrot/iso/current",
checksumPath: "/signed-hashes.txt",
LocalImageName: "parrot-%s.iso",
VersionRegex: regexp.MustCompile(`\d+\.\d+`),
VersionRegex: regexp.MustCompile(`\d+\.\d+(?:\.\d+)?`),
SSHUser: "user",
SSHPassword: "parrot",
MacAddress: "52:54:00:08:f9:e9",
Expand Down Expand Up @@ -130,12 +130,9 @@ func (i *Image) GetLatestPath() string {
}

matches, err := filepath.Glob(path)
if err != nil {
log.Fatalf("Malformed glob pattern: %s\n", err)
}

if matches == nil {
log.Fatalf("Image for %s not found; download with get command\n", i.DisplayName)
if err != nil || len(matches) == 0 {
log.Fatalf("Cannot find image for %s\n", i.DisplayName)
return "" // Won't actually return due to log.Fatal
}

latestPath := matches[0]
Expand Down
50 changes: 23 additions & 27 deletions internal/images/kali.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,49 @@ import (
"bufio"
"errors"
"fmt"
"net/http"
"regexp"
"runtime"
"strings"
"time"

log "github.com/sirupsen/logrus"
rawLibvirt "libvirt.org/libvirt-go"

"github.com/eikendev/hackenv/internal/network"
)

var kaliConfigurationCmds = []string{
"touch ~/.hushlogin",
}

func kaliInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
resp, err := http.Get(url) //#nosec G107
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
}

var line string
scanner := bufio.NewScanner(resp.Body)

func findKaliChecksumLine(scanner *bufio.Scanner) (string, error) {
for scanner.Scan() {
line = scanner.Text()

line := scanner.Text()
if strings.Contains(line, "live-"+runtime.GOARCH+".iso") {
break
return strings.TrimSpace(line), nil
}
}

if line == "" {
return nil, errors.New("bad checksum file")
return "", errors.New("checksum not found in file")
}

func kaliInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
resp, err := network.GetResponse(url)
if err != nil {
return nil, fmt.Errorf("failed to get response: %w", err)
}
defer func() {
if err := resp.Body.Close(); err != nil {
log.Warnf("failed to close response body: %v", err)
}
}()

line = strings.TrimSpace(line)
parts := strings.Split(line, " ")
filename := parts[len(parts)-1]
line, err := findKaliChecksumLine(bufio.NewScanner(resp.Body))
if err != nil {
return nil, err
}

return &DownloadInfo{
parts[0],
versionRegex.FindString(filename),
filename,
}, nil
return parseChecksumLine(line, versionRegex)
}

func kaliBootInitializer(dom *rawLibvirt.Domain) {
Expand Down
73 changes: 38 additions & 35 deletions internal/images/parrot.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,62 @@ import (
"bufio"
"errors"
"fmt"
"net/http"
"regexp"
"runtime"
"strings"
"time"

log "github.com/sirupsen/logrus"
rawLibvirt "libvirt.org/libvirt-go"
)

func parrotInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
resp, err := http.Get(url) //#nosec G107
if err != nil {
return nil, err
}
"github.com/eikendev/hackenv/internal/network"
)

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
}
func findParrotChecksumLine(scanner *bufio.Scanner) (string, error) {
const (
sha256Section = "sha256"
sha384Section = "sha384"
)

var line string
skipped := false
scanner := bufio.NewScanner(resp.Body)
var inSha256Section bool

for scanner.Scan() {
line = scanner.Text()
line := scanner.Text()

if skipped {
if strings.Contains(line, "Parrot-security") && strings.Contains(line, "_"+runtime.GOARCH+".iso") {
break
}
} else {
if strings.Contains(line, "sha256") {
skipped = true
}
if strings.Contains(line, "sha384") {
skipped = false
}
switch {
case strings.Contains(line, sha256Section):
inSha256Section = true
continue
case strings.Contains(line, sha384Section):
inSha256Section = false
continue
case inSha256Section &&
strings.Contains(line, "Parrot-security") &&
strings.Contains(line, "_"+runtime.GOARCH+".iso"):
return strings.TrimSpace(line), nil
}
}

if line == "" {
return nil, errors.New("bad checksum file")
return "", errors.New("checksum not found in file")
}

func parrotInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
resp, err := network.GetResponse(url)
if err != nil {
return nil, fmt.Errorf("failed to get response: %w", err)
}
defer func() {
if err := resp.Body.Close(); err != nil {
log.Warnf("failed to close response body: %v", err)
}
}()

line = strings.TrimSpace(line)
parts := strings.Split(line, " ")
filename := parts[len(parts)-1]
line, err := findParrotChecksumLine(bufio.NewScanner(resp.Body))
if err != nil {
return nil, err
}

return &DownloadInfo{
parts[0],
versionRegex.FindString(filename),
filename,
}, nil
return parseChecksumLine(line, versionRegex)
}

func parrotBootInitializer(dom *rawLibvirt.Domain) {
Expand Down
31 changes: 31 additions & 0 deletions internal/network/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Package network provides HTTP client functionality.
package network

import (
"fmt"
"net/http"

log "github.com/sirupsen/logrus"
)

// GetResponse performs an HTTP GET request and returns the response with proper error handling
func GetResponse(url string) (*http.Response, error) {
resp, err := http.Get(url) //#nosec G107
if err != nil {
return nil, err
}
if resp == nil {
return nil, fmt.Errorf("nil HTTP response from %s", url)
}

if resp.StatusCode != http.StatusOK {
err = resp.Body.Close()
if err != nil {
log.Warnf("failed to close response body: %v", err)
}

return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
}

return resp, nil
}

0 comments on commit 38d31ed

Please sign in to comment.