Skip to content

Commit 38d31ed

Browse files
committed
Enable nilaway and fix issues
1 parent d99d9ad commit 38d31ed

10 files changed

Lines changed: 150 additions & 75 deletions

File tree

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ test: lint_scripts
2929
errcheck ./...
3030
gocritic check -disable='#experimental,#opinionated' -@ifElseChain.minThreshold 3 ./...
3131
revive -set_exit_status ./...
32+
nilaway ./...
3233
go test -v -cover ./...
3334
gosec -exclude-dir=tests ./...
3435
govulncheck ./...
@@ -42,6 +43,7 @@ setup:
4243
go install github.com/kisielk/errcheck@latest
4344
go install github.com/mgechev/revive@latest
4445
go install github.com/securego/gosec/v2/cmd/gosec@latest
46+
go install go.uber.org/nilaway/cmd/nilaway@latest
4547
go install golang.org/x/vuln/cmd/govulncheck@latest
4648
go install honnef.co/go/tools/cmd/staticcheck@latest
4749
go install mvdan.cc/gofumpt@latest

internal/commands/get.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ func downloadImage(path, url string) error {
5757
log.Errorf("Cannot download image file: %s\n", err)
5858
return err
5959
}
60+
if resp == nil {
61+
return fmt.Errorf("received nil response")
62+
}
6063
defer handling.Close(resp.Body)
6164

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

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

internal/commands/up.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package commands
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"os/exec"
@@ -137,16 +138,19 @@ func provisionClient(_ *UpCommand, image *images.Image, guestIPAddr string) {
137138
}
138139
}
139140

140-
func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, guestIPAddr string, keymap string) {
141+
func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, guestIPAddr string, keymap string) error {
141142
client, err := goph.NewUnknown(image.SSHUser, guestIPAddr, goph.Password(image.SSHPassword))
142143
if err != nil {
143-
log.Fatal(err)
144+
return err
145+
}
146+
if client == nil {
147+
return errors.New("nil goph client")
144148
}
145149

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

@@ -180,9 +184,11 @@ func configureClient(c *UpCommand, _ *rawLibvirt.Domain, image *images.Image, gu
180184
for _, cmd := range cmds {
181185
_, err := client.Run(cmd)
182186
if err != nil {
183-
log.Fatalf("Failed to run command over SSH: %s\n", err)
187+
return fmt.Errorf("failed to run command '%s' over SSH: %s", cmd, err)
184188
}
185189
}
190+
191+
return nil
186192
}
187193

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

256-
configureClient(c, dom, &image, guestIPAddr, s.Keymap)
262+
err = configureClient(c, dom, &image, guestIPAddr, s.Keymap)
263+
if err != nil {
264+
log.Errorf("Cannot configure client: %s\n", err)
265+
return err
266+
}
267+
257268
log.Printf("%s is now ready to use\n", image.DisplayName)
258269

259270
if s.Provision {

internal/host/host.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,9 @@ func GetHostKeyboardLayout() string {
8080

8181
line = strings.TrimSpace(line)
8282
parts := strings.Split(line, " ")
83+
if len(parts) < 2 {
84+
log.Fatalf("Unable to retrieve host's keyboard layout\n")
85+
return ""
86+
}
8387
return parts[len(parts)-1]
8488
}

internal/images/checksums.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package images
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
)
8+
9+
// parseChecksumLine extracts checksum information from a line
10+
func parseChecksumLine(line string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
11+
parts := strings.Fields(line)
12+
if len(parts) < 2 {
13+
return nil, fmt.Errorf("invalid checksum line format: %s", line)
14+
}
15+
16+
checksum := parts[0]
17+
filename := parts[len(parts)-1]
18+
19+
return &DownloadInfo{
20+
Checksum: checksum,
21+
Version: versionRegex.FindString(filename),
22+
Filename: filename,
23+
}, nil
24+
}

internal/images/generic.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ func (vc genericVersionComparer) Lt(a, b string) bool {
2020
aParts := strings.Split(a, ".")
2121
bParts := strings.Split(b, ".")
2222

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

2728
for i := range aParts {

internal/images/images.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ var images = map[string]Image{
7474
ArchiveURL: "https://deb.parrot.sh/parrot/iso/current",
7575
checksumPath: "/signed-hashes.txt",
7676
LocalImageName: "parrot-%s.iso",
77-
VersionRegex: regexp.MustCompile(`\d+\.\d+`),
77+
VersionRegex: regexp.MustCompile(`\d+\.\d+(?:\.\d+)?`),
7878
SSHUser: "user",
7979
SSHPassword: "parrot",
8080
MacAddress: "52:54:00:08:f9:e9",
@@ -130,12 +130,9 @@ func (i *Image) GetLatestPath() string {
130130
}
131131

132132
matches, err := filepath.Glob(path)
133-
if err != nil {
134-
log.Fatalf("Malformed glob pattern: %s\n", err)
135-
}
136-
137-
if matches == nil {
138-
log.Fatalf("Image for %s not found; download with get command\n", i.DisplayName)
133+
if err != nil || len(matches) == 0 {
134+
log.Fatalf("Cannot find image for %s\n", i.DisplayName)
135+
return "" // Won't actually return due to log.Fatal
139136
}
140137

141138
latestPath := matches[0]

internal/images/kali.go

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,49 @@ import (
44
"bufio"
55
"errors"
66
"fmt"
7-
"net/http"
87
"regexp"
98
"runtime"
109
"strings"
1110
"time"
1211

12+
log "github.com/sirupsen/logrus"
1313
rawLibvirt "libvirt.org/libvirt-go"
14+
15+
"github.com/eikendev/hackenv/internal/network"
1416
)
1517

1618
var kaliConfigurationCmds = []string{
1719
"touch ~/.hushlogin",
1820
}
1921

20-
func kaliInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
21-
resp, err := http.Get(url) //#nosec G107
22-
if err != nil {
23-
return nil, err
24-
}
25-
26-
if resp.StatusCode != http.StatusOK {
27-
return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
28-
}
29-
30-
var line string
31-
scanner := bufio.NewScanner(resp.Body)
32-
22+
func findKaliChecksumLine(scanner *bufio.Scanner) (string, error) {
3323
for scanner.Scan() {
34-
line = scanner.Text()
35-
24+
line := scanner.Text()
3625
if strings.Contains(line, "live-"+runtime.GOARCH+".iso") {
37-
break
26+
return strings.TrimSpace(line), nil
3827
}
3928
}
4029

41-
if line == "" {
42-
return nil, errors.New("bad checksum file")
30+
return "", errors.New("checksum not found in file")
31+
}
32+
33+
func kaliInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
34+
resp, err := network.GetResponse(url)
35+
if err != nil {
36+
return nil, fmt.Errorf("failed to get response: %w", err)
4337
}
38+
defer func() {
39+
if err := resp.Body.Close(); err != nil {
40+
log.Warnf("failed to close response body: %v", err)
41+
}
42+
}()
4443

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

49-
return &DownloadInfo{
50-
parts[0],
51-
versionRegex.FindString(filename),
52-
filename,
53-
}, nil
49+
return parseChecksumLine(line, versionRegex)
5450
}
5551

5652
func kaliBootInitializer(dom *rawLibvirt.Domain) {

internal/images/parrot.go

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,62 @@ import (
44
"bufio"
55
"errors"
66
"fmt"
7-
"net/http"
87
"regexp"
98
"runtime"
109
"strings"
1110
"time"
1211

12+
log "github.com/sirupsen/logrus"
1313
rawLibvirt "libvirt.org/libvirt-go"
14-
)
1514

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

22-
if resp.StatusCode != http.StatusOK {
23-
return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
24-
}
18+
func findParrotChecksumLine(scanner *bufio.Scanner) (string, error) {
19+
const (
20+
sha256Section = "sha256"
21+
sha384Section = "sha384"
22+
)
2523

26-
var line string
27-
skipped := false
28-
scanner := bufio.NewScanner(resp.Body)
24+
var inSha256Section bool
2925

3026
for scanner.Scan() {
31-
line = scanner.Text()
27+
line := scanner.Text()
3228

33-
if skipped {
34-
if strings.Contains(line, "Parrot-security") && strings.Contains(line, "_"+runtime.GOARCH+".iso") {
35-
break
36-
}
37-
} else {
38-
if strings.Contains(line, "sha256") {
39-
skipped = true
40-
}
41-
if strings.Contains(line, "sha384") {
42-
skipped = false
43-
}
29+
switch {
30+
case strings.Contains(line, sha256Section):
31+
inSha256Section = true
32+
continue
33+
case strings.Contains(line, sha384Section):
34+
inSha256Section = false
35+
continue
36+
case inSha256Section &&
37+
strings.Contains(line, "Parrot-security") &&
38+
strings.Contains(line, "_"+runtime.GOARCH+".iso"):
39+
return strings.TrimSpace(line), nil
4440
}
4541
}
4642

47-
if line == "" {
48-
return nil, errors.New("bad checksum file")
43+
return "", errors.New("checksum not found in file")
44+
}
45+
46+
func parrotInfoRetriever(url string, versionRegex *regexp.Regexp) (*DownloadInfo, error) {
47+
resp, err := network.GetResponse(url)
48+
if err != nil {
49+
return nil, fmt.Errorf("failed to get response: %w", err)
4950
}
51+
defer func() {
52+
if err := resp.Body.Close(); err != nil {
53+
log.Warnf("failed to close response body: %v", err)
54+
}
55+
}()
5056

51-
line = strings.TrimSpace(line)
52-
parts := strings.Split(line, " ")
53-
filename := parts[len(parts)-1]
57+
line, err := findParrotChecksumLine(bufio.NewScanner(resp.Body))
58+
if err != nil {
59+
return nil, err
60+
}
5461

55-
return &DownloadInfo{
56-
parts[0],
57-
versionRegex.FindString(filename),
58-
filename,
59-
}, nil
62+
return parseChecksumLine(line, versionRegex)
6063
}
6164

6265
func parrotBootInitializer(dom *rawLibvirt.Domain) {

internal/network/http.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Package network provides HTTP client functionality.
2+
package network
3+
4+
import (
5+
"fmt"
6+
"net/http"
7+
8+
log "github.com/sirupsen/logrus"
9+
)
10+
11+
// GetResponse performs an HTTP GET request and returns the response with proper error handling
12+
func GetResponse(url string) (*http.Response, error) {
13+
resp, err := http.Get(url) //#nosec G107
14+
if err != nil {
15+
return nil, err
16+
}
17+
if resp == nil {
18+
return nil, fmt.Errorf("nil HTTP response from %s", url)
19+
}
20+
21+
if resp.StatusCode != http.StatusOK {
22+
err = resp.Body.Close()
23+
if err != nil {
24+
log.Warnf("failed to close response body: %v", err)
25+
}
26+
27+
return nil, fmt.Errorf("bad HTTP status code (%s)", resp.Status)
28+
}
29+
30+
return resp, nil
31+
}

0 commit comments

Comments
 (0)