cmd: continuing linter fixes
This commit is contained in:
@@ -242,6 +242,10 @@ linters:
|
||||
check-type-assertions: true
|
||||
exclude-functions:
|
||||
- (*git.wntrmute.dev/kyle/goutils/sbuf.Buffer).Write
|
||||
- git.wntrmute.dev/kyle/goutils/lib.Warn
|
||||
- git.wntrmute.dev/kyle/goutils/lib.Warnx
|
||||
- git.wntrmute.dev/kyle/goutils/lib.Err
|
||||
- git.wntrmute.dev/kyle/goutils/lib.Errx
|
||||
|
||||
exhaustive:
|
||||
# Program elements to check for exhaustiveness.
|
||||
@@ -333,6 +337,12 @@ linters:
|
||||
# https://github.com/godoc-lint/godoc-lint?tab=readme-ov-file#no-unused-link
|
||||
- no-unused-link
|
||||
|
||||
gosec:
|
||||
excludes:
|
||||
- G104 # handled by errcheck
|
||||
- G301
|
||||
- G306
|
||||
|
||||
govet:
|
||||
# Enable all analyzers.
|
||||
# Default: false
|
||||
@@ -368,6 +378,12 @@ linters:
|
||||
- os.WriteFile
|
||||
- prometheus.ExponentialBuckets.*
|
||||
- prometheus.LinearBuckets
|
||||
ignored-numbers:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 8
|
||||
|
||||
nakedret:
|
||||
# Make an issue if func has more lines of code than this setting, and it has naked returns.
|
||||
@@ -436,6 +452,8 @@ linters:
|
||||
# Omit embedded fields from selector expression.
|
||||
# https://staticcheck.dev/docs/checks/#QF1008
|
||||
- -QF1008
|
||||
# We often explicitly enable old/deprecated ciphers for research.
|
||||
- -SA1019
|
||||
|
||||
usetesting:
|
||||
# Enable/disable `os.TempDir()` detections.
|
||||
|
||||
@@ -458,8 +458,6 @@ func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) {
|
||||
}
|
||||
if procType, ok := keyDER.Headers["Proc-Type"]; ok && strings.Contains(procType, "ENCRYPTED") {
|
||||
if password != nil {
|
||||
// nolintlint requires rationale:
|
||||
//nolint:staticcheck // legacy RFC1423 PEM encryption supported for backward compatibility when caller supplies a password
|
||||
return x509.DecryptPEMBlock(keyDER, password)
|
||||
}
|
||||
return nil, certerr.DecodeError(certerr.ErrorSourcePrivateKey, certerr.ErrEncryptedPrivateKey)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
@@ -22,22 +23,26 @@ func main() {
|
||||
server += ":443"
|
||||
}
|
||||
|
||||
var chain string
|
||||
|
||||
conn, err := tls.Dial("tcp", server, nil)
|
||||
d := &tls.Dialer{Config: &tls.Config{}} // #nosec G402
|
||||
nc, err := d.DialContext(context.Background(), "tcp", server)
|
||||
die.If(err)
|
||||
conn, ok := nc.(*tls.Conn)
|
||||
if !ok {
|
||||
die.With("invalid TLS connection (not a *tls.Conn)")
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
details := conn.ConnectionState()
|
||||
var chainSb30 strings.Builder
|
||||
var chain strings.Builder
|
||||
for _, cert := range details.PeerCertificates {
|
||||
p := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: cert.Raw,
|
||||
}
|
||||
chainSb30.WriteString(string(pem.EncodeToMemory(&p)))
|
||||
chain.Write(pem.EncodeToMemory(&p))
|
||||
}
|
||||
chain += chainSb30.String()
|
||||
|
||||
fmt.Fprintln(os.Stdout, chain)
|
||||
fmt.Fprintln(os.Stdout, chain.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
@@ -246,18 +247,34 @@ func displayAllCerts(in []byte, leafOnly bool) {
|
||||
|
||||
func displayAllCertsWeb(uri string, leafOnly bool) {
|
||||
ci := getConnInfo(uri)
|
||||
conn, err := tls.Dial("tcp", ci.Addr, permissiveConfig())
|
||||
d := &tls.Dialer{Config: permissiveConfig()}
|
||||
nc, err := d.DialContext(context.Background(), "tcp", ci.Addr)
|
||||
if err != nil {
|
||||
_, _ = lib.Warn(err, "couldn't connect to %s", ci.Addr)
|
||||
return
|
||||
}
|
||||
|
||||
conn, ok := nc.(*tls.Conn)
|
||||
if !ok {
|
||||
_, _ = lib.Warnx("invalid TLS connection (not a *tls.Conn)")
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
state := conn.ConnectionState()
|
||||
conn.Close()
|
||||
if err = conn.Close(); err != nil {
|
||||
_, _ = lib.Warn(err, "couldn't close TLS connection")
|
||||
}
|
||||
|
||||
conn, err = tls.Dial("tcp", ci.Addr, verifyConfig(ci.Host))
|
||||
d = &tls.Dialer{Config: verifyConfig(ci.Host)}
|
||||
nc, err = d.DialContext(context.Background(), "tcp", ci.Addr)
|
||||
if err == nil {
|
||||
conn, ok = nc.(*tls.Conn)
|
||||
if !ok {
|
||||
_, _ = lib.Warnx("invalid TLS connection (not a *tls.Conn)")
|
||||
return
|
||||
}
|
||||
|
||||
err = conn.VerifyHostname(ci.Host)
|
||||
if err == nil {
|
||||
state = conn.ConnectionState()
|
||||
@@ -293,14 +310,19 @@ func displayAllCertsWeb(uri string, leafOnly bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var leafOnly bool
|
||||
flag.BoolVar(&showHash, "d", false, "show hashes of raw DER contents")
|
||||
flag.StringVar(&dateFormat, "s", oneTrueDateFormat, "date `format` in Go time format")
|
||||
flag.BoolVar(&leafOnly, "l", false, "only show the leaf certificate")
|
||||
flag.Parse()
|
||||
func shouldReadStdin(argc int, argv []string) bool {
|
||||
if argc == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if flag.NArg() == 0 || (flag.NArg() == 1 && flag.Arg(0) == "-") {
|
||||
if argc == 1 && argv[0] == "-" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func readStdin(leafOnly bool) {
|
||||
certs, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
_, _ = lib.Warn(err, "couldn't read certificates from standard input")
|
||||
@@ -312,7 +334,20 @@ func main() {
|
||||
certs = bytes.ReplaceAll(certs, []byte(`\n`), []byte{0xa})
|
||||
certs = bytes.Trim(certs, `"`)
|
||||
displayAllCerts(certs, leafOnly)
|
||||
} else {
|
||||
}
|
||||
|
||||
func main() {
|
||||
var leafOnly bool
|
||||
flag.BoolVar(&showHash, "d", false, "show hashes of raw DER contents")
|
||||
flag.StringVar(&dateFormat, "s", oneTrueDateFormat, "date `format` in Go time format")
|
||||
flag.BoolVar(&leafOnly, "l", false, "only show the leaf certificate")
|
||||
flag.Parse()
|
||||
|
||||
if shouldReadStdin(flag.NArg(), flag.Args()) {
|
||||
readStdin(leafOnly)
|
||||
return
|
||||
}
|
||||
|
||||
for _, filename := range flag.Args() {
|
||||
fmt.Fprintf(os.Stdout, "--%s ---%s", filename, "\n")
|
||||
if strings.HasPrefix(filename, "https://") {
|
||||
@@ -328,4 +363,3 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ import (
|
||||
// following two lifted from CFSSL, (replace-regexp "\(.+\): \(.+\),"
|
||||
// "\2: \1,")
|
||||
|
||||
const (
|
||||
sSHA256 = "SHA256"
|
||||
sSHA512 = "SHA512"
|
||||
)
|
||||
|
||||
var keyUsage = map[x509.KeyUsage]string{
|
||||
x509.KeyUsageDigitalSignature: "digital signature",
|
||||
x509.KeyUsageContentCommitment: "content committment",
|
||||
@@ -70,19 +75,19 @@ func sigAlgoHash(a x509.SignatureAlgorithm) string {
|
||||
case x509.SHA1WithRSA, x509.ECDSAWithSHA1, x509.DSAWithSHA1:
|
||||
return "SHA1"
|
||||
case x509.SHA256WithRSA, x509.ECDSAWithSHA256, x509.DSAWithSHA256:
|
||||
return "SHA256"
|
||||
return sSHA256
|
||||
case x509.SHA256WithRSAPSS:
|
||||
return "SHA256"
|
||||
return sSHA256
|
||||
case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
|
||||
return "SHA384"
|
||||
case x509.SHA384WithRSAPSS:
|
||||
return "SHA384"
|
||||
case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
|
||||
return "SHA512"
|
||||
return sSHA512
|
||||
case x509.SHA512WithRSAPSS:
|
||||
return "SHA512"
|
||||
return sSHA512
|
||||
case x509.PureEd25519:
|
||||
return "SHA512"
|
||||
return sSHA512
|
||||
case x509.UnknownSignatureAlgorithm:
|
||||
return "unknown hash algorithm"
|
||||
default:
|
||||
@@ -144,14 +149,14 @@ func dumpHex(in []byte) string {
|
||||
func permissiveConfig() *tls.Config {
|
||||
return &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
} // #nosec G402
|
||||
}
|
||||
|
||||
// verifyConfig returns a config that will verify the connection.
|
||||
func verifyConfig(hostname string) *tls.Config {
|
||||
return &tls.Config{
|
||||
ServerName: hostname,
|
||||
}
|
||||
} // #nosec G402
|
||||
}
|
||||
|
||||
type connInfo struct {
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -57,7 +58,7 @@ var modes = ssh.TerminalModes{
|
||||
}
|
||||
|
||||
func sshAgent() ssh.AuthMethod {
|
||||
a, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||
a, err := (&net.Dialer{}).DialContext(context.Background(), "unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||
if err == nil {
|
||||
return ssh.PublicKeysCallback(agent.NewClient(a).Signers)
|
||||
}
|
||||
@@ -116,7 +117,7 @@ func exec(wg *sync.WaitGroup, user, host string, commands []string) {
|
||||
}
|
||||
shutdown = append(shutdown, session.Close)
|
||||
|
||||
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
|
||||
if err = session.RequestPty("xterm", 80, 40, modes); err != nil {
|
||||
session.Close()
|
||||
logError(host, err, "request for pty failed")
|
||||
return
|
||||
|
||||
@@ -26,7 +26,7 @@ func setupFile(hdr *tar.Header, file *os.File) error {
|
||||
if verbose {
|
||||
fmt.Printf("\tchmod %0#o\n", hdr.Mode)
|
||||
}
|
||||
err := file.Chmod(os.FileMode(hdr.Mode))
|
||||
err := file.Chmod(os.FileMode(hdr.Mode & 0xFFFFFFFF)) // #nosec G115
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -55,7 +55,9 @@ func processFile(tfr *tar.Reader, hdr *tar.Header, top string) error {
|
||||
if verbose {
|
||||
fmt.Println(hdr.Name)
|
||||
}
|
||||
|
||||
filePath := filepath.Clean(filepath.Join(top, hdr.Name))
|
||||
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeReg:
|
||||
file, err := os.Create(filePath)
|
||||
@@ -109,7 +111,7 @@ func processFile(tfr *tar.Reader, hdr *tar.Header, top string) error {
|
||||
return err
|
||||
}
|
||||
case tar.TypeDir:
|
||||
err := os.MkdirAll(filePath, os.FileMode(hdr.Mode))
|
||||
err := os.MkdirAll(filePath, os.FileMode(hdr.Mode&0xFFFFFFFF)) // #nosec G115
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -261,8 +263,9 @@ func main() {
|
||||
die.If(err)
|
||||
|
||||
tfr := tar.NewReader(r)
|
||||
var hdr *tar.Header
|
||||
for {
|
||||
hdr, err := tfr.Next()
|
||||
hdr, err = tfr.Next()
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func main() {
|
||||
Bytes: out,
|
||||
}
|
||||
|
||||
err = os.WriteFile(fileName+".pub", pem.EncodeToMemory(p), 0o644)
|
||||
err = os.WriteFile(fileName+".pub", pem.EncodeToMemory(p), 0o644) // #nosec G306
|
||||
die.If(err)
|
||||
fmt.Fprintf(os.Stdout, "[+] wrote %s.\n", fileName+".pub")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -152,7 +153,7 @@ func rsync(syncDir, target, excludeFile string, verboseRsync bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command(path, args...)
|
||||
cmd := exec.CommandContext(context.Background(), path, args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
@@ -218,7 +219,7 @@ func main() {
|
||||
if excludeFile != "" {
|
||||
defer func() {
|
||||
log.Infof("removing exclude file %s", excludeFile)
|
||||
if err := os.Remove(excludeFile); err != nil {
|
||||
if rmErr := os.Remove(excludeFile); rmErr != nil {
|
||||
log.Warningf("failed to remove temp file %s", excludeFile)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -30,7 +30,7 @@ func openImage(imageFile string) (*os.File, []byte, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, err := f.Seek(0, 0); err != nil {
|
||||
if _, err = f.Seek(0, 0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -103,12 +103,12 @@ func main() {
|
||||
die.If(err)
|
||||
|
||||
if !bytes.Equal(deviceHash, hash) {
|
||||
fmt.Fprintln(os.Stderr, "Hash mismatch:")
|
||||
fmt.Fprintf(os.Stderr, "\t%s: %s\n", imageFile, hash)
|
||||
fmt.Fprintf(os.Stderr, "\t%s: %s\n", devicePath, deviceHash)
|
||||
os.Exit(1)
|
||||
buf := &bytes.Buffer{}
|
||||
fmt.Fprintln(buf, "Hash mismatch:")
|
||||
fmt.Fprintf(buf, "\t%s: %s\n", imageFile, hash)
|
||||
fmt.Fprintf(buf, "\t%s: %s\n", devicePath, deviceHash)
|
||||
die.With(buf.String())
|
||||
}
|
||||
|
||||
debug.Println("OK")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -37,10 +38,11 @@ func dumpFile(path string, indentLevel int) error {
|
||||
defer file.Close()
|
||||
|
||||
fmt.Printf("%svar buffer = []byte{\n", indent.String())
|
||||
var n int
|
||||
for {
|
||||
buf := make([]byte, 8)
|
||||
n, err := file.Read(buf)
|
||||
if err == io.EOF {
|
||||
n, err = file.Read(buf)
|
||||
if errors.Is(err, io.EOF) {
|
||||
if n > 0 {
|
||||
fmt.Printf("%s", indent.String())
|
||||
printBytes(buf[:n])
|
||||
|
||||
@@ -26,7 +26,7 @@ func main() {
|
||||
path = flag.Arg(0)
|
||||
}
|
||||
|
||||
fillByte := uint8(*fill)
|
||||
fillByte := uint8(*fill & 0xff) // #nosec G115 clearing out of bounds bits
|
||||
|
||||
buf := make([]byte, pageSize)
|
||||
for i := range pageSize {
|
||||
|
||||
@@ -72,9 +72,7 @@ func main() {
|
||||
|
||||
if end < start {
|
||||
fmt.Fprintln(os.Stderr, "[!] end < start, swapping values")
|
||||
tmp := end
|
||||
end = start
|
||||
start = tmp
|
||||
start, end = end, start
|
||||
}
|
||||
|
||||
var fmtStr string
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -8,7 +9,8 @@ import (
|
||||
)
|
||||
|
||||
func lookupHost(host string) error {
|
||||
cname, err := net.LookupCNAME(host)
|
||||
r := &net.Resolver{}
|
||||
cname, err := r.LookupCNAME(context.Background(), host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -18,7 +20,7 @@ func lookupHost(host string) error {
|
||||
host = cname
|
||||
}
|
||||
|
||||
addrs, err := net.LookupHost(host)
|
||||
addrs, err := r.LookupHost(context.Background(), host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ based on whether the source filename ends in ".gz".
|
||||
Flags:
|
||||
-l level Compression level (0-9). Only meaninful when
|
||||
compressing a file.
|
||||
-u Do not restrict the size during decompression. As
|
||||
a safeguard against gzip bombs, the maximum size
|
||||
allowed is 32 * the compressed file size.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -40,26 +40,42 @@ func compress(path, target string, level int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func uncompress(path, target string) error {
|
||||
func uncompress(path, target string, unrestrict bool) error {
|
||||
sourceFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening file for read: %w", err)
|
||||
}
|
||||
defer sourceFile.Close()
|
||||
|
||||
fi, err := sourceFile.Stat()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading file stats: %w", err)
|
||||
}
|
||||
|
||||
maxDecompressionSize := fi.Size() * 32
|
||||
|
||||
gzipUncompressor, err := gzip.NewReader(sourceFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading gzip headers: %w", err)
|
||||
}
|
||||
defer gzipUncompressor.Close()
|
||||
|
||||
var reader io.Reader = &io.LimitedReader{
|
||||
R: gzipUncompressor,
|
||||
N: maxDecompressionSize,
|
||||
}
|
||||
|
||||
if unrestrict {
|
||||
reader = gzipUncompressor
|
||||
}
|
||||
|
||||
destFile, err := os.Create(target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening file for write: %w", err)
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
_, err = io.Copy(destFile, gzipUncompressor)
|
||||
_, err = io.Copy(destFile, reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("uncompressing file: %w", err)
|
||||
}
|
||||
@@ -87,8 +103,8 @@ func isDir(path string) bool {
|
||||
file, err := os.Open(path)
|
||||
if err == nil {
|
||||
defer file.Close()
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
stat, err2 := file.Stat()
|
||||
if err2 != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -132,8 +148,11 @@ func main() {
|
||||
var level int
|
||||
var path string
|
||||
var target = "."
|
||||
var err error
|
||||
var unrestrict bool
|
||||
|
||||
flag.IntVar(&level, "l", flate.DefaultCompression, "compression level")
|
||||
flag.BoolVar(&unrestrict, "u", false, "do not restrict decompression")
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() < 1 || flag.NArg() > 2 {
|
||||
@@ -147,20 +166,22 @@ func main() {
|
||||
}
|
||||
|
||||
if strings.HasSuffix(path, gzipExt) {
|
||||
target, err := pathForUncompressing(path, target)
|
||||
target, err = pathForUncompressing(path, target)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = uncompress(path, target)
|
||||
err = uncompress(path, target, unrestrict)
|
||||
if err != nil {
|
||||
os.Remove(target)
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
target, err := pathForCompressing(path, target)
|
||||
return
|
||||
}
|
||||
|
||||
target, err = pathForCompressing(path, target)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(1)
|
||||
@@ -173,4 +194,3 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func main() {
|
||||
if p == nil {
|
||||
lib.Errx(lib.ExitFailure, "%s isn't a PEM-encoded file", flag.Arg(0))
|
||||
}
|
||||
if _, err := os.Stdout.Write(p.Bytes); err != nil {
|
||||
if _, err = os.Stdout.Write(p.Bytes); err != nil {
|
||||
lib.Err(lib.ExitFailure, err, "writing body")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ func main() {
|
||||
break
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(p.Bytes)
|
||||
var cert *x509.Certificate
|
||||
cert, err = x509.ParseCertificate(p.Bytes)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[!] %s: %v\n", fileName, err)
|
||||
break
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -76,7 +77,13 @@ func main() {
|
||||
continue
|
||||
}
|
||||
|
||||
resp, err := http.Get(remote)
|
||||
req, reqErr := http.NewRequestWithContext(context.Background(), http.MethodGet, remote, nil)
|
||||
if reqErr != nil {
|
||||
_, _ = lib.Warn(reqErr, "building request for %s", remote)
|
||||
continue
|
||||
}
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
_, _ = lib.Warn(err, "fetching %s", remote)
|
||||
continue
|
||||
|
||||
@@ -18,7 +18,7 @@ func rollDie(count, sides int) []int {
|
||||
var rolls []int
|
||||
|
||||
for range count {
|
||||
roll := rand.IntN(sides) + 1
|
||||
roll := rand.IntN(sides) + 1 // #nosec G404
|
||||
sum += roll
|
||||
rolls = append(rolls, roll)
|
||||
}
|
||||
|
||||
@@ -75,13 +75,14 @@ func walkFile(path string, _ os.FileInfo, err error) error {
|
||||
|
||||
for _, importSpec := range f.Imports {
|
||||
importPath := strings.Trim(importSpec.Path.Value, `"`)
|
||||
if stdLibRegexp.MatchString(importPath) {
|
||||
switch {
|
||||
case stdLibRegexp.MatchString(importPath):
|
||||
debug.Println("standard lib:", importPath)
|
||||
continue
|
||||
} else if strings.HasPrefix(importPath, project) {
|
||||
case strings.HasPrefix(importPath, project):
|
||||
debug.Println("internal import:", importPath)
|
||||
continue
|
||||
} else if strings.HasPrefix(importPath, "golang.org/") {
|
||||
case strings.HasPrefix(importPath, "golang.org/"):
|
||||
debug.Println("extended lib:", importPath)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/sha1" // #nosec G505
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
@@ -20,6 +20,11 @@ import (
|
||||
"git.wntrmute.dev/kyle/goutils/lib"
|
||||
)
|
||||
|
||||
const (
|
||||
keyTypeRSA = "RSA"
|
||||
keyTypeECDSA = "ECDSA"
|
||||
)
|
||||
|
||||
func usage(w io.Writer) {
|
||||
fmt.Fprintf(w, `ski: print subject key info for PEM-encoded files
|
||||
|
||||
@@ -94,10 +99,10 @@ func parseKey(data []byte) ([]byte, string) {
|
||||
switch p := privInterface.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
priv = p
|
||||
kt = "RSA"
|
||||
kt = keyTypeRSA
|
||||
case *ecdsa.PrivateKey:
|
||||
priv = p
|
||||
kt = "ECDSA"
|
||||
kt = keyTypeECDSA
|
||||
default:
|
||||
die.With("unknown private key type %T", privInterface)
|
||||
}
|
||||
@@ -116,9 +121,9 @@ func parseCertificate(data []byte) ([]byte, string) {
|
||||
var kt string
|
||||
switch pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
kt = "RSA"
|
||||
kt = keyTypeRSA
|
||||
case *ecdsa.PublicKey:
|
||||
kt = "ECDSA"
|
||||
kt = keyTypeECDSA
|
||||
default:
|
||||
die.With("unknown public key type %T", pub)
|
||||
}
|
||||
@@ -136,9 +141,9 @@ func parseCSR(data []byte) ([]byte, string) {
|
||||
var kt string
|
||||
switch pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
kt = "RSA"
|
||||
kt = keyTypeRSA
|
||||
case *ecdsa.PublicKey:
|
||||
kt = "ECDSA"
|
||||
kt = keyTypeECDSA
|
||||
default:
|
||||
die.With("unknown public key type %T", pub)
|
||||
}
|
||||
@@ -186,7 +191,7 @@ func main() {
|
||||
continue
|
||||
}
|
||||
|
||||
pubHash := sha1.Sum(subPKI.SubjectPublicKey.Bytes)
|
||||
pubHash := sha1.Sum(subPKI.SubjectPublicKey.Bytes) // #nosec G401 this is the standard
|
||||
pubHashString := dumpHex(pubHash[:])
|
||||
if ski == "" {
|
||||
ski = pubHashString
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"io"
|
||||
"net"
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func proxy(conn net.Conn, inside string) error {
|
||||
proxyConn, err := net.Dial("tcp", inside)
|
||||
proxyConn, err := (&net.Dialer{}).DialContext(context.Background(), "tcp", inside)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -31,18 +32,20 @@ func main() {
|
||||
flag.StringVar(&inside, "p", "4000", "inside port")
|
||||
flag.Parse()
|
||||
|
||||
l, err := net.Listen("tcp", "0.0.0.0:"+outside)
|
||||
lc := &net.ListenConfig{}
|
||||
l, err := lc.Listen(context.Background(), "tcp", "0.0.0.0:"+outside)
|
||||
die.If(err)
|
||||
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
var conn net.Conn
|
||||
conn, err = l.Accept()
|
||||
if err != nil {
|
||||
_, _ = lib.Warn(err, "accept failed")
|
||||
continue
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := proxy(conn, "127.0.0.1:"+inside); err != nil {
|
||||
if err = proxy(conn, "127.0.0.1:"+inside); err != nil {
|
||||
_, _ = lib.Warn(err, "proxy error")
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := &tls.Config{}
|
||||
cfg := &tls.Config{} // #nosec G402
|
||||
|
||||
var sysRoot, listenAddr, certFile, keyFile string
|
||||
var verify bool
|
||||
@@ -46,7 +47,8 @@ func main() {
|
||||
}
|
||||
cfg.Certificates = append(cfg.Certificates, cert)
|
||||
if sysRoot != "" {
|
||||
pemList, err := os.ReadFile(sysRoot)
|
||||
var pemList []byte
|
||||
pemList, err = os.ReadFile(sysRoot)
|
||||
die.If(err)
|
||||
|
||||
roots := x509.NewCertPool()
|
||||
@@ -58,14 +60,16 @@ func main() {
|
||||
cfg.RootCAs = roots
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", listenAddr)
|
||||
lc := &net.ListenConfig{}
|
||||
l, err := lc.Listen(context.Background(), "tcp", listenAddr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
var conn net.Conn
|
||||
conn, err = l.Accept()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
continue
|
||||
@@ -79,7 +83,7 @@ func handleConn(conn net.Conn, cfg *tls.Config) {
|
||||
defer conn.Close()
|
||||
raddr := conn.RemoteAddr()
|
||||
tconn := tls.Server(conn, cfg)
|
||||
if err := tconn.Handshake(); err != nil {
|
||||
if err := tconn.HandshakeContext(context.Background()); err != nil {
|
||||
fmt.Printf("[+] %v: failed to complete handshake: %v\n", raddr, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
@@ -13,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var cfg = &tls.Config{}
|
||||
var cfg = &tls.Config{} // #nosec G402
|
||||
|
||||
var sysRoot, serverName string
|
||||
flag.StringVar(&sysRoot, "ca", "", "provide an alternate CA bundle")
|
||||
@@ -43,10 +44,13 @@ func main() {
|
||||
if err != nil {
|
||||
site += ":443"
|
||||
}
|
||||
conn, err := tls.Dial("tcp", site, cfg)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
d := &tls.Dialer{Config: cfg}
|
||||
nc, err := d.DialContext(context.Background(), "tcp", site)
|
||||
die.If(err)
|
||||
|
||||
conn, ok := nc.(*tls.Conn)
|
||||
if !ok {
|
||||
die.With("invalid TLS connection (not a *tls.Conn)")
|
||||
}
|
||||
|
||||
cs := conn.ConnectionState()
|
||||
@@ -62,6 +66,7 @@ func main() {
|
||||
|
||||
err = os.WriteFile(site+".pem", chain, 0644)
|
||||
die.If(err)
|
||||
|
||||
fmt.Printf("[+] wrote %s.pem.\n", site)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.wntrmute.dev/kyle/goutils/certlib/hosts"
|
||||
"git.wntrmute.dev/kyle/goutils/die"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -13,16 +17,23 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
hostPort := os.Args[1]
|
||||
conn, err := tls.Dial("tcp", hostPort, &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
hostPort, err := hosts.ParseHost(os.Args[1])
|
||||
die.If(err)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to connect to the TLS server: %v\n", err)
|
||||
os.Exit(1)
|
||||
d := &tls.Dialer{Config: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}} // #nosec G402
|
||||
|
||||
nc, err := d.DialContext(context.Background(), "tcp", hostPort.String())
|
||||
die.If(err)
|
||||
|
||||
conn, ok := nc.(*tls.Conn)
|
||||
if !ok {
|
||||
die.With("invalid TLS connection (not a *tls.Conn)")
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
state := conn.ConnectionState()
|
||||
printConnectionDetails(state)
|
||||
}
|
||||
|
||||
@@ -253,15 +253,16 @@ func main() {
|
||||
showTime(time.Now())
|
||||
os.Exit(0)
|
||||
case 1:
|
||||
if flag.Arg(0) == "-" {
|
||||
switch {
|
||||
case flag.Arg(0) == "-":
|
||||
s := bufio.NewScanner(os.Stdin)
|
||||
|
||||
for s.Scan() {
|
||||
times = append(times, s.Text())
|
||||
}
|
||||
} else if flag.Arg(0) == "help" {
|
||||
case flag.Arg(0) == "help":
|
||||
usageExamples()
|
||||
} else {
|
||||
default:
|
||||
times = flag.Args()
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -11,9 +11,8 @@ import (
|
||||
|
||||
type empty struct{}
|
||||
|
||||
func errorf(format string, args ...any) {
|
||||
format += "\n"
|
||||
fmt.Fprintf(os.Stderr, format, args...)
|
||||
func errorf(path string, err error) {
|
||||
fmt.Fprintf(os.Stderr, "%s FAILED: %s\n", path, err)
|
||||
}
|
||||
|
||||
func usage(w io.Writer) {
|
||||
@@ -45,14 +44,14 @@ func main() {
|
||||
path := "stdin"
|
||||
in, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
errorf("%s FAILED: %s", path, err)
|
||||
errorf(path, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var e empty
|
||||
err = yaml.Unmarshal(in, &e)
|
||||
if err != nil {
|
||||
errorf("%s FAILED: %s", path, err)
|
||||
errorf(path, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -66,14 +65,14 @@ func main() {
|
||||
for _, path := range flag.Args() {
|
||||
in, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
errorf("%s FAILED: %s", path, err)
|
||||
errorf(path, err)
|
||||
continue
|
||||
}
|
||||
|
||||
var e empty
|
||||
err = yaml.Unmarshal(in, &e)
|
||||
if err != nil {
|
||||
errorf("%s FAILED: %s", path, err)
|
||||
errorf(path, err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -14,16 +14,16 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"git.wntrmute.dev/kyle/goutils/lib"
|
||||
)
|
||||
|
||||
const defaultDirectory = ".git/objects"
|
||||
|
||||
func errorf(format string, a ...any) {
|
||||
fmt.Fprintf(os.Stderr, format, a...)
|
||||
if format[len(format)-1] != '\n' {
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
}
|
||||
}
|
||||
// maxDecompressedSize limits how many bytes we will decompress from a zlib
|
||||
// stream to mitigate decompression bombs (gosec G110).
|
||||
// Increase this if you expect larger objects.
|
||||
const maxDecompressedSize int64 = 64 << 30 // 64 GiB
|
||||
|
||||
func isDir(path string) bool {
|
||||
fi, err := os.Stat(path)
|
||||
@@ -48,17 +48,21 @@ func loadFile(path string) ([]byte, error) {
|
||||
}
|
||||
defer zread.Close()
|
||||
|
||||
_, err = io.Copy(buf, zread)
|
||||
if err != nil {
|
||||
// Protect against decompression bombs by limiting how much we read.
|
||||
lr := io.LimitReader(zread, maxDecompressedSize+1)
|
||||
if _, err = buf.ReadFrom(lr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if int64(buf.Len()) > maxDecompressedSize {
|
||||
return nil, fmt.Errorf("decompressed size exceeds limit (%d bytes)", maxDecompressedSize)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func showFile(path string) {
|
||||
fileData, err := loadFile(path)
|
||||
if err != nil {
|
||||
errorf("%v", err)
|
||||
lib.Warn(err, "failed to load %s", path)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,37 +72,69 @@ func showFile(path string) {
|
||||
func searchFile(path string, search *regexp.Regexp) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
errorf("%v", err)
|
||||
lib.Warn(err, "failed to open %s", path)
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
zread, err := zlib.NewReader(file)
|
||||
if err != nil {
|
||||
errorf("%v", err)
|
||||
lib.Warn(err, "failed to decompress %s", path)
|
||||
return err
|
||||
}
|
||||
defer zread.Close()
|
||||
|
||||
zbuf := bufio.NewReader(zread)
|
||||
if search.MatchReader(zbuf) {
|
||||
// Limit how much we scan to avoid DoS via huge decompression.
|
||||
lr := io.LimitReader(zread, maxDecompressedSize+1)
|
||||
zbuf := bufio.NewReader(lr)
|
||||
if !search.MatchReader(zbuf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
fileData, err := loadFile(path)
|
||||
if err != nil {
|
||||
errorf("%v", err)
|
||||
lib.Warn(err, "failed to load %s", path)
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s:\n%s\n", path, fileData)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildWalker(searchExpr *regexp.Regexp) filepath.WalkFunc {
|
||||
return func(path string, info os.FileInfo, _ error) error {
|
||||
if info.Mode().IsRegular() {
|
||||
return searchFile(path, searchExpr)
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
return nil
|
||||
}
|
||||
return searchFile(path, searchExpr)
|
||||
}
|
||||
}
|
||||
|
||||
// runSearch compiles the search expression and processes the provided paths.
|
||||
// It returns an error for fatal conditions; per-file errors are logged.
|
||||
func runSearch(expr string) error {
|
||||
search, err := regexp.Compile(expr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid regexp: %w", err)
|
||||
}
|
||||
|
||||
pathList := flag.Args()
|
||||
if len(pathList) == 0 {
|
||||
pathList = []string{defaultDirectory}
|
||||
}
|
||||
|
||||
for _, path := range pathList {
|
||||
if isDir(path) {
|
||||
if err2 := filepath.Walk(path, buildWalker(search)); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err2 := searchFile(path, search); err2 != nil {
|
||||
// Non-fatal: keep going, but report it.
|
||||
lib.Warn(err2, "non-fatal error while searching files")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -109,29 +145,10 @@ func main() {
|
||||
for _, path := range flag.Args() {
|
||||
showFile(path)
|
||||
}
|
||||
} else {
|
||||
search, err := regexp.Compile(*flSearch)
|
||||
if err != nil {
|
||||
errorf("Bad regexp: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
pathList := flag.Args()
|
||||
if len(pathList) == 0 {
|
||||
pathList = []string{defaultDirectory}
|
||||
}
|
||||
|
||||
for _, path := range pathList {
|
||||
if isDir(path) {
|
||||
if err := filepath.Walk(path, buildWalker(search)); err != nil {
|
||||
errorf("%v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := searchFile(path, search); err != nil {
|
||||
errorf("%v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := runSearch(*flSearch); err != nil {
|
||||
lib.Err(lib.ExitFailure, err, "failed to run search")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user