diff --git a/acme/error.go b/acme/error.go index d44d1581..4313a7b2 100644 --- a/acme/error.go +++ b/acme/error.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" ) const ( @@ -28,6 +29,27 @@ type TOSError struct { RemoteError } +type domainError struct { + Domain string + Error error +} + +type challengeError struct { + RemoteError + records []validationRecord +} + +func (c challengeError) Error() string { + + var errStr string + for _, validation := range c.records { + errStr = errStr + fmt.Sprintf("\tValidation for %s:%s\n\tResolved to:\n\t\t%s\n\tUsed: %s\n\n", + validation.Hostname, validation.Port, strings.Join(validation.ResolvedAddresses, "\n\t\t"), validation.UsedAddress) + } + + return fmt.Sprintf("%s\nError Detail:\n%s", c.RemoteError.Error(), errStr) +} + func handleHTTPError(resp *http.Response) error { var errorDetail RemoteError decoder := json.NewDecoder(resp.Body) @@ -46,7 +68,6 @@ func handleHTTPError(resp *http.Response) error { return errorDetail } -type domainError struct { - Domain string - Error error +func handleChallengeError(chlng challenge) error { + return challengeError{chlng.Error, chlng.ValidationRecords} } diff --git a/acme/http_challenge.go b/acme/http_challenge.go index 8ace6795..55238542 100644 --- a/acme/http_challenge.go +++ b/acme/http_challenge.go @@ -80,7 +80,7 @@ Loop: case "pending": break case "invalid": - return errors.New("The server could not validate our request.") + return handleChallengeError(challengeResponse) default: return errors.New("The server returned an unexpected state.") } diff --git a/acme/messages.go b/acme/messages.go index 2ec0bb74..910f6c06 100644 --- a/acme/messages.go +++ b/acme/messages.go @@ -72,15 +72,25 @@ type identifier struct { Value string `json:"value"` } +type validationRecord struct { + URI string `json:"url,omitempty"` + Hostname string `json:"hostname,omitempty"` + Port string `json:"port,omitempty"` + ResolvedAddresses []string `json:"addressesResolved,omitempty"` + UsedAddress string `json:"addressUsed,omitempty"` +} + type challenge struct { - Resource string `json:"resource,omitempty"` - Type string `json:"type,omitempty"` - Status string `json:"status,omitempty"` - URI string `json:"uri,omitempty"` - Token string `json:"token,omitempty"` - KeyAuthorization string `json:"keyAuthorization,omitempty"` - TLS bool `json:"tls,omitempty"` - Iterations int `json:"n,omitempty"` + Resource string `json:"resource,omitempty"` + Type string `json:"type,omitempty"` + Status string `json:"status,omitempty"` + URI string `json:"uri,omitempty"` + Token string `json:"token,omitempty"` + KeyAuthorization string `json:"keyAuthorization,omitempty"` + TLS bool `json:"tls,omitempty"` + Iterations int `json:"n,omitempty"` + Error RemoteError `json:"error,omitempty"` + ValidationRecords []validationRecord `json:"validationRecord,omitempty"` } type csrMessage struct { diff --git a/acme/tls_sni_challenge.go b/acme/tls_sni_challenge.go index 57ddd7d6..37ffd8f8 100644 --- a/acme/tls_sni_challenge.go +++ b/acme/tls_sni_challenge.go @@ -90,7 +90,7 @@ Loop: case "pending": break case "invalid": - return errors.New("The server could not validate our request.") + return handleChallengeError(challengeResponse) default: return errors.New("The server returned an unexpected state.") } @@ -146,8 +146,8 @@ func (t *tlsSNIChallenge) startSNITLSServer(cert tls.Certificate) { } // Signal successfull start t.start <- tlsListener - + http.Serve(tlsListener, nil) - + t.end <- nil }