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