func TestChecking(t *testing.T) { type CAATest struct { Domain string Present bool Valid bool } tests := []CAATest{ // Reserved {"reserved.com", true, false}, // Critical {"critical.com", true, false}, {"nx.critical.com", true, false}, // Good (absent) {"absent.com", false, true}, {"example.co.uk", false, true}, // Good (present) {"present.com", true, true}, {"present.servfail.com", true, true}, // Good (multiple critical, one matching) {"multi-crit-present.com", true, true}, // Bad (unknown critical) {"unknown-critical.com", true, false}, {"unknown-critical2.com", true, false}, // Good (unknown noncritical, no issue/issuewild records) {"unknown-noncritical.com", true, true}, // Good (issue record with unknown parameters) {"present-with-parameter.com", true, true}, // Bad (unsatisfiable issue record) {"unsatisfiable.com", true, false}, } stats, _ := statsd.NewNoopClient() ccs := &caaCheckerServer{&bdns.MockDNSResolver{}, stats} issuerDomain := "letsencrypt.org" ctx := context.Background() for _, caaTest := range tests { result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &caaTest.Domain, IssuerDomain: &issuerDomain}) if err != nil { t.Errorf("CheckCAARecords error for %s: %s", caaTest.Domain, err) } if *result.Present != caaTest.Present { t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Present, caaTest.Present) } if *result.Valid != caaTest.Valid { t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Valid, caaTest.Valid) } } servfail := "servfail.com" servfailPresent := "servfail.present.com" result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfail, IssuerDomain: &issuerDomain}) test.AssertError(t, err, "servfail.com") test.Assert(t, result == nil, "result should be nil") result, err = ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfailPresent, IssuerDomain: &issuerDomain}) test.AssertError(t, err, "servfail.present.com") test.Assert(t, result == nil, "result should be nil") }
func TestAllowNilInIsSafeDomain(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl( &cmd.PortConfig{}, nil, nil, nil, nil, "user agent 1.0", "letsencrypt.org", stats, clock.NewFake(), blog.NewMock()) // Be cool with a nil SafeBrowsing. This will happen in prod when we have // flag mismatch between the VA and RA. domain := "example.com" resp, err := va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain}) if err != nil { t.Errorf("nil SafeBrowsing, unexpected error: %s", err) } if !resp.GetIsSafe() { t.Errorf("nil Safebrowsing, should fail open but failed closed") } }
func TestValidateHTTP(t *testing.T) { chall := core.HTTPChallenge01(accountKey) setChallengeToken(&chall, core.NewToken()) hs := httpSrv(t, chall.Token) port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA defer hs.Close() var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chall}, } va.validate(ctx, authz, 0) test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status) }
// connect makes a 'connection' to the statsd host (doing a DNS lookup), // setting the internal client. If that fails we set the internal client to // noop. If reconEvery is set non 0, periodically re-connects on that duration. func (s *StatsdClient) connect() bool { s.Lock() defer s.Unlock() if s.reconTimer != nil { s.reconTimer.Stop() s.reconTimer = nil } var err error if s.client != nil { // TODO we could be closing a client that is in use by one of // the methods below. This code needs rewriting. s.client.Close() } s.client, err = statsd.New(s.hostPort, s.prefix) if err != nil { s.Error("STATSD Failed to create client (stats will noop): " + err.Error()) s.client, err = statsd.NewNoopClient() } else { s.Finef("STATSD sending to [%s] with prefix [%s] at rate [%f]", s.hostPort, s.prefix, s.rate) } if s.reconEvery != 0 { s.reconTimer = time.AfterFunc(s.reconEvery, func() { s.connect() }) } return true }
func TestSendNags(t *testing.T) { stats, _ := statsd.NewNoopClient(nil) mc := mocks.Mailer{} rs := newFakeRegStore() fc := newFakeClock(t) m := mailer{ stats: stats, mailer: &mc, emailTemplate: tmpl, subject: testEmailSubject, rs: rs, clk: fc, } cert := &x509.Certificate{ Subject: pkix.Name{ CommonName: "happy", }, NotAfter: fc.Now().AddDate(0, 0, 2), DNSNames: []string{"example.com"}, } err := m.sendNags([]*core.AcmeURL{emailA}, []*x509.Certificate{cert}) test.AssertNotError(t, err, "Failed to send warning messages") test.AssertEquals(t, len(mc.Messages), 1) test.AssertEquals(t, mocks.MailerMessage{ To: emailARaw, Subject: testEmailSubject, Body: fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), }, mc.Messages[0]) mc.Clear() err = m.sendNags([]*core.AcmeURL{emailA, emailB}, []*x509.Certificate{cert}) test.AssertNotError(t, err, "Failed to send warning messages") test.AssertEquals(t, len(mc.Messages), 2) test.AssertEquals(t, mocks.MailerMessage{ To: emailARaw, Subject: testEmailSubject, Body: fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), }, mc.Messages[0]) test.AssertEquals(t, mocks.MailerMessage{ To: emailBRaw, Subject: testEmailSubject, Body: fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), }, mc.Messages[1]) mc.Clear() err = m.sendNags([]*core.AcmeURL{}, []*x509.Certificate{cert}) test.AssertNotError(t, err, "Not an error to pass no email contacts") test.AssertEquals(t, len(mc.Messages), 0) templates, err := template.ParseGlob("../../data/*.template") test.AssertNotError(t, err, "Failed to parse templates") for _, template := range templates.Templates() { m.emailTemplate = template err = m.sendNags(nil, []*x509.Certificate{cert}) test.AssertNotError(t, err, "failed to send nag") } }
func TestHTTPRedirectUserAgent(t *testing.T) { chall := core.HTTPChallenge01(accountKey) setChallengeToken(&chall, expectedToken) hs := httpSrv(t, expectedToken) defer hs.Close() port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} va.UserAgent = rejectUserAgent setChallengeToken(&chall, pathMoved) _, prob := va.validateHTTP01(ctx, ident, chall) if prob == nil { t.Fatalf("Challenge with rejectUserAgent should have failed (%s).", pathMoved) } setChallengeToken(&chall, pathFound) _, prob = va.validateHTTP01(ctx, ident, chall) if prob == nil { t.Fatalf("Challenge with rejectUserAgent should have failed (%s).", pathFound) } }
func TestDNSValidationServFail(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA chalDNS := createChallenge(core.ChallengeTypeDNS01) badIdent := core.AcmeIdentifier{ Type: core.IdentifierDNS, Value: "servfail.com", } var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: badIdent, Challenges: []core.Challenge{chalDNS}, } va.validate(ctx, authz, 0) test.AssertNotNil(t, mockRA.lastAuthz, "Should have gotten an authorization") test.Assert(t, authz.Challenges[0].Status == core.StatusInvalid, "Should be invalid.") test.AssertEquals(t, authz.Challenges[0].Error.Type, probs.ConnectionProblem) }
func TestDNSValidationInvalid(t *testing.T) { var notDNS = core.AcmeIdentifier{ Type: core.IdentifierType("iris"), Value: "790DB180-A274-47A4-855F-31C428CB1072", } chalDNS := core.DNSChallenge01(accountKey) chalDNS.ProvidedKeyAuthorization, _ = chalDNS.ExpectedKeyAuthorization() var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: notDNS, Challenges: []core.Challenge{chalDNS}, } stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA va.validate(ctx, authz, 0) test.AssertNotNil(t, mockRA.lastAuthz, "Should have gotten an authorization") test.Assert(t, authz.Challenges[0].Status == core.StatusInvalid, "Should be invalid.") test.AssertEquals(t, authz.Challenges[0].Error.Type, probs.MalformedProblem) }
func TestDNSValidationNotSane(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA chal0 := core.DNSChallenge01(accountKey) chal0.Token = "" chal1 := core.DNSChallenge01(accountKey) chal1.Token = "yfCBb-bRTLz8Wd1C0lTUQK3qlKj3-t2tYGwx5Hj7r_" chal2 := core.DNSChallenge01(accountKey) chal2.ProvidedKeyAuthorization = "" chal3 := core.DNSChallenge01(accountKey) chal3.ProvidedKeyAuthorization = "a.a" var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chal0, chal1, chal2, chal3}, } for i := 0; i < len(authz.Challenges); i++ { va.validate(ctx, authz, i) test.AssertEquals(t, authz.Challenges[i].Status, core.StatusInvalid) test.AssertEquals(t, authz.Challenges[i].Error.Type, probs.MalformedProblem) if !strings.Contains(authz.Challenges[i].Error.Error(), "Challenge failed sanity check.") { t.Errorf("Got wrong error: %s", authz.Challenges[i].Error) } } }
func TestUpdateValidations(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA chall := core.HTTPChallenge01(accountKey) chall.ValidationRecord = []core.ValidationRecord{} setChallengeToken(&chall, core.NewToken()) var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chall}, } started := time.Now() err := va.UpdateValidations(ctx, authz, 0) if err != nil { test.AssertNotError(t, err, "UpdateValidations failed") } took := time.Since(started) // Check that the call to va.UpdateValidations didn't block for 3 seconds test.Assert(t, (took < (time.Second * 3)), "UpdateValidations blocked") }
func TestValidateHTTPResponseDocument(t *testing.T) { chall := core.HTTPChallenge01(accountKey) setChallengeToken(&chall, core.NewToken()) hs := httpSrv(t, `a.StartOfLine.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.PastTruncationPoint.aaaaaaaaaaaaaaaaaaaa`) port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA defer hs.Close() var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chall}, } va.validate(ctx, authz, 0) test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status) test.Assert(t, len(log.GetAllMatching("StartOfLine")) > 1, "Beginning of response body not logged") test.Assert(t, len(log.GetAllMatching("…")) > 1, "Ellipsis not logged") test.AssertEquals(t, len(log.GetAllMatching("PastTruncationPoint")), 0) // End of response body was logged }
func TestCAAFailure(t *testing.T) { chall := createChallenge(core.ChallengeTypeTLSSNI01) hs := tlssniSrv(t, chall) defer hs.Close() port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{TLSPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA ident.Value = "reserved.com" var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chall}, } va.validate(ctx, authz, 0) test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status) }
func TestDNSValidationNoAuthorityOK(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA // create a challenge with well known token chalDNS := core.DNSChallenge01(accountKey) chalDNS.Token = expectedToken chalDNS.ProvidedKeyAuthorization, _ = chalDNS.ExpectedKeyAuthorization() goodIdent := core.AcmeIdentifier{ Type: core.IdentifierDNS, Value: "no-authority-dns01.com", } var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: goodIdent, Challenges: []core.Challenge{chalDNS}, } va.validate(ctx, authz, 0) test.AssertNotNil(t, mockRA.lastAuthz, "Should have gotten an authorization") test.Assert(t, authz.Challenges[0].Status == core.StatusValid, "Should be valid.") }
func TestHTTPRedirectLookup(t *testing.T) { chall := core.HTTPChallenge01(accountKey) setChallengeToken(&chall, expectedToken) hs := httpSrv(t, expectedToken) defer hs.Close() port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} log.Clear() setChallengeToken(&chall, pathMoved) _, prob := va.validateHTTP01(ctx, ident, chall) if prob != nil { t.Fatalf("Unexpected failure in redirect (%s): %s", pathMoved, prob) } test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/`+pathMoved+`" to ".*/`+pathValid+`"`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 2) log.Clear() setChallengeToken(&chall, pathFound) _, prob = va.validateHTTP01(ctx, ident, chall) if prob != nil { t.Fatalf("Unexpected failure in redirect (%s): %s", pathFound, prob) } test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/`+pathFound+`" to ".*/`+pathMoved+`"`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/`+pathMoved+`" to ".*/`+pathValid+`"`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 3) log.Clear() setChallengeToken(&chall, pathReLookupInvalid) _, err = va.validateHTTP01(ctx, ident, chall) test.AssertError(t, err, chall.Token) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`No IPv4 addresses found for invalid.invalid`)), 1) log.Clear() setChallengeToken(&chall, pathReLookup) _, prob = va.validateHTTP01(ctx, ident, chall) if prob != nil { t.Fatalf("Unexpected error in redirect (%s): %s", pathReLookup, prob) } test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/`+pathReLookup+`" to ".*other.valid:\d+/path"`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for other.valid \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) log.Clear() setChallengeToken(&chall, pathRedirectPort) _, err = va.validateHTTP01(ctx, ident, chall) test.AssertError(t, err, chall.Token) test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/port-redirect" to ".*other.valid:8080/path"`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for other.valid \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) }
// InitializeStatsdCollector creates the connection to the Statsd server // and should be called before any metrics are recorded. // // Users should ensure to call Close() on the client. func InitializeStatsdCollector(config *StatsdCollectorConfig) (*StatsdCollectorClient, error) { c, err := statsd.NewClient(config.StatsdAddr, config.Prefix) if err != nil { log.Printf("Could not initiale buffered client: %s. Falling back to a Noop Statsd client", err) c, _ = statsd.NewNoopClient() } return &StatsdCollectorClient{ client: c, }, err }
// Open allocates resources for the stats writer. func (s *StatsWriter) Open(host string, port string, prefix string) error { var err error if s.isOpen { return errors.New("Stats Writer is already open") } s.isOpen = true // If necessary, use the no-op client so we don't need to test everywhere. if host == "" { s.Client, _ = statsd.NewNoopClient() err = errors.New("Stats Writer not configured") } else { addr := net.JoinHostPort(host, port) s.Client, err = statsd.NewClient(addr, prefix) if err != nil { s.Client, _ = statsd.NewNoopClient() } } // Report memory usage stats every second. s.quit = make(chan struct{}) if err == nil { // Don't bother starting the ticker when using the no-op client. // (We still make the channel, to simplify the close.) statsTicker := time.NewTicker(time.Second * 1) go func() { for _ = range statsTicker.C { select { case <-s.quit: return default: s.sendMemoryStats() } } }() } return err }
func TestAllowNilInIsSafeDomain(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.NewFake()) // Be cool with a nil SafeBrowsing. This will happen in prod when we have // flag mismatch between the VA and RA. resp, err := va.IsSafeDomain(ctx, &core.IsSafeDomainRequest{Domain: "example.com"}) if err != nil { t.Errorf("nil SafeBrowsing, unexpected error: %s", err) } else if !resp.IsSafe { t.Errorf("nil Safebrowsing, should fail open but failed closed") } }
// TestDNSValidationLive is an integration test, depending on // the existence of some Internet resources. Because of that, // it asserts nothing; it is intended for coverage. func TestDNSValidationLive(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA goodChalDNS := core.DNSChallenge01(accountKey) // The matching value LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo // is set at _acme-challenge.good.bin.coffee goodChalDNS.Token = expectedToken var goodIdent = core.AcmeIdentifier{ Type: core.IdentifierDNS, Value: "good.bin.coffee", } var badIdent = core.AcmeIdentifier{ Type: core.IdentifierType("dns"), Value: "bad.bin.coffee", } var authzGood = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: goodIdent, Challenges: []core.Challenge{goodChalDNS}, } va.validate(ctx, authzGood, 0) if authzGood.Challenges[0].Status != core.StatusValid { t.Logf("TestDNSValidationLive on Good did not succeed.") } badChalDNS := core.DNSChallenge01(accountKey) // The matching value is NOT set at _acme-challenge.bad.bin.coffee badChalDNS.Token = "yfCBb-bRTLz8Wd1C0lTUQK3qlKj3-t2tYGwx5Hj7r_w" var authzBad = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: badIdent, Challenges: []core.Challenge{badChalDNS}, } va.validate(ctx, authzBad, 0) if authzBad.Challenges[0].Status != core.StatusInvalid { t.Logf("TestDNSValidationLive on Bad did succeed inappropriately.") } }
func TestCAATimeout(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} va.IssuerDomain = "letsencrypt.org" err := va.checkCAA(ctx, core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "caa-timeout.com"}) if err.Type != probs.ConnectionProblem { t.Errorf("Expected timeout error type %s, got %s", probs.ConnectionProblem, err.Type) } expected := "DNS problem: query timed out looking up CAA for always.timeout" if err.Detail != expected { t.Errorf("checkCAA: got %#v, expected %#v", err.Detail, expected) } }
func TestTLSError(t *testing.T) { chall := createChallenge(core.ChallengeTypeTLSSNI01) hs := brokenTLSSrv() port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{TLSPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} _, prob := va.validateTLSSNI01(ctx, ident, chall) if prob == nil { t.Fatalf("TLS validation should have failed: What cert was used?") } test.AssertEquals(t, prob.Type, probs.TLSProblem) }
func TestHTTPRedirectLoop(t *testing.T) { chall := core.HTTPChallenge01(accountKey) setChallengeToken(&chall, "looper") hs := httpSrv(t, expectedToken) defer hs.Close() port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{HTTPPort: port}, nil, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} log.Clear() _, prob := va.validateHTTP01(ctx, ident, chall) if prob == nil { t.Fatalf("Challenge should have failed for %s", chall.Token) } }
func TestIsSafeDomain(t *testing.T) { // TODO(jmhodges): use more of the GSB lib by teaching it how to not make // http requests // This test is mocked out at the wrong level (SafeBrowsing) because the gsb lib // we rely on is a little funny and overcomplicated, but still hasn't // learned out how not make HTTP requests in tests. stats, _ := statsd.NewNoopClient() ctrl := gomock.NewController(t) defer ctrl.Finish() sbc := NewMockSafeBrowsing(ctrl) sbc.EXPECT().IsListed("good.com").Return("", nil) sbc.EXPECT().IsListed("bad.com").Return("bad", nil) sbc.EXPECT().IsListed("errorful.com").Return("", errors.New("welp")) sbc.EXPECT().IsListed("outofdate.com").Return("", safebrowsing.ErrOutOfDateHashes) va := NewValidationAuthorityImpl(&cmd.PortConfig{}, sbc, nil, stats, clock.NewFake()) resp, err := va.IsSafeDomain(ctx, &core.IsSafeDomainRequest{Domain: "good.com"}) if err != nil { t.Errorf("good.com: want no error, got '%s'", err) } if !resp.IsSafe { t.Errorf("good.com: want true, got %t", resp.IsSafe) } resp, err = va.IsSafeDomain(ctx, &core.IsSafeDomainRequest{Domain: "bad.com"}) if err != nil { t.Errorf("bad.com: want no error, got '%s'", err) } if resp.IsSafe { t.Errorf("bad.com: want false, got %t", resp.IsSafe) } _, err = va.IsSafeDomain(ctx, &core.IsSafeDomainRequest{Domain: "errorful.com"}) if err == nil { t.Errorf("errorful.com: want error, got none") } resp, err = va.IsSafeDomain(ctx, &core.IsSafeDomainRequest{Domain: "outofdate.com"}) if err != nil { t.Errorf("outofdate.com: want no error, got '%s'", err) } if !resp.IsSafe { t.Errorf("outofdate.com: IsSafeDomain should fail open on out of date hashes") } }
func setup(t *testing.T, nagTimes []time.Duration) *testCtx { // We use the test_setup user (which has full permissions to everything) // because the SA we return is used for inserting data to set up the test. dbMap, err := sa.NewDbMap(vars.DBConnSAFullPerms, 0) if err != nil { t.Fatalf("Couldn't connect the database: %s", err) } fc := newFakeClock(t) ssa, err := sa.NewSQLStorageAuthority(dbMap, fc, log) if err != nil { t.Fatalf("unable to create SQLStorageAuthority: %s", err) } cleanUp := test.ResetSATestDatabase(t) stats, _ := statsd.NewNoopClient(nil) mc := &mocks.Mailer{} offsetNags := make([]time.Duration, len(nagTimes)) for i, t := range nagTimes { offsetNags[i] = t + defaultNagCheckInterval } m := &mailer{ log: log, stats: stats, mailer: mc, emailTemplate: tmpl, dbMap: dbMap, rs: ssa, nagTimes: offsetNags, limit: 100, clk: fc, } return &testCtx{ dbMap: dbMap, ssa: ssa, mc: mc, fc: fc, m: m, cleanUp: cleanUp, } }
func TestValidateTLSSNINotSane(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, stats, clock.Default()) // no calls made va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA chall := createChallenge(core.ChallengeTypeTLSSNI01) chall.Token = "not sane" var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chall}, } va.validate(ctx, authz, 0) test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status) }
func TestPurgeAuthzs(t *testing.T) { dbMap, err := sa.NewDbMap(vars.DBConnSAFullPerms, 0) if err != nil { t.Fatalf("Couldn't connect the database: %s", err) } log := blog.UseMock() fc := clock.NewFake() fc.Add(time.Hour) ssa, err := sa.NewSQLStorageAuthority(dbMap, fc, log) if err != nil { t.Fatalf("unable to create SQLStorageAuthority: %s", err) } cleanUp := test.ResetSATestDatabase(t) defer cleanUp() stats, _ := statsd.NewNoopClient(nil) p := expiredAuthzPurger{stats, log, fc, dbMap, 1} rows, err := p.purgeAuthzs(time.Time{}, true) test.AssertNotError(t, err, "purgeAuthzs failed") test.AssertEquals(t, rows, int64(0)) old, new := fc.Now().Add(-time.Hour), fc.Now().Add(time.Hour) reg := satest.CreateWorkingRegistration(t, ssa) _, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &old}) test.AssertNotError(t, err, "NewPendingAuthorization failed") _, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &old}) test.AssertNotError(t, err, "NewPendingAuthorization failed") _, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &new}) test.AssertNotError(t, err, "NewPendingAuthorization failed") rows, err = p.purgeAuthzs(fc.Now(), true) test.AssertNotError(t, err, "purgeAuthzs failed") test.AssertEquals(t, rows, int64(2)) rows, err = p.purgeAuthzs(fc.Now().Add(time.Hour), true) test.AssertNotError(t, err, "purgeAuthzs failed") test.AssertEquals(t, rows, int64(1)) }
func TestDNSValidationNoServer(t *testing.T) { c, _ := statsd.NewNoopClient() stats := metrics.NewNoopScope() va := NewValidationAuthorityImpl(&cmd.PortConfig{}, nil, nil, c, clock.Default()) va.DNSResolver = bdns.NewTestDNSResolverImpl(time.Second*5, []string{}, stats, clock.Default(), 1) mockRA := &MockRegistrationAuthority{} va.RA = mockRA chalDNS := createChallenge(core.ChallengeTypeDNS01) var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{chalDNS}, } va.validate(ctx, authz, 0) test.AssertNotNil(t, mockRA.lastAuthz, "Should have gotten an authorization") test.Assert(t, authz.Challenges[0].Status == core.StatusInvalid, "Should be invalid.") test.AssertEquals(t, authz.Challenges[0].Error.Type, probs.ConnectionProblem) }
func TestConstructAuthHeader(t *testing.T) { stats, _ := statsd.NewNoopClient(nil) cpc, err := NewCachePurgeClient( "https://akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net", "akab-client-token-xxx-xxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=", "akab-access-token-xxx-xxxxxxxxxxxxxxxx", 0, time.Second, nil, stats, ) test.AssertNotError(t, err, "Failed to create cache purge client") fc := clock.NewFake() cpc.clk = fc wantedTimestamp, err := time.Parse(timestampFormat, "20140321T19:34:21+0000") test.AssertNotError(t, err, "Failed to parse timestamp") fc.Add(wantedTimestamp.Sub(fc.Now())) req, err := http.NewRequest( "POST", fmt.Sprintf("%s%s", cpc.apiEndpoint, purgePath), bytes.NewBuffer([]byte{0}), ) test.AssertNotError(t, err, "Failed to create request") expectedHeader := "EG1-HMAC-SHA256 client_token=akab-client-token-xxx-xxxxxxxxxxxxxxxx;access_token=akab-access-token-xxx-xxxxxxxxxxxxxxxx;timestamp=20140321T19:34:21+0000;nonce=nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;signature=hXm4iCxtpN22m4cbZb4lVLW5rhX8Ca82vCFqXzSTPe4=" authHeader, err := cpc.constructAuthHeader( req, []byte("datadatadatadatadatadatadatadata"), "/testapi/v1/t3", "nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ) test.AssertNotError(t, err, "Failed to create authorization header") test.AssertEquals(t, authHeader, expectedHeader) }
// NewNoopScope returns a Scope that won't collect anything func NewNoopScope() Scope { c, _ := statsd.NewNoopClient() return NewStatsdScope(c, "noop") }
func newTestStats() metrics.Scope { c, _ := statsd.NewNoopClient() return metrics.NewStatsdScope(c, "fakesvc") }
func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, clock.FakeClock, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshal JWK") fc := clock.NewFake() dbMap, err := sa.NewDbMap(vars.DBConnSA, 0) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } ssa, err := sa.NewSQLStorageAuthority(dbMap, fc, log) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetSATestDatabase(t) va := &DummyValidationAuthority{} pa, err := policy.New(SupportedChallenges) test.AssertNotError(t, err, "Couldn't create PA") err = pa.SetHostnamePolicyFile("../test/hostname-policy.json") test.AssertNotError(t, err, "Couldn't set hostname policy") stats, _ := statsd.NewNoopClient() ca := &mocks.MockCA{ PEM: eeCertPEM, } cleanUp := func() { saDBCleanUp() } block, _ := pem.Decode(CSRPEM) ExampleCSR, _ = x509.ParseCertificateRequest(block.Bytes) Registration, _ = ssa.NewRegistration(ctx, core.Registration{ Key: AccountKeyA, InitialIP: net.ParseIP("3.2.3.3"), }) ra := NewRegistrationAuthorityImpl(fc, log, stats, 1, testKeyPolicy, 0, true, false) ra.SA = ssa ra.VA = va ra.CA = ca ra.PA = pa ra.DNSResolver = &bdns.MockDNSResolver{} AuthzInitial.RegistrationID = Registration.ID challenges, combinations := pa.ChallengesFor(AuthzInitial.Identifier, &Registration.Key) AuthzInitial.Challenges = challenges AuthzInitial.Combinations = combinations AuthzFinal = AuthzInitial AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return va, ssa, ra, fc, cleanUp }