diff --git a/vendor/github.com/xenolf/lego/acme/challenges.go b/vendor/github.com/xenolf/lego/acme/challenges.go index 1140b107..d10f82b8 100644 --- a/vendor/github.com/xenolf/lego/acme/challenges.go +++ b/vendor/github.com/xenolf/lego/acme/challenges.go @@ -7,9 +7,11 @@ const ( // HTTP01 is the "http-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http // Note: HTTP01ChallengePath returns the URL path to fulfill this challenge HTTP01 = Challenge("http-01") + // DNS01 is the "dns-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#dns // Note: DNS01Record returns a DNS record which will fulfill this challenge DNS01 = Challenge("dns-01") + // TLSALPN01 is the "tls-alpn-01" ACME challenge https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01 TLSALPN01 = Challenge("tls-alpn-01") ) diff --git a/vendor/github.com/xenolf/lego/acme/client.go b/vendor/github.com/xenolf/lego/acme/client.go index b8daa751..f9857ebd 100644 --- a/vendor/github.com/xenolf/lego/acme/client.go +++ b/vendor/github.com/xenolf/lego/acme/client.go @@ -26,6 +26,9 @@ const ( // “new-reg”, “new-authz” and “new-cert” endpoints. From the documentation the // limitation is 20 requests per second, but using 20 as value doesn't work but 18 do overallRequestLimit = 18 + + statusValid = "valid" + statusInvalid = "invalid" ) // User interface is to be implemented by users of this library. @@ -41,6 +44,17 @@ type solver interface { Solve(challenge challenge, domain string) error } +// Interface for challenges like dns, where we can set a record in advance for ALL challenges. +// This saves quite a bit of time vs creating the records and solving them serially. +type preSolver interface { + PreSolve(challenge challenge, domain string) error +} + +// Interface for challenges like dns, where we can solve all the challenges before to delete them. +type cleanup interface { + CleanUp(challenge challenge, domain string) error +} + type validateFunc func(j *jws, domain, uri string, chlng challenge) error // Client is the user-friendy way to ACME @@ -374,8 +388,10 @@ DNSNames: } } - // Add the CSR to the certificate so that it can be used for renewals. - cert.CSR = pemEncode(&csr) + if cert != nil { + // Add the CSR to the certificate so that it can be used for renewals. + cert.CSR = pemEncode(&csr) + } // do not return an empty failures map, because // it would still be a non-nil error value @@ -396,7 +412,7 @@ DNSNames: // the whole certificate will fail. func (c *Client) ObtainCertificate(domains []string, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (*CertificateResource, error) { if len(domains) == 0 { - return nil, errors.New("No domains to obtain a certificate for") + return nil, errors.New("no domains to obtain a certificate for") } if bundle { @@ -489,9 +505,9 @@ func (c *Client) RenewCertificate(cert CertificateResource, bundle, mustStaple b // Start by checking to see if the certificate was based off a CSR, and // use that if it's defined. if len(cert.CSR) > 0 { - csr, err := pemDecodeTox509CSR(cert.CSR) - if err != nil { - return nil, err + csr, errP := pemDecodeTox509CSR(cert.CSR) + if errP != nil { + return nil, errP } newCert, failures := c.ObtainCertificateForCSR(*csr, bundle) return newCert, failures @@ -524,7 +540,6 @@ func (c *Client) RenewCertificate(cert CertificateResource, bundle, mustStaple b } func (c *Client) createOrderForIdentifiers(domains []string) (orderResource, error) { - var identifiers []identifier for _, domain := range domains { identifiers = append(identifiers, identifier{Type: "dns", Value: domain}) @@ -548,29 +563,75 @@ func (c *Client) createOrderForIdentifiers(domains []string) (orderResource, err return orderRes, nil } +// an authz with the solver we have chosen and the index of the challenge associated with it +type selectedAuthSolver struct { + authz authorization + challengeIndex int + solver solver +} + // Looks through the challenge combinations to find a solvable match. // Then solves the challenges in series and returns. func (c *Client) solveChallengeForAuthz(authorizations []authorization) error { failures := make(ObtainError) - // loop through the resources, basically through the domains. + authSolvers := []*selectedAuthSolver{} + + // loop through the resources, basically through the domains. First pass just selects a solver for each authz. for _, authz := range authorizations { - if authz.Status == "valid" { + if authz.Status == statusValid { // Boulder might recycle recent validated authz (see issue #267) log.Infof("[%s] acme: Authorization already valid; skipping challenge", authz.Identifier.Value) continue } + if i, solvr := c.chooseSolver(authz, authz.Identifier.Value); solvr != nil { + authSolvers = append(authSolvers, &selectedAuthSolver{ + authz: authz, + challengeIndex: i, + solver: solvr, + }) + } else { + failures[authz.Identifier.Value] = fmt.Errorf("[%s] acme: Could not determine solvers", authz.Identifier.Value) + } + } - // no solvers - no solving - if i, solver := c.chooseSolver(authz, authz.Identifier.Value); solver != nil { - err := solver.Solve(authz.Challenges[i], authz.Identifier.Value) - if err != nil { - //c.disableAuthz(authz.Identifier) + // for all valid presolvers, first submit the challenges so they have max time to propagate + for _, item := range authSolvers { + authz := item.authz + i := item.challengeIndex + if presolver, ok := item.solver.(preSolver); ok { + if err := presolver.PreSolve(authz.Challenges[i], authz.Identifier.Value); err != nil { failures[authz.Identifier.Value] = err } - } else { - //c.disableAuthz(authz) - failures[authz.Identifier.Value] = fmt.Errorf("[%s] acme: Could not determine solvers", authz.Identifier.Value) + } + } + + defer func() { + // clean all created TXT records + for _, item := range authSolvers { + if clean, ok := item.solver.(cleanup); ok { + if failures[item.authz.Identifier.Value] != nil { + // already failed in previous loop + continue + } + err := clean.CleanUp(item.authz.Challenges[item.challengeIndex], item.authz.Identifier.Value) + if err != nil { + log.Warnf("Error cleaning up %s: %v ", item.authz.Identifier.Value, err) + } + } + } + }() + + // finally solve all challenges for real + for _, item := range authSolvers { + authz := item.authz + i := item.challengeIndex + if failures[authz.Identifier.Value] != nil { + // already failed in previous loop + continue + } + if err := item.solver.Solve(authz.Challenges[i], authz.Identifier.Value); err != nil { + failures[authz.Identifier.Value] = err } } @@ -604,7 +665,7 @@ func (c *Client) getAuthzForOrder(order orderResource) ([]authorization, error) go func(authzURL string) { var authz authorization - _, err := getJSON(authzURL, &authz) + _, err := postAsGet(c.jws, authzURL, &authz) if err != nil { errc <- domainError{Domain: authz.Identifier.Value, Error: err} return @@ -696,7 +757,7 @@ func (c *Client) requestCertificateForCsr(order orderResource, bundle bool, csr return nil, err } - if retOrder.Status == "invalid" { + if retOrder.Status == statusInvalid { return nil, err } @@ -706,7 +767,7 @@ func (c *Client) requestCertificateForCsr(order orderResource, bundle bool, csr PrivateKey: privateKeyPem, } - if retOrder.Status == "valid" { + if retOrder.Status == statusValid { // if the certificate is available right away, short cut! ok, err := c.checkCertResponse(retOrder, &certRes, bundle) if err != nil { @@ -728,7 +789,7 @@ func (c *Client) requestCertificateForCsr(order orderResource, bundle bool, csr case <-stopTimer.C: return nil, errors.New("certificate polling timed out") case <-retryTick.C: - _, err := getJSON(order.URL, &retOrder) + _, err := postAsGet(c.jws, order.URL, &retOrder) if err != nil { return nil, err } @@ -750,10 +811,9 @@ func (c *Client) requestCertificateForCsr(order orderResource, bundle bool, csr // should already have the Domain (common name) field populated. If bundle is // true, the certificate will be bundled with the issuer's cert. func (c *Client) checkCertResponse(order orderMessage, certRes *CertificateResource, bundle bool) (bool, error) { - switch order.Status { - case "valid": - resp, err := httpGet(order.Certificate) + case statusValid: + resp, err := postAsGet(c.jws, order.Certificate, nil) if err != nil { return false, err } @@ -801,7 +861,7 @@ func (c *Client) checkCertResponse(order orderMessage, certRes *CertificateResou case "processing": return false, nil - case "invalid": + case statusInvalid: return false, errors.New("order has invalid state: invalid") default: return false, nil @@ -811,7 +871,7 @@ func (c *Client) checkCertResponse(order orderMessage, certRes *CertificateResou // getIssuerCertificate requests the issuer certificate func (c *Client) getIssuerCertificate(url string) ([]byte, error) { log.Infof("acme: Requesting issuer cert from %s", url) - resp, err := httpGet(url) + resp, err := postAsGet(c.jws, url, nil) if err != nil { return nil, err } @@ -854,7 +914,10 @@ func parseLinks(links []string) map[string]string { func validate(j *jws, domain, uri string, c challenge) error { var chlng challenge - hdr, err := postJSON(j, uri, c, &chlng) + // Challenge initiation is done by sending a JWS payload containing the + // trivial JSON object `{}`. We use an empty struct instance as the postJSON + // payload here to achieve this result. + hdr, err := postJSON(j, uri, struct{}{}, &chlng) if err != nil { return err } @@ -863,12 +926,12 @@ func validate(j *jws, domain, uri string, c challenge) error { // Repeatedly check the server for an updated status on our request. for { switch chlng.Status { - case "valid": + case statusValid: log.Infof("[%s] The server validated our request", domain) return nil case "pending": case "processing": - case "invalid": + case statusInvalid: return handleChallengeError(chlng) default: return errors.New("the server returned an unexpected state") @@ -880,11 +943,15 @@ func validate(j *jws, domain, uri string, c challenge) error { // If it doesn't, we'll just poll hard. ra = 5 } + time.Sleep(time.Duration(ra) * time.Second) - hdr, err = getJSON(uri, &chlng) + resp, err := postAsGet(j, uri, &chlng) if err != nil { return err } + if resp != nil { + hdr = resp.Header + } } } diff --git a/vendor/github.com/xenolf/lego/acme/crypto.go b/vendor/github.com/xenolf/lego/acme/crypto.go index f5ebbf08..5ddeeaec 100644 --- a/vendor/github.com/xenolf/lego/acme/crypto.go +++ b/vendor/github.com/xenolf/lego/acme/crypto.go @@ -81,20 +81,20 @@ func GetOCSPForCert(bundle []byte) ([]byte, *ocsp.Response, error) { return nil, nil, errors.New("no issuing certificate URL") } - resp, err := httpGet(issuedCert.IssuingCertificateURL[0]) - if err != nil { - return nil, nil, err + resp, errC := httpGet(issuedCert.IssuingCertificateURL[0]) + if errC != nil { + return nil, nil, errC } defer resp.Body.Close() - issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024)) - if err != nil { - return nil, nil, err + issuerBytes, errC := ioutil.ReadAll(limitReader(resp.Body, 1024*1024)) + if errC != nil { + return nil, nil, errC } - issuerCert, err := x509.ParseCertificate(issuerBytes) - if err != nil { - return nil, nil, err + issuerCert, errC := x509.ParseCertificate(issuerBytes) + if errC != nil { + return nil, nil, errC } // Insert it into the slice on position 0 @@ -258,15 +258,6 @@ func pemDecode(data []byte) (*pem.Block, error) { return pemBlock, nil } -func pemDecodeTox509(pem []byte) (*x509.Certificate, error) { - pemBlock, err := pemDecode(pem) - if pemBlock == nil { - return nil, err - } - - return x509.ParseCertificate(pemBlock.Bytes) -} - func pemDecodeTox509CSR(pem []byte) (*x509.CertificateRequest, error) { pemBlock, err := pemDecode(pem) if pemBlock == nil { diff --git a/vendor/github.com/xenolf/lego/acme/dns_challenge.go b/vendor/github.com/xenolf/lego/acme/dns_challenge.go index c8a35eb8..d9c252e7 100644 --- a/vendor/github.com/xenolf/lego/acme/dns_challenge.go +++ b/vendor/github.com/xenolf/lego/acme/dns_challenge.go @@ -7,6 +7,7 @@ import ( "fmt" "net" "strings" + "sync" "time" "github.com/miekg/dns" @@ -18,18 +19,30 @@ type preCheckDNSFunc func(fqdn, value string) (bool, error) var ( // PreCheckDNS checks DNS propagation before notifying ACME that // the DNS challenge is ready. - PreCheckDNS preCheckDNSFunc = checkDNSPropagation - fqdnToZone = map[string]string{} + PreCheckDNS preCheckDNSFunc = checkDNSPropagation + fqdnToZone = map[string]string{} + muFqdnToZone sync.Mutex ) const defaultResolvConf = "/etc/resolv.conf" +const ( + // DefaultPropagationTimeout default propagation timeout + DefaultPropagationTimeout = 60 * time.Second + + // DefaultPollingInterval default polling interval + DefaultPollingInterval = 2 * time.Second + + // DefaultTTL default TTL + DefaultTTL = 120 +) + var defaultNameservers = []string{ "google-public-dns-a.google.com:53", "google-public-dns-b.google.com:53", } -// RecursiveNameservers are used to pre-check DNS propagations +// RecursiveNameservers are used to pre-check DNS propagation var RecursiveNameservers = getNameservers(defaultResolvConf, defaultNameservers) // DNSTimeout is used to override the default DNS timeout of 10 seconds. @@ -59,7 +72,7 @@ func DNS01Record(domain, keyAuth string) (fqdn string, value string, ttl int) { keyAuthShaBytes := sha256.Sum256([]byte(keyAuth)) // base64URL encoding without padding value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size]) - ttl = 120 + ttl = DefaultTTL fqdn = fmt.Sprintf("_acme-challenge.%s.", domain) return } @@ -71,8 +84,10 @@ type dnsChallenge struct { provider ChallengeProvider } -func (s *dnsChallenge) Solve(chlng challenge, domain string) error { - log.Infof("[%s] acme: Trying to solve DNS-01", domain) +// PreSolve just submits the txt record to the dns provider. It does not validate record propagation, or +// do anything at all with the acme server. +func (s *dnsChallenge) PreSolve(chlng challenge, domain string) error { + log.Infof("[%s] acme: Preparing to solve DNS-01", domain) if s.provider == nil { return errors.New("no DNS Provider configured") @@ -88,12 +103,18 @@ func (s *dnsChallenge) Solve(chlng challenge, domain string) error { if err != nil { return fmt.Errorf("error presenting token: %s", err) } - defer func() { - err := s.provider.CleanUp(domain, chlng.Token, keyAuth) - if err != nil { - log.Warnf("Error cleaning up %s: %v ", domain, err) - } - }() + + return nil +} + +func (s *dnsChallenge) Solve(chlng challenge, domain string) error { + log.Infof("[%s] acme: Trying to solve DNS-01", domain) + + // Generate the Key Authorization for the challenge + keyAuth, err := getKeyAuthorization(chlng.Token, s.jws.privKey) + if err != nil { + return err + } fqdn, value, _ := DNS01Record(domain, keyAuth) @@ -104,7 +125,7 @@ func (s *dnsChallenge) Solve(chlng challenge, domain string) error { case ChallengeProviderTimeout: timeout, interval = provider.Timeout() default: - timeout, interval = 60*time.Second, 2*time.Second + timeout, interval = DefaultPropagationTimeout, DefaultPollingInterval } err = WaitFor(timeout, interval, func() (bool, error) { @@ -117,6 +138,15 @@ func (s *dnsChallenge) Solve(chlng challenge, domain string) error { return s.validate(s.jws, domain, chlng.URL, challenge{Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth}) } +// CleanUp cleans the challenge +func (s *dnsChallenge) CleanUp(chlng challenge, domain string) error { + keyAuth, err := getKeyAuthorization(chlng.Token, s.jws.privKey) + if err != nil { + return err + } + return s.provider.CleanUp(domain, chlng.Token, keyAuth) +} + // checkDNSPropagation checks if the expected TXT record has been propagated to all authoritative nameservers. func checkDNSPropagation(fqdn, value string) (bool, error) { // Initial attempt to resolve at the recursive NS @@ -124,6 +154,7 @@ func checkDNSPropagation(fqdn, value string) (bool, error) { if err != nil { return false, err } + if r.Rcode == dns.RcodeSuccess { // If we see a CNAME here then use the alias for _, rr := range r.Answer { @@ -167,7 +198,7 @@ func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, erro } if !found { - return false, fmt.Errorf("NS %s did not return the expected TXT record", ns) + return false, fmt.Errorf("NS %s did not return the expected TXT record [fqdn: %s]", ns, fqdn) } } @@ -210,7 +241,7 @@ func lookupNameservers(fqdn string) ([]string, error) { zone, err := FindZoneByFqdn(fqdn, RecursiveNameservers) if err != nil { - return nil, fmt.Errorf("Could not determine the zone: %v", err) + return nil, fmt.Errorf("could not determine the zone: %v", err) } r, err := dnsQuery(zone, dns.TypeNS, RecursiveNameservers, true) @@ -227,12 +258,15 @@ func lookupNameservers(fqdn string) ([]string, error) { if len(authoritativeNss) > 0 { return authoritativeNss, nil } - return nil, fmt.Errorf("Could not determine authoritative nameservers") + return nil, fmt.Errorf("could not determine authoritative nameservers") } // FindZoneByFqdn determines the zone apex for the given fqdn by recursing up the // domain labels until the nameserver returns a SOA record in the answer section. func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) { + muFqdnToZone.Lock() + defer muFqdnToZone.Unlock() + // Do we have it cached? if zone, ok := fqdnToZone[fqdn]; ok { return zone, nil @@ -249,7 +283,7 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) { // Any response code other than NOERROR and NXDOMAIN is treated as error if in.Rcode != dns.RcodeNameError && in.Rcode != dns.RcodeSuccess { - return "", fmt.Errorf("Unexpected response code '%s' for %s", + return "", fmt.Errorf("unexpected response code '%s' for %s", dns.RcodeToString[in.Rcode], domain) } @@ -272,7 +306,7 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) { } } - return "", fmt.Errorf("Could not find the start of authority") + return "", fmt.Errorf("could not find the start of authority") } // dnsMsgContainsCNAME checks for a CNAME answer in msg diff --git a/vendor/github.com/xenolf/lego/acme/http.go b/vendor/github.com/xenolf/lego/acme/http.go index 8d7ee51e..8343b369 100644 --- a/vendor/github.com/xenolf/lego/acme/http.go +++ b/vendor/github.com/xenolf/lego/acme/http.go @@ -42,12 +42,14 @@ var ( ) const ( - // defaultGoUserAgent is the Go HTTP package user agent string. Too - // bad it isn't exported. If it changes, we should update it here, too. - defaultGoUserAgent = "Go-http-client/1.1" - // ourUserAgent is the User-Agent of this underlying library package. - ourUserAgent = "xenolf-acme" + // NOTE: Update this with each tagged release. + ourUserAgent = "xenolf-acme/1.2.1" + + // ourUserAgentComment is part of the UA comment linked to the version status of this underlying library package. + // values: detach|release + // NOTE: Update this with each tagged release. + ourUserAgentComment = "detach" // caCertificatesEnvVar is the environment variable name that can be used to // specify the path to PEM encoded CA Certificates that can be used to @@ -148,59 +150,63 @@ func getJSON(uri string, respBody interface{}) (http.Header, error) { func postJSON(j *jws, uri string, reqBody, respBody interface{}) (http.Header, error) { jsonBytes, err := json.Marshal(reqBody) if err != nil { - return nil, errors.New("Failed to marshal network message") + return nil, errors.New("failed to marshal network message") } - resp, err := j.post(uri, jsonBytes) - if err != nil { - return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) + resp, err := post(j, uri, jsonBytes, respBody) + if resp == nil { + return nil, err } defer resp.Body.Close() + return resp.Header, err +} + +func postAsGet(j *jws, uri string, respBody interface{}) (*http.Response, error) { + return post(j, uri, []byte{}, respBody) +} + +func post(j *jws, uri string, reqBody []byte, respBody interface{}) (*http.Response, error) { + resp, err := j.post(uri, reqBody) + if err != nil { + return nil, fmt.Errorf("failed to post JWS message. -> %v", err) + } + if resp.StatusCode >= http.StatusBadRequest { - - err := handleHTTPError(resp) - + err = handleHTTPError(resp) switch err.(type) { - case NonceError: - // Retry once if the nonce was invalidated - retryResp, err := j.post(uri, jsonBytes) - if err != nil { - return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) + retryResp, errP := j.post(uri, reqBody) + if errP != nil { + return nil, fmt.Errorf("failed to post JWS message. -> %v", errP) } - defer retryResp.Body.Close() - if retryResp.StatusCode >= http.StatusBadRequest { - return retryResp.Header, handleHTTPError(retryResp) + return retryResp, handleHTTPError(retryResp) } if respBody == nil { - return retryResp.Header, nil + return retryResp, nil } - return retryResp.Header, json.NewDecoder(retryResp.Body).Decode(respBody) - + return retryResp, json.NewDecoder(retryResp.Body).Decode(respBody) default: - return resp.Header, err - + return resp, err } - } if respBody == nil { - return resp.Header, nil + return resp, nil } - return resp.Header, json.NewDecoder(resp.Body).Decode(respBody) + return resp, json.NewDecoder(resp.Body).Decode(respBody) } // userAgent builds and returns the User-Agent string to use in requests. func userAgent() string { - ua := fmt.Sprintf("%s %s (%s; %s) %s", UserAgent, ourUserAgent, runtime.GOOS, runtime.GOARCH, defaultGoUserAgent) + ua := fmt.Sprintf("%s %s (%s; %s; %s)", UserAgent, ourUserAgent, ourUserAgentComment, runtime.GOOS, runtime.GOARCH) return strings.TrimSpace(ua) } diff --git a/vendor/github.com/xenolf/lego/acme/http_challenge_server.go b/vendor/github.com/xenolf/lego/acme/http_challenge_server.go index 319e2618..9c595d7f 100644 --- a/vendor/github.com/xenolf/lego/acme/http_challenge_server.go +++ b/vendor/github.com/xenolf/lego/acme/http_challenge_server.go @@ -35,7 +35,7 @@ func (s *HTTPProviderServer) Present(domain, token, keyAuth string) error { var err error s.listener, err = net.Listen("tcp", net.JoinHostPort(s.iface, s.port)) if err != nil { - return fmt.Errorf("Could not start HTTP server for challenge -> %v", err) + return fmt.Errorf("could not start HTTP server for challenge -> %v", err) } s.done = make(chan bool) @@ -62,20 +62,31 @@ func (s *HTTPProviderServer) serve(domain, token, keyAuth string) { mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.Host, domain) && r.Method == http.MethodGet { w.Header().Add("Content-Type", "text/plain") - w.Write([]byte(keyAuth)) + _, err := w.Write([]byte(keyAuth)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } log.Infof("[%s] Served key authentication", domain) } else { log.Warnf("Received request for domain %s with method %s but the domain did not match any challenge. Please ensure your are passing the HOST header properly.", r.Host, r.Method) - w.Write([]byte("TEST")) + _, err := w.Write([]byte("TEST")) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } } }) - httpServer := &http.Server{ - Handler: mux, - } + httpServer := &http.Server{Handler: mux} + // Once httpServer is shut down we don't want any lingering // connections, so disable KeepAlives. httpServer.SetKeepAlivesEnabled(false) - httpServer.Serve(s.listener) + + err := httpServer.Serve(s.listener) + if err != nil { + log.Println(err) + } s.done <- true } diff --git a/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge.go b/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge.go index d8035199..cc70c350 100644 --- a/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge.go +++ b/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge.go @@ -12,8 +12,8 @@ import ( ) // idPeAcmeIdentifierV1 is the SMI Security for PKIX Certification Extension OID referencing the ACME extension. -// Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.1 -var idPeAcmeIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1} +// Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-5.1 +var idPeAcmeIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31} type tlsALPNChallenge struct { jws *jws @@ -58,7 +58,7 @@ func TLSALPNChallengeBlocks(domain, keyAuth string) ([]byte, []byte, error) { // Add the keyAuth digest as the acmeValidation-v1 extension // (marked as critical such that it won't be used by non-ACME software). - // Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-3 + // Reference: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-3 extensions := []pkix.Extension{ { Id: idPeAcmeIdentifierV1, diff --git a/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge_server.go b/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge_server.go index 8d33668e..ee06a16d 100644 --- a/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge_server.go +++ b/vendor/github.com/xenolf/lego/acme/tls_alpn_challenge_server.go @@ -3,6 +3,7 @@ package acme import ( "crypto/tls" "fmt" + "log" "net" "net/http" ) @@ -65,7 +66,10 @@ func (t *TLSALPNProviderServer) Present(domain, token, keyAuth string) error { // Shut the server down when we're finished. go func() { - http.Serve(t.listener, nil) + err := http.Serve(t.listener, nil) + if err != nil { + log.Println(err) + } }() return nil diff --git a/vendor/github.com/xenolf/lego/acme/utils.go b/vendor/github.com/xenolf/lego/acme/utils.go index 2fa0db30..f3160806 100644 --- a/vendor/github.com/xenolf/lego/acme/utils.go +++ b/vendor/github.com/xenolf/lego/acme/utils.go @@ -3,16 +3,20 @@ package acme import ( "fmt" "time" + + "github.com/xenolf/lego/log" ) // WaitFor polls the given function 'f', once every 'interval', up to 'timeout'. func WaitFor(timeout, interval time.Duration, f func() (bool, error)) error { + log.Infof("Wait [timeout: %s, interval: %s]", timeout, interval) + var lastErr string - timeup := time.After(timeout) + timeUp := time.After(timeout) for { select { - case <-timeup: - return fmt.Errorf("Time limit exceeded. Last error: %s", lastErr) + case <-timeUp: + return fmt.Errorf("time limit exceeded: last error: %s", lastErr) default: } diff --git a/vendor/manifest b/vendor/manifest index 998f2cfa..c2b2f3d4 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -170,7 +170,7 @@ "importpath": "github.com/xenolf/lego/acme", "repository": "https://github.com/xenolf/lego", "vcs": "git", - "revision": "04e2d74406d42a3727e7a132c1a39735ac527f51", + "revision": "4e842a5eb6dcb9520e03db70cd5896f1df14b72a", "branch": "master", "path": "/acme", "notests": true