Merge branch 'master' into log-actual-ip

Conflicts:
	wfe/web-front-end_test.go
This commit is contained in:
Tom Clegg 2015-10-07 11:58:23 -07:00
commit f32c26c1de
23 changed files with 252 additions and 199 deletions

View File

@ -203,7 +203,7 @@ func TestRevoke(t *testing.T) {
test.AssertNotError(t, err, "Failed to create CA")
ca.PA = ctx.pa
ca.SA = ctx.sa
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
csr, _ := x509.ParseCertificateRequest(CNandSANCSR)
certObj, err := ca.IssueCertificate(*csr, ctx.reg.ID)
@ -242,7 +242,7 @@ func TestIssueCertificate(t *testing.T) {
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -319,7 +319,7 @@ func TestRejectNoName(t *testing.T) {
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -336,7 +336,7 @@ func TestRejectTooManyNames(t *testing.T) {
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -353,7 +353,7 @@ func TestDeduplication(t *testing.T) {
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -377,7 +377,7 @@ func TestRejectValidityTooLong(t *testing.T) {
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -394,7 +394,7 @@ func TestShortKey(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa
@ -410,7 +410,7 @@ func TestRejectBadAlgorithm(t *testing.T) {
ctx := setup(t)
defer ctx.cleanUp()
ca, err := NewCertificateAuthorityImpl(ctx.caConfig, ctx.fc, caCertFile)
ca.Publisher = &mocks.MockPublisher{}
ca.Publisher = &mocks.Publisher{}
ca.PA = ctx.pa
ca.SA = ctx.sa

View File

@ -130,6 +130,21 @@ func revokeByReg(regID int64, reasonCode core.RevocationCode, deny bool, rac rpc
return
}
// This abstraction is needed so that we can use sort.Sort below
type revocationCodes []core.RevocationCode
func (rc revocationCodes) Len() int {
return len(rc)
}
func (rc revocationCodes) Less(i, j int) bool {
return rc[i] < rc[j]
}
func (rc revocationCodes) Swap(i, j int) {
rc[i], rc[j] = rc[j], rc[i]
}
func main() {
app := cli.NewApp()
app.Name = "admin-revoker"
@ -219,7 +234,7 @@ func main() {
Name: "list-reasons",
Usage: "List all revocation reason codes",
Action: func(c *cli.Context) {
var codes core.RevocationCodes
var codes revocationCodes
for k := range core.RevocationReasons {
codes = append(codes, k)
}

View File

@ -145,7 +145,7 @@ func TestCheckCert(t *testing.T) {
}
delete(problemsMap, p)
}
for k, _ := range problemsMap {
for k := range problemsMap {
t.Errorf("Found unexpected problem '%s'.", k)
}

View File

@ -56,11 +56,11 @@ func (m *mockMail) SendMail(to []string, msg string) (err error) {
}
type fakeRegStore struct {
RegById map[int64]core.Registration
RegByID map[int64]core.Registration
}
func (f fakeRegStore) GetRegistration(id int64) (core.Registration, error) {
r, ok := f.RegById[id]
r, ok := f.RegByID[id]
if !ok {
msg := fmt.Sprintf("no such registration %d", id)
return r, core.NoSuchRegistrationError(msg)
@ -69,7 +69,7 @@ func (f fakeRegStore) GetRegistration(id int64) (core.Registration, error) {
}
func newFakeRegStore() fakeRegStore {
return fakeRegStore{RegById: make(map[int64]core.Registration)}
return fakeRegStore{RegByID: make(map[int64]core.Registration)}
}
const testTmpl = `hi, cert for DNS names {{.DNSNames}} is going to expire in {{.DaysToExpiration}} days ({{.ExpirationDate}})`

View File

@ -30,7 +30,7 @@ import (
"log"
"net"
"net/http"
_ "net/http/pprof"
_ "net/http/pprof" // HTTP performance profiling, added transparently to HTTP APIs
"os"
"runtime"
"time"
@ -219,6 +219,9 @@ type Config struct {
SubscriberAgreementURL string
}
// CAConfig structs have configuration information for the certificate
// authority, including database parameters as well as controls for
// issued certificates.
type CAConfig struct {
Profile string
TestMode bool
@ -241,6 +244,8 @@ type CAConfig struct {
DebugAddr string
}
// PAConfig specifies how a policy authority should connect to its
// database, and what policies it should enforce.
type PAConfig struct {
DBConnect string
EnforcePolicyWhitelist bool
@ -327,6 +332,7 @@ type AppShell struct {
App *cli.App
}
// Version returns a string representing the version of boulder running.
func Version() string {
return fmt.Sprintf("0.1.0 [%s]", core.GetBuildID())
}
@ -438,6 +444,11 @@ func LoadCert(path string) (cert []byte, err error) {
return
}
// DebugServer starts a server to receive debug information. Typical
// usage is to start it in a goroutine, configured with an address
// from the appropriate configuration object:
//
// go cmd.DebugServer(c.XA.DebugAddr)
func DebugServer(addr string) {
if addr == "" {
log.Fatalf("unable to boot debug server because no address was given for it. Set debugAddr.")
@ -450,12 +461,19 @@ func DebugServer(addr string) {
log.Println(http.Serve(ln, nil))
}
// ConfigDuration is just an alias for time.Duration that allows
// serialization to YAML as well as JSON.
type ConfigDuration struct {
time.Duration
}
// ErrDurationMustBeString is returned when a non-string value is
// presented to be deserialized as a ConfigDuration
var ErrDurationMustBeString = errors.New("cannot JSON unmarshal something other than a string into a ConfigDuration")
// UnmarshalJSON parses a string into a ConfigDuration using
// time.ParseDuration. If the input does not unmarshal as a
// string, then UnmarshalJSON returns ErrDurationMustBeString.
func (d *ConfigDuration) UnmarshalJSON(b []byte) error {
s := ""
err := json.Unmarshal(b, &s)
@ -470,10 +488,13 @@ func (d *ConfigDuration) UnmarshalJSON(b []byte) error {
return err
}
// MarshalJSON returns the string form of the duration, as a byte array.
func (d ConfigDuration) MarshalJSON() ([]byte, error) {
return []byte(d.Duration.String()), nil
}
// UnmarshalYAML uses the same frmat as JSON, but is called by the YAML
// parser (vs. the JSON parser).
func (d *ConfigDuration) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {

View File

@ -38,7 +38,7 @@ func HTTPChallenge01(accountKey *jose.JsonWebKey) Challenge {
return newChallenge(ChallengeTypeHTTP01, accountKey)
}
// DvsniChallenge01 constructs a random tls-sni-00 challenge
// TLSSNIChallenge01 constructs a random tls-sni-00 challenge
func TLSSNIChallenge01(accountKey *jose.JsonWebKey) Challenge {
return newChallenge(ChallengeTypeTLSSNI01, accountKey)
}

View File

@ -617,11 +617,6 @@ type Certificate struct {
Expires time.Time `db:"expires"`
}
type IssuedCertIdentifierData struct {
ReversedName string
Serial string
}
// IdentifierData holds information about what certificates are known for a
// given identifier. This is used to present Proof of Posession challenges in
// the case where a certificate already exists. The DB table holding
@ -724,6 +719,8 @@ type OCSPSigningRequest struct {
RevokedAt time.Time
}
// SignedCertificateTimestamp represents objects used by Certificate Transparency
// to demonstrate that a certificate was submitted to a CT log. See RFC 6962.
type SignedCertificateTimestamp struct {
ID int `db:"id"`
// The version of the protocol to which the SCT conforms
@ -744,8 +741,6 @@ type SignedCertificateTimestamp struct {
LockCol int64
}
type RPCSignedCertificateTimestamp SignedCertificateTimestamp
type rawSignedCertificateTimestamp struct {
Version uint8 `json:"sct_version"`
LogID string `json:"id"`
@ -754,6 +749,9 @@ type rawSignedCertificateTimestamp struct {
Extensions string `json:"extensions"`
}
// UnmarshalJSON parses the add-chain response from a CT log. It fills all of
// the fields in the SignedCertificateTimestamp struct except for ID and
// CertificateSerial, which are used for local recordkeeping in the Boulder DB.
func (sct *SignedCertificateTimestamp) UnmarshalJSON(data []byte) error {
var err error
var rawSCT rawSignedCertificateTimestamp
@ -816,20 +814,6 @@ func (sct *SignedCertificateTimestamp) CheckSignature() error {
// RevocationCode is used to specify a certificate revocation reason
type RevocationCode int
type RevocationCodes []RevocationCode
func (rc RevocationCodes) Len() int {
return len(rc)
}
func (rc RevocationCodes) Less(i, j int) bool {
return rc[i] < rc[j]
}
func (rc RevocationCodes) Swap(i, j int) {
rc[i], rc[j] = rc[j], rc[i]
}
// RevocationReasons provides a map from reason code to string explaining the
// code
var RevocationReasons = map[RevocationCode]string{

View File

@ -301,6 +301,7 @@ func KeyDigestEquals(j, k crypto.PublicKey) bool {
// AcmeURL is a URL that automatically marshal/unmarshal to JSON strings
type AcmeURL url.URL
// ParseAcmeURL is just a wrapper around url.Parse that returns an *AcmeURL
func ParseAcmeURL(s string) (*AcmeURL, error) {
u, err := url.Parse(s)
if err != nil {
@ -427,6 +428,9 @@ func StringToSerial(serial string) (*big.Int, error) {
return &serialNum, err
}
// ValidSerial tests whether the input string represents a syntactically
// valid serial number, i.e., that it is a valid hex string between 32
// and 36 characters long.
func ValidSerial(serial string) bool {
// Originally, serial numbers were 32 hex characters long. We later increased
// them to 36, but we allow the shorter ones because they exist in some

View File

@ -13,10 +13,10 @@ import (
blog "github.com/letsencrypt/boulder/log"
)
// MockSyslogWriter implements the blog.SyslogWriter interface. It
// SyslogWriter implements the blog.SyslogWriter interface. It
// stores all logged messages in a buffer for inspection by test
// functions (via GetAll()) instead of sending them to syslog.
type MockSyslogWriter struct {
type SyslogWriter struct {
logged []*LogMessage
msgChan chan<- *LogMessage
getChan <-chan []*LogMessage
@ -24,7 +24,7 @@ type MockSyslogWriter struct {
closeChan chan<- struct{}
}
// LogMessage is a log entry that has been sent to a MockSyslogWriter.
// LogMessage is a log entry that has been sent to a SyslogWriter.
type LogMessage struct {
Priority syslog.Priority // aka Log level
Message string // content of log message
@ -54,19 +54,19 @@ func (lm *LogMessage) String() string {
// // ...
// Assert(t, len(log.GetAll()) > 0, "Should have logged something")
// }
func UseMockLog() *MockSyslogWriter {
func UseMockLog() *SyslogWriter {
sw := NewSyslogWriter()
blog.GetAuditLogger().SyslogWriter = sw
return sw
}
// NewSyslogWriter returns a new MockSyslogWriter.
func NewSyslogWriter() *MockSyslogWriter {
// NewSyslogWriter returns a new SyslogWriter.
func NewSyslogWriter() *SyslogWriter {
msgChan := make(chan *LogMessage)
getChan := make(chan []*LogMessage)
clearChan := make(chan struct{})
closeChan := make(chan struct{})
msw := &MockSyslogWriter{
msw := &SyslogWriter{
logged: []*LogMessage{},
msgChan: msgChan,
getChan: getChan,
@ -91,7 +91,7 @@ func NewSyslogWriter() *MockSyslogWriter {
return msw
}
func (msw *MockSyslogWriter) write(m string, priority syslog.Priority) error {
func (msw *SyslogWriter) write(m string, priority syslog.Priority) error {
msw.msgChan <- &LogMessage{Message: m, Priority: priority}
return nil
}
@ -100,7 +100,7 @@ func (msw *MockSyslogWriter) write(m string, priority syslog.Priority) error {
// Clear(), if applicable).
//
// The caller must not modify the returned slice or its elements.
func (msw *MockSyslogWriter) GetAll() []*LogMessage {
func (msw *SyslogWriter) GetAll() []*LogMessage {
return <-msw.getChan
}
@ -110,7 +110,7 @@ func (msw *MockSyslogWriter) GetAll() []*LogMessage {
// is more important than performance.
//
// The caller must not modify the elements of the returned slice.
func (msw *MockSyslogWriter) GetAllMatching(reString string) (matches []*LogMessage) {
func (msw *SyslogWriter) GetAllMatching(reString string) (matches []*LogMessage) {
re := regexp.MustCompile(reString)
for _, logMsg := range <-msw.getChan {
if re.MatchString(logMsg.Message) {
@ -121,52 +121,52 @@ func (msw *MockSyslogWriter) GetAllMatching(reString string) (matches []*LogMess
}
// Clear resets the log buffer.
func (msw *MockSyslogWriter) Clear() {
func (msw *SyslogWriter) Clear() {
msw.clearChan <- struct{}{}
}
// Close releases resources. No other methods may be called after this.
func (msw *MockSyslogWriter) Close() error {
func (msw *SyslogWriter) Close() error {
msw.closeChan <- struct{}{}
return nil
}
// Alert logs at LOG_ALERT
func (msw *MockSyslogWriter) Alert(m string) error {
func (msw *SyslogWriter) Alert(m string) error {
return msw.write(m, syslog.LOG_ALERT)
}
// Crit logs at LOG_CRIT
func (msw *MockSyslogWriter) Crit(m string) error {
func (msw *SyslogWriter) Crit(m string) error {
return msw.write(m, syslog.LOG_CRIT)
}
// Debug logs at LOG_DEBUG
func (msw *MockSyslogWriter) Debug(m string) error {
func (msw *SyslogWriter) Debug(m string) error {
return msw.write(m, syslog.LOG_DEBUG)
}
// Emerg logs at LOG_EMERG
func (msw *MockSyslogWriter) Emerg(m string) error {
func (msw *SyslogWriter) Emerg(m string) error {
return msw.write(m, syslog.LOG_EMERG)
}
// Err logs at LOG_ERR
func (msw *MockSyslogWriter) Err(m string) error {
func (msw *SyslogWriter) Err(m string) error {
return msw.write(m, syslog.LOG_ERR)
}
// Info logs at LOG_INFO
func (msw *MockSyslogWriter) Info(m string) error {
func (msw *SyslogWriter) Info(m string) error {
return msw.write(m, syslog.LOG_INFO)
}
// Notice logs at LOG_NOTICE
func (msw *MockSyslogWriter) Notice(m string) error {
func (msw *SyslogWriter) Notice(m string) error {
return msw.write(m, syslog.LOG_NOTICE)
}
// Warning logs at LOG_WARNING
func (msw *MockSyslogWriter) Warning(m string) error {
func (msw *SyslogWriter) Warning(m string) error {
return msw.write(m, syslog.LOG_WARNING)
}

View File

@ -20,17 +20,17 @@ import (
"github.com/letsencrypt/boulder/core"
)
// MockDNS is a mock
type MockDNS struct {
// DNSResolver is a mock
type DNSResolver struct {
}
// ExchangeOne is a mock
func (mock *MockDNS) ExchangeOne(hostname string, qt uint16) (rsp *dns.Msg, rtt time.Duration, err error) {
func (mock *DNSResolver) ExchangeOne(hostname string, qt uint16) (rsp *dns.Msg, rtt time.Duration, err error) {
return nil, 0, nil
}
// LookupTXT is a mock
func (mock *MockDNS) LookupTXT(hostname string) ([]string, time.Duration, error) {
func (mock *DNSResolver) LookupTXT(hostname string) ([]string, time.Duration, error) {
if hostname == "_acme-challenge.servfail.com" {
return nil, 0, fmt.Errorf("SERVFAIL")
}
@ -38,7 +38,7 @@ func (mock *MockDNS) LookupTXT(hostname string) ([]string, time.Duration, error)
}
// LookupHost is a mock
func (mock *MockDNS) LookupHost(hostname string) ([]net.IP, time.Duration, error) {
func (mock *DNSResolver) LookupHost(hostname string) ([]net.IP, time.Duration, error) {
if hostname == "always.invalid" || hostname == "invalid.invalid" {
return []net.IP{}, 0, nil
}
@ -47,7 +47,7 @@ func (mock *MockDNS) LookupHost(hostname string) ([]net.IP, time.Duration, error
}
// LookupCNAME is a mock
func (mock *MockDNS) LookupCNAME(domain string) (string, time.Duration, error) {
func (mock *DNSResolver) LookupCNAME(domain string) (string, time.Duration, error) {
switch strings.TrimRight(domain, ".") {
case "cname-absent.com":
return "absent.com.", 30, nil
@ -76,7 +76,7 @@ func (mock *MockDNS) LookupCNAME(domain string) (string, time.Duration, error) {
}
// LookupDNAME is a mock
func (mock *MockDNS) LookupDNAME(domain string) (string, time.Duration, error) {
func (mock *DNSResolver) LookupDNAME(domain string) (string, time.Duration, error) {
switch strings.TrimRight(domain, ".") {
case "cname-and-dname.com", "dname-present.com":
return "dname-target.present.com.", time.Minute, nil
@ -94,7 +94,7 @@ func (mock *MockDNS) LookupDNAME(domain string) (string, time.Duration, error) {
}
// LookupCAA is a mock
func (mock *MockDNS) LookupCAA(domain string) ([]*dns.CAA, time.Duration, error) {
func (mock *DNSResolver) LookupCAA(domain string) ([]*dns.CAA, time.Duration, error) {
var results []*dns.CAA
var record dns.CAA
switch strings.TrimRight(domain, ".") {
@ -118,7 +118,7 @@ func (mock *MockDNS) LookupCAA(domain string) ([]*dns.CAA, time.Duration, error)
}
// LookupMX is a mock
func (mock *MockDNS) LookupMX(domain string) ([]string, time.Duration, error) {
func (mock *DNSResolver) LookupMX(domain string) ([]string, time.Duration, error) {
switch strings.TrimRight(domain, ".") {
case "letsencrypt.org":
fallthrough
@ -128,8 +128,8 @@ func (mock *MockDNS) LookupMX(domain string) ([]string, time.Duration, error) {
return nil, 0, nil
}
// MockSA is a mock
type MockSA struct {
// StorageAuthority is a mock
type StorageAuthority struct {
authorizedDomains map[string]bool
}
@ -149,7 +149,7 @@ const (
)
// GetRegistration is a mock
func (sa *MockSA) GetRegistration(id int64) (core.Registration, error) {
func (sa *StorageAuthority) GetRegistration(id int64) (core.Registration, error) {
if id == 100 {
// Tag meaning "Missing"
return core.Registration{}, errors.New("missing")
@ -167,7 +167,7 @@ func (sa *MockSA) GetRegistration(id int64) (core.Registration, error) {
}
// GetRegistrationByKey is a mock
func (sa *MockSA) GetRegistrationByKey(jwk jose.JsonWebKey) (core.Registration, error) {
func (sa *StorageAuthority) GetRegistrationByKey(jwk jose.JsonWebKey) (core.Registration, error) {
var test1KeyPublic jose.JsonWebKey
var test2KeyPublic jose.JsonWebKey
test1KeyPublic.UnmarshalJSON([]byte(test1KeyPublicJSON))
@ -187,7 +187,7 @@ func (sa *MockSA) GetRegistrationByKey(jwk jose.JsonWebKey) (core.Registration,
}
// GetAuthorization is a mock
func (sa *MockSA) GetAuthorization(id string) (core.Authorization, error) {
func (sa *StorageAuthority) GetAuthorization(id string) (core.Authorization, error) {
if id == "valid" {
exp := time.Now().AddDate(100, 0, 0)
return core.Authorization{
@ -209,7 +209,7 @@ func (sa *MockSA) GetAuthorization(id string) (core.Authorization, error) {
}
// GetCertificate is a mock
func (sa *MockSA) GetCertificate(serial string) (core.Certificate, error) {
func (sa *StorageAuthority) GetCertificate(serial string) (core.Certificate, error) {
// Serial ee == 238.crt
if serial == "0000000000000000000000000000000000ee" {
certPemBytes, _ := ioutil.ReadFile("test/238.crt")
@ -231,7 +231,7 @@ func (sa *MockSA) GetCertificate(serial string) (core.Certificate, error) {
}
// GetCertificateStatus is a mock
func (sa *MockSA) GetCertificateStatus(serial string) (core.CertificateStatus, error) {
func (sa *StorageAuthority) GetCertificateStatus(serial string) (core.CertificateStatus, error) {
// Serial ee == 238.crt
if serial == "0000000000000000000000000000000000ee" {
return core.CertificateStatus{
@ -247,57 +247,57 @@ func (sa *MockSA) GetCertificateStatus(serial string) (core.CertificateStatus, e
}
// AlreadyDeniedCSR is a mock
func (sa *MockSA) AlreadyDeniedCSR([]string) (bool, error) {
func (sa *StorageAuthority) AlreadyDeniedCSR([]string) (bool, error) {
return false, nil
}
// AddCertificate is a mock
func (sa *MockSA) AddCertificate(certDER []byte, regID int64) (digest string, err error) {
func (sa *StorageAuthority) AddCertificate(certDER []byte, regID int64) (digest string, err error) {
return
}
// FinalizeAuthorization is a mock
func (sa *MockSA) FinalizeAuthorization(authz core.Authorization) (err error) {
func (sa *StorageAuthority) FinalizeAuthorization(authz core.Authorization) (err error) {
return
}
// MarkCertificateRevoked is a mock
func (sa *MockSA) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode core.RevocationCode) (err error) {
func (sa *StorageAuthority) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode core.RevocationCode) (err error) {
return
}
// UpdateOCSP is a mock
func (sa *MockSA) UpdateOCSP(serial string, ocspResponse []byte) (err error) {
func (sa *StorageAuthority) UpdateOCSP(serial string, ocspResponse []byte) (err error) {
return
}
// NewPendingAuthorization is a mock
func (sa *MockSA) NewPendingAuthorization(authz core.Authorization) (output core.Authorization, err error) {
func (sa *StorageAuthority) NewPendingAuthorization(authz core.Authorization) (output core.Authorization, err error) {
return
}
// NewRegistration is a mock
func (sa *MockSA) NewRegistration(reg core.Registration) (regR core.Registration, err error) {
func (sa *StorageAuthority) NewRegistration(reg core.Registration) (regR core.Registration, err error) {
return
}
// UpdatePendingAuthorization is a mock
func (sa *MockSA) UpdatePendingAuthorization(authz core.Authorization) (err error) {
func (sa *StorageAuthority) UpdatePendingAuthorization(authz core.Authorization) (err error) {
return
}
// UpdateRegistration is a mock
func (sa *MockSA) UpdateRegistration(reg core.Registration) (err error) {
func (sa *StorageAuthority) UpdateRegistration(reg core.Registration) (err error) {
return
}
// GetSCTReceipt is a mock
func (sa *MockSA) GetSCTReceipt(serial string, logID string) (sct core.SignedCertificateTimestamp, err error) {
func (sa *StorageAuthority) GetSCTReceipt(serial string, logID string) (sct core.SignedCertificateTimestamp, err error) {
return
}
// AddSCTReceipt is a mock
func (sa *MockSA) AddSCTReceipt(sct core.SignedCertificateTimestamp) (err error) {
func (sa *StorageAuthority) AddSCTReceipt(sct core.SignedCertificateTimestamp) (err error) {
if sct.Signature == nil {
err = fmt.Errorf("Bad times")
}
@ -305,8 +305,8 @@ func (sa *MockSA) AddSCTReceipt(sct core.SignedCertificateTimestamp) (err error)
}
// GetLatestValidAuthorization is a mock
func (sa *MockSA) GetLatestValidAuthorization(registrationId int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
if registrationId == 1 && identifier.Type == "dns" {
func (sa *StorageAuthority) GetLatestValidAuthorization(registrationID int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
if registrationID == 1 && identifier.Type == "dns" {
if sa.authorizedDomains[identifier.Value] || identifier.Value == "not-an-example.com" {
exp := time.Now().AddDate(100, 0, 0)
return core.Authorization{Status: core.StatusValid, RegistrationID: 1, Expires: &exp, Identifier: identifier}, nil
@ -316,16 +316,16 @@ func (sa *MockSA) GetLatestValidAuthorization(registrationId int64, identifier c
}
// CountCertificatesRange is a mock
func (sa *MockSA) CountCertificatesRange(_, _ time.Time) (int64, error) {
func (sa *StorageAuthority) CountCertificatesRange(_, _ time.Time) (int64, error) {
return 0, nil
}
// MockPublisher is a mock
type MockPublisher struct {
// Publisher is a mock
type Publisher struct {
// empty
}
// SubmitToCT is a mock
func (*MockPublisher) SubmitToCT([]byte) error {
func (*Publisher) SubmitToCT([]byte) error {
return nil
}

View File

@ -24,6 +24,7 @@ import (
"github.com/letsencrypt/boulder/sa"
)
// LogDescription tells you how to connect to a log and verify its statements.
type LogDescription struct {
ID string
URI string
@ -35,6 +36,9 @@ type rawLogDescription struct {
PublicKey string `json:"key"`
}
// UnmarshalJSON parses a simple JSON format for log descriptions. Both the
// URI and the public key are expected to be strings. The public key is a
// base64-encoded PKIX public key structure.
func (logDesc *LogDescription) UnmarshalJSON(data []byte) error {
var rawLogDesc rawLogDescription
if err := json.Unmarshal(data, &rawLogDesc); err != nil {

View File

@ -196,7 +196,7 @@ func setup(t *testing.T, port, retries int) (PublisherImpl, *x509.Certificate) {
})
test.AssertNotError(t, err, "Couldn't create new Publisher")
pub.issuerBundle = append(pub.issuerBundle, base64.StdEncoding.EncodeToString(intermediatePEM.Bytes))
pub.SA = &mocks.MockSA{}
pub.SA = &mocks.StorageAuthority{}
leafPEM, _ := pem.Decode([]byte(testLeaf))
leaf, err := x509.ParseCertificate(leafPEM.Bytes)

View File

@ -202,7 +202,7 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
ValidityPeriod: time.Hour * 2190,
NotAfter: time.Now().Add(time.Hour * 8761),
Clk: fc,
Publisher: &mocks.MockPublisher{},
Publisher: &mocks.Publisher{},
}
cleanUp := func() {
saDBCleanUp()
@ -225,7 +225,7 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
ra.VA = va
ra.CA = &ca
ra.PA = pa
ra.DNSResolver = &mocks.MockDNS{}
ra.DNSResolver = &mocks.DNSResolver{}
AuthzInitial.RegistrationID = Registration.ID
@ -263,38 +263,38 @@ func TestValidateContacts(t *testing.T) {
nStats, _ := statsd.NewNoopClient()
err := validateContacts([]*core.AcmeURL{}, &mocks.MockDNS{}, nStats)
err := validateContacts([]*core.AcmeURL{}, &mocks.DNSResolver{}, nStats)
test.AssertNotError(t, err, "No Contacts")
err = validateContacts([]*core.AcmeURL{tel}, &mocks.MockDNS{}, nStats)
err = validateContacts([]*core.AcmeURL{tel}, &mocks.DNSResolver{}, nStats)
test.AssertNotError(t, err, "Simple Telephone")
err = validateContacts([]*core.AcmeURL{validEmail}, &mocks.MockDNS{}, nStats)
err = validateContacts([]*core.AcmeURL{validEmail}, &mocks.DNSResolver{}, nStats)
test.AssertNotError(t, err, "Valid Email")
err = validateContacts([]*core.AcmeURL{invalidEmail}, &mocks.MockDNS{}, nStats)
err = validateContacts([]*core.AcmeURL{invalidEmail}, &mocks.DNSResolver{}, nStats)
test.AssertError(t, err, "Invalid Email")
err = validateContacts([]*core.AcmeURL{malformedEmail}, &mocks.MockDNS{}, nStats)
err = validateContacts([]*core.AcmeURL{malformedEmail}, &mocks.DNSResolver{}, nStats)
test.AssertError(t, err, "Malformed Email")
err = validateContacts([]*core.AcmeURL{ansible}, &mocks.MockDNS{}, nStats)
err = validateContacts([]*core.AcmeURL{ansible}, &mocks.DNSResolver{}, nStats)
test.AssertError(t, err, "Unknown scehme")
}
func TestValidateEmail(t *testing.T) {
_, err := validateEmail("an email`", &mocks.MockDNS{})
_, err := validateEmail("an email`", &mocks.DNSResolver{})
test.AssertError(t, err, "Malformed")
_, err = validateEmail("a@not.a.domain", &mocks.MockDNS{})
_, err = validateEmail("a@not.a.domain", &mocks.DNSResolver{})
test.AssertError(t, err, "Cannot resolve")
t.Logf("No Resolve: %s", err)
_, err = validateEmail("a@example.com", &mocks.MockDNS{})
_, err = validateEmail("a@example.com", &mocks.DNSResolver{})
test.AssertError(t, err, "No MX Record")
t.Logf("No MX: %s", err)
_, err = validateEmail("a@email.com", &mocks.MockDNS{})
_, err = validateEmail("a@email.com", &mocks.DNSResolver{})
test.AssertNotError(t, err, "Valid")
}

View File

@ -200,16 +200,16 @@ func (rpc *AmqpRPCServer) Handle(method string, handler func([]byte) ([]byte, er
rpc.dispatchTable[method] = handler
}
// RPCError is a JSON wrapper for error as it cannot be un/marshalled
// rpcError is a JSON wrapper for error as it cannot be un/marshalled
// due to type interface{}.
type RPCError struct {
type rpcError struct {
Value string `json:"value"`
Type string `json:"type,omitempty"`
}
// Wraps a error in a RPCError so it can be marshalled to
// Wraps a error in a rpcError so it can be marshalled to
// JSON.
func wrapError(err error) (rpcError RPCError) {
func wrapError(err error) (rpcError rpcError) {
if err != nil {
rpcError.Value = err.Error()
switch err.(type) {
@ -240,8 +240,8 @@ func wrapError(err error) (rpcError RPCError) {
return
}
// Unwraps a RPCError and returns the correct error type.
func unwrapError(rpcError RPCError) (err error) {
// Unwraps a rpcError and returns the correct error type.
func unwrapError(rpcError rpcError) (err error) {
if rpcError.Value != "" {
switch rpcError.Type {
case "InternalServerError":
@ -273,11 +273,11 @@ func unwrapError(rpcError RPCError) (err error) {
return
}
// RPCResponse is a stuct for wire-representation of response messages
// rpcResponse is a stuct for wire-representation of response messages
// used by DispatchSync
type RPCResponse struct {
type rpcResponse struct {
ReturnVal []byte `json:"returnVal,omitempty"`
Error RPCError `json:"error,omitempty"`
Error rpcError `json:"error,omitempty"`
}
// AmqpChannel sets a AMQP connection up using SSL if configuration is provided
@ -362,7 +362,7 @@ func (rpc *AmqpRPCServer) processMessage(msg amqp.Delivery) {
rpc.log.Audit(fmt.Sprintf(" [s<][%s][%s] Misrouted message: %s - %s - %s", rpc.serverQueue, msg.ReplyTo, msg.Type, core.B64enc(msg.Body), msg.CorrelationId))
return
}
var response RPCResponse
var response rpcResponse
var err error
response.ReturnVal, err = cb(msg.Body)
response.Error = wrapError(err)
@ -407,7 +407,7 @@ func (rpc *AmqpRPCServer) replyTooManyRequests(msg amqp.Delivery) {
// until a fatal error is returned or AmqpRPCServer.Stop() is called and all
// remaining messages are processed.
func (rpc *AmqpRPCServer) Start(c cmd.Config) error {
tooManyGoroutines := RPCResponse{
tooManyGoroutines := rpcResponse{
Error: wrapError(core.TooManyRPCRequestsError("RPC server has spawned too many Goroutines")),
}
tooManyRequestsResponse, err := json.Marshal(tooManyGoroutines)
@ -632,7 +632,7 @@ func (rpc *AmqpRPCCLient) DispatchSync(method string, body []byte) (response []b
callStarted := time.Now()
select {
case jsonResponse := <-rpc.Dispatch(method, body):
var rpcResponse RPCResponse
var rpcResponse rpcResponse
err = json.Unmarshal(jsonResponse, &rpcResponse)
if err != nil {
return

View File

@ -9,14 +9,14 @@ import (
"time"
)
// RPCClient describes the functions an RPC Client performs
type RPCClient interface {
// Client describes the functions an RPC Client performs
type Client interface {
SetTimeout(time.Duration)
Dispatch(string, []byte) chan []byte
DispatchSync(string, []byte) ([]byte, error)
}
// RPCServer describes the functions an RPC Server performs
type RPCServer interface {
// Server describes the functions an RPC Server performs
type Server interface {
Handle(string, func([]byte) ([]byte, error))
}

View File

@ -161,7 +161,7 @@ func errorCondition(method string, err error, obj interface{}) {
}
// NewRegistrationAuthorityServer constructs an RPC server
func NewRegistrationAuthorityServer(rpc RPCServer, impl core.RegistrationAuthority) error {
func NewRegistrationAuthorityServer(rpc Server, impl core.RegistrationAuthority) error {
log := blog.GetAuditLogger()
rpc.Handle(MethodNewRegistration, func(req []byte) (response []byte, err error) {
@ -338,11 +338,11 @@ func NewRegistrationAuthorityServer(rpc RPCServer, impl core.RegistrationAuthori
// RegistrationAuthorityClient represents an RA RPC client
type RegistrationAuthorityClient struct {
rpc RPCClient
rpc Client
}
// NewRegistrationAuthorityClient constructs an RPC client
func NewRegistrationAuthorityClient(client RPCClient) (rac RegistrationAuthorityClient, err error) {
func NewRegistrationAuthorityClient(client Client) (rac RegistrationAuthorityClient, err error) {
rac = RegistrationAuthorityClient{rpc: client}
return
}
@ -489,7 +489,7 @@ func (rac RegistrationAuthorityClient) OnValidationUpdate(authz core.Authorizati
//
// ValidationAuthorityClient / Server
// -> UpdateValidations
func NewValidationAuthorityServer(rpc RPCServer, impl core.ValidationAuthority) (err error) {
func NewValidationAuthorityServer(rpc Server, impl core.ValidationAuthority) (err error) {
rpc.Handle(MethodUpdateValidations, func(req []byte) (response []byte, err error) {
var vaReq validationRequest
if err = json.Unmarshal(req, &vaReq); err != nil {
@ -533,11 +533,11 @@ func NewValidationAuthorityServer(rpc RPCServer, impl core.ValidationAuthority)
// ValidationAuthorityClient represents an RPC client for the VA
type ValidationAuthorityClient struct {
rpc RPCClient
rpc Client
}
// NewValidationAuthorityClient constructs an RPC client
func NewValidationAuthorityClient(client RPCClient) (vac ValidationAuthorityClient, err error) {
func NewValidationAuthorityClient(client Client) (vac ValidationAuthorityClient, err error) {
vac = ValidationAuthorityClient{rpc: client}
return
}
@ -582,7 +582,8 @@ func (vac ValidationAuthorityClient) CheckCAARecords(ident core.AcmeIdentifier)
return
}
func NewPublisherServer(rpc RPCServer, impl core.Publisher) (err error) {
// NewPublisherServer creates a new server that wraps a CT publisher
func NewPublisherServer(rpc Server, impl core.Publisher) (err error) {
rpc.Handle(MethodSubmitToCT, func(req []byte) (response []byte, err error) {
err = impl.SubmitToCT(req)
return
@ -593,11 +594,11 @@ func NewPublisherServer(rpc RPCServer, impl core.Publisher) (err error) {
// PublisherClient is a client to communicate with the Publisher Authority
type PublisherClient struct {
rpc RPCClient
rpc Client
}
// NewPublisherClient constructs an RPC client
func NewPublisherClient(client RPCClient) (pub PublisherClient, err error) {
func NewPublisherClient(client Client) (pub PublisherClient, err error) {
pub = PublisherClient{rpc: client}
return
}
@ -612,7 +613,7 @@ func (pub PublisherClient) SubmitToCT(der []byte) (err error) {
//
// CertificateAuthorityClient / Server
// -> IssueCertificate
func NewCertificateAuthorityServer(rpc RPCServer, impl core.CertificateAuthority) (err error) {
func NewCertificateAuthorityServer(rpc Server, impl core.CertificateAuthority) (err error) {
rpc.Handle(MethodIssueCertificate, func(req []byte) (response []byte, err error) {
var icReq issueCertificateRequest
err = json.Unmarshal(req, &icReq)
@ -679,11 +680,11 @@ func NewCertificateAuthorityServer(rpc RPCServer, impl core.CertificateAuthority
// CertificateAuthorityClient is a client to communicate with the CA.
type CertificateAuthorityClient struct {
rpc RPCClient
rpc Client
}
// NewCertificateAuthorityClient constructs an RPC client
func NewCertificateAuthorityClient(client RPCClient) (cac CertificateAuthorityClient, err error) {
func NewCertificateAuthorityClient(client Client) (cac CertificateAuthorityClient, err error) {
cac = CertificateAuthorityClient{rpc: client}
return
}
@ -745,7 +746,7 @@ func (cac CertificateAuthorityClient) GenerateOCSP(signRequest core.OCSPSigningR
}
// NewStorageAuthorityServer constructs an RPC server
func NewStorageAuthorityServer(rpc RPCServer, impl core.StorageAuthority) error {
func NewStorageAuthorityServer(rpc Server, impl core.StorageAuthority) error {
rpc.Handle(MethodUpdateRegistration, func(req []byte) (response []byte, err error) {
var reg core.Registration
if err = json.Unmarshal(req, &reg); err != nil {
@ -1034,7 +1035,7 @@ func NewStorageAuthorityServer(rpc RPCServer, impl core.StorageAuthority) error
}
sct, err := impl.GetSCTReceipt(gsctReq.Serial, gsctReq.LogID)
jsonResponse, err := json.Marshal(core.RPCSignedCertificateTimestamp(sct))
jsonResponse, err := json.Marshal(core.SignedCertificateTimestamp(sct))
if err != nil {
// AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3
errorCondition(MethodGetSCTReceipt, err, req)
@ -1045,7 +1046,7 @@ func NewStorageAuthorityServer(rpc RPCServer, impl core.StorageAuthority) error
})
rpc.Handle(MethodAddSCTReceipt, func(req []byte) (response []byte, err error) {
var sct core.RPCSignedCertificateTimestamp
var sct core.SignedCertificateTimestamp
err = json.Unmarshal(req, &sct)
if err != nil {
// AUDIT[ Improper Messages ] 0786b6f2-91ca-4f48-9883-842a19084c64
@ -1068,11 +1069,11 @@ func NewStorageAuthorityServer(rpc RPCServer, impl core.StorageAuthority) error
// StorageAuthorityClient is a client to communicate with the Storage Authority
type StorageAuthorityClient struct {
rpc RPCClient
rpc Client
}
// NewStorageAuthorityClient constructs an RPC client
func NewStorageAuthorityClient(client RPCClient) (sac StorageAuthorityClient, err error) {
func NewStorageAuthorityClient(client Client) (sac StorageAuthorityClient, err error) {
sac = StorageAuthorityClient{rpc: client}
return
}
@ -1124,10 +1125,10 @@ func (cac StorageAuthorityClient) GetAuthorization(id string) (authz core.Author
}
// GetLatestValidAuthorization sends a request to get an Authorization by RegID, Identifier
func (cac StorageAuthorityClient) GetLatestValidAuthorization(registrationId int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
func (cac StorageAuthorityClient) GetLatestValidAuthorization(registrationID int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
var lvar latestValidAuthorizationRequest
lvar.RegID = registrationId
lvar.RegID = registrationID
lvar.Identifier = identifier
data, err := json.Marshal(lvar)
@ -1331,6 +1332,8 @@ func (cac StorageAuthorityClient) CountCertificatesRange(start, end time.Time) (
return
}
// GetSCTReceipt retrieves an SCT according to the serial number of a certificate
// and the logID of the log to which it was submitted.
func (cac StorageAuthorityClient) GetSCTReceipt(serial string, logID string) (receipt core.SignedCertificateTimestamp, err error) {
var gsctReq struct {
Serial string
@ -1353,6 +1356,7 @@ func (cac StorageAuthorityClient) GetSCTReceipt(serial string, logID string) (re
return
}
// AddSCTReceipt adds a new SCT to the database.
func (cac StorageAuthorityClient) AddSCTReceipt(sct core.SignedCertificateTimestamp) (err error) {
data, err := json.Marshal(sct)
if err != nil {

View File

@ -11,6 +11,7 @@ import (
"net/url"
"strings"
// Provide access to the MySQL driver
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/go-sql-driver/mysql"
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
"github.com/letsencrypt/boulder/core"

View File

@ -212,16 +212,16 @@ func (ssa *SQLStorageAuthority) GetAuthorization(id string) (authz core.Authoriz
}
// GetLatestValidAuthorization gets the valid authorization with biggest expire date for a given domain and registrationId
func (ssa *SQLStorageAuthority) GetLatestValidAuthorization(registrationId int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
func (ssa *SQLStorageAuthority) GetLatestValidAuthorization(registrationID int64, identifier core.AcmeIdentifier) (authz core.Authorization, err error) {
ident, err := json.Marshal(identifier)
if err != nil {
return
}
var auth core.Authorization
err = ssa.dbMap.SelectOne(&auth, "SELECT id FROM authz "+
"WHERE identifier = :identifier AND registrationID = :registrationId AND status = 'valid' "+
"WHERE identifier = :identifier AND registrationID = :registrationID AND status = 'valid' "+
"ORDER BY expires DESC LIMIT 1",
map[string]interface{}{"identifier": string(ident), "registrationId": registrationId})
map[string]interface{}{"identifier": string(ident), "registrationID": registrationID})
if err != nil {
return
}
@ -229,15 +229,18 @@ func (ssa *SQLStorageAuthority) GetLatestValidAuthorization(registrationId int64
return ssa.GetAuthorization(auth.ID)
}
// TooManyCertificatesError indicates that the number of certificates returned by
// CountCertificates exceeded the hard-coded limit of 10,000 certificates.
type TooManyCertificatesError string
func (t TooManyCertificatesError) Error() string {
return string(t)
}
// CountCertificates returns the number of certificates issued within a time
// CountCertificatesByName returns the number of certificates issued within a time
// period containing DNSNames that are equal to, or subdomains of, the given
// domain name.
//
// The highest count this function can return is 10,000. If there are more
// certificates than that matching the provided domain name, it will return
// TooManyCertificatesError.

View File

@ -168,10 +168,10 @@ func TestAddAuthorization(t *testing.T) {
}
func CreateDomainAuth(t *testing.T, domainName string, sa *SQLStorageAuthority) (authz core.Authorization) {
return CreateDomainAuthWithRegId(t, domainName, sa, 42)
return CreateDomainAuthWithRegID(t, domainName, sa, 42)
}
func CreateDomainAuthWithRegId(t *testing.T, domainName string, sa *SQLStorageAuthority, regID int64) (authz core.Authorization) {
func CreateDomainAuthWithRegID(t *testing.T, domainName string, sa *SQLStorageAuthority, regID int64) (authz core.Authorization) {
// create pending auth
authz, err := sa.NewPendingAuthorization(core.Authorization{RegistrationID: regID, Challenges: []core.Challenge{core.Challenge{}}})
@ -212,7 +212,7 @@ func TestGetLatestValidAuthorizationBasic(t *testing.T) {
reg := satest.CreateWorkingRegistration(t, sa)
// authorize "example.org"
authz = CreateDomainAuthWithRegId(t, "example.org", sa, reg.ID)
authz = CreateDomainAuthWithRegID(t, "example.org", sa, reg.ID)
// finalize auth
authz.Status = core.StatusValid
@ -243,7 +243,7 @@ func TestGetLatestValidAuthorizationMultiple(t *testing.T) {
reg := satest.CreateWorkingRegistration(t, sa)
// create invalid authz
authz := CreateDomainAuthWithRegId(t, domain, sa, reg.ID)
authz := CreateDomainAuthWithRegID(t, domain, sa, reg.ID)
exp := time.Now().AddDate(0, 0, 10) // expire in 10 day
authz.Expires = &exp
authz.Status = core.StatusInvalid
@ -255,7 +255,7 @@ func TestGetLatestValidAuthorizationMultiple(t *testing.T) {
test.AssertError(t, err, "Should not have found a valid auth for "+domain)
// create valid auth
authz = CreateDomainAuthWithRegId(t, domain, sa, reg.ID)
authz = CreateDomainAuthWithRegID(t, domain, sa, reg.ID)
exp = time.Now().AddDate(0, 0, 1) // expire in 1 day
authz.Expires = &exp
authz.Status = core.StatusValid
@ -271,7 +271,7 @@ func TestGetLatestValidAuthorizationMultiple(t *testing.T) {
test.AssertEquals(t, authz.RegistrationID, reg.ID)
// create a newer auth
newAuthz := CreateDomainAuthWithRegId(t, domain, sa, reg.ID)
newAuthz := CreateDomainAuthWithRegID(t, domain, sa, reg.ID)
exp = time.Now().AddDate(0, 0, 2) // expire in 2 day
newAuthz.Expires = &exp
newAuthz.Status = core.StatusValid

24
test.sh
View File

@ -63,13 +63,23 @@ function run() {
}
function run_and_comment() {
if [ "x${TRAVIS}" = "x" ] || [ "${TRAVIS_PULL_REQUEST}" == "false" ] || [ ! -f "${GITHUB_SECRET_FILE}" ] ; then
run "$@"
echo "$@"
result=$("$@" 2>&1)
echo ${result}
if [ "x${result}" == "x" ]; then
update_status --state success
echo "Success: $@"
else
result=$(run "$@")
local status=$?
# Only send a comment if exit code > 0
if [ ${status} -ne 0 ] ; then
FAILURE=1
update_status --state failure
echo "[!] FAILURE: $@"
fi
# If this is a travis PR run, post a comment
if [ "x${TRAVIS}" != "x" ] && [ "${TRAVIS_PULL_REQUEST}" != "false" ] && [ -f "${GITHUB_SECRET_FILE}" ] ; then
# If the output is non-empty, post a comment and mark this as a failure
if [ "x${result}" -ne "x" ] ; then
echo $'```\n'${result}$'\n```' | github-pr-status --authfile $GITHUB_SECRET_FILE \
--owner "letsencrypt" --repo "boulder" \
comment --pr "${TRAVIS_PULL_REQUEST}" -b -
@ -157,7 +167,7 @@ fi
#
if [[ "$RUN" =~ "lint" ]] ; then
start_context "test/golint"
[ -x "$(which golint)" ] && run golint ./...
run_and_comment golint -min_confidence=0.81 ./...
end_context #test/golint
fi

View File

@ -245,7 +245,7 @@ func TestSimpleHttpTLS(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateSimpleHTTP(ident, chall)
@ -288,7 +288,7 @@ func TestSimpleHttp(t *testing.T) {
}
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: badPort}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
invalidChall, err := va.validateSimpleHTTP(ident, chall)
test.AssertEquals(t, invalidChall.Status, core.StatusInvalid)
@ -296,7 +296,7 @@ func TestSimpleHttp(t *testing.T) {
test.AssertEquals(t, invalidChall.Error.Type, core.ConnectionProblem)
va = NewValidationAuthorityImpl(&PortConfig{HTTPPort: goodPort}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateSimpleHTTP(ident, chall)
test.AssertEquals(t, finChall.Status, core.StatusValid)
@ -375,7 +375,7 @@ func TestSimpleHttpRedirectLookup(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
chall.Token = pathMoved
@ -437,7 +437,7 @@ func TestSimpleHttpRedirectLoop(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateSimpleHTTP(ident, chall)
@ -457,7 +457,7 @@ func TestDvsni(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateDvsni(ident, chall)
@ -517,7 +517,7 @@ func TestDVSNIWithTLSError(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
invalidChall, err := va.validateDvsni(ident, chall)
test.AssertEquals(t, invalidChall.Status, core.StatusInvalid)
@ -660,7 +660,7 @@ func TestHttp(t *testing.T) {
}
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: badPort}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
invalidChall, err := va.validateHTTP01(ident, chall)
test.AssertEquals(t, invalidChall.Status, core.StatusInvalid)
@ -668,7 +668,7 @@ func TestHttp(t *testing.T) {
test.AssertEquals(t, invalidChall.Error.Type, core.ConnectionProblem)
va = NewValidationAuthorityImpl(&PortConfig{HTTPPort: goodPort}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
t.Logf("Trying to validate: %+v\n", chall)
finChall, err := va.validateHTTP01(ident, chall)
@ -743,7 +743,7 @@ func TestHTTPRedirectLookup(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
setChallengeToken(&chall, pathMoved)
@ -801,7 +801,7 @@ func TestHTTPRedirectLoop(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateHTTP01(ident, chall)
@ -836,7 +836,7 @@ func TestTLSSNI(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
log.Clear()
finChall, err := va.validateTLSSNI01(ident, chall)
@ -903,7 +903,7 @@ func TestTLSError(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
invalidChall, err := va.validateTLSSNI01(ident, chall)
test.AssertEquals(t, invalidChall.Status, core.StatusInvalid)
@ -921,7 +921,7 @@ func TestValidateHTTP(t *testing.T) {
test.AssertNotError(t, err, "failed to get test server port")
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -986,7 +986,7 @@ func TestValidateTLSSNI01(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1004,7 +1004,7 @@ func TestValidateTLSSNI01(t *testing.T) {
func TestValidateTLSSNINotSane(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default()) // no calls made
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1026,7 +1026,7 @@ func TestValidateTLSSNINotSane(t *testing.T) {
func TestUpdateValidations(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1082,7 +1082,7 @@ func TestCAAChecking(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
va.IssuerDomain = "letsencrypt.org"
for _, caaTest := range tests {
present, valid, err := va.CheckCAARecords(core.AcmeIdentifier{Type: "dns", Value: caaTest.Domain})
@ -1115,7 +1115,7 @@ func TestCAAChecking(t *testing.T) {
func TestDNSValidationFailure(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1152,7 +1152,7 @@ func TestDNSValidationInvalid(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1166,7 +1166,7 @@ func TestDNSValidationInvalid(t *testing.T) {
func TestDNSValidationNotSane(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1197,7 +1197,7 @@ func TestDNSValidationNotSane(t *testing.T) {
func TestDNSValidationServFail(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA
@ -1248,7 +1248,7 @@ func TestDNSValidationNoServer(t *testing.T) {
func TestDNSValidationLive(t *testing.T) {
stats, _ := statsd.NewNoopClient()
va := NewValidationAuthorityImpl(&PortConfig{}, stats, clock.Default())
va.DNSResolver = &mocks.MockDNS{}
va.DNSResolver = &mocks.DNSResolver{}
mockRA := &MockRegistrationAuthority{}
va.RA = mockRA

View File

@ -38,10 +38,14 @@ const (
IssuerPath = "/acme/issuer-cert"
BuildIDPath = "/build"
// Not included in net/http
// StatusRateLimited is not in net/http
StatusRateLimited = 429
)
// WebFrontEndImpl provides all the logic for Boulder's web-facing interface,
// i.e., ACME. Its members configure the paths for various ACME functions,
// plus a few other data items used in ACME. Its methods are primarily handlers
// for HTTPS requests for the various ACME functions.
type WebFrontEndImpl struct {
RA core.RegistrationAuthority
SA core.StorageGetter
@ -302,6 +306,8 @@ func addCacheHeader(w http.ResponseWriter, age float64) {
w.Header().Add("Cache-Control", fmt.Sprintf("public, max-age=%.f", age))
}
// Directory is an HTTP request handler that simply provides the directory
// object stored in the WFE's DirectoryJSON member.
func (wfe *WebFrontEndImpl) Directory(response http.ResponseWriter, request *http.Request) {
response.Header().Set("Content-Type", "application/json")
response.Write(wfe.DirectoryJSON)
@ -553,8 +559,7 @@ func (wfe *WebFrontEndImpl) NewRegistration(response http.ResponseWriter, reques
// Use an explicitly typed variable. Otherwise `go vet' incorrectly complains
// that reg.ID is a string being passed to %d.
var id int64 = reg.ID
regURL := fmt.Sprintf("%s%d", wfe.RegBase, id)
regURL := fmt.Sprintf("%s%d", wfe.RegBase, reg.ID)
responseBody, err := json.Marshal(reg)
if err != nil {
logEvent.Error = err.Error()
@ -833,6 +838,8 @@ func (wfe *WebFrontEndImpl) NewCertificate(response http.ResponseWriter, request
}
}
// Challenge handles POST requests to challenge URLs. Such requests are clients'
// responses to the server's challenges.
func (wfe *WebFrontEndImpl) Challenge(
response http.ResponseWriter,
request *http.Request) {

View File

@ -213,7 +213,7 @@ func setupWFE(t *testing.T) WebFrontEndImpl {
wfe.log.SyslogWriter = mocks.NewSyslogWriter()
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.stats, _ = statsd.NewNoopClient()
wfe.SubscriberAgreementURL = agreementURL
@ -533,7 +533,7 @@ func TestIssueCertificate(t *testing.T) {
wfe := setupWFE(t)
mux, err := wfe.Handler()
test.AssertNotError(t, err, "Problem setting up HTTP handlers")
mockLog := wfe.log.SyslogWriter.(*mocks.MockSyslogWriter)
mockLog := wfe.log.SyslogWriter.(*mocks.SyslogWriter)
// The mock CA we use always returns the same test certificate, with a Not
// Before of 2015-09-22. Since we're currently using a real RA instead of a
@ -548,10 +548,10 @@ func TestIssueCertificate(t *testing.T) {
// authorized, etc.
stats, _ := statsd.NewNoopClient(nil)
ra := ra.NewRegistrationAuthorityImpl(fakeClock, wfe.log, stats, cmd.RateLimitConfig{})
ra.SA = &mocks.MockSA{}
ra.SA = &mocks.StorageAuthority{}
ra.CA = &MockCA{}
ra.PA = &MockPA{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.RA = &ra
responseWriter := httptest.NewRecorder()
@ -670,7 +670,7 @@ func TestChallenge(t *testing.T) {
wfe := setupWFE(t)
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
responseWriter := httptest.NewRecorder()
var key jose.JsonWebKey
@ -706,7 +706,7 @@ func TestNewRegistration(t *testing.T) {
test.AssertNotError(t, err, "Problem setting up HTTP handlers")
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.stats, _ = statsd.NewNoopClient()
wfe.SubscriberAgreementURL = agreementURL
@ -878,7 +878,7 @@ func makeRevokeRequestJSON() ([]byte, error) {
// registration when GetRegistrationByKey is called, and we want to get a
// NoSuchRegistrationError for tests that pass regCheck = false to verifyPOST.
type mockSANoSuchRegistration struct {
mocks.MockSA
mocks.StorageAuthority
}
func (msa mockSANoSuchRegistration) GetRegistrationByKey(jwk jose.JsonWebKey) (core.Registration, error) {
@ -901,7 +901,7 @@ func TestRevokeCertificateCertKey(t *testing.T) {
test.AssertNotError(t, err, "Failed to make revokeRequestJSON")
wfe := setupWFE(t)
wfe.SA = &mockSANoSuchRegistration{mocks.MockSA{}}
wfe.SA = &mockSANoSuchRegistration{mocks.StorageAuthority{}}
responseWriter := httptest.NewRecorder()
nonce, err := wfe.nonceService.Nonce()
@ -991,7 +991,7 @@ func TestRevokeCertificateAlreadyRevoked(t *testing.T) {
wfe := setupWFE(t)
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mockSANoSuchRegistration{mocks.MockSA{}}
wfe.SA = &mockSANoSuchRegistration{mocks.StorageAuthority{}}
wfe.stats, _ = statsd.NewNoopClient()
wfe.SubscriberAgreementURL = agreementURL
responseWriter := httptest.NewRecorder()
@ -1012,7 +1012,7 @@ func TestAuthorization(t *testing.T) {
test.AssertNotError(t, err, "Problem setting up HTTP handlers")
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.stats, _ = statsd.NewNoopClient()
responseWriter := httptest.NewRecorder()
@ -1100,7 +1100,7 @@ func TestRegistration(t *testing.T) {
test.AssertNotError(t, err, "Problem setting up HTTP handlers")
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.stats, _ = statsd.NewNoopClient()
wfe.SubscriberAgreementURL = agreementURL
responseWriter := httptest.NewRecorder()
@ -1191,7 +1191,7 @@ func TestTermsRedirect(t *testing.T) {
wfe := setupWFE(t)
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
wfe.stats, _ = statsd.NewNoopClient()
wfe.SubscriberAgreementURL = agreementURL
@ -1227,14 +1227,14 @@ func TestGetCertificate(t *testing.T) {
wfe := setupWFE(t)
wfe.CertCacheDuration = time.Second * 10
wfe.CertNoCacheExpirationWindow = time.Hour * 24 * 7
wfe.SA = &mocks.MockSA{}
wfe.SA = &mocks.StorageAuthority{}
certPemBytes, _ := ioutil.ReadFile("test/178.crt")
certBlock, _ := pem.Decode(certPemBytes)
responseWriter := httptest.NewRecorder()
mockLog := wfe.log.SyslogWriter.(*mocks.MockSyslogWriter)
mockLog := wfe.log.SyslogWriter.(*mocks.SyslogWriter)
mockLog.Clear()
// Valid serial, cached
@ -1284,7 +1284,7 @@ func TestGetCertificate(t *testing.T) {
test.AssertEquals(t, responseWriter.Body.String(), `{"type":"urn:acme:error:malformed","detail":"Certificate not found"}`)
}
func assertCsrLogged(t *testing.T, mockLog *mocks.MockSyslogWriter) {
func assertCsrLogged(t *testing.T, mockLog *mocks.SyslogWriter) {
matches := mockLog.GetAllMatching("^\\[AUDIT\\] Certificate request JSON=")
test.Assert(t, len(matches) == 1,
fmt.Sprintf("Incorrect number of certificate request log entries: %d",
@ -1301,7 +1301,7 @@ func TestLogCsrPem(t *testing.T) {
err := json.Unmarshal([]byte(certificateRequestJSON), &certificateRequest)
test.AssertNotError(t, err, "Unable to parse certificateRequest")
mockSA := mocks.MockSA{}
mockSA := mocks.StorageAuthority{}
reg, err := mockSA.GetRegistration(789)
test.AssertNotError(t, err, "Unable to get registration")
@ -1310,7 +1310,7 @@ func TestLogCsrPem(t *testing.T) {
req.RemoteAddr = "12.34.98.76"
req.Header.Set("X-Forwarded-For", "10.0.0.1,172.16.0.1")
mockLog := wfe.log.SyslogWriter.(*mocks.MockSyslogWriter)
mockLog := wfe.log.SyslogWriter.(*mocks.SyslogWriter)
mockLog.Clear()
wfe.logCsr(req, certificateRequest, reg)
@ -1334,7 +1334,7 @@ func TestLengthRequired(t *testing.T) {
}
type mockSADifferentStoredKey struct {
mocks.MockSA
mocks.StorageAuthority
}
func (sa mockSADifferentStoredKey) GetRegistrationByKey(jwk jose.JsonWebKey) (core.Registration, error) {
@ -1349,7 +1349,7 @@ func (sa mockSADifferentStoredKey) GetRegistrationByKey(jwk jose.JsonWebKey) (co
func TestVerifyPOSTUsesStoredKey(t *testing.T) {
wfe := setupWFE(t)
wfe.SA = &mockSADifferentStoredKey{mocks.MockSA{}}
wfe.SA = &mockSADifferentStoredKey{mocks.StorageAuthority{}}
// signRequest signs with test1Key, but our special mock returns a
// registration with test2Key
_, _, _, err := wfe.verifyPOST(makePostRequest(signRequest(t, `{"resource":"foo"}`, &wfe.nonceService)), true, "foo")