initial commit [141.14.140.180,mike]

This commit is contained in:
2026-08-14 09:09:59 +02:00
commit 6a991a25a6
19 changed files with 6691 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
package main
import (
"crypto/x509"
"encoding/pem"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
// resetTransport clears the memoised client so a test can change the
// verification mode.
func resetTransport(t *testing.T, mode caMode) {
t.Helper()
client, clientMode, caCurrent = nil, -1, mode
opt.timeout = 10
t.Cleanup(func() {
client, clientMode, caCurrent = nil, -1, caSystem
opt.cacert, opt.insecure = "", false
})
}
// tlsServer returns a server with a certificate no public CA has signed, plus
// that certificate as PEM - the stand-in for a root the system does not know.
func tlsServer(t *testing.T) (*httptest.Server, []byte) {
t.Helper()
srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, `{"tag_name":"v1.2.3"}`)
}))
t.Cleanup(srv.Close)
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: srv.Certificate().Raw})
return srv, certPEM
}
func TestSystemStoreRejectsUnknownIssuer(t *testing.T) {
srv, _ := tlsServer(t)
resetTransport(t, caSystem)
// Nothing to fall back to: the bundled list does not know it either.
old := caBundle
caBundle = nil
t.Cleanup(func() { caBundle = old })
_, err := httpGet(srv.URL, nil, nil)
if err == nil {
t.Fatal("expected the system store to reject this certificate")
}
if !isUnknownAuthority(err) {
t.Errorf("not recognised as an unknown authority: %v", err)
}
if !isPermanent(err) {
t.Error("a rejected certificate must not be retried")
}
if !strings.Contains(err.Error(), "--cacert") {
t.Errorf("error should point at the way out, got: %v", err)
}
}
// The failure from the old box: the system store predates the issuer's root.
// upd must notice, switch to its own list and carry on.
func TestFallbackToBundledCAs(t *testing.T) {
srv, certPEM := tlsServer(t)
resetTransport(t, caSystem)
old := caBundle
caBundle = certPEM
t.Cleanup(func() { caBundle = old })
resp, err := httpGet(srv.URL, nil, nil)
if err != nil {
t.Fatalf("fallback did not happen: %v", err)
}
if resp.status != http.StatusOK {
t.Errorf("status %d", resp.status)
}
if caCurrent != caBundled {
t.Errorf("mode is %v, want the bundled list", caCurrent)
}
}
func TestCacertFile(t *testing.T) {
srv, certPEM := tlsServer(t)
path := filepath.Join(t.TempDir(), "ca.pem")
if err := os.WriteFile(path, certPEM, 0o644); err != nil {
t.Fatal(err)
}
resetTransport(t, caFile)
opt.cacert = path
if _, err := httpGet(srv.URL, nil, nil); err != nil {
t.Fatalf("--cacert did not verify: %v", err)
}
// A bundle without the right root must still fail, and say which file.
resetTransport(t, caFile)
opt.cacert = filepath.Join(t.TempDir(), "empty.pem")
os.WriteFile(opt.cacert, []byte("not a certificate\n"), 0o644)
if _, err := httpGet(srv.URL, nil, nil); err == nil {
t.Error("expected an error for a bundle without certificates")
} else if !strings.Contains(err.Error(), "no certificates found") {
t.Errorf("unexpected error: %v", err)
}
}
func TestInsecureSkipsVerification(t *testing.T) {
srv, _ := tlsServer(t)
resetTransport(t, caNone)
if _, err := httpGet(srv.URL, nil, nil); err != nil {
t.Fatalf("--insecure should have connected anyway: %v", err)
}
}
// The bundled list has to be a usable pool and carry the roots that the old
// machines are missing - that is the whole point of embedding it.
func TestBundledCAList(t *testing.T) {
pool := bundledPool()
if pool == nil {
t.Fatal("the embedded CA bundle does not parse")
}
var subjects []string
for block, rest := pem.Decode(caBundle); block != nil; block, rest = pem.Decode(rest) {
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
t.Fatalf("unparsable certificate in the bundle: %v", err)
}
subjects = append(subjects, cert.Subject.CommonName)
}
if len(subjects) < 100 {
t.Errorf("only %d roots in the bundle, expected the full Mozilla list", len(subjects))
}
for _, want := range []string{"ISRG Root X1", "ISRG Root X2"} {
found := false
for _, s := range subjects {
if s == want {
found = true
}
}
if !found {
t.Errorf("%s missing - Let's Encrypt hosts would still fail", want)
}
}
}
func TestPermanentClassification(t *testing.T) {
// A DNS failure for a name that cannot exist is permanent, a plain
// connection refused is not: the second one is worth another attempt.
resetTransport(t, caSystem)
if _, err := httpGet("https://no-such-host.invalid/x", nil, nil); err == nil {
t.Fatal("expected a DNS failure")
} else if !isPermanent(err) {
t.Errorf("an unresolvable host should not be retried: %v", err)
}
}