Dep ensure -update (#1912)
* dep ensure -update Signed-off-by: Miek Gieben <miek@miek.nl> * Add new files Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
parent
6fe27d99be
commit
9d555ab8d2
1505 changed files with 179032 additions and 208137 deletions
422
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
422
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
|
@ -14,7 +14,6 @@
|
|||
package acme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
|
@ -23,6 +22,8 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
@ -33,7 +34,6 @@ import (
|
|||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -42,6 +42,9 @@ import (
|
|||
// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
|
||||
const LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
|
||||
|
||||
// idPeACMEIdentifierV1 is the OID for the ACME extension for the TLS-ALPN challenge.
|
||||
var idPeACMEIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
|
||||
|
||||
const (
|
||||
maxChainLen = 5 // max depth and breadth of a certificate chain
|
||||
maxCertSize = 1 << 20 // max size of a certificate, in bytes
|
||||
|
@ -76,6 +79,22 @@ type Client struct {
|
|||
// will have no effect.
|
||||
DirectoryURL string
|
||||
|
||||
// RetryBackoff computes the duration after which the nth retry of a failed request
|
||||
// should occur. The value of n for the first call on failure is 1.
|
||||
// The values of r and resp are the request and response of the last failed attempt.
|
||||
// If the returned value is negative or zero, no more retries are done and an error
|
||||
// is returned to the caller of the original method.
|
||||
//
|
||||
// Requests which result in a 4xx client error are not retried,
|
||||
// except for 400 Bad Request due to "bad nonce" errors and 429 Too Many Requests.
|
||||
//
|
||||
// If RetryBackoff is nil, a truncated exponential backoff algorithm
|
||||
// with the ceiling of 10 seconds is used, where each subsequent retry n
|
||||
// is done after either ("Retry-After" + jitter) or (2^n seconds + jitter),
|
||||
// preferring the former if "Retry-After" header is found in the resp.
|
||||
// The jitter is a random value up to 1 second.
|
||||
RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
|
||||
|
||||
dirMu sync.Mutex // guards writes to dir
|
||||
dir *Directory // cached result of Client's Discover method
|
||||
|
||||
|
@ -99,15 +118,12 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
|
|||
if dirURL == "" {
|
||||
dirURL = LetsEncryptURL
|
||||
}
|
||||
res, err := c.get(ctx, dirURL)
|
||||
res, err := c.get(ctx, dirURL, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return Directory{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
c.addNonce(res.Header)
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return Directory{}, responseError(res)
|
||||
}
|
||||
|
||||
var v struct {
|
||||
Reg string `json:"new-reg"`
|
||||
|
@ -166,14 +182,11 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
|
|||
req.NotAfter = now.Add(exp).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
res, err := c.retryPostJWS(ctx, c.Key, c.dir.CertURL, req)
|
||||
res, err := c.post(ctx, c.Key, c.dir.CertURL, req, wantStatus(http.StatusCreated))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return nil, "", responseError(res)
|
||||
}
|
||||
|
||||
curl := res.Header.Get("Location") // cert permanent URL
|
||||
if res.ContentLength == 0 {
|
||||
|
@ -196,26 +209,11 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
|
|||
// Callers are encouraged to parse the returned value to ensure the certificate is valid
|
||||
// and has expected features.
|
||||
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
|
||||
for {
|
||||
res, err := c.get(ctx, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode == http.StatusOK {
|
||||
return c.responseCert(ctx, res, bundle)
|
||||
}
|
||||
if res.StatusCode > 299 {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
d := retryAfter(res.Header.Get("Retry-After"), 3*time.Second)
|
||||
select {
|
||||
case <-time.After(d):
|
||||
// retry
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.responseCert(ctx, res, bundle)
|
||||
}
|
||||
|
||||
// RevokeCert revokes a previously issued certificate cert, provided in DER format.
|
||||
|
@ -241,14 +239,11 @@ func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte,
|
|||
if key == nil {
|
||||
key = c.Key
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, key, c.dir.RevokeURL, body)
|
||||
res, err := c.post(ctx, key, c.dir.RevokeURL, body, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return responseError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -329,14 +324,11 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
|||
Resource: "new-authz",
|
||||
Identifier: authzID{Type: "dns", Value: domain},
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, c.dir.AuthzURL, req)
|
||||
res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v wireAuthz
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
|
@ -353,14 +345,11 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
|||
// If a caller needs to poll an authorization until its status is final,
|
||||
// see the WaitAuthorization method.
|
||||
func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
var v wireAuthz
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
return nil, fmt.Errorf("acme: invalid response: %v", err)
|
||||
|
@ -387,14 +376,11 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
|
|||
Status: "deactivated",
|
||||
Delete: true,
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, url, req)
|
||||
res, err := c.post(ctx, c.Key, url, req, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return responseError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -406,44 +392,42 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
|
|||
// In all other cases WaitAuthorization returns an error.
|
||||
// If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
|
||||
func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
|
||||
sleep := sleeper(ctx)
|
||||
for {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.StatusCode >= 400 && res.StatusCode <= 499 {
|
||||
// Non-retriable error. For instance, Let's Encrypt may return 404 Not Found
|
||||
// when requesting an expired authorization.
|
||||
defer res.Body.Close()
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
retry := res.Header.Get("Retry-After")
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
res.Body.Close()
|
||||
if err := sleep(retry, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
var raw wireAuthz
|
||||
err = json.NewDecoder(res.Body).Decode(&raw)
|
||||
res.Body.Close()
|
||||
if err != nil {
|
||||
if err := sleep(retry, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if raw.Status == StatusValid {
|
||||
switch {
|
||||
case err != nil:
|
||||
// Skip and retry.
|
||||
case raw.Status == StatusValid:
|
||||
return raw.authorization(url), nil
|
||||
}
|
||||
if raw.Status == StatusInvalid {
|
||||
case raw.Status == StatusInvalid:
|
||||
return nil, raw.error(url)
|
||||
}
|
||||
if err := sleep(retry, 0); err != nil {
|
||||
return nil, err
|
||||
|
||||
// Exponential backoff is implemented in c.get above.
|
||||
// This is just to prevent continuously hitting the CA
|
||||
// while waiting for a final authorization status.
|
||||
d := retryAfter(res.Header.Get("Retry-After"))
|
||||
if d == 0 {
|
||||
// Given that the fastest challenges TLS-SNI and HTTP-01
|
||||
// require a CA to make at least 1 network round trip
|
||||
// and most likely persist a challenge state,
|
||||
// this default delay seems reasonable.
|
||||
d = time.Second
|
||||
}
|
||||
t := time.NewTimer(d)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
t.Stop()
|
||||
return nil, ctx.Err()
|
||||
case <-t.C:
|
||||
// Retry.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,14 +436,11 @@ func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorizat
|
|||
//
|
||||
// A client typically polls a challenge status using this method.
|
||||
func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
v := wireChallenge{URI: url}
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
return nil, fmt.Errorf("acme: invalid response: %v", err)
|
||||
|
@ -486,16 +467,14 @@ func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error
|
|||
Type: chal.Type,
|
||||
Auth: auth,
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, chal.URI, req)
|
||||
res, err := c.post(ctx, c.Key, chal.URI, req, wantStatus(
|
||||
http.StatusOK, // according to the spec
|
||||
http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
// Note: the protocol specifies 200 as the expected response code, but
|
||||
// letsencrypt seems to be returning 202.
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v wireChallenge
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
|
@ -552,7 +531,7 @@ func (c *Client) HTTP01ChallengePath(token string) string {
|
|||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name of the client hello matches exactly the returned name value.
|
||||
// the server name of the TLS ClientHello matches exactly the returned name value.
|
||||
func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
|
||||
ka, err := keyAuth(c.Key.Public(), token)
|
||||
if err != nil {
|
||||
|
@ -579,7 +558,7 @@ func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tl
|
|||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name in the client hello matches exactly the returned name value.
|
||||
// the server name in the TLS ClientHello matches exactly the returned name value.
|
||||
func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
|
||||
b := sha256.Sum256([]byte(token))
|
||||
h := hex.EncodeToString(b[:])
|
||||
|
@ -600,6 +579,52 @@ func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tl
|
|||
return cert, sanA, nil
|
||||
}
|
||||
|
||||
// TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response.
|
||||
// Servers can present the certificate to validate the challenge and prove control
|
||||
// over a domain name. For more details on TLS-ALPN-01 see
|
||||
// https://tools.ietf.org/html/draft-shoemaker-acme-tls-alpn-00#section-3
|
||||
//
|
||||
// The token argument is a Challenge.Token value.
|
||||
// If a WithKey option is provided, its private part signs the returned cert,
|
||||
// and the public part is used to specify the signee.
|
||||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name in the TLS ClientHello matches the domain, and the special acme-tls/1 ALPN protocol
|
||||
// has been specified.
|
||||
func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption) (cert tls.Certificate, err error) {
|
||||
ka, err := keyAuth(c.Key.Public(), token)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
shasum := sha256.Sum256([]byte(ka))
|
||||
extValue, err := asn1.Marshal(shasum[:])
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
acmeExtension := pkix.Extension{
|
||||
Id: idPeACMEIdentifierV1,
|
||||
Critical: true,
|
||||
Value: extValue,
|
||||
}
|
||||
|
||||
tmpl := defaultTLSChallengeCertTemplate()
|
||||
|
||||
var newOpt []CertOption
|
||||
for _, o := range opt {
|
||||
switch o := o.(type) {
|
||||
case *certOptTemplate:
|
||||
t := *(*x509.Certificate)(o) // shallow copy is ok
|
||||
tmpl = &t
|
||||
default:
|
||||
newOpt = append(newOpt, o)
|
||||
}
|
||||
}
|
||||
tmpl.ExtraExtensions = append(tmpl.ExtraExtensions, acmeExtension)
|
||||
newOpt = append(newOpt, WithTemplate(tmpl))
|
||||
return tlsChallengeCert([]string{domain}, newOpt)
|
||||
}
|
||||
|
||||
// doReg sends all types of registration requests.
|
||||
// The type of request is identified by typ argument, which is a "resource"
|
||||
// in the ACME spec terms.
|
||||
|
@ -619,14 +644,14 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
|
|||
req.Contact = acct.Contact
|
||||
req.Agreement = acct.AgreedTerms
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, url, req)
|
||||
res, err := c.post(ctx, c.Key, url, req, wantStatus(
|
||||
http.StatusOK, // updates and deletes
|
||||
http.StatusCreated, // new account creation
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode < 200 || res.StatusCode > 299 {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v struct {
|
||||
Contact []string
|
||||
|
@ -656,59 +681,6 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
|
|||
}, nil
|
||||
}
|
||||
|
||||
// retryPostJWS will retry calls to postJWS if there is a badNonce error,
|
||||
// clearing the stored nonces after each error.
|
||||
// If the response was 4XX-5XX, then responseError is called on the body,
|
||||
// the body is closed, and the error returned.
|
||||
func (c *Client) retryPostJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
|
||||
sleep := sleeper(ctx)
|
||||
for {
|
||||
res, err := c.postJWS(ctx, key, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// handle errors 4XX-5XX with responseError
|
||||
if res.StatusCode >= 400 && res.StatusCode <= 599 {
|
||||
err := responseError(res)
|
||||
res.Body.Close()
|
||||
// according to spec badNonce is urn:ietf:params:acme:error:badNonce
|
||||
// however, acme servers in the wild return their version of the error
|
||||
// https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
|
||||
if ae, ok := err.(*Error); ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce") {
|
||||
// clear any nonces that we might've stored that might now be
|
||||
// considered bad
|
||||
c.clearNonces()
|
||||
retry := res.Header.Get("Retry-After")
|
||||
if err := sleep(retry, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
// postJWS signs the body with the given key and POSTs it to the provided url.
|
||||
// The body argument must be JSON-serializable.
|
||||
func (c *Client) postJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
|
||||
nonce, err := c.popNonce(ctx, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err := jwsEncodeJSON(body, key, nonce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := c.post(ctx, url, "application/jose+json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.addNonce(res.Header)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// popNonce returns a nonce value previously stored with c.addNonce
|
||||
// or fetches a fresh one from the given URL.
|
||||
func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
|
||||
|
@ -749,58 +721,12 @@ func (c *Client) addNonce(h http.Header) {
|
|||
c.nonces[v] = struct{}{}
|
||||
}
|
||||
|
||||
func (c *Client) httpClient() *http.Client {
|
||||
if c.HTTPClient != nil {
|
||||
return c.HTTPClient
|
||||
}
|
||||
return http.DefaultClient
|
||||
}
|
||||
|
||||
func (c *Client) get(ctx context.Context, urlStr string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) head(ctx context.Context, urlStr string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("HEAD", urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) post(ctx context.Context, urlStr, contentType string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest("POST", urlStr, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
res, err := c.httpClient().Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Prefer the unadorned context error.
|
||||
// (The acme package had tests assuming this, previously from ctxhttp's
|
||||
// behavior, predating net/http supporting contexts natively)
|
||||
// TODO(bradfitz): reconsider this in the future. But for now this
|
||||
// requires no test updates.
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
|
||||
resp, err := c.head(ctx, url)
|
||||
r, err := http.NewRequest("HEAD", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err := c.doNoRetry(ctx, r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -852,24 +778,6 @@ func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bo
|
|||
return cert, nil
|
||||
}
|
||||
|
||||
// responseError creates an error of Error type from resp.
|
||||
func responseError(resp *http.Response) error {
|
||||
// don't care if ReadAll returns an error:
|
||||
// json.Unmarshal will fail in that case anyway
|
||||
b, _ := ioutil.ReadAll(resp.Body)
|
||||
e := &wireError{Status: resp.StatusCode}
|
||||
if err := json.Unmarshal(b, e); err != nil {
|
||||
// this is not a regular error response:
|
||||
// populate detail with anything we received,
|
||||
// e.Status will already contain HTTP response code value
|
||||
e.Detail = string(b)
|
||||
if e.Detail == "" {
|
||||
e.Detail = resp.Status
|
||||
}
|
||||
}
|
||||
return e.error(resp.Header)
|
||||
}
|
||||
|
||||
// chainCert fetches CA certificate chain recursively by following "up" links.
|
||||
// Each recursive call increments the depth by 1, resulting in an error
|
||||
// if the recursion level reaches maxChainLen.
|
||||
|
@ -880,14 +788,11 @@ func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte
|
|||
return nil, errors.New("acme: certificate chain is too deep")
|
||||
}
|
||||
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -932,65 +837,6 @@ func linkHeader(h http.Header, rel string) []string {
|
|||
return links
|
||||
}
|
||||
|
||||
// sleeper returns a function that accepts the Retry-After HTTP header value
|
||||
// and an increment that's used with backoff to increasingly sleep on
|
||||
// consecutive calls until the context is done. If the Retry-After header
|
||||
// cannot be parsed, then backoff is used with a maximum sleep time of 10
|
||||
// seconds.
|
||||
func sleeper(ctx context.Context) func(ra string, inc int) error {
|
||||
var count int
|
||||
return func(ra string, inc int) error {
|
||||
count += inc
|
||||
d := backoff(count, 10*time.Second)
|
||||
d = retryAfter(ra, d)
|
||||
wakeup := time.NewTimer(d)
|
||||
defer wakeup.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-wakeup.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// retryAfter parses a Retry-After HTTP header value,
|
||||
// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
|
||||
// It returns d if v cannot be parsed.
|
||||
func retryAfter(v string, d time.Duration) time.Duration {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return time.Duration(i) * time.Second
|
||||
}
|
||||
t, err := http.ParseTime(v)
|
||||
if err != nil {
|
||||
return d
|
||||
}
|
||||
return t.Sub(timeNow())
|
||||
}
|
||||
|
||||
// backoff computes a duration after which an n+1 retry iteration should occur
|
||||
// using truncated exponential backoff algorithm.
|
||||
//
|
||||
// The n argument is always bounded between 0 and 30.
|
||||
// The max argument defines upper bound for the returned value.
|
||||
func backoff(n int, max time.Duration) time.Duration {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
if n > 30 {
|
||||
n = 30
|
||||
}
|
||||
var d time.Duration
|
||||
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
|
||||
d = time.Duration(x.Int64()) * time.Millisecond
|
||||
}
|
||||
d += time.Duration(1<<uint(n)) * time.Second
|
||||
if d > max {
|
||||
return max
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// keyAuth generates a key authorization string for a given token.
|
||||
func keyAuth(pub crypto.PublicKey, token string) (string, error) {
|
||||
th, err := JWKThumbprint(pub)
|
||||
|
@ -1000,15 +846,25 @@ func keyAuth(pub crypto.PublicKey, token string) (string, error) {
|
|||
return fmt.Sprintf("%s.%s", token, th), nil
|
||||
}
|
||||
|
||||
// defaultTLSChallengeCertTemplate is a template used to create challenge certs for TLS challenges.
|
||||
func defaultTLSChallengeCertTemplate() *x509.Certificate {
|
||||
return &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
}
|
||||
|
||||
// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
|
||||
// with the given SANs and auto-generated public/private key pair.
|
||||
// The Subject Common Name is set to the first SAN to aid debugging.
|
||||
// To create a cert with a custom key pair, specify WithKey option.
|
||||
func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
||||
var (
|
||||
key crypto.Signer
|
||||
tmpl *x509.Certificate
|
||||
)
|
||||
var key crypto.Signer
|
||||
tmpl := defaultTLSChallengeCertTemplate()
|
||||
for _, o := range opt {
|
||||
switch o := o.(type) {
|
||||
case *certOptKey:
|
||||
|
@ -1017,7 +873,7 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
|||
}
|
||||
key = o.key
|
||||
case *certOptTemplate:
|
||||
var t = *(*x509.Certificate)(o) // shallow copy is ok
|
||||
t := *(*x509.Certificate)(o) // shallow copy is ok
|
||||
tmpl = &t
|
||||
default:
|
||||
// package's fault, if we let this happen:
|
||||
|
@ -1030,16 +886,6 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
|||
return tls.Certificate{}, err
|
||||
}
|
||||
}
|
||||
if tmpl == nil {
|
||||
tmpl = &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
}
|
||||
tmpl.DNSNames = san
|
||||
if len(san) > 0 {
|
||||
tmpl.Subject.CommonName = san[0]
|
||||
|
|
325
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
325
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
|
@ -13,9 +13,9 @@ import (
|
|||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -485,88 +485,37 @@ func TestGetAuthorization(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWaitAuthorization(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
t.Run("wait loop", func(t *testing.T) {
|
||||
var count int
|
||||
authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("non-nil error: %v", err)
|
||||
}
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
type res struct {
|
||||
authz *Authorization
|
||||
err error
|
||||
}
|
||||
done := make(chan res)
|
||||
defer close(done)
|
||||
go func() {
|
||||
var client Client
|
||||
a, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
done <- res{a, err}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case res := <-done:
|
||||
if res.err != nil {
|
||||
t.Fatalf("res.err = %v", res.err)
|
||||
}
|
||||
if res.authz == nil {
|
||||
t.Fatal("res.authz is nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationInvalid(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `{"status":"invalid"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
res := make(chan error)
|
||||
defer close(res)
|
||||
go func() {
|
||||
var client Client
|
||||
_, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
res <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-res:
|
||||
if err == nil {
|
||||
t.Error("err is nil")
|
||||
if authz == nil {
|
||||
t.Fatal("authz is nil")
|
||||
}
|
||||
})
|
||||
t.Run("invalid status", func(t *testing.T) {
|
||||
_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `{"status":"invalid"}`)
|
||||
})
|
||||
if _, ok := err.(*AuthorizationError); !ok {
|
||||
t.Errorf("err is %T; want *AuthorizationError", err)
|
||||
t.Errorf("err is %v (%T); want non-nil *AuthorizationError", err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationClientError(t *testing.T) {
|
||||
const code = http.StatusBadRequest
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(code)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ch := make(chan error, 1)
|
||||
go func() {
|
||||
var client Client
|
||||
_, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
ch <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-ch:
|
||||
})
|
||||
t.Run("non-retriable error", func(t *testing.T) {
|
||||
const code = http.StatusBadRequest
|
||||
_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(code)
|
||||
})
|
||||
res, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err is %v (%T); want a non-nil *Error", err, err)
|
||||
|
@ -574,34 +523,60 @@ func TestWaitAuthorizationClientError(t *testing.T) {
|
|||
if res.StatusCode != code {
|
||||
t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, code)
|
||||
}
|
||||
})
|
||||
for _, code := range []int{http.StatusTooManyRequests, http.StatusInternalServerError} {
|
||||
t.Run(fmt.Sprintf("retriable %d error", code), func(t *testing.T) {
|
||||
var count int
|
||||
authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("non-nil error: %v", err)
|
||||
}
|
||||
if authz == nil {
|
||||
t.Fatal("authz is nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationCancel(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Retry-After", "60")
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
res := make(chan error)
|
||||
defer close(res)
|
||||
go func() {
|
||||
var client Client
|
||||
t.Run("context cancel", func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := client.WaitAuthorization(ctx, ts.URL)
|
||||
res <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-res:
|
||||
_, err := runWaitAuthorization(ctx, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Retry-After", "60")
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("err is nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
func runWaitAuthorization(ctx context.Context, t *testing.T, h http.HandlerFunc) (*Authorization, error) {
|
||||
t.Helper()
|
||||
ts := httptest.NewServer(h)
|
||||
defer ts.Close()
|
||||
type res struct {
|
||||
authz *Authorization
|
||||
err error
|
||||
}
|
||||
ch := make(chan res, 1)
|
||||
go func() {
|
||||
var client Client
|
||||
a, err := client.WaitAuthorization(ctx, ts.URL)
|
||||
ch <- res{a, err}
|
||||
}()
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthorization took too long to return")
|
||||
case v := <-ch:
|
||||
return v.authz, v.err
|
||||
}
|
||||
panic("runWaitAuthorization: out of select")
|
||||
}
|
||||
|
||||
func TestRevokeAuthorization(t *testing.T) {
|
||||
|
@ -628,7 +603,7 @@ func TestRevokeAuthorization(t *testing.T) {
|
|||
t.Errorf("req.Delete is false")
|
||||
}
|
||||
case "/2":
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
@ -849,7 +824,7 @@ func TestFetchCertRetry(t *testing.T) {
|
|||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if count < 1 {
|
||||
w.Header().Set("Retry-After", "0")
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
w.WriteHeader(http.StatusTooManyRequests)
|
||||
count++
|
||||
return
|
||||
}
|
||||
|
@ -1096,44 +1071,6 @@ func TestNonce_postJWS(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRetryPostJWS(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Replay-Nonce", fmt.Sprintf("nonce%d", count))
|
||||
if r.Method == "HEAD" {
|
||||
// We expect the client to do 2 head requests to fetch
|
||||
// nonces, one to start and another after getting badNonce
|
||||
return
|
||||
}
|
||||
|
||||
head, err := decodeJWSHead(r)
|
||||
if err != nil {
|
||||
t.Errorf("decodeJWSHead: %v", err)
|
||||
} else if head.Nonce == "" {
|
||||
t.Error("head.Nonce is empty")
|
||||
} else if head.Nonce == "nonce1" {
|
||||
// return a badNonce error to force the call to retry
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"type":"urn:ietf:params:acme:error:badNonce"}`))
|
||||
return
|
||||
}
|
||||
// Make client.Authorize happy; we're not testing its result.
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(`{"status":"valid"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
|
||||
// This call will fail with badNonce, causing a retry
|
||||
if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
|
||||
t.Errorf("client.Authorize 1: %v", err)
|
||||
}
|
||||
if count != 4 {
|
||||
t.Errorf("total requests count: %d; want 4", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkHeader(t *testing.T) {
|
||||
h := http.Header{"Link": {
|
||||
`<https://example.com/acme/new-authz>;rel="next"`,
|
||||
|
@ -1157,37 +1094,6 @@ func TestLinkHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
s := `{
|
||||
"status": 400,
|
||||
"type": "urn:acme:error:xxx",
|
||||
"detail": "text"
|
||||
}`
|
||||
res := &http.Response{
|
||||
StatusCode: 400,
|
||||
Status: "400 Bad Request",
|
||||
Body: ioutil.NopCloser(strings.NewReader(s)),
|
||||
Header: http.Header{"X-Foo": {"bar"}},
|
||||
}
|
||||
err := responseError(res)
|
||||
v, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err = %+v (%T); want *Error type", err, err)
|
||||
}
|
||||
if v.StatusCode != 400 {
|
||||
t.Errorf("v.StatusCode = %v; want 400", v.StatusCode)
|
||||
}
|
||||
if v.ProblemType != "urn:acme:error:xxx" {
|
||||
t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType)
|
||||
}
|
||||
if v.Detail != "text" {
|
||||
t.Errorf("v.Detail = %q; want text", v.Detail)
|
||||
}
|
||||
if !reflect.DeepEqual(v.Header, res.Header) {
|
||||
t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSSNI01ChallengeCert(t *testing.T) {
|
||||
const (
|
||||
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
|
||||
|
@ -1255,6 +1161,58 @@ func TestTLSSNI02ChallengeCert(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTLSALPN01ChallengeCert(t *testing.T) {
|
||||
const (
|
||||
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
|
||||
keyAuth = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA." + testKeyECThumbprint
|
||||
// echo -n <token.testKeyECThumbprint> | shasum -a 256
|
||||
h = "0420dbbd5eefe7b4d06eb9d1d9f5acb4c7cda27d320e4b30332f0b6cb441734ad7b0"
|
||||
domain = "example.com"
|
||||
)
|
||||
|
||||
extValue, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &Client{Key: testKeyEC}
|
||||
tlscert, err := client.TLSALPN01ChallengeCert(token, domain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n := len(tlscert.Certificate); n != 1 {
|
||||
t.Fatalf("len(tlscert.Certificate) = %d; want 1", n)
|
||||
}
|
||||
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
names := []string{domain}
|
||||
if !reflect.DeepEqual(cert.DNSNames, names) {
|
||||
t.Fatalf("cert.DNSNames = %v;\nwant %v", cert.DNSNames, names)
|
||||
}
|
||||
if cn := cert.Subject.CommonName; cn != domain {
|
||||
t.Errorf("CommonName = %q; want %q", cn, domain)
|
||||
}
|
||||
acmeExts := []pkix.Extension{}
|
||||
for _, ext := range cert.Extensions {
|
||||
if idPeACMEIdentifierV1.Equal(ext.Id) {
|
||||
acmeExts = append(acmeExts, ext)
|
||||
}
|
||||
}
|
||||
if len(acmeExts) != 1 {
|
||||
t.Errorf("acmeExts = %v; want exactly one", acmeExts)
|
||||
}
|
||||
if !acmeExts[0].Critical {
|
||||
t.Errorf("acmeExt.Critical = %v; want true", acmeExts[0].Critical)
|
||||
}
|
||||
if bytes.Compare(acmeExts[0].Value, extValue) != 0 {
|
||||
t.Errorf("acmeExt.Value = %v; want %v", acmeExts[0].Value, extValue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTLSChallengeCertOpt(t *testing.T) {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
|
@ -1353,28 +1311,3 @@ func TestDNS01ChallengeRecord(t *testing.T) {
|
|||
t.Errorf("val = %q; want %q", val, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackoff(t *testing.T) {
|
||||
tt := []struct{ min, max time.Duration }{
|
||||
{time.Second, 2 * time.Second},
|
||||
{2 * time.Second, 3 * time.Second},
|
||||
{4 * time.Second, 5 * time.Second},
|
||||
{8 * time.Second, 9 * time.Second},
|
||||
}
|
||||
for i, test := range tt {
|
||||
d := backoff(i, time.Minute)
|
||||
if d < test.min || test.max < d {
|
||||
t.Errorf("%d: d = %v; want between %v and %v", i, d, test.min, test.max)
|
||||
}
|
||||
}
|
||||
|
||||
min, max := time.Second, 2*time.Second
|
||||
if d := backoff(-1, time.Minute); d < min || max < d {
|
||||
t.Errorf("d = %v; want between %v and %v", d, min, max)
|
||||
}
|
||||
|
||||
bound := 10 * time.Second
|
||||
if d := backoff(100, bound); d != bound {
|
||||
t.Errorf("d = %v; want %v", d, bound)
|
||||
}
|
||||
}
|
||||
|
|
278
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
278
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
|
@ -98,11 +98,11 @@ type Manager struct {
|
|||
// To always accept the terms, the callers can use AcceptTOS.
|
||||
Prompt func(tosURL string) bool
|
||||
|
||||
// Cache optionally stores and retrieves previously-obtained certificates.
|
||||
// If nil, certs will only be cached for the lifetime of the Manager.
|
||||
// Cache optionally stores and retrieves previously-obtained certificates
|
||||
// and other state. If nil, certs will only be cached for the lifetime of
|
||||
// the Manager. Multiple Managers can share the same Cache.
|
||||
//
|
||||
// Manager passes the Cache certificates data encoded in PEM, with private/public
|
||||
// parts combined in a single Cache.Put call, private key first.
|
||||
// Using a persistent Cache, such as DirCache, is strongly recommended.
|
||||
Cache Cache
|
||||
|
||||
// HostPolicy controls which domains the Manager will attempt
|
||||
|
@ -127,8 +127,10 @@ type Manager struct {
|
|||
|
||||
// Client is used to perform low-level operations, such as account registration
|
||||
// and requesting new certificates.
|
||||
//
|
||||
// If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
|
||||
// directory endpoint and a newly-generated ECDSA P-256 key.
|
||||
// as directory endpoint. If the Client.Key is nil, a new ECDSA P-256 key is
|
||||
// generated and, if Cache is not nil, stored in cache.
|
||||
//
|
||||
// Mutating the field after the first call of GetCertificate method will have no effect.
|
||||
Client *acme.Client
|
||||
|
@ -140,22 +142,30 @@ type Manager struct {
|
|||
// If the Client's account key is already registered, Email is not used.
|
||||
Email string
|
||||
|
||||
// ForceRSA makes the Manager generate certificates with 2048-bit RSA keys.
|
||||
// ForceRSA used to make the Manager generate RSA certificates. It is now ignored.
|
||||
//
|
||||
// If false, a default is used. Currently the default
|
||||
// is EC-based keys using the P-256 curve.
|
||||
// Deprecated: the Manager will request the correct type of certificate based
|
||||
// on what each client supports.
|
||||
ForceRSA bool
|
||||
|
||||
// ExtraExtensions are used when generating a new CSR (Certificate Request),
|
||||
// thus allowing customization of the resulting certificate.
|
||||
// For instance, TLS Feature Extension (RFC 7633) can be used
|
||||
// to prevent an OCSP downgrade attack.
|
||||
//
|
||||
// The field value is passed to crypto/x509.CreateCertificateRequest
|
||||
// in the template's ExtraExtensions field as is.
|
||||
ExtraExtensions []pkix.Extension
|
||||
|
||||
clientMu sync.Mutex
|
||||
client *acme.Client // initialized by acmeClient method
|
||||
|
||||
stateMu sync.Mutex
|
||||
state map[string]*certState // keyed by domain name
|
||||
state map[certKey]*certState
|
||||
|
||||
// renewal tracks the set of domains currently running renewal timers.
|
||||
// It is keyed by domain name.
|
||||
renewalMu sync.Mutex
|
||||
renewal map[string]*domainRenewal
|
||||
renewal map[certKey]*domainRenewal
|
||||
|
||||
// tokensMu guards the rest of the fields: tryHTTP01, certTokens and httpTokens.
|
||||
tokensMu sync.RWMutex
|
||||
|
@ -174,6 +184,23 @@ type Manager struct {
|
|||
certTokens map[string]*tls.Certificate
|
||||
}
|
||||
|
||||
// certKey is the key by which certificates are tracked in state, renewal and cache.
|
||||
type certKey struct {
|
||||
domain string // without trailing dot
|
||||
isRSA bool // RSA cert for legacy clients (as opposed to default ECDSA)
|
||||
isToken bool // tls-sni challenge token cert; key type is undefined regardless of isRSA
|
||||
}
|
||||
|
||||
func (c certKey) String() string {
|
||||
if c.isToken {
|
||||
return c.domain + "+token"
|
||||
}
|
||||
if c.isRSA {
|
||||
return c.domain + "+rsa"
|
||||
}
|
||||
return c.domain
|
||||
}
|
||||
|
||||
// GetCertificate implements the tls.Config.GetCertificate hook.
|
||||
// It provides a TLS certificate for hello.ServerName host, including answering
|
||||
// *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
|
||||
|
@ -194,7 +221,7 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||
if !strings.Contains(strings.Trim(name, "."), ".") {
|
||||
return nil, errors.New("acme/autocert: server name component count invalid")
|
||||
}
|
||||
if strings.ContainsAny(name, `/\`) {
|
||||
if strings.ContainsAny(name, `+/\`) {
|
||||
return nil, errors.New("acme/autocert: server name contains invalid character")
|
||||
}
|
||||
|
||||
|
@ -210,7 +237,7 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||
if cert := m.certTokens[name]; cert != nil {
|
||||
return cert, nil
|
||||
}
|
||||
if cert, err := m.cacheGet(ctx, name); err == nil {
|
||||
if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
|
||||
return cert, nil
|
||||
}
|
||||
// TODO: cache error results?
|
||||
|
@ -218,8 +245,11 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||
}
|
||||
|
||||
// regular domain
|
||||
name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
|
||||
cert, err := m.cert(ctx, name)
|
||||
ck := certKey{
|
||||
domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
|
||||
isRSA: !supportsECDSA(hello),
|
||||
}
|
||||
cert, err := m.cert(ctx, ck)
|
||||
if err == nil {
|
||||
return cert, nil
|
||||
}
|
||||
|
@ -231,14 +261,60 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||
if err := m.hostPolicy()(ctx, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert, err = m.createCert(ctx, name)
|
||||
cert, err = m.createCert(ctx, ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.cachePut(ctx, name, cert)
|
||||
m.cachePut(ctx, ck, cert)
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func supportsECDSA(hello *tls.ClientHelloInfo) bool {
|
||||
// The "signature_algorithms" extension, if present, limits the key exchange
|
||||
// algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.
|
||||
if hello.SignatureSchemes != nil {
|
||||
ecdsaOK := false
|
||||
schemeLoop:
|
||||
for _, scheme := range hello.SignatureSchemes {
|
||||
const tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10
|
||||
switch scheme {
|
||||
case tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,
|
||||
tls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:
|
||||
ecdsaOK = true
|
||||
break schemeLoop
|
||||
}
|
||||
}
|
||||
if !ecdsaOK {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if hello.SupportedCurves != nil {
|
||||
ecdsaOK := false
|
||||
for _, curve := range hello.SupportedCurves {
|
||||
if curve == tls.CurveP256 {
|
||||
ecdsaOK = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ecdsaOK {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, suite := range hello.CipherSuites {
|
||||
switch suite {
|
||||
case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
|
||||
// It returns an http.Handler that responds to the challenges and must be
|
||||
// running on port 80. If it receives a request that is not an ACME challenge,
|
||||
|
@ -304,16 +380,16 @@ func stripPort(hostport string) string {
|
|||
// cert returns an existing certificate either from m.state or cache.
|
||||
// If a certificate is found in cache but not in m.state, the latter will be filled
|
||||
// with the cached value.
|
||||
func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, error) {
|
||||
func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
m.stateMu.Lock()
|
||||
if s, ok := m.state[name]; ok {
|
||||
if s, ok := m.state[ck]; ok {
|
||||
m.stateMu.Unlock()
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.tlscert()
|
||||
}
|
||||
defer m.stateMu.Unlock()
|
||||
cert, err := m.cacheGet(ctx, name)
|
||||
cert, err := m.cacheGet(ctx, ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -322,25 +398,25 @@ func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, erro
|
|||
return nil, errors.New("acme/autocert: private key cannot sign")
|
||||
}
|
||||
if m.state == nil {
|
||||
m.state = make(map[string]*certState)
|
||||
m.state = make(map[certKey]*certState)
|
||||
}
|
||||
s := &certState{
|
||||
key: signer,
|
||||
cert: cert.Certificate,
|
||||
leaf: cert.Leaf,
|
||||
}
|
||||
m.state[name] = s
|
||||
go m.renew(name, s.key, s.leaf.NotAfter)
|
||||
m.state[ck] = s
|
||||
go m.renew(ck, s.key, s.leaf.NotAfter)
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// cacheGet always returns a valid certificate, or an error otherwise.
|
||||
// If a cached certficate exists but is not valid, ErrCacheMiss is returned.
|
||||
func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate, error) {
|
||||
// If a cached certificate exists but is not valid, ErrCacheMiss is returned.
|
||||
func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
if m.Cache == nil {
|
||||
return nil, ErrCacheMiss
|
||||
}
|
||||
data, err := m.Cache.Get(ctx, domain)
|
||||
data, err := m.Cache.Get(ctx, ck.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -371,7 +447,7 @@ func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate
|
|||
}
|
||||
|
||||
// verify and create TLS cert
|
||||
leaf, err := validCert(domain, pubDER, privKey)
|
||||
leaf, err := validCert(ck, pubDER, privKey)
|
||||
if err != nil {
|
||||
return nil, ErrCacheMiss
|
||||
}
|
||||
|
@ -383,7 +459,7 @@ func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate
|
|||
return tlscert, nil
|
||||
}
|
||||
|
||||
func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Certificate) error {
|
||||
func (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {
|
||||
if m.Cache == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -415,7 +491,7 @@ func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Cert
|
|||
}
|
||||
}
|
||||
|
||||
return m.Cache.Put(ctx, domain, buf.Bytes())
|
||||
return m.Cache.Put(ctx, ck.String(), buf.Bytes())
|
||||
}
|
||||
|
||||
func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
|
||||
|
@ -432,9 +508,9 @@ func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
|
|||
//
|
||||
// If the domain is already being verified, it waits for the existing verification to complete.
|
||||
// Either way, createCert blocks for the duration of the whole process.
|
||||
func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
|
||||
func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
// TODO: maybe rewrite this whole piece using sync.Once
|
||||
state, err := m.certState(domain)
|
||||
state, err := m.certState(ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -452,44 +528,44 @@ func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certifica
|
|||
defer state.Unlock()
|
||||
state.locked = false
|
||||
|
||||
der, leaf, err := m.authorizedCert(ctx, state.key, domain)
|
||||
der, leaf, err := m.authorizedCert(ctx, state.key, ck)
|
||||
if err != nil {
|
||||
// Remove the failed state after some time,
|
||||
// making the manager call createCert again on the following TLS hello.
|
||||
time.AfterFunc(createCertRetryAfter, func() {
|
||||
defer testDidRemoveState(domain)
|
||||
defer testDidRemoveState(ck)
|
||||
m.stateMu.Lock()
|
||||
defer m.stateMu.Unlock()
|
||||
// Verify the state hasn't changed and it's still invalid
|
||||
// before deleting.
|
||||
s, ok := m.state[domain]
|
||||
s, ok := m.state[ck]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if _, err := validCert(domain, s.cert, s.key); err == nil {
|
||||
if _, err := validCert(ck, s.cert, s.key); err == nil {
|
||||
return
|
||||
}
|
||||
delete(m.state, domain)
|
||||
delete(m.state, ck)
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
state.cert = der
|
||||
state.leaf = leaf
|
||||
go m.renew(domain, state.key, state.leaf.NotAfter)
|
||||
go m.renew(ck, state.key, state.leaf.NotAfter)
|
||||
return state.tlscert()
|
||||
}
|
||||
|
||||
// certState returns a new or existing certState.
|
||||
// If a new certState is returned, state.exist is false and the state is locked.
|
||||
// The returned error is non-nil only in the case where a new state could not be created.
|
||||
func (m *Manager) certState(domain string) (*certState, error) {
|
||||
func (m *Manager) certState(ck certKey) (*certState, error) {
|
||||
m.stateMu.Lock()
|
||||
defer m.stateMu.Unlock()
|
||||
if m.state == nil {
|
||||
m.state = make(map[string]*certState)
|
||||
m.state = make(map[certKey]*certState)
|
||||
}
|
||||
// existing state
|
||||
if state, ok := m.state[domain]; ok {
|
||||
if state, ok := m.state[ck]; ok {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
|
@ -498,7 +574,7 @@ func (m *Manager) certState(domain string) (*certState, error) {
|
|||
err error
|
||||
key crypto.Signer
|
||||
)
|
||||
if m.ForceRSA {
|
||||
if ck.isRSA {
|
||||
key, err = rsa.GenerateKey(rand.Reader, 2048)
|
||||
} else {
|
||||
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
|
@ -512,22 +588,22 @@ func (m *Manager) certState(domain string) (*certState, error) {
|
|||
locked: true,
|
||||
}
|
||||
state.Lock() // will be unlocked by m.certState caller
|
||||
m.state[domain] = state
|
||||
m.state[ck] = state
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
|
||||
// The key argument is the certificate private key.
|
||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
|
||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := m.verify(ctx, client, domain); err != nil {
|
||||
if err := m.verify(ctx, client, ck.domain); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
csr, err := certRequest(key, domain)
|
||||
csr, err := certRequest(key, ck.domain, m.ExtraExtensions)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -535,13 +611,25 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
leaf, err = validCert(domain, der, key)
|
||||
leaf, err = validCert(ck, der, key)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return der, leaf, nil
|
||||
}
|
||||
|
||||
// revokePendingAuthz revokes all authorizations idenfied by the elements of uri slice.
|
||||
// It ignores revocation errors.
|
||||
func (m *Manager) revokePendingAuthz(ctx context.Context, uri []string) {
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, u := range uri {
|
||||
client.RevokeAuthorization(ctx, u)
|
||||
}
|
||||
}
|
||||
|
||||
// verify runs the identifier (domain) authorization flow
|
||||
// using each applicable ACME challenge type.
|
||||
func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
|
||||
|
@ -554,6 +642,24 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
|||
}
|
||||
m.tokensMu.RUnlock()
|
||||
|
||||
// Keep track of pending authzs and revoke the ones that did not validate.
|
||||
pendingAuthzs := make(map[string]bool)
|
||||
defer func() {
|
||||
var uri []string
|
||||
for k, pending := range pendingAuthzs {
|
||||
if pending {
|
||||
uri = append(uri, k)
|
||||
}
|
||||
}
|
||||
if len(uri) > 0 {
|
||||
// Use "detached" background context.
|
||||
// The revocations need not happen in the current verification flow.
|
||||
go m.revokePendingAuthz(context.Background(), uri)
|
||||
}
|
||||
}()
|
||||
|
||||
// errs accumulates challenge failure errors, printed if all fail
|
||||
errs := make(map[*acme.Challenge]error)
|
||||
var nextTyp int // challengeType index of the next challenge type to try
|
||||
for {
|
||||
// Start domain authorization and get the challenge.
|
||||
|
@ -570,6 +676,8 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
|||
return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
|
||||
}
|
||||
|
||||
pendingAuthzs[authz.URI] = true
|
||||
|
||||
// Pick the next preferred challenge.
|
||||
var chal *acme.Challenge
|
||||
for chal == nil && nextTyp < len(challengeTypes) {
|
||||
|
@ -577,21 +685,30 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
|||
nextTyp++
|
||||
}
|
||||
if chal == nil {
|
||||
return fmt.Errorf("acme/autocert: unable to authorize %q; tried %q", domain, challengeTypes)
|
||||
errorMsg := fmt.Sprintf("acme/autocert: unable to authorize %q", domain)
|
||||
for chal, err := range errs {
|
||||
errorMsg += fmt.Sprintf("; challenge %q failed with error: %v", chal.Type, err)
|
||||
}
|
||||
return errors.New(errorMsg)
|
||||
}
|
||||
cleanup, err := m.fulfill(ctx, client, chal)
|
||||
if err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
defer cleanup()
|
||||
if _, err := client.Accept(ctx, chal); err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
|
||||
// A challenge is fulfilled and accepted: wait for the CA to validate.
|
||||
if _, err := client.WaitAuthorization(ctx, authz.URI); err == nil {
|
||||
return nil
|
||||
if _, err := client.WaitAuthorization(ctx, authz.URI); err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
delete(pendingAuthzs, authz.URI)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,8 +751,8 @@ func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
|
|||
return nil
|
||||
}
|
||||
|
||||
// putCertToken stores the cert under the named key in both m.certTokens map
|
||||
// and m.Cache.
|
||||
// putCertToken stores the token certificate with the specified name
|
||||
// in both m.certTokens map and m.Cache.
|
||||
func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
|
||||
m.tokensMu.Lock()
|
||||
defer m.tokensMu.Unlock()
|
||||
|
@ -643,17 +760,18 @@ func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certi
|
|||
m.certTokens = make(map[string]*tls.Certificate)
|
||||
}
|
||||
m.certTokens[name] = cert
|
||||
m.cachePut(ctx, name, cert)
|
||||
m.cachePut(ctx, certKey{domain: name, isToken: true}, cert)
|
||||
}
|
||||
|
||||
// deleteCertToken removes the token certificate for the specified domain name
|
||||
// deleteCertToken removes the token certificate with the specified name
|
||||
// from both m.certTokens map and m.Cache.
|
||||
func (m *Manager) deleteCertToken(name string) {
|
||||
m.tokensMu.Lock()
|
||||
defer m.tokensMu.Unlock()
|
||||
delete(m.certTokens, name)
|
||||
if m.Cache != nil {
|
||||
m.Cache.Delete(context.Background(), name)
|
||||
ck := certKey{domain: name, isToken: true}
|
||||
m.Cache.Delete(context.Background(), ck.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,7 +822,7 @@ func (m *Manager) deleteHTTPToken(tokenPath string) {
|
|||
// httpTokenCacheKey returns a key at which an http-01 token value may be stored
|
||||
// in the Manager's optional Cache.
|
||||
func httpTokenCacheKey(tokenPath string) string {
|
||||
return "http-01-" + path.Base(tokenPath)
|
||||
return path.Base(tokenPath) + "+http-01"
|
||||
}
|
||||
|
||||
// renew starts a cert renewal timer loop, one per domain.
|
||||
|
@ -715,18 +833,18 @@ func httpTokenCacheKey(tokenPath string) string {
|
|||
//
|
||||
// The key argument is a certificate private key.
|
||||
// The exp argument is the cert expiration time (NotAfter).
|
||||
func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
|
||||
func (m *Manager) renew(ck certKey, key crypto.Signer, exp time.Time) {
|
||||
m.renewalMu.Lock()
|
||||
defer m.renewalMu.Unlock()
|
||||
if m.renewal[domain] != nil {
|
||||
if m.renewal[ck] != nil {
|
||||
// another goroutine is already on it
|
||||
return
|
||||
}
|
||||
if m.renewal == nil {
|
||||
m.renewal = make(map[string]*domainRenewal)
|
||||
m.renewal = make(map[certKey]*domainRenewal)
|
||||
}
|
||||
dr := &domainRenewal{m: m, domain: domain, key: key}
|
||||
m.renewal[domain] = dr
|
||||
dr := &domainRenewal{m: m, ck: ck, key: key}
|
||||
m.renewal[ck] = dr
|
||||
dr.start(exp)
|
||||
}
|
||||
|
||||
|
@ -742,7 +860,10 @@ func (m *Manager) stopRenew() {
|
|||
}
|
||||
|
||||
func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
|
||||
const keyName = "acme_account.key"
|
||||
const keyName = "acme_account+key"
|
||||
|
||||
// Previous versions of autocert stored the value under a different key.
|
||||
const legacyKeyName = "acme_account.key"
|
||||
|
||||
genKey := func() (*ecdsa.PrivateKey, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
|
@ -753,6 +874,9 @@ func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
|
|||
}
|
||||
|
||||
data, err := m.Cache.Get(ctx, keyName)
|
||||
if err == ErrCacheMiss {
|
||||
data, err = m.Cache.Get(ctx, legacyKeyName)
|
||||
}
|
||||
if err == ErrCacheMiss {
|
||||
key, err := genKey()
|
||||
if err != nil {
|
||||
|
@ -849,12 +973,12 @@ func (s *certState) tlscert() (*tls.Certificate, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// certRequest creates a certificate request for the given common name cn
|
||||
// and optional SANs.
|
||||
func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
|
||||
// certRequest generates a CSR for the given common name cn and optional SANs.
|
||||
func certRequest(key crypto.Signer, cn string, ext []pkix.Extension, san ...string) ([]byte, error) {
|
||||
req := &x509.CertificateRequest{
|
||||
Subject: pkix.Name{CommonName: cn},
|
||||
DNSNames: san,
|
||||
Subject: pkix.Name{CommonName: cn},
|
||||
DNSNames: san,
|
||||
ExtraExtensions: ext,
|
||||
}
|
||||
return x509.CreateCertificateRequest(rand.Reader, req, key)
|
||||
}
|
||||
|
@ -885,12 +1009,12 @@ func parsePrivateKey(der []byte) (crypto.Signer, error) {
|
|||
return nil, errors.New("acme/autocert: failed to parse private key")
|
||||
}
|
||||
|
||||
// validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
|
||||
// corresponds to the private key, as well as the domain match and expiration dates.
|
||||
// It doesn't do any revocation checking.
|
||||
// validCert parses a cert chain provided as der argument and verifies the leaf and der[0]
|
||||
// correspond to the private key, the domain and key type match, and expiration dates
|
||||
// are valid. It doesn't do any revocation checking.
|
||||
//
|
||||
// The returned value is the verified leaf cert.
|
||||
func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
||||
func validCert(ck certKey, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
||||
// parse public part(s)
|
||||
var n int
|
||||
for _, b := range der {
|
||||
|
@ -902,7 +1026,7 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
|||
n += copy(pub[n:], b)
|
||||
}
|
||||
x509Cert, err := x509.ParseCertificates(pub)
|
||||
if len(x509Cert) == 0 {
|
||||
if err != nil || len(x509Cert) == 0 {
|
||||
return nil, errors.New("acme/autocert: no public key found")
|
||||
}
|
||||
// verify the leaf is not expired and matches the domain name
|
||||
|
@ -914,10 +1038,10 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
|||
if now.After(leaf.NotAfter) {
|
||||
return nil, errors.New("acme/autocert: expired certificate")
|
||||
}
|
||||
if err := leaf.VerifyHostname(domain); err != nil {
|
||||
if err := leaf.VerifyHostname(ck.domain); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// ensure the leaf corresponds to the private key
|
||||
// ensure the leaf corresponds to the private key and matches the certKey type
|
||||
switch pub := leaf.PublicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
prv, ok := key.(*rsa.PrivateKey)
|
||||
|
@ -927,6 +1051,9 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
|||
if pub.N.Cmp(prv.N) != 0 {
|
||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
||||
}
|
||||
if !ck.isRSA && !ck.isToken {
|
||||
return nil, errors.New("acme/autocert: key type does not match expected value")
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
prv, ok := key.(*ecdsa.PrivateKey)
|
||||
if !ok {
|
||||
|
@ -935,6 +1062,9 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
|||
if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
|
||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
||||
}
|
||||
if ck.isRSA && !ck.isToken {
|
||||
return nil, errors.New("acme/autocert: key type does not match expected value")
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("acme/autocert: unknown public key algorithm")
|
||||
}
|
||||
|
@ -958,5 +1088,5 @@ var (
|
|||
timeNow = time.Now
|
||||
|
||||
// Called when a state is removed.
|
||||
testDidRemoveState = func(domain string) {}
|
||||
testDidRemoveState = func(certKey) {}
|
||||
)
|
||||
|
|
563
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
563
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
|
@ -5,6 +5,7 @@
|
|||
package autocert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
|
@ -14,6 +15,7 @@ import (
|
|||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -31,6 +33,12 @@ import (
|
|||
"golang.org/x/crypto/acme"
|
||||
)
|
||||
|
||||
var (
|
||||
exampleDomain = "example.org"
|
||||
exampleCertKey = certKey{domain: exampleDomain}
|
||||
exampleCertKeyRSA = certKey{domain: exampleDomain, isRSA: true}
|
||||
)
|
||||
|
||||
var discoTmpl = template.Must(template.New("disco").Parse(`{
|
||||
"new-reg": "{{.}}/new-reg",
|
||||
"new-authz": "{{.}}/new-authz",
|
||||
|
@ -64,6 +72,7 @@ var authzTmpl = template.Must(template.New("authz").Parse(`{
|
|||
}`))
|
||||
|
||||
type memCache struct {
|
||||
t *testing.T
|
||||
mu sync.Mutex
|
||||
keyData map[string][]byte
|
||||
}
|
||||
|
@ -79,7 +88,26 @@ func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
|
|||
return v, nil
|
||||
}
|
||||
|
||||
// filenameSafe returns whether all characters in s are printable ASCII
|
||||
// and safe to use in a filename on most filesystems.
|
||||
func filenameSafe(s string) bool {
|
||||
for _, c := range s {
|
||||
if c < 0x20 || c > 0x7E {
|
||||
return false
|
||||
}
|
||||
switch c {
|
||||
case '\\', '/', ':', '*', '?', '"', '<', '>', '|':
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
|
||||
if !filenameSafe(key) {
|
||||
m.t.Errorf("invalid characters in cache key %q", key)
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
|
@ -95,12 +123,29 @@ func (m *memCache) Delete(ctx context.Context, key string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func newMemCache() *memCache {
|
||||
func newMemCache(t *testing.T) *memCache {
|
||||
return &memCache{
|
||||
t: t,
|
||||
keyData: make(map[string][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *memCache) numCerts() int {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
res := 0
|
||||
for key := range m.keyData {
|
||||
if strings.HasSuffix(key, "+token") ||
|
||||
strings.HasSuffix(key, "+key") ||
|
||||
strings.HasSuffix(key, "+http-01") {
|
||||
continue
|
||||
}
|
||||
res++
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dummyCert(pub interface{}, san ...string) ([]byte, error) {
|
||||
return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
|
||||
}
|
||||
|
@ -137,53 +182,58 @@ func decodePayload(v interface{}, r io.Reader) error {
|
|||
return json.Unmarshal(payload, v)
|
||||
}
|
||||
|
||||
func clientHelloInfo(sni string, ecdsaSupport bool) *tls.ClientHelloInfo {
|
||||
hello := &tls.ClientHelloInfo{
|
||||
ServerName: sni,
|
||||
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
|
||||
}
|
||||
if ecdsaSupport {
|
||||
hello.CipherSuites = append(hello.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)
|
||||
}
|
||||
return hello
|
||||
}
|
||||
|
||||
func TestGetCertificate(t *testing.T) {
|
||||
man := &Manager{Prompt: AcceptTOS}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_trailingDot(t *testing.T) {
|
||||
man := &Manager{Prompt: AcceptTOS}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org."}
|
||||
hello := clientHelloInfo("example.org.", true)
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_ForceRSA(t *testing.T) {
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
ForceRSA: true,
|
||||
}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
testGetCertificate(t, man, exampleDomain, hello)
|
||||
|
||||
cert, err := man.cacheGet(context.Background(), "example.org")
|
||||
// ForceRSA was deprecated and is now ignored.
|
||||
cert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if _, ok := cert.PrivateKey.(*rsa.PrivateKey); !ok {
|
||||
t.Errorf("cert.PrivateKey is %T; want *rsa.PrivateKey", cert.PrivateKey)
|
||||
if _, ok := cert.PrivateKey.(*ecdsa.PrivateKey); !ok {
|
||||
t.Errorf("cert.PrivateKey is %T; want *ecdsa.PrivateKey", cert.PrivateKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_nilPrompt(t *testing.T) {
|
||||
man := &Manager{}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, man, "example.org")
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
|
||||
defer finish()
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.Client = &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: url,
|
||||
}
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
if _, err := man.GetCertificate(hello); err == nil {
|
||||
t.Error("got certificate for example.org; wanted error")
|
||||
}
|
||||
|
@ -197,7 +247,7 @@ func TestGetCertificate_expiredCache(t *testing.T) {
|
|||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "example.org"},
|
||||
Subject: pkix.Name{CommonName: exampleDomain},
|
||||
NotAfter: time.Now(),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
|
||||
|
@ -209,16 +259,16 @@ func TestGetCertificate_expiredCache(t *testing.T) {
|
|||
PrivateKey: pk,
|
||||
}
|
||||
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: newMemCache()}
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: newMemCache(t)}
|
||||
defer man.stopRenew()
|
||||
if err := man.cachePut(context.Background(), "example.org", tlscert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
// The expired cached cert should trigger a new cert issuance
|
||||
// and return without an error.
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
testGetCertificate(t, man, exampleDomain, hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_failedAttempt(t *testing.T) {
|
||||
|
@ -227,7 +277,6 @@ func TestGetCertificate_failedAttempt(t *testing.T) {
|
|||
}))
|
||||
defer ts.Close()
|
||||
|
||||
const example = "example.org"
|
||||
d := createCertRetryAfter
|
||||
f := testDidRemoveState
|
||||
defer func() {
|
||||
|
@ -236,51 +285,167 @@ func TestGetCertificate_failedAttempt(t *testing.T) {
|
|||
}()
|
||||
createCertRetryAfter = 0
|
||||
done := make(chan struct{})
|
||||
testDidRemoveState = func(domain string) {
|
||||
if domain != example {
|
||||
t.Errorf("testDidRemoveState: domain = %q; want %q", domain, example)
|
||||
testDidRemoveState = func(ck certKey) {
|
||||
if ck != exampleCertKey {
|
||||
t.Errorf("testDidRemoveState: domain = %v; want %v", ck, exampleCertKey)
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ts.URL,
|
||||
},
|
||||
}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: example}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
if _, err := man.GetCertificate(hello); err == nil {
|
||||
t.Error("GetCertificate: err is nil")
|
||||
}
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Errorf("took too long to remove the %q state", example)
|
||||
t.Errorf("took too long to remove the %q state", exampleCertKey)
|
||||
case <-done:
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
if v, exist := man.state[example]; exist {
|
||||
t.Errorf("state exists for %q: %+v", example, v)
|
||||
if v, exist := man.state[exampleCertKey]; exist {
|
||||
t.Errorf("state exists for %v: %+v", exampleCertKey, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testGetCertificate_tokenCache tests the fallback of token certificate fetches
|
||||
// to cache when Manager.certTokens misses. ecdsaSupport refers to the CA when
|
||||
// verifying the certificate token.
|
||||
func testGetCertificate_tokenCache(t *testing.T, ecdsaSupport bool) {
|
||||
man1 := &Manager{
|
||||
Cache: newMemCache(t),
|
||||
Prompt: AcceptTOS,
|
||||
}
|
||||
defer man1.stopRenew()
|
||||
man2 := &Manager{
|
||||
Cache: man1.Cache,
|
||||
Prompt: AcceptTOS,
|
||||
}
|
||||
defer man2.stopRenew()
|
||||
|
||||
// Send the verification request to a different Manager from the one that
|
||||
// initiated the authorization, when they share caches.
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man2, ecdsaSupport), "example.org")
|
||||
defer finish()
|
||||
man1.Client = &acme.Client{DirectoryURL: url}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
if _, err := man1.GetCertificate(hello); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := man2.GetCertificate(hello); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_tokenCache(t *testing.T) {
|
||||
t.Run("ecdsaSupport=true", func(t *testing.T) {
|
||||
testGetCertificate_tokenCache(t, true)
|
||||
})
|
||||
t.Run("ecdsaSupport=false", func(t *testing.T) {
|
||||
testGetCertificate_tokenCache(t, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCertificate_ecdsaVsRSA(t *testing.T) {
|
||||
cache := newMemCache(t)
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: cache}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
|
||||
defer finish()
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
cert, err := man.GetCertificate(clientHelloInfo("example.org", true))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
|
||||
t.Error("an ECDSA client was served a non-ECDSA certificate")
|
||||
}
|
||||
|
||||
cert, err = man.GetCertificate(clientHelloInfo("example.org", false))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*rsa.PublicKey); !ok {
|
||||
t.Error("a RSA client was served a non-RSA certificate")
|
||||
}
|
||||
|
||||
if _, err := man.GetCertificate(clientHelloInfo("example.org", true)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := man.GetCertificate(clientHelloInfo("example.org", false)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if numCerts := cache.numCerts(); numCerts != 2 {
|
||||
t.Errorf("found %d certificates in cache; want %d", numCerts, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_wrongCacheKeyType(t *testing.T) {
|
||||
cache := newMemCache(t)
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: cache}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), exampleDomain)
|
||||
defer finish()
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
// Make an RSA cert and cache it without suffix.
|
||||
pk, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: exampleDomain},
|
||||
NotAfter: time.Now().Add(90 * 24 * time.Hour),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{pub},
|
||||
PrivateKey: pk,
|
||||
}
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, rsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
// The RSA cached cert should be silently ignored and replaced.
|
||||
cert, err := man.GetCertificate(clientHelloInfo(exampleDomain, true))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
|
||||
t.Error("an ECDSA client was served a non-ECDSA certificate")
|
||||
}
|
||||
if numCerts := cache.numCerts(); numCerts != 1 {
|
||||
t.Errorf("found %d certificates in cache; want %d", numCerts, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func getCertificateFromManager(man *Manager, ecdsaSupport bool) func(string) error {
|
||||
return func(sni string) error {
|
||||
_, err := man.GetCertificate(clientHelloInfo(sni, ecdsaSupport))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// startACMEServerStub runs an ACME server
|
||||
// The domain argument is the expected domain name of a certificate request.
|
||||
func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string, finish func()) {
|
||||
func startACMEServerStub(t *testing.T, getCertificate func(string) error, domain string) (url string, finish func()) {
|
||||
// echo token-02 | shasum -a 256
|
||||
// then divide result in 2 parts separated by dot
|
||||
tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
|
||||
verifyTokenCert := func() {
|
||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
||||
_, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
if err := getCertificate(tokenCertName); err != nil {
|
||||
t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
|
||||
return
|
||||
}
|
||||
|
@ -362,8 +527,7 @@ func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string,
|
|||
tick := time.NewTicker(100 * time.Millisecond)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
||||
if _, err := man.GetCertificate(hello); err != nil {
|
||||
if err := getCertificate(tokenCertName); err != nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
|
@ -387,21 +551,13 @@ func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string,
|
|||
// tests man.GetCertificate flow using the provided hello argument.
|
||||
// The domain argument is the expected domain name of a certificate request.
|
||||
func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
|
||||
url, finish := startACMEServerStub(t, man, domain)
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), domain)
|
||||
defer finish()
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.Client = &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: url,
|
||||
}
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
// simulate tls.Config.GetCertificate
|
||||
var tlscert *tls.Certificate
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
tlscert, err = man.GetCertificate(hello)
|
||||
|
@ -445,7 +601,7 @@ func TestVerifyHTTP01(t *testing.T) {
|
|||
if w.Code != http.StatusOK {
|
||||
t.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
|
||||
}
|
||||
if v := string(w.Body.Bytes()); !strings.HasPrefix(v, "token-http-01.") {
|
||||
if v := w.Body.String(); !strings.HasPrefix(v, "token-http-01.") {
|
||||
t.Errorf("http token value = %q; want 'token-http-01.' prefix", v)
|
||||
}
|
||||
}
|
||||
|
@ -505,18 +661,18 @@ func TestVerifyHTTP01(t *testing.T) {
|
|||
}))
|
||||
defer ca.Close()
|
||||
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m := &Manager{
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ca.URL,
|
||||
},
|
||||
}
|
||||
http01 = m.HTTPHandler(nil)
|
||||
if err := m.verify(context.Background(), m.Client, "example.org"); err != nil {
|
||||
ctx := context.Background()
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("m.acmeClient: %v", err)
|
||||
}
|
||||
if err := m.verify(ctx, client, "example.org"); err != nil {
|
||||
t.Errorf("m.verify: %v", err)
|
||||
}
|
||||
// Only tls-sni-01, tls-sni-02 and http-01 must be accepted
|
||||
|
@ -529,6 +685,111 @@ func TestVerifyHTTP01(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRevokeFailedAuthz(t *testing.T) {
|
||||
// Prefill authorization URIs expected to be revoked.
|
||||
// The challenges are selected in a specific order,
|
||||
// each tried within a newly created authorization.
|
||||
// This means each authorization URI corresponds to a different challenge type.
|
||||
revokedAuthz := map[string]bool{
|
||||
"/authz/0": false, // tls-sni-02
|
||||
"/authz/1": false, // tls-sni-01
|
||||
"/authz/2": false, // no viable challenge, but authz is created
|
||||
}
|
||||
|
||||
var authzCount int // num. of created authorizations
|
||||
var revokeCount int // num. of revoked authorizations
|
||||
done := make(chan struct{}) // closed when revokeCount is 3
|
||||
|
||||
// ACME CA server stub, only the needed bits.
|
||||
// TODO: Merge this with startACMEServerStub, making it a configurable CA for testing.
|
||||
var ca *httptest.Server
|
||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", "nonce")
|
||||
if r.Method == "HEAD" {
|
||||
// a nonce request
|
||||
return
|
||||
}
|
||||
|
||||
switch r.URL.Path {
|
||||
// Discovery.
|
||||
case "/":
|
||||
if err := discoTmpl.Execute(w, ca.URL); err != nil {
|
||||
t.Errorf("discoTmpl: %v", err)
|
||||
}
|
||||
// Client key registration.
|
||||
case "/new-reg":
|
||||
w.Write([]byte("{}"))
|
||||
// New domain authorization.
|
||||
case "/new-authz":
|
||||
w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
if err := authzTmpl.Execute(w, ca.URL); err != nil {
|
||||
t.Errorf("authzTmpl: %v", err)
|
||||
}
|
||||
authzCount++
|
||||
// tls-sni-02 challenge "accept" request.
|
||||
case "/challenge/2":
|
||||
// Refuse.
|
||||
http.Error(w, "won't accept tls-sni-02 challenge", http.StatusBadRequest)
|
||||
// tls-sni-01 challenge "accept" request.
|
||||
case "/challenge/1":
|
||||
// Accept but the authorization will be "expired".
|
||||
w.Write([]byte("{}"))
|
||||
// Authorization requests.
|
||||
case "/authz/0", "/authz/1", "/authz/2":
|
||||
// Revocation requests.
|
||||
if r.Method == "POST" {
|
||||
var req struct{ Status string }
|
||||
if err := decodePayload(&req, r.Body); err != nil {
|
||||
t.Errorf("%s: decodePayload: %v", r.URL, err)
|
||||
}
|
||||
switch req.Status {
|
||||
case "deactivated":
|
||||
revokedAuthz[r.URL.Path] = true
|
||||
revokeCount++
|
||||
if revokeCount >= 3 {
|
||||
// Last authorization is revoked.
|
||||
defer close(done)
|
||||
}
|
||||
default:
|
||||
t.Errorf("%s: req.Status = %q; want 'deactivated'", r.URL, req.Status)
|
||||
}
|
||||
w.Write([]byte(`{"status": "invalid"}`))
|
||||
return
|
||||
}
|
||||
// Authorization status requests.
|
||||
// Simulate abandoned authorization, deleted by the CA.
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
defer ca.Close()
|
||||
|
||||
m := &Manager{
|
||||
Client: &acme.Client{DirectoryURL: ca.URL},
|
||||
}
|
||||
// Should fail and revoke 3 authorizations.
|
||||
// The first 2 are tsl-sni-02 and tls-sni-01 challenges.
|
||||
// The third time an authorization is created but no viable challenge is found.
|
||||
// See revokedAuthz above for more explanation.
|
||||
if _, err := m.createCert(context.Background(), exampleCertKey); err == nil {
|
||||
t.Errorf("m.createCert returned nil error")
|
||||
}
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Error("revocations took too long")
|
||||
case <-done:
|
||||
// revokeCount is at least 3.
|
||||
}
|
||||
for uri, ok := range revokedAuthz {
|
||||
if !ok {
|
||||
t.Errorf("%q authorization was not revoked", uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPHandlerDefaultFallback(t *testing.T) {
|
||||
tt := []struct {
|
||||
method, url string
|
||||
|
@ -571,7 +832,7 @@ func TestHTTPHandlerDefaultFallback(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAccountKeyCache(t *testing.T) {
|
||||
m := Manager{Cache: newMemCache()}
|
||||
m := Manager{Cache: newMemCache(t)}
|
||||
ctx := context.Background()
|
||||
k1, err := m.accountKey(ctx)
|
||||
if err != nil {
|
||||
|
@ -587,36 +848,57 @@ func TestAccountKeyCache(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "example.org"},
|
||||
NotAfter: time.Now().Add(time.Hour),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privKey.PublicKey, privKey)
|
||||
cert, err := dummyCert(ecdsaKey.Public(), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlscert := &tls.Certificate{
|
||||
Certificate: [][]byte{pub},
|
||||
PrivateKey: privKey,
|
||||
ecdsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{cert},
|
||||
PrivateKey: ecdsaKey,
|
||||
}
|
||||
|
||||
man := &Manager{Cache: newMemCache()}
|
||||
rsaKey, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cert, err = dummyCert(rsaKey.Public(), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{cert},
|
||||
PrivateKey: rsaKey,
|
||||
}
|
||||
|
||||
man := &Manager{Cache: newMemCache(t)}
|
||||
defer man.stopRenew()
|
||||
ctx := context.Background()
|
||||
if err := man.cachePut(ctx, "example.org", tlscert); err != nil {
|
||||
|
||||
if err := man.cachePut(ctx, exampleCertKey, ecdsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
res, err := man.cacheGet(ctx, "example.org")
|
||||
if err := man.cachePut(ctx, exampleCertKeyRSA, rsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
res, err := man.cacheGet(ctx, exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if res == nil {
|
||||
t.Fatal("res is nil")
|
||||
if res == nil || !bytes.Equal(res.Certificate[0], ecdsaCert.Certificate[0]) {
|
||||
t.Errorf("man.cacheGet = %+v; want %+v", res, ecdsaCert)
|
||||
}
|
||||
|
||||
res, err = man.cacheGet(ctx, exampleCertKeyRSA)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if res == nil || !bytes.Equal(res.Certificate[0], rsaCert.Certificate[0]) {
|
||||
t.Errorf("man.cacheGet = %+v; want %+v", res, rsaCert)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -680,26 +962,28 @@ func TestValidCert(t *testing.T) {
|
|||
}
|
||||
|
||||
tt := []struct {
|
||||
domain string
|
||||
key crypto.Signer
|
||||
cert [][]byte
|
||||
ok bool
|
||||
ck certKey
|
||||
key crypto.Signer
|
||||
cert [][]byte
|
||||
ok bool
|
||||
}{
|
||||
{"example.org", key1, [][]byte{cert1}, true},
|
||||
{"example.org", key3, [][]byte{cert3}, true},
|
||||
{"example.org", key1, [][]byte{cert1, cert2, cert3}, true},
|
||||
{"example.org", key1, [][]byte{cert1, {1}}, false},
|
||||
{"example.org", key1, [][]byte{{1}}, false},
|
||||
{"example.org", key1, [][]byte{cert2}, false},
|
||||
{"example.org", key2, [][]byte{cert1}, false},
|
||||
{"example.org", key1, [][]byte{cert3}, false},
|
||||
{"example.org", key3, [][]byte{cert1}, false},
|
||||
{"example.net", key1, [][]byte{cert1}, false},
|
||||
{"example.org", key1, [][]byte{early}, false},
|
||||
{"example.org", key1, [][]byte{expired}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1}, true},
|
||||
{certKey{domain: "example.org", isRSA: true}, key3, [][]byte{cert3}, true},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1, cert2, cert3}, true},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1, {1}}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{{1}}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert2}, false},
|
||||
{certKey{domain: "example.org"}, key2, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert3}, false},
|
||||
{certKey{domain: "example.org"}, key3, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.net"}, key1, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{early}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{expired}, false},
|
||||
{certKey{domain: "example.org", isRSA: true}, key1, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key3, [][]byte{cert3}, false},
|
||||
}
|
||||
for i, test := range tt {
|
||||
leaf, err := validCert(test.domain, test.cert, test.key)
|
||||
leaf, err := validCert(test.ck, test.cert, test.key)
|
||||
if err != nil && test.ok {
|
||||
t.Errorf("%d: err = %v", i, err)
|
||||
}
|
||||
|
@ -748,10 +1032,99 @@ func TestManagerGetCertificateBogusSNI(t *testing.T) {
|
|||
{"fo.o", "cache.Get of fo.o"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
_, err := m.GetCertificate(&tls.ClientHelloInfo{ServerName: tt.name})
|
||||
_, err := m.GetCertificate(clientHelloInfo(tt.name, true))
|
||||
got := fmt.Sprint(err)
|
||||
if got != tt.wantErr {
|
||||
t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertRequest(t *testing.T) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// An extension from RFC7633. Any will do.
|
||||
ext := pkix.Extension{
|
||||
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1},
|
||||
Value: []byte("dummy"),
|
||||
}
|
||||
b, err := certRequest(key, "example.org", []pkix.Extension{ext}, "san.example.org")
|
||||
if err != nil {
|
||||
t.Fatalf("certRequest: %v", err)
|
||||
}
|
||||
r, err := x509.ParseCertificateRequest(b)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificateRequest: %v", err)
|
||||
}
|
||||
var found bool
|
||||
for _, v := range r.Extensions {
|
||||
if v.Id.Equal(ext.Id) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("want %v in Extensions: %v", ext, r.Extensions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSupportsECDSA(t *testing.T) {
|
||||
tests := []struct {
|
||||
CipherSuites []uint16
|
||||
SignatureSchemes []tls.SignatureScheme
|
||||
SupportedCurves []tls.CurveID
|
||||
ecdsaOk bool
|
||||
}{
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}, nil, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, nil, nil, true},
|
||||
|
||||
// SignatureSchemes limits, not extends, CipherSuites
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256,
|
||||
}, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, nil, true},
|
||||
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, []tls.CurveID{
|
||||
tls.CurveP521,
|
||||
}, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, []tls.CurveID{
|
||||
tls.CurveP256,
|
||||
tls.CurveP521,
|
||||
}, true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
result := supportsECDSA(&tls.ClientHelloInfo{
|
||||
CipherSuites: tt.CipherSuites,
|
||||
SignatureSchemes: tt.SignatureSchemes,
|
||||
SupportedCurves: tt.SupportedCurves,
|
||||
})
|
||||
if result != tt.ecdsaOk {
|
||||
t.Errorf("%d: supportsECDSA = %v; want %v", i, result, tt.ecdsaOk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
6
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
6
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
|
@ -16,10 +16,10 @@ import (
|
|||
var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
|
||||
|
||||
// Cache is used by Manager to store and retrieve previously obtained certificates
|
||||
// as opaque data.
|
||||
// and other account data as opaque blobs.
|
||||
//
|
||||
// The key argument of the methods refers to a domain name but need not be an FQDN.
|
||||
// Cache implementations should not rely on the key naming pattern.
|
||||
// Cache implementations should not rely on the key naming pattern. Keys can
|
||||
// include any printable ASCII characters, except the following: \/:*?"<>|
|
||||
type Cache interface {
|
||||
// Get returns a certificate data for the specified key.
|
||||
// If there's no such key, Get returns ErrCacheMiss.
|
||||
|
|
14
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
14
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
|
@ -17,9 +17,9 @@ const renewJitter = time.Hour
|
|||
// domainRenewal tracks the state used by the periodic timers
|
||||
// renewing a single domain's cert.
|
||||
type domainRenewal struct {
|
||||
m *Manager
|
||||
domain string
|
||||
key crypto.Signer
|
||||
m *Manager
|
||||
ck certKey
|
||||
key crypto.Signer
|
||||
|
||||
timerMu sync.Mutex
|
||||
timer *time.Timer
|
||||
|
@ -77,7 +77,7 @@ func (dr *domainRenewal) updateState(state *certState) {
|
|||
dr.m.stateMu.Lock()
|
||||
defer dr.m.stateMu.Unlock()
|
||||
dr.key = state.key
|
||||
dr.m.state[dr.domain] = state
|
||||
dr.m.state[dr.ck] = state
|
||||
}
|
||||
|
||||
// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
|
||||
|
@ -91,7 +91,7 @@ func (dr *domainRenewal) updateState(state *certState) {
|
|||
func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
||||
// a race is likely unavoidable in a distributed environment
|
||||
// but we try nonetheless
|
||||
if tlscert, err := dr.m.cacheGet(ctx, dr.domain); err == nil {
|
||||
if tlscert, err := dr.m.cacheGet(ctx, dr.ck); err == nil {
|
||||
next := dr.next(tlscert.Leaf.NotAfter)
|
||||
if next > dr.m.renewBefore()+renewJitter {
|
||||
signer, ok := tlscert.PrivateKey.(crypto.Signer)
|
||||
|
@ -107,7 +107,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
|||
}
|
||||
}
|
||||
|
||||
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.domain)
|
||||
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.ck)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := dr.m.cachePut(ctx, dr.domain, tlscert); err != nil {
|
||||
if err := dr.m.cachePut(ctx, dr.ck, tlscert); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
dr.updateState(state)
|
||||
|
|
72
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
72
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
|
@ -48,8 +48,6 @@ func TestRenewalNext(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRenewFromCache(t *testing.T) {
|
||||
const domain = "example.org"
|
||||
|
||||
// ACME CA server stub
|
||||
var ca *httptest.Server
|
||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -84,7 +82,7 @@ func TestRenewFromCache(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("new-cert: CSR: %v", err)
|
||||
}
|
||||
der, err := dummyCert(csr.PublicKey, domain)
|
||||
der, err := dummyCert(csr.PublicKey, exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatalf("new-cert: dummyCert: %v", err)
|
||||
}
|
||||
|
@ -105,30 +103,28 @@ func TestRenewFromCache(t *testing.T) {
|
|||
}))
|
||||
defer ca.Close()
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
RenewBefore: 24 * time.Hour,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ca.URL,
|
||||
},
|
||||
}
|
||||
defer man.stopRenew()
|
||||
|
||||
// cache an almost expired cert
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
now := time.Now()
|
||||
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
|
||||
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlscert := &tls.Certificate{PrivateKey: key, Certificate: [][]byte{cert}}
|
||||
if err := man.cachePut(context.Background(), domain, tlscert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -152,7 +148,7 @@ func TestRenewFromCache(t *testing.T) {
|
|||
|
||||
// ensure the new cert is cached
|
||||
after := time.Now().Add(future)
|
||||
tlscert, err := man.cacheGet(context.Background(), domain)
|
||||
tlscert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
|
@ -163,9 +159,9 @@ func TestRenewFromCache(t *testing.T) {
|
|||
// verify the old cert is also replaced in memory
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
s := man.state[domain]
|
||||
s := man.state[exampleCertKey]
|
||||
if s == nil {
|
||||
t.Fatalf("m.state[%q] is nil", domain)
|
||||
t.Fatalf("m.state[%q] is nil", exampleCertKey)
|
||||
}
|
||||
tlscert, err = s.tlscert()
|
||||
if err != nil {
|
||||
|
@ -177,7 +173,7 @@ func TestRenewFromCache(t *testing.T) {
|
|||
}
|
||||
|
||||
// trigger renew
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
if _, err := man.GetCertificate(hello); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -191,19 +187,11 @@ func TestRenewFromCache(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
const domain = "example.org"
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
RenewBefore: 24 * time.Hour,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: "invalid",
|
||||
},
|
||||
}
|
||||
|
@ -215,38 +203,42 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
now := time.Now()
|
||||
newCert, err := dateDummyCert(newKey.Public(), now.Add(-2*time.Hour), now.Add(time.Hour*24*90), domain)
|
||||
newCert, err := dateDummyCert(newKey.Public(), now.Add(-2*time.Hour), now.Add(time.Hour*24*90), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newLeaf, err := validCert(domain, [][]byte{newCert}, newKey)
|
||||
newLeaf, err := validCert(exampleCertKey, [][]byte{newCert}, newKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newTLSCert := &tls.Certificate{PrivateKey: newKey, Certificate: [][]byte{newCert}, Leaf: newLeaf}
|
||||
if err := man.cachePut(context.Background(), domain, newTLSCert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, newTLSCert); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// set internal state to an almost expired cert
|
||||
oldCert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldLeaf, err := validCert(domain, [][]byte{oldCert}, key)
|
||||
oldCert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldLeaf, err := validCert(exampleCertKey, [][]byte{oldCert}, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.stateMu.Lock()
|
||||
if man.state == nil {
|
||||
man.state = make(map[string]*certState)
|
||||
man.state = make(map[certKey]*certState)
|
||||
}
|
||||
s := &certState{
|
||||
key: key,
|
||||
cert: [][]byte{oldCert},
|
||||
leaf: oldLeaf,
|
||||
}
|
||||
man.state[domain] = s
|
||||
man.state[exampleCertKey] = s
|
||||
man.stateMu.Unlock()
|
||||
|
||||
// veriy the renewal accepted the newer cached cert
|
||||
|
@ -267,7 +259,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
}
|
||||
|
||||
// ensure the cached cert was not modified
|
||||
tlscert, err := man.cacheGet(context.Background(), domain)
|
||||
tlscert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
|
@ -278,9 +270,9 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
// verify the old cert is also replaced in memory
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
s := man.state[domain]
|
||||
s := man.state[exampleCertKey]
|
||||
if s == nil {
|
||||
t.Fatalf("m.state[%q] is nil", domain)
|
||||
t.Fatalf("m.state[%q] is nil", exampleCertKey)
|
||||
}
|
||||
stateKey := s.key.Public().(*ecdsa.PublicKey)
|
||||
if stateKey.X.Cmp(newKey.X) != 0 || stateKey.Y.Cmp(newKey.Y) != 0 {
|
||||
|
@ -295,9 +287,9 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
}
|
||||
|
||||
// verify the private key is replaced in the renewal state
|
||||
r := man.renewal[domain]
|
||||
r := man.renewal[exampleCertKey]
|
||||
if r == nil {
|
||||
t.Fatalf("m.renewal[%q] is nil", domain)
|
||||
t.Fatalf("m.renewal[%q] is nil", exampleCertKey)
|
||||
}
|
||||
renewalKey := r.key.Public().(*ecdsa.PublicKey)
|
||||
if renewalKey.X.Cmp(newKey.X) != 0 || renewalKey.Y.Cmp(newKey.Y) != 0 {
|
||||
|
@ -307,7 +299,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
}
|
||||
|
||||
// assert the expiring cert is returned from state
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
tlscert, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -317,7 +309,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
}
|
||||
|
||||
// trigger renew
|
||||
go man.renew(domain, s.key, s.leaf.NotAfter)
|
||||
go man.renew(exampleCertKey, s.key, s.leaf.NotAfter)
|
||||
|
||||
// wait for renew loop
|
||||
select {
|
||||
|
@ -325,7 +317,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
|||
t.Fatal("renew took too long to occur")
|
||||
case <-done:
|
||||
// assert the new cert is returned from state after renew
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
tlscert, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
281
vendor/golang.org/x/crypto/acme/http.go
generated
vendored
Normal file
281
vendor/golang.org/x/crypto/acme/http.go
generated
vendored
Normal file
|
@ -0,0 +1,281 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package acme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// retryTimer encapsulates common logic for retrying unsuccessful requests.
|
||||
// It is not safe for concurrent use.
|
||||
type retryTimer struct {
|
||||
// backoffFn provides backoff delay sequence for retries.
|
||||
// See Client.RetryBackoff doc comment.
|
||||
backoffFn func(n int, r *http.Request, res *http.Response) time.Duration
|
||||
// n is the current retry attempt.
|
||||
n int
|
||||
}
|
||||
|
||||
func (t *retryTimer) inc() {
|
||||
t.n++
|
||||
}
|
||||
|
||||
// backoff pauses the current goroutine as described in Client.RetryBackoff.
|
||||
func (t *retryTimer) backoff(ctx context.Context, r *http.Request, res *http.Response) error {
|
||||
d := t.backoffFn(t.n, r, res)
|
||||
if d <= 0 {
|
||||
return fmt.Errorf("acme: no more retries for %s; tried %d time(s)", r.URL, t.n)
|
||||
}
|
||||
wakeup := time.NewTimer(d)
|
||||
defer wakeup.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-wakeup.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) retryTimer() *retryTimer {
|
||||
f := c.RetryBackoff
|
||||
if f == nil {
|
||||
f = defaultBackoff
|
||||
}
|
||||
return &retryTimer{backoffFn: f}
|
||||
}
|
||||
|
||||
// defaultBackoff provides default Client.RetryBackoff implementation
|
||||
// using a truncated exponential backoff algorithm,
|
||||
// as described in Client.RetryBackoff.
|
||||
//
|
||||
// The n argument is always bounded between 1 and 30.
|
||||
// The returned value is always greater than 0.
|
||||
func defaultBackoff(n int, r *http.Request, res *http.Response) time.Duration {
|
||||
const max = 10 * time.Second
|
||||
var jitter time.Duration
|
||||
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
|
||||
// Set the minimum to 1ms to avoid a case where
|
||||
// an invalid Retry-After value is parsed into 0 below,
|
||||
// resulting in the 0 returned value which would unintentionally
|
||||
// stop the retries.
|
||||
jitter = (1 + time.Duration(x.Int64())) * time.Millisecond
|
||||
}
|
||||
if v, ok := res.Header["Retry-After"]; ok {
|
||||
return retryAfter(v[0]) + jitter
|
||||
}
|
||||
|
||||
if n < 1 {
|
||||
n = 1
|
||||
}
|
||||
if n > 30 {
|
||||
n = 30
|
||||
}
|
||||
d := time.Duration(1<<uint(n-1))*time.Second + jitter
|
||||
if d > max {
|
||||
return max
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// retryAfter parses a Retry-After HTTP header value,
|
||||
// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
|
||||
// It returns zero value if v cannot be parsed.
|
||||
func retryAfter(v string) time.Duration {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return time.Duration(i) * time.Second
|
||||
}
|
||||
t, err := http.ParseTime(v)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return t.Sub(timeNow())
|
||||
}
|
||||
|
||||
// resOkay is a function that reports whether the provided response is okay.
|
||||
// It is expected to keep the response body unread.
|
||||
type resOkay func(*http.Response) bool
|
||||
|
||||
// wantStatus returns a function which reports whether the code
|
||||
// matches the status code of a response.
|
||||
func wantStatus(codes ...int) resOkay {
|
||||
return func(res *http.Response) bool {
|
||||
for _, code := range codes {
|
||||
if code == res.StatusCode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// get issues an unsigned GET request to the specified URL.
|
||||
// It returns a non-error value only when ok reports true.
|
||||
//
|
||||
// get retries unsuccessful attempts according to c.RetryBackoff
|
||||
// until the context is done or a non-retriable error is received.
|
||||
func (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Response, error) {
|
||||
retry := c.retryTimer()
|
||||
for {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := c.doNoRetry(ctx, req)
|
||||
switch {
|
||||
case err != nil:
|
||||
return nil, err
|
||||
case ok(res):
|
||||
return res, nil
|
||||
case isRetriable(res.StatusCode):
|
||||
retry.inc()
|
||||
resErr := responseError(res)
|
||||
res.Body.Close()
|
||||
// Ignore the error value from retry.backoff
|
||||
// and return the one from last retry, as received from the CA.
|
||||
if retry.backoff(ctx, req, res) != nil {
|
||||
return nil, resErr
|
||||
}
|
||||
default:
|
||||
defer res.Body.Close()
|
||||
return nil, responseError(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// post issues a signed POST request in JWS format using the provided key
|
||||
// to the specified URL.
|
||||
// It returns a non-error value only when ok reports true.
|
||||
//
|
||||
// post retries unsuccessful attempts according to c.RetryBackoff
|
||||
// until the context is done or a non-retriable error is received.
|
||||
// It uses postNoRetry to make individual requests.
|
||||
func (c *Client) post(ctx context.Context, key crypto.Signer, url string, body interface{}, ok resOkay) (*http.Response, error) {
|
||||
retry := c.retryTimer()
|
||||
for {
|
||||
res, req, err := c.postNoRetry(ctx, key, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok(res) {
|
||||
return res, nil
|
||||
}
|
||||
resErr := responseError(res)
|
||||
res.Body.Close()
|
||||
switch {
|
||||
// Check for bad nonce before isRetriable because it may have been returned
|
||||
// with an unretriable response code such as 400 Bad Request.
|
||||
case isBadNonce(resErr):
|
||||
// Consider any previously stored nonce values to be invalid.
|
||||
c.clearNonces()
|
||||
case !isRetriable(res.StatusCode):
|
||||
return nil, resErr
|
||||
}
|
||||
retry.inc()
|
||||
// Ignore the error value from retry.backoff
|
||||
// and return the one from last retry, as received from the CA.
|
||||
if err := retry.backoff(ctx, req, res); err != nil {
|
||||
return nil, resErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// postNoRetry signs the body with the given key and POSTs it to the provided url.
|
||||
// The body argument must be JSON-serializable.
|
||||
// It is used by c.post to retry unsuccessful attempts.
|
||||
func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {
|
||||
nonce, err := c.popNonce(ctx, url)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
b, err := jwsEncodeJSON(body, key, nonce)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/jose+json")
|
||||
res, err := c.doNoRetry(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
c.addNonce(res.Header)
|
||||
return res, req, nil
|
||||
}
|
||||
|
||||
// doNoRetry issues a request req, replacing its context (if any) with ctx.
|
||||
func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
res, err := c.httpClient().Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Prefer the unadorned context error.
|
||||
// (The acme package had tests assuming this, previously from ctxhttp's
|
||||
// behavior, predating net/http supporting contexts natively)
|
||||
// TODO(bradfitz): reconsider this in the future. But for now this
|
||||
// requires no test updates.
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) httpClient() *http.Client {
|
||||
if c.HTTPClient != nil {
|
||||
return c.HTTPClient
|
||||
}
|
||||
return http.DefaultClient
|
||||
}
|
||||
|
||||
// isBadNonce reports whether err is an ACME "badnonce" error.
|
||||
func isBadNonce(err error) bool {
|
||||
// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.
|
||||
// However, ACME servers in the wild return their versions of the error.
|
||||
// See https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
|
||||
// and https://github.com/letsencrypt/boulder/blob/0e07eacb/docs/acme-divergences.md#section-66.
|
||||
ae, ok := err.(*Error)
|
||||
return ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce")
|
||||
}
|
||||
|
||||
// isRetriable reports whether a request can be retried
|
||||
// based on the response status code.
|
||||
//
|
||||
// Note that a "bad nonce" error is returned with a non-retriable 400 Bad Request code.
|
||||
// Callers should parse the response and check with isBadNonce.
|
||||
func isRetriable(code int) bool {
|
||||
return code <= 399 || code >= 500 || code == http.StatusTooManyRequests
|
||||
}
|
||||
|
||||
// responseError creates an error of Error type from resp.
|
||||
func responseError(resp *http.Response) error {
|
||||
// don't care if ReadAll returns an error:
|
||||
// json.Unmarshal will fail in that case anyway
|
||||
b, _ := ioutil.ReadAll(resp.Body)
|
||||
e := &wireError{Status: resp.StatusCode}
|
||||
if err := json.Unmarshal(b, e); err != nil {
|
||||
// this is not a regular error response:
|
||||
// populate detail with anything we received,
|
||||
// e.Status will already contain HTTP response code value
|
||||
e.Detail = string(b)
|
||||
if e.Detail == "" {
|
||||
e.Detail = resp.Status
|
||||
}
|
||||
}
|
||||
return e.error(resp.Header)
|
||||
}
|
209
vendor/golang.org/x/crypto/acme/http_test.go
generated
vendored
Normal file
209
vendor/golang.org/x/crypto/acme/http_test.go
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package acme
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDefaultBackoff(t *testing.T) {
|
||||
tt := []struct {
|
||||
nretry int
|
||||
retryAfter string // Retry-After header
|
||||
out time.Duration // expected min; max = min + jitter
|
||||
}{
|
||||
{-1, "", time.Second}, // verify the lower bound is 1
|
||||
{0, "", time.Second}, // verify the lower bound is 1
|
||||
{100, "", 10 * time.Second}, // verify the ceiling
|
||||
{1, "3600", time.Hour}, // verify the header value is used
|
||||
{1, "", 1 * time.Second},
|
||||
{2, "", 2 * time.Second},
|
||||
{3, "", 4 * time.Second},
|
||||
{4, "", 8 * time.Second},
|
||||
}
|
||||
for i, test := range tt {
|
||||
r := httptest.NewRequest("GET", "/", nil)
|
||||
resp := &http.Response{Header: http.Header{}}
|
||||
if test.retryAfter != "" {
|
||||
resp.Header.Set("Retry-After", test.retryAfter)
|
||||
}
|
||||
d := defaultBackoff(test.nretry, r, resp)
|
||||
max := test.out + time.Second // + max jitter
|
||||
if d < test.out || max < d {
|
||||
t.Errorf("%d: defaultBackoff(%v) = %v; want between %v and %v", i, test.nretry, d, test.out, max)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
s := `{
|
||||
"status": 400,
|
||||
"type": "urn:acme:error:xxx",
|
||||
"detail": "text"
|
||||
}`
|
||||
res := &http.Response{
|
||||
StatusCode: 400,
|
||||
Status: "400 Bad Request",
|
||||
Body: ioutil.NopCloser(strings.NewReader(s)),
|
||||
Header: http.Header{"X-Foo": {"bar"}},
|
||||
}
|
||||
err := responseError(res)
|
||||
v, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err = %+v (%T); want *Error type", err, err)
|
||||
}
|
||||
if v.StatusCode != 400 {
|
||||
t.Errorf("v.StatusCode = %v; want 400", v.StatusCode)
|
||||
}
|
||||
if v.ProblemType != "urn:acme:error:xxx" {
|
||||
t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType)
|
||||
}
|
||||
if v.Detail != "text" {
|
||||
t.Errorf("v.Detail = %q; want text", v.Detail)
|
||||
}
|
||||
if !reflect.DeepEqual(v.Header, res.Header) {
|
||||
t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostWithRetries(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Replay-Nonce", fmt.Sprintf("nonce%d", count))
|
||||
if r.Method == "HEAD" {
|
||||
// We expect the client to do 2 head requests to fetch
|
||||
// nonces, one to start and another after getting badNonce
|
||||
return
|
||||
}
|
||||
|
||||
head, err := decodeJWSHead(r)
|
||||
switch {
|
||||
case err != nil:
|
||||
t.Errorf("decodeJWSHead: %v", err)
|
||||
case head.Nonce == "":
|
||||
t.Error("head.Nonce is empty")
|
||||
case head.Nonce == "nonce1":
|
||||
// Return a badNonce error to force the call to retry.
|
||||
w.Header().Set("Retry-After", "0")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"type":"urn:ietf:params:acme:error:badNonce"}`))
|
||||
return
|
||||
}
|
||||
// Make client.Authorize happy; we're not testing its result.
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(`{"status":"valid"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client := &Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
|
||||
// This call will fail with badNonce, causing a retry
|
||||
if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
|
||||
t.Errorf("client.Authorize 1: %v", err)
|
||||
}
|
||||
if count != 4 {
|
||||
t.Errorf("total requests count: %d; want 4", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryErrorType(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", "nonce")
|
||||
w.WriteHeader(http.StatusTooManyRequests)
|
||||
w.Write([]byte(`{"type":"rateLimited"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client := &Client{
|
||||
Key: testKey,
|
||||
RetryBackoff: func(n int, r *http.Request, res *http.Response) time.Duration {
|
||||
// Do no retries.
|
||||
return 0
|
||||
},
|
||||
dir: &Directory{AuthzURL: ts.URL},
|
||||
}
|
||||
|
||||
t.Run("post", func(t *testing.T) {
|
||||
testRetryErrorType(t, func() error {
|
||||
_, err := client.Authorize(context.Background(), "example.com")
|
||||
return err
|
||||
})
|
||||
})
|
||||
t.Run("get", func(t *testing.T) {
|
||||
testRetryErrorType(t, func() error {
|
||||
_, err := client.GetAuthorization(context.Background(), ts.URL)
|
||||
return err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testRetryErrorType(t *testing.T, callClient func() error) {
|
||||
t.Helper()
|
||||
err := callClient()
|
||||
if err == nil {
|
||||
t.Fatal("client.Authorize returned nil error")
|
||||
}
|
||||
acmeErr, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err is %v (%T); want *Error", err, err)
|
||||
}
|
||||
if acmeErr.StatusCode != http.StatusTooManyRequests {
|
||||
t.Errorf("acmeErr.StatusCode = %d; want %d", acmeErr.StatusCode, http.StatusTooManyRequests)
|
||||
}
|
||||
if acmeErr.ProblemType != "rateLimited" {
|
||||
t.Errorf("acmeErr.ProblemType = %q; want 'rateLimited'", acmeErr.ProblemType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryBackoffArgs(t *testing.T) {
|
||||
const resCode = http.StatusInternalServerError
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", "test-nonce")
|
||||
w.WriteHeader(resCode)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
// Canceled in backoff.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
var nretry int
|
||||
backoff := func(n int, r *http.Request, res *http.Response) time.Duration {
|
||||
nretry++
|
||||
if n != nretry {
|
||||
t.Errorf("n = %d; want %d", n, nretry)
|
||||
}
|
||||
if nretry == 3 {
|
||||
cancel()
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
t.Error("r is nil")
|
||||
}
|
||||
if res.StatusCode != resCode {
|
||||
t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, resCode)
|
||||
}
|
||||
return time.Millisecond
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
Key: testKey,
|
||||
RetryBackoff: backoff,
|
||||
dir: &Directory{AuthzURL: ts.URL},
|
||||
}
|
||||
if _, err := client.Authorize(ctx, "example.com"); err == nil {
|
||||
t.Error("err is nil")
|
||||
}
|
||||
if nretry != 3 {
|
||||
t.Errorf("nretry = %d; want 3", nretry)
|
||||
}
|
||||
}
|
8
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
8
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
|
@ -104,7 +104,7 @@ func RateLimit(err error) (time.Duration, bool) {
|
|||
if e.Header == nil {
|
||||
return 0, true
|
||||
}
|
||||
return retryAfter(e.Header.Get("Retry-After"), 0), true
|
||||
return retryAfter(e.Header.Get("Retry-After")), true
|
||||
}
|
||||
|
||||
// Account is a user account. It is associated with a private key.
|
||||
|
@ -296,8 +296,8 @@ func (e *wireError) error(h http.Header) *Error {
|
|||
}
|
||||
}
|
||||
|
||||
// CertOption is an optional argument type for the TLSSNIxChallengeCert methods for
|
||||
// customizing a temporary certificate for TLS-SNI challenges.
|
||||
// CertOption is an optional argument type for the TLS ChallengeCert methods for
|
||||
// customizing a temporary certificate for TLS-based challenges.
|
||||
type CertOption interface {
|
||||
privateCertOpt()
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ func (*certOptKey) privateCertOpt() {}
|
|||
// WithTemplate creates an option for specifying a certificate template.
|
||||
// See x509.CreateCertificate for template usage details.
|
||||
//
|
||||
// In TLSSNIxChallengeCert methods, the template is also used as parent,
|
||||
// In TLS ChallengeCert methods, the template is also used as parent,
|
||||
// resulting in a self-signed certificate.
|
||||
// The DNSNames field of t is always overwritten for tls-sni challenge certs.
|
||||
func WithTemplate(t *x509.Certificate) CertOption {
|
||||
|
|
2
vendor/golang.org/x/crypto/bn256/bn256.go
generated
vendored
2
vendor/golang.org/x/crypto/bn256/bn256.go
generated
vendored
|
@ -109,7 +109,6 @@ func (e *G1) Marshal() []byte {
|
|||
xBytes := new(big.Int).Mod(e.p.x, p).Bytes()
|
||||
yBytes := new(big.Int).Mod(e.p.y, p).Bytes()
|
||||
|
||||
|
||||
ret := make([]byte, numBytes*2)
|
||||
copy(ret[1*numBytes-len(xBytes):], xBytes)
|
||||
copy(ret[2*numBytes-len(yBytes):], yBytes)
|
||||
|
@ -224,7 +223,6 @@ func (n *G2) Marshal() []byte {
|
|||
yxBytes := new(big.Int).Mod(n.p.y.x, p).Bytes()
|
||||
yyBytes := new(big.Int).Mod(n.p.y.y, p).Bytes()
|
||||
|
||||
|
||||
ret := make([]byte, numBytes*4)
|
||||
copy(ret[1*numBytes-len(xxBytes):], xxBytes)
|
||||
copy(ret[2*numBytes-len(xyBytes):], xyBytes)
|
||||
|
|
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
|
@ -9,6 +9,7 @@ package chacha20poly1305
|
|||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
|
@ -55,6 +56,9 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []
|
|||
setupState(&state, &c.key, nonce)
|
||||
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
||||
if subtle.InexactOverlap(out, plaintext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
|
||||
return ret
|
||||
}
|
||||
|
@ -69,6 +73,9 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) (
|
|||
|
||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||
if subtle.InexactOverlap(out, ciphertext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
|
|
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
|||
"encoding/binary"
|
||||
|
||||
"golang.org/x/crypto/internal/chacha20"
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
)
|
||||
|
||||
|
@ -17,6 +18,9 @@ func roundTo16(n int) int {
|
|||
|
||||
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
||||
if subtle.InexactOverlap(out, plaintext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var polyKey [32]byte
|
||||
s := chacha20.New(c.key, [3]uint32{
|
||||
|
@ -62,6 +66,9 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
|
|||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext)))
|
||||
|
||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||
if subtle.InexactOverlap(out, ciphertext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
if !poly1305.Verify(&tag, polyInput, &polyKey) {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
|
|
47
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
47
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
|
@ -6,7 +6,10 @@
|
|||
// https://ed25519.cr.yp.to/.
|
||||
//
|
||||
// These functions are also compatible with the “Ed25519” function defined in
|
||||
// RFC 8032.
|
||||
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||
// representation includes a public key suffix to make multiple signing
|
||||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
package ed25519
|
||||
|
||||
// This code is a port of the public domain, “ref10” implementation of ed25519
|
||||
|
@ -31,6 +34,8 @@ const (
|
|||
PrivateKeySize = 64
|
||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||
SignatureSize = 64
|
||||
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||
SeedSize = 32
|
||||
)
|
||||
|
||||
// PublicKey is the type of Ed25519 public keys.
|
||||
|
@ -46,6 +51,15 @@ func (priv PrivateKey) Public() crypto.PublicKey {
|
|||
return PublicKey(publicKey)
|
||||
}
|
||||
|
||||
// Seed returns the private key seed corresponding to priv. It is provided for
|
||||
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
|
||||
// in this package.
|
||||
func (priv PrivateKey) Seed() []byte {
|
||||
seed := make([]byte, SeedSize)
|
||||
copy(seed, priv[:32])
|
||||
return seed
|
||||
}
|
||||
|
||||
// Sign signs the given message with priv.
|
||||
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
||||
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
||||
|
@ -61,19 +75,33 @@ func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOp
|
|||
|
||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||
// If rand is nil, crypto/rand.Reader will be used.
|
||||
func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, err error) {
|
||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
if rand == nil {
|
||||
rand = cryptorand.Reader
|
||||
}
|
||||
|
||||
privateKey = make([]byte, PrivateKeySize)
|
||||
publicKey = make([]byte, PublicKeySize)
|
||||
_, err = io.ReadFull(rand, privateKey[:32])
|
||||
if err != nil {
|
||||
seed := make([]byte, SeedSize)
|
||||
if _, err := io.ReadFull(rand, seed); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
digest := sha512.Sum512(privateKey[:32])
|
||||
privateKey := NewKeyFromSeed(seed)
|
||||
publicKey := make([]byte, PublicKeySize)
|
||||
copy(publicKey, privateKey[32:])
|
||||
|
||||
return publicKey, privateKey, nil
|
||||
}
|
||||
|
||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
if l := len(seed); l != SeedSize {
|
||||
panic("ed25519: bad seed length: " + strconv.Itoa(l))
|
||||
}
|
||||
|
||||
digest := sha512.Sum512(seed)
|
||||
digest[0] &= 248
|
||||
digest[31] &= 127
|
||||
digest[31] |= 64
|
||||
|
@ -85,10 +113,11 @@ func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, er
|
|||
var publicKeyBytes [32]byte
|
||||
A.ToBytes(&publicKeyBytes)
|
||||
|
||||
privateKey := make([]byte, PrivateKeySize)
|
||||
copy(privateKey, seed)
|
||||
copy(privateKey[32:], publicKeyBytes[:])
|
||||
copy(publicKey, publicKeyBytes[:])
|
||||
|
||||
return publicKey, privateKey, nil
|
||||
return privateKey
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
|
|
13
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
13
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
|
@ -139,6 +139,19 @@ func TestGolden(t *testing.T) {
|
|||
if !Verify(pubKey, msg, sig2) {
|
||||
t.Errorf("signature failed to verify on line %d", lineNo)
|
||||
}
|
||||
|
||||
priv2 := NewKeyFromSeed(priv[:32])
|
||||
if !bytes.Equal(priv[:], priv2) {
|
||||
t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
|
||||
}
|
||||
|
||||
if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) {
|
||||
t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
|
||||
}
|
||||
|
||||
if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) {
|
||||
t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
|
|
9
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
9
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
|
@ -9,6 +9,8 @@ package chacha20
|
|||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// assert that *Cipher implements cipher.Stream
|
||||
|
@ -41,6 +43,13 @@ func New(key [8]uint32, nonce [3]uint32) *Cipher {
|
|||
// the src buffers was passed in a single run. That is, Cipher
|
||||
// maintains state and does not reset at each XORKeyStream call.
|
||||
func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||
if len(dst) < len(src) {
|
||||
panic("chacha20: output smaller than input")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:len(src)], src) {
|
||||
panic("chacha20: invalid buffer overlap")
|
||||
}
|
||||
|
||||
// xor src with buffered keystream first
|
||||
if s.len != 0 {
|
||||
buf := s.buf[len(s.buf)-s.len:]
|
||||
|
|
32
vendor/golang.org/x/crypto/internal/subtle/aliasing.go
generated
vendored
Normal file
32
vendor/golang.org/x/crypto/internal/subtle/aliasing.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||
// corresponding) index. The memory beyond the slice length is ignored.
|
||||
func AnyOverlap(x, y []byte) bool {
|
||||
return len(x) > 0 && len(y) > 0 &&
|
||||
uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
|
||||
uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
|
||||
}
|
||||
|
||||
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||
// have different lengths and still not have any inexact overlap.
|
||||
//
|
||||
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||
// AEAD, Block, BlockMode and Stream interfaces.
|
||||
func InexactOverlap(x, y []byte) bool {
|
||||
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||
return false
|
||||
}
|
||||
return AnyOverlap(x, y)
|
||||
}
|
35
vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
generated
vendored
Normal file
35
vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build appengine
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
|
||||
// This is the Google App Engine standard variant based on reflect
|
||||
// because the unsafe package and cgo are disallowed.
|
||||
|
||||
import "reflect"
|
||||
|
||||
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||
// corresponding) index. The memory beyond the slice length is ignored.
|
||||
func AnyOverlap(x, y []byte) bool {
|
||||
return len(x) > 0 && len(y) > 0 &&
|
||||
reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
|
||||
reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
|
||||
}
|
||||
|
||||
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||
// have different lengths and still not have any inexact overlap.
|
||||
//
|
||||
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||
// AEAD, Block, BlockMode and Stream interfaces.
|
||||
func InexactOverlap(x, y []byte) bool {
|
||||
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||
return false
|
||||
}
|
||||
return AnyOverlap(x, y)
|
||||
}
|
50
vendor/golang.org/x/crypto/internal/subtle/aliasing_test.go
generated
vendored
Normal file
50
vendor/golang.org/x/crypto/internal/subtle/aliasing_test.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package subtle_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
var a, b [100]byte
|
||||
|
||||
var aliasingTests = []struct {
|
||||
x, y []byte
|
||||
anyOverlap, inexactOverlap bool
|
||||
}{
|
||||
{a[:], b[:], false, false},
|
||||
{a[:], b[:0], false, false},
|
||||
{a[:], b[:50], false, false},
|
||||
{a[40:50], a[50:60], false, false},
|
||||
{a[40:50], a[60:70], false, false},
|
||||
{a[:51], a[50:], true, true},
|
||||
{a[:], a[:], true, false},
|
||||
{a[:50], a[:60], true, false},
|
||||
{a[:], nil, false, false},
|
||||
{nil, nil, false, false},
|
||||
{a[:], a[:0], false, false},
|
||||
{a[:10], a[:10:20], true, false},
|
||||
{a[:10], a[5:10:20], true, true},
|
||||
}
|
||||
|
||||
func testAliasing(t *testing.T, i int, x, y []byte, anyOverlap, inexactOverlap bool) {
|
||||
any := subtle.AnyOverlap(x, y)
|
||||
if any != anyOverlap {
|
||||
t.Errorf("%d: wrong AnyOverlap result, expected %v, got %v", i, anyOverlap, any)
|
||||
}
|
||||
inexact := subtle.InexactOverlap(x, y)
|
||||
if inexact != inexactOverlap {
|
||||
t.Errorf("%d: wrong InexactOverlap result, expected %v, got %v", i, inexactOverlap, any)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasing(t *testing.T) {
|
||||
for i, tt := range aliasingTests {
|
||||
testAliasing(t, i, tt.x, tt.y, tt.anyOverlap, tt.inexactOverlap)
|
||||
testAliasing(t, i, tt.y, tt.x, tt.anyOverlap, tt.inexactOverlap)
|
||||
}
|
||||
}
|
9
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
9
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
|
@ -35,6 +35,7 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
|
|||
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
|
@ -87,6 +88,9 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
|||
copy(poly1305Key[:], firstBlock[:])
|
||||
|
||||
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
|
||||
if subtle.AnyOverlap(out, message) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
// We XOR up to 32 bytes of message with the keystream generated from
|
||||
// the first block.
|
||||
|
@ -118,7 +122,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
|||
// Open authenticates and decrypts a box produced by Seal and appends the
|
||||
// message to out, which must not overlap box. The output will be Overhead
|
||||
// bytes smaller than box.
|
||||
func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||
func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||
if len(box) < Overhead {
|
||||
return nil, false
|
||||
}
|
||||
|
@ -143,6 +147,9 @@ func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool)
|
|||
}
|
||||
|
||||
ret, out := sliceForAppend(out, len(box)-Overhead)
|
||||
if subtle.AnyOverlap(out, box) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
// We XOR up to 32 bytes of box with the keystream generated from
|
||||
// the first block.
|
||||
|
|
7
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
7
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
|
@ -24,6 +24,7 @@ import (
|
|||
"io"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// Overhead is the number of bytes of overhead when signing a message.
|
||||
|
@ -47,6 +48,9 @@ func GenerateKey(rand io.Reader) (publicKey *[32]byte, privateKey *[64]byte, err
|
|||
func Sign(out, message []byte, privateKey *[64]byte) []byte {
|
||||
sig := ed25519.Sign(ed25519.PrivateKey((*privateKey)[:]), message)
|
||||
ret, out := sliceForAppend(out, Overhead+len(message))
|
||||
if subtle.AnyOverlap(out, message) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
copy(out, sig)
|
||||
copy(out[Overhead:], message)
|
||||
return ret
|
||||
|
@ -63,6 +67,9 @@ func Open(out, signedMessage []byte, publicKey *[32]byte) ([]byte, bool) {
|
|||
return nil, false
|
||||
}
|
||||
ret, out := sliceForAppend(out, len(signedMessage)-Overhead)
|
||||
if subtle.AnyOverlap(out, signedMessage) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
copy(out, signedMessage[Overhead:])
|
||||
return ret, true
|
||||
}
|
||||
|
|
33
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
33
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
|
@ -346,22 +346,25 @@ EachPacket:
|
|||
|
||||
switch pkt := p.(type) {
|
||||
case *packet.UserId:
|
||||
// Make a new Identity object, that we might wind up throwing away.
|
||||
// We'll only add it if we get a valid self-signature over this
|
||||
// userID.
|
||||
current = new(Identity)
|
||||
current.Name = pkt.Id
|
||||
current.UserId = pkt
|
||||
e.Identities[pkt.Id] = current
|
||||
|
||||
for {
|
||||
p, err = packets.Next()
|
||||
if err == io.EOF {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
break EachPacket
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, ok := p.(*packet.Signature)
|
||||
if !ok {
|
||||
return nil, errors.StructuralError("user ID packet not followed by self-signature")
|
||||
packets.Unread(p)
|
||||
continue EachPacket
|
||||
}
|
||||
|
||||
if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
|
||||
|
@ -369,9 +372,10 @@ EachPacket:
|
|||
return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
|
||||
}
|
||||
current.SelfSignature = sig
|
||||
break
|
||||
e.Identities[pkt.Id] = current
|
||||
} else {
|
||||
current.Signatures = append(current.Signatures, sig)
|
||||
}
|
||||
current.Signatures = append(current.Signatures, sig)
|
||||
}
|
||||
case *packet.Signature:
|
||||
if pkt.SigType == packet.SigTypeKeyRevocation {
|
||||
|
@ -500,6 +504,10 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||
IssuerKeyId: &e.PrimaryKey.KeyId,
|
||||
},
|
||||
}
|
||||
err = e.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If the user passes in a DefaultHash via packet.Config,
|
||||
// set the PreferredHash for the SelfSignature.
|
||||
|
@ -529,13 +537,16 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||
}
|
||||
e.Subkeys[0].PublicKey.IsSubkey = true
|
||||
e.Subkeys[0].PrivateKey.IsSubkey = true
|
||||
|
||||
err = e.Subkeys[0].Sig.SignKey(e.Subkeys[0].PublicKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// SerializePrivate serializes an Entity, including private key material, to
|
||||
// the given Writer. For now, it must only be used on an Entity returned from
|
||||
// NewEntity.
|
||||
// SerializePrivate serializes an Entity, including private key material, but
|
||||
// excluding signatures from other entities, to the given Writer.
|
||||
// Identities and subkeys are re-signed in case they changed since NewEntry.
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
|
||||
err = e.PrivateKey.Serialize(w)
|
||||
|
@ -573,8 +584,8 @@ func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error
|
|||
return nil
|
||||
}
|
||||
|
||||
// Serialize writes the public part of the given Entity to w. (No private
|
||||
// key material will be output).
|
||||
// Serialize writes the public part of the given Entity to w, including
|
||||
// signatures from other entities. No private key material will be output.
|
||||
func (e *Entity) Serialize(w io.Writer) error {
|
||||
err := e.PrimaryKey.Serialize(w)
|
||||
if err != nil {
|
||||
|
|
88
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
88
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
|
@ -29,16 +29,16 @@ func TestKeyExpiry(t *testing.T) {
|
|||
//
|
||||
// So this should select the newest, non-expired encryption key.
|
||||
key, _ := entity.encryptionKey(time1)
|
||||
if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" {
|
||||
t.Errorf("Expected key 1ABB25A0 at time %s, but got key %s", time1.Format(timeFormat), id)
|
||||
if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
|
||||
t.Errorf("Expected key %s at time %s, but got key %s", expected, time1.Format(timeFormat), id)
|
||||
}
|
||||
|
||||
// Once the first encryption subkey has expired, the second should be
|
||||
// selected.
|
||||
time2, _ := time.Parse(timeFormat, "2013-07-09")
|
||||
key, _ = entity.encryptionKey(time2)
|
||||
if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" {
|
||||
t.Errorf("Expected key 96A672F5 at time %s, but got key %s", time2.Format(timeFormat), id)
|
||||
if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
|
||||
t.Errorf("Expected key %s at time %s, but got key %s", expected, time2.Format(timeFormat), id)
|
||||
}
|
||||
|
||||
// Once all the keys have expired, nothing should be returned.
|
||||
|
@ -105,6 +105,33 @@ func TestGoodCrossSignature(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRevokedUserID(t *testing.T) {
|
||||
// This key contains 2 UIDs, one of which is revoked:
|
||||
// [ultimate] (1) Golang Gopher <no-reply@golang.com>
|
||||
// [ revoked] (2) Golang Gopher <revoked@golang.com>
|
||||
keys, err := ReadArmoredKeyRing(bytes.NewBufferString(revokedUserIDKey))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(keys) != 1 {
|
||||
t.Fatal("Failed to read key with a revoked user id")
|
||||
}
|
||||
|
||||
var identities []*Identity
|
||||
for _, identity := range keys[0].Identities {
|
||||
identities = append(identities, identity)
|
||||
}
|
||||
|
||||
if numIdentities, numExpected := len(identities), 1; numIdentities != numExpected {
|
||||
t.Errorf("obtained %d identities, expected %d", numIdentities, numExpected)
|
||||
}
|
||||
|
||||
if identityName, expectedName := identities[0].Name, "Golang Gopher <no-reply@golang.com>"; identityName != expectedName {
|
||||
t.Errorf("obtained identity %s expected %s", identityName, expectedName)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission.
|
||||
func TestExternallyRevocableKey(t *testing.T) {
|
||||
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
|
@ -370,6 +397,20 @@ func TestNewEntityWithoutPreferredSymmetric(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewEntityPublicSerialization(t *testing.T) {
|
||||
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serializedEntity := bytes.NewBuffer(nil)
|
||||
entity.Serialize(serializedEntity)
|
||||
|
||||
_, err = ReadEntity(packet.NewReader(bytes.NewBuffer(serializedEntity.Bytes())))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e"
|
||||
const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
|
||||
const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"
|
||||
|
@ -467,3 +508,42 @@ SqLHvbKh2dL/RXymC3+rjPvQf5cup9bPxNMa6WagdYBNAfzWGtkVISeaQW+cTEp/
|
|||
MtgVijRGXR/lGLGETPg2X3Afwn9N9bLMBkBprKgbBqU7lpaoPupxT61bL70=
|
||||
=vtbN
|
||||
-----END PGP PUBLIC KEY BLOCK-----`
|
||||
|
||||
const revokedUserIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2e
|
||||
DZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/
|
||||
uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBW
|
||||
ClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkx
|
||||
nmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJ
|
||||
x1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAG0I0dvbGFuZyBHb3BoZXIg
|
||||
PG5vLXJlcGx5QGdvbGFuZy5jb20+iQFUBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy
|
||||
9I6cUoMFAlsgO5ECGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
|
||||
1oFy9I6cUoMIkwf8DNPeD23i4jRwd/pylbvxwZintZl1fSwTJW1xcOa1emXaEtX2
|
||||
depuqhP04fjlRQGfsYAQh7X9jOJxAHjTmhqFBi5sD7QvKU00cPFYbJ/JTx0B41bl
|
||||
aXnSbGhRPh63QtEZL7ACAs+shwvvojJqysx7kyVRu0EW2wqjXdHwR/SJO6nhNBa2
|
||||
DXzSiOU/SUA42mmG+5kjF8Aabq9wPwT9wjraHShEweNerNMmOqJExBOy3yFeyDpa
|
||||
XwEZFzBfOKoxFNkIaVf5GSdIUGhFECkGvBMB935khftmgR8APxdU4BE7XrXexFJU
|
||||
8RCuPXonm4WQOwTWR0vQg64pb2WKAzZ8HhwTGbQiR29sYW5nIEdvcGhlciA8cmV2
|
||||
b2tlZEBnb2xhbmcuY29tPokBNgQwAQoAIBYhBOSJOSS3Dcepeq2X8NaBcvSOnFKD
|
||||
BQJbIDv3Ah0AAAoJENaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT6bC1JttG
|
||||
0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZq8KxHn/KvN6N
|
||||
s85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy+I0sGyI/Inro0Pzb
|
||||
tvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarYbYB2idtGRci4b9tObOK0
|
||||
BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8jSwEr2O2sUR0yjbgUAXbTxDVE
|
||||
/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3FazkkSYQD6b97+dkWwb1iWG5AQ0EWyA7
|
||||
kQEIALkg04REDZo1JgdYV4x8HJKFS4xAYWbIva1ZPqvDNmZRUbQZR2+gpJGEwn7z
|
||||
VofGvnOYiGW56AS5j31SFf5kro1+1bZQ5iOONBng08OOo58/l1hRseIIVGB5TGSa
|
||||
PCdChKKHreJI6hS3mShxH6hdfFtiZuB45rwoaArMMsYcjaezLwKeLc396cpUwwcZ
|
||||
snLUNd1Xu5EWEF2OdFkZ2a1qYdxBvAYdQf4+1Nr+NRIx1u1NS9c8jp3PuMOkrQEi
|
||||
bNtc1v6v0Jy52mKLG4y7mC/erIkvkQBYJdxPaP7LZVaPYc3/xskcyijrJ/5ufoD8
|
||||
K71/ShtsZUXSQn9jlRaYR0EbojMAEQEAAYkBPAQYAQoAJhYhBOSJOSS3Dcepeq2X
|
||||
8NaBcvSOnFKDBQJbIDuRAhsMBQkDwmcAAAoJENaBcvSOnFKDkFMIAIt64bVZ8x7+
|
||||
TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2NnDyf1cLOSimSTILpwLIuv9Uft5Pb
|
||||
OraQbYt3xi9yrqdKqGLv80bxqK0NuryNkvh9yyx5WoG1iKqMj9/FjGghuPrRaT4l
|
||||
QinNAghGVkEy1+aXGFrG2DsOC1FFI51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2V
|
||||
yJl9bD5R4SUNy8oQmhOxi+gbhD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+U
|
||||
heiQvzkApQup5c+BhH5zFDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB
|
||||
7qTZOahrETw=
|
||||
=IKnw
|
||||
-----END PGP PUBLIC KEY BLOCK-----`
|
||||
|
|
4
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
4
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
|
@ -24,6 +24,7 @@ package salsa20 // import "golang.org/x/crypto/salsa20"
|
|||
// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
|
||||
|
@ -34,6 +35,9 @@ func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
|
|||
if len(out) < len(in) {
|
||||
panic("salsa20: output smaller than input")
|
||||
}
|
||||
if subtle.InexactOverlap(out[:len(in)], in) {
|
||||
panic("salsa20: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var subNonce [16]byte
|
||||
|
||||
|
|
6
vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
generated
vendored
6
vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
generated
vendored
|
@ -10,6 +10,7 @@ import (
|
|||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -326,6 +327,11 @@ func TestMakeRawState(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to get terminal state from GetState: %s", err)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
|
||||
t.Skip("MakeRaw not allowed on iOS; skipping test")
|
||||
}
|
||||
|
||||
defer Restore(fd, st)
|
||||
raw, err := MakeRaw(fd)
|
||||
if err != nil {
|
||||
|
|
8
vendor/golang.org/x/crypto/xts/xts.go
generated
vendored
8
vendor/golang.org/x/crypto/xts/xts.go
generated
vendored
|
@ -25,6 +25,8 @@ import (
|
|||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// Cipher contains an expanded key structure. It doesn't contain mutable state
|
||||
|
@ -64,6 +66,9 @@ func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
|
|||
if len(plaintext)%blockSize != 0 {
|
||||
panic("xts: plaintext is not a multiple of the block size")
|
||||
}
|
||||
if subtle.InexactOverlap(ciphertext[:len(plaintext)], plaintext) {
|
||||
panic("xts: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var tweak [blockSize]byte
|
||||
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||
|
@ -95,6 +100,9 @@ func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
|
|||
if len(ciphertext)%blockSize != 0 {
|
||||
panic("xts: ciphertext is not a multiple of the block size")
|
||||
}
|
||||
if subtle.InexactOverlap(plaintext[:len(ciphertext)], ciphertext) {
|
||||
panic("xts: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var tweak [blockSize]byte
|
||||
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||
|
|
15
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
15
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
|
@ -14,21 +14,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// SniffedContentType reports whether ct is a Content-Type that is known
|
||||
// to cause client-side content sniffing.
|
||||
//
|
||||
// This provides just a partial implementation of mime.ParseMediaType
|
||||
// with the assumption that the Content-Type is not attacker controlled.
|
||||
func SniffedContentType(ct string) bool {
|
||||
if i := strings.Index(ct, ";"); i != -1 {
|
||||
ct = ct[:i]
|
||||
}
|
||||
ct = strings.ToLower(strings.TrimSpace(ct))
|
||||
return ct == "text/plain" || ct == "application/octet-stream" ||
|
||||
ct == "application/unknown" || ct == "unknown/unknown" || ct == "*/*" ||
|
||||
!strings.Contains(ct, "/")
|
||||
}
|
||||
|
||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
||||
// in trailers.
|
||||
// See RFC 7230, Section 4.1.2
|
||||
|
|
10
vendor/golang.org/x/net/http2/flow.go
generated
vendored
10
vendor/golang.org/x/net/http2/flow.go
generated
vendored
|
@ -41,10 +41,10 @@ func (f *flow) take(n int32) {
|
|||
// add adds n bytes (positive or negative) to the flow control window.
|
||||
// It returns false if the sum would exceed 2^31-1.
|
||||
func (f *flow) add(n int32) bool {
|
||||
remain := (1<<31 - 1) - f.n
|
||||
if n > remain {
|
||||
return false
|
||||
sum := f.n + n
|
||||
if (sum > n) == (f.n > 0) {
|
||||
f.n = sum
|
||||
return true
|
||||
}
|
||||
f.n += n
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
|
34
vendor/golang.org/x/net/http2/flow_test.go
generated
vendored
34
vendor/golang.org/x/net/http2/flow_test.go
generated
vendored
|
@ -49,5 +49,39 @@ func TestFlowAdd(t *testing.T) {
|
|||
if f.add(1) {
|
||||
t.Fatal("adding 1 to max shouldn't be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlowAddOverflow(t *testing.T) {
|
||||
var f flow
|
||||
if !f.add(0) {
|
||||
t.Fatal("failed to add 0")
|
||||
}
|
||||
if !f.add(-1) {
|
||||
t.Fatal("failed to add -1")
|
||||
}
|
||||
if !f.add(0) {
|
||||
t.Fatal("failed to add 0")
|
||||
}
|
||||
if !f.add(1) {
|
||||
t.Fatal("failed to add 1")
|
||||
}
|
||||
if !f.add(1) {
|
||||
t.Fatal("failed to add 1")
|
||||
}
|
||||
if !f.add(0) {
|
||||
t.Fatal("failed to add 0")
|
||||
}
|
||||
if !f.add(-3) {
|
||||
t.Fatal("failed to add -3")
|
||||
}
|
||||
if got, want := f.available(), int32(-2); got != want {
|
||||
t.Fatalf("size = %d; want %d", got, want)
|
||||
}
|
||||
if !f.add(1<<31 - 1) {
|
||||
t.Fatal("failed to add 2^31-1")
|
||||
}
|
||||
if got, want := f.available(), int32(1+-3+(1<<31-1)); got != want {
|
||||
t.Fatalf("size = %d; want %d", got, want)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
28
vendor/golang.org/x/net/http2/http2_test.go
generated
vendored
28
vendor/golang.org/x/net/http2/http2_test.go
generated
vendored
|
@ -14,6 +14,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/http2/hpack"
|
||||
)
|
||||
|
@ -197,3 +198,30 @@ func TestSorterPoolAllocs(t *testing.T) {
|
|||
t.Logf("Keys allocs = %v; want <1", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
// waitCondition reports whether fn eventually returned true,
|
||||
// checking immediately and then every checkEvery amount,
|
||||
// until waitFor has elapsed, at which point it returns false.
|
||||
func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
|
||||
deadline := time.Now().Add(waitFor)
|
||||
for time.Now().Before(deadline) {
|
||||
if fn() {
|
||||
return true
|
||||
}
|
||||
time.Sleep(checkEvery)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// waitErrCondition is like waitCondition but with errors instead of bools.
|
||||
func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error {
|
||||
deadline := time.Now().Add(waitFor)
|
||||
var err error
|
||||
for time.Now().Before(deadline) {
|
||||
if err = fn(); err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(checkEvery)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
35
vendor/golang.org/x/net/http2/server.go
generated
vendored
35
vendor/golang.org/x/net/http2/server.go
generated
vendored
|
@ -1608,7 +1608,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||
// Sender sending more than they'd declared?
|
||||
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
|
||||
st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
|
||||
return streamError(id, ErrCodeStreamClosed)
|
||||
// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
|
||||
// value of a content-length header field does not equal the sum of the
|
||||
// DATA frame payload lengths that form the body.
|
||||
return streamError(id, ErrCodeProtocol)
|
||||
}
|
||||
if f.Length > 0 {
|
||||
// Check whether the client has flow control quota.
|
||||
|
@ -2309,7 +2312,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||
isHeadResp := rws.req.Method == "HEAD"
|
||||
if !rws.sentHeader {
|
||||
rws.sentHeader = true
|
||||
|
||||
var ctype, clen string
|
||||
if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
|
||||
rws.snapHeader.Del("Content-Length")
|
||||
|
@ -2323,7 +2325,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||
if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
|
||||
clen = strconv.Itoa(len(p))
|
||||
}
|
||||
|
||||
_, hasContentType := rws.snapHeader["Content-Type"]
|
||||
if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
||||
if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) {
|
||||
|
@ -2336,20 +2337,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||
ctype = http.DetectContentType(p)
|
||||
}
|
||||
}
|
||||
|
||||
var noSniff bool
|
||||
if bodyAllowedForStatus(rws.status) && (rws.sentContentLen > 0 || len(p) > 0) {
|
||||
// If the content type triggers client-side sniffing on old browsers,
|
||||
// attach a X-Content-Type-Options header if not present (or explicitly nil).
|
||||
if _, ok := rws.snapHeader["X-Content-Type-Options"]; !ok {
|
||||
if hasContentType {
|
||||
noSniff = httpguts.SniffedContentType(rws.snapHeader.Get("Content-Type"))
|
||||
} else if ctype != "" {
|
||||
noSniff = httpguts.SniffedContentType(ctype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var date string
|
||||
if _, ok := rws.snapHeader["Date"]; !ok {
|
||||
// TODO(bradfitz): be faster here, like net/http? measure.
|
||||
|
@ -2360,6 +2347,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||
foreachHeaderElement(v, rws.declareTrailer)
|
||||
}
|
||||
|
||||
// "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
|
||||
// but respect "Connection" == "close" to mean sending a GOAWAY and tearing
|
||||
// down the TCP connection when idle, like we do for HTTP/1.
|
||||
// TODO: remove more Connection-specific header fields here, in addition
|
||||
// to "Connection".
|
||||
if _, ok := rws.snapHeader["Connection"]; ok {
|
||||
v := rws.snapHeader.Get("Connection")
|
||||
delete(rws.snapHeader, "Connection")
|
||||
if v == "close" {
|
||||
rws.conn.startGracefulShutdown()
|
||||
}
|
||||
}
|
||||
|
||||
endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
|
||||
err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
|
||||
streamID: rws.stream.id,
|
||||
|
@ -2368,7 +2368,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||
endStream: endStream,
|
||||
contentType: ctype,
|
||||
contentLength: clen,
|
||||
noSniff: noSniff,
|
||||
date: date,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
87
vendor/golang.org/x/net/http2/server_test.go
generated
vendored
87
vendor/golang.org/x/net/http2/server_test.go
generated
vendored
|
@ -1810,7 +1810,6 @@ func TestServer_Response_TransferEncoding_chunked(t *testing.T) {
|
|||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", strconv.Itoa(len(msg))},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Got headers %v; want %v", goth, wanth)
|
||||
|
@ -1999,7 +1998,6 @@ func TestServer_Response_LargeWrite(t *testing.T) {
|
|||
wanth := [][2]string{
|
||||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"}, // sniffed
|
||||
{"x-content-type-options", "nosniff"},
|
||||
// and no content-length
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
|
@ -2214,7 +2212,6 @@ func TestServer_Response_Automatic100Continue(t *testing.T) {
|
|||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", strconv.Itoa(len(reply))},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Got headers %v; want %v", goth, wanth)
|
||||
|
@ -2938,7 +2935,6 @@ func testServerWritesTrailers(t *testing.T, withFlush bool) {
|
|||
{"trailer", "Transfer-Encoding, Content-Length, Trailer"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", "5"},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
|
||||
|
@ -3330,7 +3326,6 @@ func TestServerNoDuplicateContentType(t *testing.T) {
|
|||
{":status", "200"},
|
||||
{"content-type", ""},
|
||||
{"content-length", "41"},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(headers, want) {
|
||||
t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
|
||||
|
@ -3764,3 +3759,85 @@ func TestIssue20704Race(t *testing.T) {
|
|||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_Rejects_TooSmall(t *testing.T) {
|
||||
testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
|
||||
ioutil.ReadAll(r.Body)
|
||||
return nil
|
||||
}, func(st *serverTester) {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: 1, // clients send odd numbers
|
||||
BlockFragment: st.encodeHeader(
|
||||
":method", "POST",
|
||||
"content-length", "4",
|
||||
),
|
||||
EndStream: false, // to say DATA frames are coming
|
||||
EndHeaders: true,
|
||||
})
|
||||
st.writeData(1, true, []byte("12345"))
|
||||
|
||||
st.wantRSTStream(1, ErrCodeProtocol)
|
||||
})
|
||||
}
|
||||
|
||||
// Tests that a handler setting "Connection: close" results in a GOAWAY being sent,
|
||||
// and the connection still completing.
|
||||
func TestServerHandlerConnectionClose(t *testing.T) {
|
||||
unblockHandler := make(chan bool, 1)
|
||||
defer close(unblockHandler) // backup; in case of errors
|
||||
testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
|
||||
w.Header().Set("Connection", "close")
|
||||
w.Header().Set("Foo", "bar")
|
||||
w.(http.Flusher).Flush()
|
||||
<-unblockHandler
|
||||
return nil
|
||||
}, func(st *serverTester) {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: 1,
|
||||
BlockFragment: st.encodeHeader(),
|
||||
EndStream: true,
|
||||
EndHeaders: true,
|
||||
})
|
||||
var sawGoAway bool
|
||||
var sawRes bool
|
||||
for {
|
||||
f, err := st.readFrame()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch f := f.(type) {
|
||||
case *GoAwayFrame:
|
||||
sawGoAway = true
|
||||
unblockHandler <- true
|
||||
if f.LastStreamID != 1 || f.ErrCode != ErrCodeNo {
|
||||
t.Errorf("unexpected GOAWAY frame: %v", summarizeFrame(f))
|
||||
}
|
||||
case *HeadersFrame:
|
||||
goth := st.decodeHeader(f.HeaderBlockFragment())
|
||||
if !sawGoAway {
|
||||
t.Fatalf("unexpected Headers frame before GOAWAY: %s, %v", summarizeFrame(f), goth)
|
||||
}
|
||||
wanth := [][2]string{
|
||||
{":status", "200"},
|
||||
{"foo", "bar"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("got headers %v; want %v", goth, wanth)
|
||||
}
|
||||
sawRes = true
|
||||
case *DataFrame:
|
||||
if f.StreamID != 1 || !f.StreamEnded() || len(f.Data()) != 0 {
|
||||
t.Errorf("unexpected DATA frame: %v", summarizeFrame(f))
|
||||
}
|
||||
default:
|
||||
t.Logf("unexpected frame: %v", summarizeFrame(f))
|
||||
}
|
||||
}
|
||||
if !sawRes {
|
||||
t.Errorf("didn't see response")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
14
vendor/golang.org/x/net/http2/transport_test.go
generated
vendored
14
vendor/golang.org/x/net/http2/transport_test.go
generated
vendored
|
@ -145,10 +145,9 @@ func TestTransport(t *testing.T) {
|
|||
t.Errorf("Status = %q; want %q", g, w)
|
||||
}
|
||||
wantHeader := http.Header{
|
||||
"Content-Length": []string{"3"},
|
||||
"X-Content-Type-Options": []string{"nosniff"},
|
||||
"Content-Type": []string{"text/plain; charset=utf-8"},
|
||||
"Date": []string{"XXX"}, // see cleanDate
|
||||
"Content-Length": []string{"3"},
|
||||
"Content-Type": []string{"text/plain; charset=utf-8"},
|
||||
"Date": []string{"XXX"}, // see cleanDate
|
||||
}
|
||||
cleanDate(res)
|
||||
if !reflect.DeepEqual(res.Header, wantHeader) {
|
||||
|
@ -2395,11 +2394,12 @@ func TestTransportHandlerBodyClose(t *testing.T) {
|
|||
}
|
||||
tr.CloseIdleConnections()
|
||||
|
||||
gd := runtime.NumGoroutine() - g0
|
||||
if gd > numReq/2 {
|
||||
if !waitCondition(5*time.Second, 100*time.Millisecond, func() bool {
|
||||
gd := runtime.NumGoroutine() - g0
|
||||
return gd < numReq/2
|
||||
}) {
|
||||
t.Errorf("appeared to leak goroutines")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// https://golang.org/issue/15930
|
||||
|
|
4
vendor/golang.org/x/net/http2/write.go
generated
vendored
4
vendor/golang.org/x/net/http2/write.go
generated
vendored
|
@ -186,7 +186,6 @@ type writeResHeaders struct {
|
|||
date string
|
||||
contentType string
|
||||
contentLength string
|
||||
noSniff bool
|
||||
}
|
||||
|
||||
func encKV(enc *hpack.Encoder, k, v string) {
|
||||
|
@ -223,9 +222,6 @@ func (w *writeResHeaders) writeFrame(ctx writeContext) error {
|
|||
if w.contentLength != "" {
|
||||
encKV(enc, "content-length", w.contentLength)
|
||||
}
|
||||
if w.noSniff {
|
||||
encKV(enc, "x-content-type-options", "nosniff")
|
||||
}
|
||||
if w.date != "" {
|
||||
encKV(enc, "date", w.date)
|
||||
}
|
||||
|
|
2
vendor/golang.org/x/net/icmp/listen_stub.go
generated
vendored
2
vendor/golang.org/x/net/icmp/listen_stub.go
generated
vendored
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build nacl plan9
|
||||
// +build js nacl plan9
|
||||
|
||||
package icmp
|
||||
|
||||
|
|
2
vendor/golang.org/x/net/icmp/message.go
generated
vendored
2
vendor/golang.org/x/net/icmp/message.go
generated
vendored
|
@ -25,7 +25,7 @@ import (
|
|||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
// BUG(mikio): This package is not implemented on NaCl and Plan 9.
|
||||
// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
|
||||
|
||||
var (
|
||||
errMessageTooShort = errors.New("message too short")
|
||||
|
|
4
vendor/golang.org/x/net/icmp/mpls.go
generated
vendored
4
vendor/golang.org/x/net/icmp/mpls.go
generated
vendored
|
@ -6,7 +6,7 @@ package icmp
|
|||
|
||||
import "encoding/binary"
|
||||
|
||||
// A MPLSLabel represents a MPLS label stack entry.
|
||||
// MPLSLabel represents an MPLS label stack entry.
|
||||
type MPLSLabel struct {
|
||||
Label int // label value
|
||||
TC int // traffic class; formerly experimental use
|
||||
|
@ -19,7 +19,7 @@ const (
|
|||
typeIncomingMPLSLabelStack = 1
|
||||
)
|
||||
|
||||
// A MPLSLabelStack represents a MPLS label stack.
|
||||
// MPLSLabelStack represents an MPLS label stack.
|
||||
type MPLSLabelStack struct {
|
||||
Class int // extension object class number
|
||||
Type int // extension object sub-type
|
||||
|
|
60
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
60
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
|
@ -4,38 +4,34 @@
|
|||
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
|
||||
package iana // import "golang.org/x/net/internal/iana"
|
||||
|
||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2017-05-12
|
||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
|
||||
const (
|
||||
DiffServCS0 = 0x0 // CS0
|
||||
DiffServCS1 = 0x20 // CS1
|
||||
DiffServCS2 = 0x40 // CS2
|
||||
DiffServCS3 = 0x60 // CS3
|
||||
DiffServCS4 = 0x80 // CS4
|
||||
DiffServCS5 = 0xa0 // CS5
|
||||
DiffServCS6 = 0xc0 // CS6
|
||||
DiffServCS7 = 0xe0 // CS7
|
||||
DiffServAF11 = 0x28 // AF11
|
||||
DiffServAF12 = 0x30 // AF12
|
||||
DiffServAF13 = 0x38 // AF13
|
||||
DiffServAF21 = 0x48 // AF21
|
||||
DiffServAF22 = 0x50 // AF22
|
||||
DiffServAF23 = 0x58 // AF23
|
||||
DiffServAF31 = 0x68 // AF31
|
||||
DiffServAF32 = 0x70 // AF32
|
||||
DiffServAF33 = 0x78 // AF33
|
||||
DiffServAF41 = 0x88 // AF41
|
||||
DiffServAF42 = 0x90 // AF42
|
||||
DiffServAF43 = 0x98 // AF43
|
||||
DiffServEF = 0xb8 // EF
|
||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
||||
)
|
||||
|
||||
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
|
||||
const (
|
||||
NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
|
||||
ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
|
||||
ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
|
||||
CongestionExperienced = 0x3 // CE (Congestion Experienced)
|
||||
DiffServCS0 = 0x00 // CS0
|
||||
DiffServCS1 = 0x20 // CS1
|
||||
DiffServCS2 = 0x40 // CS2
|
||||
DiffServCS3 = 0x60 // CS3
|
||||
DiffServCS4 = 0x80 // CS4
|
||||
DiffServCS5 = 0xa0 // CS5
|
||||
DiffServCS6 = 0xc0 // CS6
|
||||
DiffServCS7 = 0xe0 // CS7
|
||||
DiffServAF11 = 0x28 // AF11
|
||||
DiffServAF12 = 0x30 // AF12
|
||||
DiffServAF13 = 0x38 // AF13
|
||||
DiffServAF21 = 0x48 // AF21
|
||||
DiffServAF22 = 0x50 // AF22
|
||||
DiffServAF23 = 0x58 // AF23
|
||||
DiffServAF31 = 0x68 // AF31
|
||||
DiffServAF32 = 0x70 // AF32
|
||||
DiffServAF33 = 0x78 // AF33
|
||||
DiffServAF41 = 0x88 // AF41
|
||||
DiffServAF42 = 0x90 // AF42
|
||||
DiffServAF43 = 0x98 // AF43
|
||||
DiffServEF = 0xb8 // EF
|
||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
||||
NotECNTransport = 0x00 // Not-ECT (Not ECN-Capable Transport)
|
||||
ECNTransport1 = 0x01 // ECT(1) (ECN-Capable Transport(1))
|
||||
ECNTransport0 = 0x02 // ECT(0) (ECN-Capable Transport(0))
|
||||
CongestionExperienced = 0x03 // CE (Congestion Experienced)
|
||||
)
|
||||
|
||||
// Protocol Numbers, Updated: 2017-10-13
|
||||
|
@ -179,7 +175,7 @@ const (
|
|||
ProtocolReserved = 255 // Reserved
|
||||
)
|
||||
|
||||
// Address Family Numbers, Updated: 2016-10-25
|
||||
// Address Family Numbers, Updated: 2018-04-02
|
||||
const (
|
||||
AddrFamilyIPv4 = 1 // IP (IP version 4)
|
||||
AddrFamilyIPv6 = 2 // IP6 (IP version 6)
|
||||
|
|
188
vendor/golang.org/x/net/internal/iana/gen.go
generated
vendored
188
vendor/golang.org/x/net/internal/iana/gen.go
generated
vendored
|
@ -31,16 +31,12 @@ var registries = []struct {
|
|||
"https://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
||||
parseDSCPRegistry,
|
||||
},
|
||||
{
|
||||
"https://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
||||
parseTOSTCByte,
|
||||
},
|
||||
{
|
||||
"https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
|
||||
parseProtocolNumbers,
|
||||
},
|
||||
{
|
||||
"http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml",
|
||||
"https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml",
|
||||
parseAddrFamilyNumbers,
|
||||
},
|
||||
}
|
||||
|
@ -85,31 +81,39 @@ func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
|||
if err := dec.Decode(&dr); err != nil {
|
||||
return err
|
||||
}
|
||||
drs := dr.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, dr := range drs {
|
||||
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
||||
for _, dr := range dr.escapeDSCP() {
|
||||
fmt.Fprintf(w, "DiffServ%s = %#02x", dr.Name, dr.Value)
|
||||
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
||||
}
|
||||
for _, er := range dr.escapeECN() {
|
||||
fmt.Fprintf(w, "%s = %#02x", er.Descr, er.Value)
|
||||
fmt.Fprintf(w, "// %s\n", er.OrigDescr)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type dscpRegistry struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Note string `xml:"note"`
|
||||
RegTitle string `xml:"registry>title"`
|
||||
PoolRecords []struct {
|
||||
Name string `xml:"name"`
|
||||
Space string `xml:"space"`
|
||||
} `xml:"registry>record"`
|
||||
Records []struct {
|
||||
Name string `xml:"name"`
|
||||
Space string `xml:"space"`
|
||||
} `xml:"registry>registry>record"`
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Note string `xml:"note"`
|
||||
Registries []struct {
|
||||
Title string `xml:"title"`
|
||||
Registries []struct {
|
||||
Title string `xml:"title"`
|
||||
Records []struct {
|
||||
Name string `xml:"name"`
|
||||
Space string `xml:"space"`
|
||||
} `xml:"record"`
|
||||
} `xml:"registry"`
|
||||
Records []struct {
|
||||
Value string `xml:"value"`
|
||||
Descr string `xml:"description"`
|
||||
} `xml:"record"`
|
||||
} `xml:"registry"`
|
||||
}
|
||||
|
||||
type canonDSCPRecord struct {
|
||||
|
@ -118,92 +122,84 @@ type canonDSCPRecord struct {
|
|||
Value int
|
||||
}
|
||||
|
||||
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
||||
drs := make([]canonDSCPRecord, len(drr.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, dr := range drr.Records {
|
||||
s := strings.TrimSpace(dr.Name)
|
||||
drs[i].OrigName = s
|
||||
drs[i].Name = sr.Replace(s)
|
||||
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
||||
if err != nil {
|
||||
func (drr *dscpRegistry) escapeDSCP() []canonDSCPRecord {
|
||||
var drs []canonDSCPRecord
|
||||
for _, preg := range drr.Registries {
|
||||
if !strings.Contains(preg.Title, "Differentiated Services Field Codepoints") {
|
||||
continue
|
||||
}
|
||||
drs[i].Value = int(n) << 2
|
||||
for _, reg := range preg.Registries {
|
||||
if !strings.Contains(reg.Title, "Pool 1 Codepoints") {
|
||||
continue
|
||||
}
|
||||
drs = make([]canonDSCPRecord, len(reg.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, dr := range reg.Records {
|
||||
s := strings.TrimSpace(dr.Name)
|
||||
drs[i].OrigName = s
|
||||
drs[i].Name = sr.Replace(s)
|
||||
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
drs[i].Value = int(n) << 2
|
||||
}
|
||||
}
|
||||
}
|
||||
return drs
|
||||
}
|
||||
|
||||
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
||||
dec := xml.NewDecoder(r)
|
||||
var ttb tosTCByte
|
||||
if err := dec.Decode(&ttb); err != nil {
|
||||
return err
|
||||
}
|
||||
trs := ttb.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, tr := range trs {
|
||||
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
||||
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n")
|
||||
return nil
|
||||
type canonECNRecord struct {
|
||||
OrigDescr string
|
||||
Descr string
|
||||
Value int
|
||||
}
|
||||
|
||||
type tosTCByte struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Note string `xml:"note"`
|
||||
RegTitle string `xml:"registry>title"`
|
||||
Records []struct {
|
||||
Binary string `xml:"binary"`
|
||||
Keyword string `xml:"keyword"`
|
||||
} `xml:"registry>record"`
|
||||
}
|
||||
|
||||
type canonTOSTCByteRecord struct {
|
||||
OrigKeyword string
|
||||
Keyword string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
||||
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"Capable", "",
|
||||
"(", "",
|
||||
")", "",
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, tr := range ttb.Records {
|
||||
s := strings.TrimSpace(tr.Keyword)
|
||||
trs[i].OrigKeyword = s
|
||||
ss := strings.Split(s, " ")
|
||||
if len(ss) > 1 {
|
||||
trs[i].Keyword = strings.Join(ss[1:], " ")
|
||||
} else {
|
||||
trs[i].Keyword = ss[0]
|
||||
}
|
||||
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
||||
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
||||
if err != nil {
|
||||
func (drr *dscpRegistry) escapeECN() []canonECNRecord {
|
||||
var ers []canonECNRecord
|
||||
for _, reg := range drr.Registries {
|
||||
if !strings.Contains(reg.Title, "ECN Field") {
|
||||
continue
|
||||
}
|
||||
trs[i].Value = int(n)
|
||||
ers = make([]canonECNRecord, len(reg.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"Capable", "",
|
||||
"Not-ECT", "",
|
||||
"ECT(1)", "",
|
||||
"ECT(0)", "",
|
||||
"CE", "",
|
||||
"(", "",
|
||||
")", "",
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, er := range reg.Records {
|
||||
s := strings.TrimSpace(er.Descr)
|
||||
ers[i].OrigDescr = s
|
||||
ss := strings.Split(s, " ")
|
||||
if len(ss) > 1 {
|
||||
ers[i].Descr = strings.Join(ss[1:], " ")
|
||||
} else {
|
||||
ers[i].Descr = ss[0]
|
||||
}
|
||||
ers[i].Descr = sr.Replace(er.Descr)
|
||||
n, err := strconv.ParseUint(er.Value, 2, 8)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ers[i].Value = int(n)
|
||||
}
|
||||
}
|
||||
return trs
|
||||
return ers
|
||||
}
|
||||
|
||||
func parseProtocolNumbers(w io.Writer, r io.Reader) error {
|
||||
|
|
70
vendor/golang.org/x/net/internal/socks/dial_test.go
generated
vendored
70
vendor/golang.org/x/net/internal/socks/dial_test.go
generated
vendored
|
@ -17,19 +17,11 @@ import (
|
|||
"golang.org/x/net/internal/sockstest"
|
||||
)
|
||||
|
||||
const (
|
||||
targetNetwork = "tcp6"
|
||||
targetHostname = "fqdn.doesnotexist"
|
||||
targetHostIP = "2001:db8::1"
|
||||
targetPort = "5963"
|
||||
)
|
||||
|
||||
func TestDial(t *testing.T) {
|
||||
t.Run("Connect", func(t *testing.T) {
|
||||
ss, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String())
|
||||
|
@ -41,21 +33,45 @@ func TestDial(t *testing.T) {
|
|||
Username: "username",
|
||||
Password: "password",
|
||||
}).Authenticate
|
||||
c, err := d.Dial(targetNetwork, net.JoinHostPort(targetHostIP, targetPort))
|
||||
if err == nil {
|
||||
c.(*socks.Conn).BoundAddr()
|
||||
c.Close()
|
||||
}
|
||||
c, err := d.DialContext(context.Background(), ss.TargetAddr().Network(), ss.TargetAddr().String())
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
c.(*socks.Conn).BoundAddr()
|
||||
c.Close()
|
||||
})
|
||||
t.Run("ConnectWithConn", func(t *testing.T) {
|
||||
ss, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
c, err := net.Dial(ss.Addr().Network(), ss.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String())
|
||||
d.AuthMethods = []socks.AuthMethod{
|
||||
socks.AuthMethodNotRequired,
|
||||
socks.AuthMethodUsernamePassword,
|
||||
}
|
||||
d.Authenticate = (&socks.UsernamePassword{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
}).Authenticate
|
||||
a, err := d.DialWithConn(context.Background(), c, ss.TargetAddr().Network(), ss.TargetAddr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := a.(*socks.Addr); !ok {
|
||||
t.Fatalf("got %+v; want socks.Addr", a)
|
||||
}
|
||||
})
|
||||
t.Run("Cancel", func(t *testing.T) {
|
||||
ss, err := sockstest.NewServer(sockstest.NoAuthRequired, blackholeCmdFunc)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String())
|
||||
|
@ -63,7 +79,7 @@ func TestDial(t *testing.T) {
|
|||
defer cancel()
|
||||
dialErr := make(chan error)
|
||||
go func() {
|
||||
c, err := d.DialContext(ctx, ss.TargetAddr().Network(), net.JoinHostPort(targetHostname, targetPort))
|
||||
c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String())
|
||||
if err == nil {
|
||||
c.Close()
|
||||
}
|
||||
|
@ -73,41 +89,37 @@ func TestDial(t *testing.T) {
|
|||
cancel()
|
||||
err = <-dialErr
|
||||
if perr, nerr := parseDialError(err); perr != context.Canceled && nerr == nil {
|
||||
t.Errorf("got %v; want context.Canceled or equivalent", err)
|
||||
return
|
||||
t.Fatalf("got %v; want context.Canceled or equivalent", err)
|
||||
}
|
||||
})
|
||||
t.Run("Deadline", func(t *testing.T) {
|
||||
ss, err := sockstest.NewServer(sockstest.NoAuthRequired, blackholeCmdFunc)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String())
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(100*time.Millisecond))
|
||||
defer cancel()
|
||||
c, err := d.DialContext(ctx, ss.TargetAddr().Network(), net.JoinHostPort(targetHostname, targetPort))
|
||||
c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String())
|
||||
if err == nil {
|
||||
c.Close()
|
||||
}
|
||||
if perr, nerr := parseDialError(err); perr != context.DeadlineExceeded && nerr == nil {
|
||||
t.Errorf("got %v; want context.DeadlineExceeded or equivalent", err)
|
||||
return
|
||||
t.Fatalf("got %v; want context.DeadlineExceeded or equivalent", err)
|
||||
}
|
||||
})
|
||||
t.Run("WithRogueServer", func(t *testing.T) {
|
||||
ss, err := sockstest.NewServer(sockstest.NoAuthRequired, rogueCmdFunc)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
d := socks.NewDialer(ss.Addr().Network(), ss.Addr().String())
|
||||
for i := 0; i < 2*len(rogueCmdList); i++ {
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(100*time.Millisecond))
|
||||
defer cancel()
|
||||
c, err := d.DialContext(ctx, targetNetwork, net.JoinHostPort(targetHostIP, targetPort))
|
||||
c, err := d.DialContext(ctx, ss.TargetAddr().Network(), ss.TargetAddr().String())
|
||||
if err == nil {
|
||||
t.Log(c.(*socks.Conn).BoundAddr())
|
||||
c.Close()
|
||||
|
|
79
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
79
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
|
@ -75,7 +75,7 @@ const (
|
|||
|
||||
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
|
||||
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
|
||||
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authetication methods
|
||||
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
|
||||
|
||||
StatusSucceeded Reply = 0x00
|
||||
)
|
||||
|
@ -149,20 +149,13 @@ type Dialer struct {
|
|||
// See func Dial of the net package of standard library for a
|
||||
// description of the network and address parameters.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp6", "tcp4":
|
||||
default:
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("network not implemented")}
|
||||
}
|
||||
switch d.cmd {
|
||||
case CmdConnect, cmdBind:
|
||||
default:
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("command not implemented")}
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||
}
|
||||
var err error
|
||||
var c net.Conn
|
||||
|
@ -185,11 +178,69 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.
|
|||
return &Conn{Conn: c, boundAddr: a}, nil
|
||||
}
|
||||
|
||||
// DialWithConn initiates a connection from SOCKS server to the target
|
||||
// network and address using the connection c that is already
|
||||
// connected to the SOCKS server.
|
||||
//
|
||||
// It returns the connection's local address assigned by the SOCKS
|
||||
// server.
|
||||
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if ctx == nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||
}
|
||||
a, err := d.connect(ctx, c, address)
|
||||
if err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Dial connects to the provided address on the provided network.
|
||||
//
|
||||
// Deprecated: Use DialContext instead.
|
||||
// Unlike DialContext, it returns a raw transport connection instead
|
||||
// of a forward proxy connection.
|
||||
//
|
||||
// Deprecated: Use DialContext or DialWithConn instead.
|
||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(context.Background(), network, address)
|
||||
if err := d.validateTarget(network, address); err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
var err error
|
||||
var c net.Conn
|
||||
if d.ProxyDial != nil {
|
||||
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
|
||||
} else {
|
||||
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
|
||||
}
|
||||
if err != nil {
|
||||
proxy, dst, _ := d.pathAddrs(address)
|
||||
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||
}
|
||||
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (d *Dialer) validateTarget(network, address string) error {
|
||||
switch network {
|
||||
case "tcp", "tcp6", "tcp4":
|
||||
default:
|
||||
return errors.New("network not implemented")
|
||||
}
|
||||
switch d.cmd {
|
||||
case CmdConnect, cmdBind:
|
||||
default:
|
||||
return errors.New("command not implemented")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
|
||||
|
|
2
vendor/golang.org/x/net/ipv4/doc.go
generated
vendored
2
vendor/golang.org/x/net/ipv4/doc.go
generated
vendored
|
@ -241,4 +241,4 @@
|
|||
// IncludeSourceSpecificGroup may return an error.
|
||||
package ipv4 // import "golang.org/x/net/ipv4"
|
||||
|
||||
// BUG(mikio): This package is not implemented on NaCl and Plan 9.
|
||||
// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
|
||||
|
|
4
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
|
@ -29,7 +29,7 @@ var packetConnReadWriteMulticastUDPTests = []struct {
|
|||
|
||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "solaris", "windows":
|
||||
case "js", "nacl", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
|
@ -117,7 +117,7 @@ var packetConnReadWriteMulticastICMPTests = []struct {
|
|||
|
||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "solaris", "windows":
|
||||
case "js", "nacl", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
|
|
10
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
10
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
|
@ -21,7 +21,7 @@ var udpMultipleGroupListenerTests = []net.Addr{
|
|||
|
||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
|
@ -61,7 +61,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|||
|
||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
|
@ -116,7 +116,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|||
|
||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
|
@ -172,7 +172,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|||
|
||||
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
|
@ -217,7 +217,7 @@ func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
|
|||
|
||||
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
|
|
4
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
|
@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct {
|
|||
|
||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9":
|
||||
case "js", "nacl", "plan9":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
|
@ -66,7 +66,7 @@ var rawConnMulticastSocketOptionTests = []struct {
|
|||
|
||||
func TestRawConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9":
|
||||
case "js", "nacl", "plan9":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
|
|
4
vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv4/readwrite_go1_8_test.go
generated
vendored
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
b.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
4
vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv4/readwrite_go1_9_test.go
generated
vendored
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
b.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
2
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
2
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
|
@ -61,7 +61,7 @@ func BenchmarkReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
6
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
6
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
|
@ -71,7 +71,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
|||
|
||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
|
@ -157,7 +157,7 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
|||
|
||||
func TestRawConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
|
|
6
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
6
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
|
@ -62,7 +62,7 @@ var packetConnUnicastSocketOptionTests = []struct {
|
|||
|
||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
|
@ -88,7 +88,7 @@ func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
|||
|
||||
func TestRawConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
|
|
2
vendor/golang.org/x/net/ipv6/doc.go
generated
vendored
2
vendor/golang.org/x/net/ipv6/doc.go
generated
vendored
|
@ -240,4 +240,4 @@
|
|||
// IncludeSourceSpecificGroup may return an error.
|
||||
package ipv6 // import "golang.org/x/net/ipv6"
|
||||
|
||||
// BUG(mikio): This package is not implemented on NaCl and Plan 9.
|
||||
// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/icmp_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/icmp_test.go
generated
vendored
|
@ -34,7 +34,7 @@ func TestICMPString(t *testing.T) {
|
|||
|
||||
func TestICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ func TestICMPFilter(t *testing.T) {
|
|||
|
||||
func TestSetICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/multicast_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/multicast_test.go
generated
vendored
|
@ -29,7 +29,7 @@ var packetConnReadWriteMulticastUDPTests = []struct {
|
|||
|
||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -129,7 +129,7 @@ var packetConnReadWriteMulticastICMPTests = []struct {
|
|||
|
||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
10
vendor/golang.org/x/net/ipv6/multicastlistener_test.go
generated
vendored
10
vendor/golang.org/x/net/ipv6/multicastlistener_test.go
generated
vendored
|
@ -21,7 +21,7 @@ var udpMultipleGroupListenerTests = []net.Addr{
|
|||
|
||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -61,7 +61,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|||
|
||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -116,7 +116,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|||
|
||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -172,7 +172,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|||
|
||||
func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -216,7 +216,7 @@ func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
2
vendor/golang.org/x/net/ipv6/multicastsockopt_test.go
generated
vendored
2
vendor/golang.org/x/net/ipv6/multicastsockopt_test.go
generated
vendored
|
@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct {
|
|||
|
||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/readwrite_go1_8_test.go
generated
vendored
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
b.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/readwrite_go1_9_test.go
generated
vendored
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
b.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
2
vendor/golang.org/x/net/ipv6/readwrite_test.go
generated
vendored
2
vendor/golang.org/x/net/ipv6/readwrite_test.go
generated
vendored
|
@ -65,7 +65,7 @@ func BenchmarkReadWriteUnicast(b *testing.B) {
|
|||
|
||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
6
vendor/golang.org/x/net/ipv6/sockopt_test.go
generated
vendored
6
vendor/golang.org/x/net/ipv6/sockopt_test.go
generated
vendored
|
@ -19,7 +19,7 @@ var supportsIPv6 bool = nettest.SupportsIPv6()
|
|||
|
||||
func TestConnInitiatorPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -57,7 +57,7 @@ func TestConnInitiatorPathMTU(t *testing.T) {
|
|||
|
||||
func TestConnResponderPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -95,7 +95,7 @@ func TestConnResponderPathMTU(t *testing.T) {
|
|||
|
||||
func TestPacketConnChecksum(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/unicast_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/unicast_test.go
generated
vendored
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -78,7 +78,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
|||
|
||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
4
vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
generated
vendored
4
vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
generated
vendored
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
@ -61,7 +61,7 @@ var packetConnUnicastSocketOptionTests = []struct {
|
|||
|
||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
case "js", "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
|
|
19113
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
19113
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
File diff suppressed because it is too large
Load diff
379
vendor/golang.org/x/net/publicsuffix/table_test.go
generated
vendored
379
vendor/golang.org/x/net/publicsuffix/table_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
54
vendor/golang.org/x/net/webdav/prop.go
generated
vendored
54
vendor/golang.org/x/net/webdav/prop.go
generated
vendored
|
@ -7,6 +7,7 @@ package webdav
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
|
@ -376,10 +377,37 @@ func findContentLength(ctx context.Context, fs FileSystem, ls LockSystem, name s
|
|||
}
|
||||
|
||||
func findLastModified(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) {
|
||||
return fi.ModTime().Format(http.TimeFormat), nil
|
||||
return fi.ModTime().UTC().Format(http.TimeFormat), nil
|
||||
}
|
||||
|
||||
// ErrNotImplemented should be returned by optional interfaces if they
|
||||
// want the original implementation to be used.
|
||||
var ErrNotImplemented = errors.New("not implemented")
|
||||
|
||||
// ContentTyper is an optional interface for the os.FileInfo
|
||||
// objects returned by the FileSystem.
|
||||
//
|
||||
// If this interface is defined then it will be used to read the
|
||||
// content type from the object.
|
||||
//
|
||||
// If this interface is not defined the file will be opened and the
|
||||
// content type will be guessed from the initial contents of the file.
|
||||
type ContentTyper interface {
|
||||
// ContentType returns the content type for the file.
|
||||
//
|
||||
// If this returns error ErrNotImplemented then the error will
|
||||
// be ignored and the base implementation will be used
|
||||
// instead.
|
||||
ContentType(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
func findContentType(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) {
|
||||
if do, ok := fi.(ContentTyper); ok {
|
||||
ctype, err := do.ContentType(ctx)
|
||||
if err != ErrNotImplemented {
|
||||
return ctype, err
|
||||
}
|
||||
}
|
||||
f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -402,7 +430,31 @@ func findContentType(ctx context.Context, fs FileSystem, ls LockSystem, name str
|
|||
return ctype, err
|
||||
}
|
||||
|
||||
// ETager is an optional interface for the os.FileInfo objects
|
||||
// returned by the FileSystem.
|
||||
//
|
||||
// If this interface is defined then it will be used to read the ETag
|
||||
// for the object.
|
||||
//
|
||||
// If this interface is not defined an ETag will be computed using the
|
||||
// ModTime() and the Size() methods of the os.FileInfo object.
|
||||
type ETager interface {
|
||||
// ETag returns an ETag for the file. This should be of the
|
||||
// form "value" or W/"value"
|
||||
//
|
||||
// If this returns error ErrNotImplemented then the error will
|
||||
// be ignored and the base implementation will be used
|
||||
// instead.
|
||||
ETag(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
func findETag(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) {
|
||||
if do, ok := fi.(ETager); ok {
|
||||
etag, err := do.ETag(ctx)
|
||||
if err != ErrNotImplemented {
|
||||
return etag, err
|
||||
}
|
||||
}
|
||||
// The Apache http 2.4 web server by default concatenates the
|
||||
// modification time and size of a file. We replicate the heuristic
|
||||
// with nanosecond granularity.
|
||||
|
|
106
vendor/golang.org/x/net/webdav/prop_test.go
generated
vendored
106
vendor/golang.org/x/net/webdav/prop_test.go
generated
vendored
|
@ -10,6 +10,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
|
@ -29,7 +30,7 @@ func TestMemPS(t *testing.T) {
|
|||
for i, p := range pst.Props {
|
||||
switch p.XMLName {
|
||||
case xml.Name{Space: "DAV:", Local: "getlastmodified"}:
|
||||
p.InnerXML = []byte(fi.ModTime().Format(http.TimeFormat))
|
||||
p.InnerXML = []byte(fi.ModTime().UTC().Format(http.TimeFormat))
|
||||
pst.Props[i] = p
|
||||
case xml.Name{Space: "DAV:", Local: "getetag"}:
|
||||
if fi.IsDir() {
|
||||
|
@ -611,3 +612,106 @@ func (f noDeadPropsFile) Readdir(count int) ([]os.FileInfo, error) { return f.f
|
|||
func (f noDeadPropsFile) Seek(off int64, whence int) (int64, error) { return f.f.Seek(off, whence) }
|
||||
func (f noDeadPropsFile) Stat() (os.FileInfo, error) { return f.f.Stat() }
|
||||
func (f noDeadPropsFile) Write(p []byte) (int, error) { return f.f.Write(p) }
|
||||
|
||||
type overrideContentType struct {
|
||||
os.FileInfo
|
||||
contentType string
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *overrideContentType) ContentType(ctx context.Context) (string, error) {
|
||||
return o.contentType, o.err
|
||||
}
|
||||
|
||||
func TestFindContentTypeOverride(t *testing.T) {
|
||||
fs, err := buildTestFS([]string{"touch /file"})
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create test filesystem: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
fi, err := fs.Stat(ctx, "/file")
|
||||
if err != nil {
|
||||
t.Fatalf("cannot Stat /file: %v", err)
|
||||
}
|
||||
|
||||
// Check non overridden case
|
||||
originalContentType, err := findContentType(ctx, fs, nil, "/file", fi)
|
||||
if err != nil {
|
||||
t.Fatalf("findContentType /file failed: %v", err)
|
||||
}
|
||||
if originalContentType != "text/plain; charset=utf-8" {
|
||||
t.Fatalf("ContentType wrong want %q got %q", "text/plain; charset=utf-8", originalContentType)
|
||||
}
|
||||
|
||||
// Now try overriding the ContentType
|
||||
o := &overrideContentType{fi, "OverriddenContentType", nil}
|
||||
ContentType, err := findContentType(ctx, fs, nil, "/file", o)
|
||||
if err != nil {
|
||||
t.Fatalf("findContentType /file failed: %v", err)
|
||||
}
|
||||
if ContentType != o.contentType {
|
||||
t.Fatalf("ContentType wrong want %q got %q", o.contentType, ContentType)
|
||||
}
|
||||
|
||||
// Now return ErrNotImplemented and check we get the original content type
|
||||
o = &overrideContentType{fi, "OverriddenContentType", ErrNotImplemented}
|
||||
ContentType, err = findContentType(ctx, fs, nil, "/file", o)
|
||||
if err != nil {
|
||||
t.Fatalf("findContentType /file failed: %v", err)
|
||||
}
|
||||
if ContentType != originalContentType {
|
||||
t.Fatalf("ContentType wrong want %q got %q", originalContentType, ContentType)
|
||||
}
|
||||
}
|
||||
|
||||
type overrideETag struct {
|
||||
os.FileInfo
|
||||
eTag string
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *overrideETag) ETag(ctx context.Context) (string, error) {
|
||||
return o.eTag, o.err
|
||||
}
|
||||
|
||||
func TestFindETagOverride(t *testing.T) {
|
||||
fs, err := buildTestFS([]string{"touch /file"})
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create test filesystem: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
fi, err := fs.Stat(ctx, "/file")
|
||||
if err != nil {
|
||||
t.Fatalf("cannot Stat /file: %v", err)
|
||||
}
|
||||
|
||||
// Check non overridden case
|
||||
originalETag, err := findETag(ctx, fs, nil, "/file", fi)
|
||||
if err != nil {
|
||||
t.Fatalf("findETag /file failed: %v", err)
|
||||
}
|
||||
matchETag := regexp.MustCompile(`^"-?[0-9a-f]{6,}"$`)
|
||||
if !matchETag.MatchString(originalETag) {
|
||||
t.Fatalf("ETag wrong, wanted something matching %v got %q", matchETag, originalETag)
|
||||
}
|
||||
|
||||
// Now try overriding the ETag
|
||||
o := &overrideETag{fi, `"OverriddenETag"`, nil}
|
||||
ETag, err := findETag(ctx, fs, nil, "/file", o)
|
||||
if err != nil {
|
||||
t.Fatalf("findETag /file failed: %v", err)
|
||||
}
|
||||
if ETag != o.eTag {
|
||||
t.Fatalf("ETag wrong want %q got %q", o.eTag, ETag)
|
||||
}
|
||||
|
||||
// Now return ErrNotImplemented and check we get the original Etag
|
||||
o = &overrideETag{fi, `"OverriddenETag"`, ErrNotImplemented}
|
||||
ETag, err = findETag(ctx, fs, nil, "/file", o)
|
||||
if err != nil {
|
||||
t.Fatalf("findETag /file failed: %v", err)
|
||||
}
|
||||
if ETag != originalETag {
|
||||
t.Fatalf("ETag wrong want %q got %q", originalETag, ETag)
|
||||
}
|
||||
}
|
||||
|
|
3
vendor/golang.org/x/net/websocket/websocket.go
generated
vendored
3
vendor/golang.org/x/net/websocket/websocket.go
generated
vendored
|
@ -241,7 +241,10 @@ func (ws *Conn) Close() error {
|
|||
return err1
|
||||
}
|
||||
|
||||
// IsClientConn reports whether ws is a client-side connection.
|
||||
func (ws *Conn) IsClientConn() bool { return ws.request == nil }
|
||||
|
||||
// IsServerConn reports whether ws is a server-side connection.
|
||||
func (ws *Conn) IsServerConn() bool { return ws.request != nil }
|
||||
|
||||
// LocalAddr returns the WebSocket Origin for the connection for client, or
|
||||
|
|
7
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
7
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
|
@ -6,6 +6,9 @@
|
|||
// various CPU architectures.
|
||||
package cpu
|
||||
|
||||
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||
|
||||
// X86 contains the supported CPU features of the
|
||||
// current X86/AMD64 platform. If the current platform
|
||||
// is not X86/AMD64 then all feature flags are false.
|
||||
|
@ -14,7 +17,7 @@ package cpu
|
|||
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||
// registers in addition to the CPUID feature bit being set.
|
||||
var X86 struct {
|
||||
_ [cacheLineSize]byte
|
||||
_ CacheLinePad
|
||||
HasAES bool // AES hardware implementation (AES NI)
|
||||
HasADX bool // Multi-precision add-carry instruction extensions
|
||||
HasAVX bool // Advanced vector extension
|
||||
|
@ -31,5 +34,5 @@ var X86 struct {
|
|||
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||
_ [cacheLineSize]byte
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
|
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build !gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func xgetbv() (eax, edx uint32)
|
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
Normal file
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build gccgo
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||
int
|
||||
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||
}
|
||||
|
||||
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||
// specified in the ECX register into registers EDX:EAX.
|
||||
// Currently, the only supported value for XCR is 0.
|
||||
//
|
||||
// TODO: Replace with a better alternative:
|
||||
//
|
||||
// #include <xsaveintrin.h>
|
||||
//
|
||||
// #pragma GCC target("xsave")
|
||||
//
|
||||
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||
// unsigned long long x = _xgetbv(0);
|
||||
// *eax = x & 0xffffffff;
|
||||
// *edx = (x >> 32) & 0xffffffff;
|
||||
// }
|
||||
//
|
||||
// Note that _xgetbv is defined starting with GCC 8.
|
||||
void
|
||||
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||
{
|
||||
__asm(" xorl %%ecx, %%ecx\n"
|
||||
" xgetbv"
|
||||
: "=a"(*eax), "=d"(*edx));
|
||||
}
|
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
Normal file
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
//extern gccgoGetCpuidCount
|
||||
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||
var a, b, c, d uint32
|
||||
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||
return a, b, c, d
|
||||
}
|
||||
|
||||
//extern gccgoXgetbv
|
||||
func gccgoXgetbv(eax, edx *uint32)
|
||||
|
||||
func xgetbv() (eax, edx uint32) {
|
||||
var a, d uint32
|
||||
gccgoXgetbv(&a, &d)
|
||||
return a, d
|
||||
}
|
6
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
6
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
|
@ -8,12 +8,6 @@ package cpu
|
|||
|
||||
const cacheLineSize = 64
|
||||
|
||||
// cpuid is implemented in cpu_x86.s.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in cpu_x86.s.
|
||||
func xgetbv() (eax, edx uint32)
|
||||
|
||||
func init() {
|
||||
maxID, _, _, _ := cpuid(0, 0)
|
||||
|
||||
|
|
1
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
1
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
|
@ -3,6 +3,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build 386 amd64 amd64p32
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
|
2
vendor/golang.org/x/sys/plan9/mkerrors.sh
generated
vendored
2
vendor/golang.org/x/sys/plan9/mkerrors.sh
generated
vendored
|
@ -140,7 +140,7 @@ echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
|||
sort >_signal.grep
|
||||
|
||||
echo '// mkerrors.sh' "$@"
|
||||
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
|
||||
echo '// Code generated by the command above; DO NOT EDIT.'
|
||||
echo
|
||||
go tool cgo -godefs -- "$@" _const.go >_error.out
|
||||
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
|
||||
|
|
2
vendor/golang.org/x/sys/plan9/mksyscall.pl
generated
vendored
2
vendor/golang.org/x/sys/plan9/mksyscall.pl
generated
vendored
|
@ -308,7 +308,7 @@ if($errors) {
|
|||
|
||||
print <<EOF;
|
||||
// $cmdline
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package plan9
|
||||
|
||||
|
|
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
generated
vendored
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
// mksyscall.pl -l32 -plan9 syscall_plan9.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package plan9
|
||||
|
||||
|
|
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
generated
vendored
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
// mksyscall.pl -l32 -plan9 syscall_plan9.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package plan9
|
||||
|
||||
|
|
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
generated
vendored
2
vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
// mksyscall.pl -l32 -plan9 -tags plan9,arm syscall_plan9.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
// +build plan9,arm
|
||||
|
||||
|
|
51
vendor/golang.org/x/sys/unix/dev_darwin_test.go
generated
vendored
51
vendor/golang.org/x/sys/unix/dev_darwin_test.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// Most of the device major/minor numbers on Darwin are
|
||||
// dynamically generated by devfs. These are some well-known
|
||||
// static numbers.
|
||||
{"/dev/ttyp0", 4, 0},
|
||||
{"/dev/ttys0", 4, 48},
|
||||
{"/dev/ptyp0", 5, 0},
|
||||
{"/dev/ptyr0", 5, 32},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
50
vendor/golang.org/x/sys/unix/dev_dragonfly_test.go
generated
vendored
50
vendor/golang.org/x/sys/unix/dev_dragonfly_test.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// Minor is a cookie instead of an index on DragonFlyBSD
|
||||
{"/dev/null", 10, 0x00000002},
|
||||
{"/dev/random", 10, 0x00000003},
|
||||
{"/dev/urandom", 10, 0x00000004},
|
||||
{"/dev/zero", 10, 0x0000000c},
|
||||
{"/dev/bpf", 15, 0xffff00ff},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
3
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
3
vendor/golang.org/x/sys/unix/dev_linux_test.go
generated
vendored
|
@ -33,6 +33,9 @@ func TestDevices(t *testing.T) {
|
|||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
if err == unix.EACCES {
|
||||
t.Skip("no permission to stat device, skipping test")
|
||||
}
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
|
50
vendor/golang.org/x/sys/unix/dev_netbsd_test.go
generated
vendored
50
vendor/golang.org/x/sys/unix/dev_netbsd_test.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// well known major/minor numbers according to /dev/MAKEDEV on
|
||||
// NetBSD 8.0
|
||||
{"/dev/null", 2, 2},
|
||||
{"/dev/zero", 2, 12},
|
||||
{"/dev/random", 46, 0},
|
||||
{"/dev/urandom", 46, 1},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
54
vendor/golang.org/x/sys/unix/dev_openbsd_test.go
generated
vendored
54
vendor/golang.org/x/sys/unix/dev_openbsd_test.go
generated
vendored
|
@ -1,54 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// well known major/minor numbers according to /dev/MAKEDEV on
|
||||
// OpenBSD 6.0
|
||||
{"/dev/null", 2, 2},
|
||||
{"/dev/zero", 2, 12},
|
||||
{"/dev/ttyp0", 5, 0},
|
||||
{"/dev/ttyp1", 5, 1},
|
||||
{"/dev/random", 45, 0},
|
||||
{"/dev/srandom", 45, 1},
|
||||
{"/dev/urandom", 45, 2},
|
||||
{"/dev/arandom", 45, 3},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
51
vendor/golang.org/x/sys/unix/dev_solaris_test.go
generated
vendored
51
vendor/golang.org/x/sys/unix/dev_solaris_test.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package unix_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDevices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
major uint32
|
||||
minor uint32
|
||||
}{
|
||||
// Well-known major/minor numbers on OpenSolaris according to
|
||||
// /etc/name_to_major
|
||||
{"/dev/zero", 134, 12},
|
||||
{"/dev/null", 134, 2},
|
||||
{"/dev/ptyp0", 172, 0},
|
||||
{"/dev/ttyp0", 175, 0},
|
||||
{"/dev/ttyp1", 175, 1},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
|
||||
var stat unix.Stat_t
|
||||
err := unix.Stat(tc.path, &stat)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat device: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
dev := uint64(stat.Rdev)
|
||||
if unix.Major(dev) != tc.major {
|
||||
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
|
||||
}
|
||||
if unix.Minor(dev) != tc.minor {
|
||||
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
|
||||
}
|
||||
if unix.Mkdev(tc.major, tc.minor) != dev {
|
||||
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
6
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
6
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
|
@ -14,7 +14,11 @@ var fcntl64Syscall uintptr = SYS_FCNTL
|
|||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
valptr, _, err := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
||||
var err error
|
||||
if errno != 0 {
|
||||
err = errno
|
||||
}
|
||||
return int(valptr), err
|
||||
}
|
||||
|
||||
|
|
9
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
9
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
|
@ -36,12 +36,3 @@ gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3
|
|||
{
|
||||
return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
}
|
||||
|
||||
// Define the use function in C so that it is not inlined.
|
||||
|
||||
extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
|
||||
|
||||
void
|
||||
use(void *p __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
|
10
vendor/golang.org/x/sys/unix/linux/Dockerfile
generated
vendored
10
vendor/golang.org/x/sys/unix/linux/Dockerfile
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
FROM ubuntu:17.10
|
||||
FROM ubuntu:18.04
|
||||
|
||||
# Dependencies to get the git sources and go binaries
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
@ -11,15 +11,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
# Get the git sources. If not cached, this takes O(5 minutes).
|
||||
WORKDIR /git
|
||||
RUN git config --global advice.detachedHead false
|
||||
# Linux Kernel: Released 01 Apr 2018
|
||||
RUN git clone --branch v4.16 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
|
||||
# Linux Kernel: Released 03 Jun 2018
|
||||
RUN git clone --branch v4.17 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
|
||||
# GNU C library: Released 01 Feb 2018 (we should try to get a secure way to clone this)
|
||||
RUN git clone --branch glibc-2.27 --depth 1 git://sourceware.org/git/glibc.git
|
||||
|
||||
# Get Go
|
||||
ENV GOLANG_VERSION 1.10.1
|
||||
ENV GOLANG_VERSION 1.10.3
|
||||
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
|
||||
ENV GOLANG_DOWNLOAD_SHA256 72d820dec546752e5a8303b33b009079c15c2390ce76d67cf514991646c6127b
|
||||
ENV GOLANG_DOWNLOAD_SHA256 fa1b0e45d3b647c252f51f5e1204aba049cde4af177ef9f2181f43004f901035
|
||||
|
||||
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
|
||||
&& echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \
|
||||
|
|
487
vendor/golang.org/x/sys/unix/linux/types.go
generated
vendored
487
vendor/golang.org/x/sys/unix/linux/types.go
generated
vendored
|
@ -49,6 +49,9 @@ package unix
|
|||
#include <linux/filter.h>
|
||||
#include <linux/icmpv6.h>
|
||||
#include <linux/keyctl.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
@ -57,7 +60,6 @@ package unix
|
|||
#include <asm/ptrace.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ustat.h>
|
||||
#include <utime.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/if_alg.h>
|
||||
|
@ -70,6 +72,7 @@ package unix
|
|||
#include <linux/genetlink.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
// abi/abi.h generated by mkall.go.
|
||||
#include "abi/abi.h"
|
||||
|
@ -138,6 +141,10 @@ struct stat {
|
|||
# define AT_STATX_DONT_SYNC 0x4000 // - Don't sync attributes with the server
|
||||
#endif
|
||||
|
||||
#ifndef AT_EACCESS
|
||||
# define AT_EACCESS 0x200 // Test access permitted for effective IDs, not real IDs.
|
||||
#endif
|
||||
|
||||
#ifdef TCSETS2
|
||||
// On systems that have "struct termios2" use this as type Termios.
|
||||
typedef struct termios2 termios_t;
|
||||
|
@ -289,6 +296,15 @@ struct perf_event_attr_go {
|
|||
__u32 __reserved_2;
|
||||
};
|
||||
|
||||
// ustat is deprecated and glibc 2.28 removed ustat.h. Provide the type here for
|
||||
// backwards compatibility. Copied from /usr/include/bits/ustat.h
|
||||
struct ustat {
|
||||
__daddr_t f_tfree;
|
||||
__ino_t f_tinode;
|
||||
char f_fname[6];
|
||||
char f_fpack[6];
|
||||
};
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
@ -646,6 +662,8 @@ const (
|
|||
|
||||
AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
|
||||
AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
|
||||
|
||||
AT_EACCESS = C.AT_EACCESS
|
||||
)
|
||||
|
||||
type PollFd C.struct_pollfd
|
||||
|
@ -1021,3 +1039,470 @@ const (
|
|||
SizeofTpacket2Hdr = C.sizeof_struct_tpacket2_hdr
|
||||
SizeofTpacket3Hdr = C.sizeof_struct_tpacket3_hdr
|
||||
)
|
||||
|
||||
// netfilter
|
||||
// generated using:
|
||||
// perl -nlE '/^\s*(NF\w+)/ && say "$1 = C.$1"' /usr/include/linux/netfilter.h
|
||||
const (
|
||||
NF_INET_PRE_ROUTING = C.NF_INET_PRE_ROUTING
|
||||
NF_INET_LOCAL_IN = C.NF_INET_LOCAL_IN
|
||||
NF_INET_FORWARD = C.NF_INET_FORWARD
|
||||
NF_INET_LOCAL_OUT = C.NF_INET_LOCAL_OUT
|
||||
NF_INET_POST_ROUTING = C.NF_INET_POST_ROUTING
|
||||
NF_INET_NUMHOOKS = C.NF_INET_NUMHOOKS
|
||||
)
|
||||
|
||||
const (
|
||||
NF_NETDEV_INGRESS = C.NF_NETDEV_INGRESS
|
||||
NF_NETDEV_NUMHOOKS = C.NF_NETDEV_NUMHOOKS
|
||||
)
|
||||
|
||||
const (
|
||||
NFPROTO_UNSPEC = C.NFPROTO_UNSPEC
|
||||
NFPROTO_INET = C.NFPROTO_INET
|
||||
NFPROTO_IPV4 = C.NFPROTO_IPV4
|
||||
NFPROTO_ARP = C.NFPROTO_ARP
|
||||
NFPROTO_NETDEV = C.NFPROTO_NETDEV
|
||||
NFPROTO_BRIDGE = C.NFPROTO_BRIDGE
|
||||
NFPROTO_IPV6 = C.NFPROTO_IPV6
|
||||
NFPROTO_DECNET = C.NFPROTO_DECNET
|
||||
NFPROTO_NUMPROTO = C.NFPROTO_NUMPROTO
|
||||
)
|
||||
|
||||
// netfilter nfnetlink
|
||||
type Nfgenmsg C.struct_nfgenmsg
|
||||
|
||||
const (
|
||||
NFNL_BATCH_UNSPEC = C.NFNL_BATCH_UNSPEC
|
||||
NFNL_BATCH_GENID = C.NFNL_BATCH_GENID
|
||||
)
|
||||
|
||||
// netfilter nf_tables
|
||||
// generated using:
|
||||
// perl -nlE '/^\s*(NFT\w+)/ && say "$1 = C.$1"' /usr/include/linux/netfilter/nf_tables.h
|
||||
const (
|
||||
NFT_REG_VERDICT = C.NFT_REG_VERDICT
|
||||
NFT_REG_1 = C.NFT_REG_1
|
||||
NFT_REG_2 = C.NFT_REG_2
|
||||
NFT_REG_3 = C.NFT_REG_3
|
||||
NFT_REG_4 = C.NFT_REG_4
|
||||
NFT_REG32_00 = C.NFT_REG32_00
|
||||
NFT_REG32_01 = C.NFT_REG32_01
|
||||
NFT_REG32_02 = C.NFT_REG32_02
|
||||
NFT_REG32_03 = C.NFT_REG32_03
|
||||
NFT_REG32_04 = C.NFT_REG32_04
|
||||
NFT_REG32_05 = C.NFT_REG32_05
|
||||
NFT_REG32_06 = C.NFT_REG32_06
|
||||
NFT_REG32_07 = C.NFT_REG32_07
|
||||
NFT_REG32_08 = C.NFT_REG32_08
|
||||
NFT_REG32_09 = C.NFT_REG32_09
|
||||
NFT_REG32_10 = C.NFT_REG32_10
|
||||
NFT_REG32_11 = C.NFT_REG32_11
|
||||
NFT_REG32_12 = C.NFT_REG32_12
|
||||
NFT_REG32_13 = C.NFT_REG32_13
|
||||
NFT_REG32_14 = C.NFT_REG32_14
|
||||
NFT_REG32_15 = C.NFT_REG32_15
|
||||
NFT_CONTINUE = C.NFT_CONTINUE
|
||||
NFT_BREAK = C.NFT_BREAK
|
||||
NFT_JUMP = C.NFT_JUMP
|
||||
NFT_GOTO = C.NFT_GOTO
|
||||
NFT_RETURN = C.NFT_RETURN
|
||||
NFT_MSG_NEWTABLE = C.NFT_MSG_NEWTABLE
|
||||
NFT_MSG_GETTABLE = C.NFT_MSG_GETTABLE
|
||||
NFT_MSG_DELTABLE = C.NFT_MSG_DELTABLE
|
||||
NFT_MSG_NEWCHAIN = C.NFT_MSG_NEWCHAIN
|
||||
NFT_MSG_GETCHAIN = C.NFT_MSG_GETCHAIN
|
||||
NFT_MSG_DELCHAIN = C.NFT_MSG_DELCHAIN
|
||||
NFT_MSG_NEWRULE = C.NFT_MSG_NEWRULE
|
||||
NFT_MSG_GETRULE = C.NFT_MSG_GETRULE
|
||||
NFT_MSG_DELRULE = C.NFT_MSG_DELRULE
|
||||
NFT_MSG_NEWSET = C.NFT_MSG_NEWSET
|
||||
NFT_MSG_GETSET = C.NFT_MSG_GETSET
|
||||
NFT_MSG_DELSET = C.NFT_MSG_DELSET
|
||||
NFT_MSG_NEWSETELEM = C.NFT_MSG_NEWSETELEM
|
||||
NFT_MSG_GETSETELEM = C.NFT_MSG_GETSETELEM
|
||||
NFT_MSG_DELSETELEM = C.NFT_MSG_DELSETELEM
|
||||
NFT_MSG_NEWGEN = C.NFT_MSG_NEWGEN
|
||||
NFT_MSG_GETGEN = C.NFT_MSG_GETGEN
|
||||
NFT_MSG_TRACE = C.NFT_MSG_TRACE
|
||||
NFT_MSG_NEWOBJ = C.NFT_MSG_NEWOBJ
|
||||
NFT_MSG_GETOBJ = C.NFT_MSG_GETOBJ
|
||||
NFT_MSG_DELOBJ = C.NFT_MSG_DELOBJ
|
||||
NFT_MSG_GETOBJ_RESET = C.NFT_MSG_GETOBJ_RESET
|
||||
NFT_MSG_MAX = C.NFT_MSG_MAX
|
||||
NFTA_LIST_UNPEC = C.NFTA_LIST_UNPEC
|
||||
NFTA_LIST_ELEM = C.NFTA_LIST_ELEM
|
||||
NFTA_HOOK_UNSPEC = C.NFTA_HOOK_UNSPEC
|
||||
NFTA_HOOK_HOOKNUM = C.NFTA_HOOK_HOOKNUM
|
||||
NFTA_HOOK_PRIORITY = C.NFTA_HOOK_PRIORITY
|
||||
NFTA_HOOK_DEV = C.NFTA_HOOK_DEV
|
||||
NFT_TABLE_F_DORMANT = C.NFT_TABLE_F_DORMANT
|
||||
NFTA_TABLE_UNSPEC = C.NFTA_TABLE_UNSPEC
|
||||
NFTA_TABLE_NAME = C.NFTA_TABLE_NAME
|
||||
NFTA_TABLE_FLAGS = C.NFTA_TABLE_FLAGS
|
||||
NFTA_TABLE_USE = C.NFTA_TABLE_USE
|
||||
NFTA_CHAIN_UNSPEC = C.NFTA_CHAIN_UNSPEC
|
||||
NFTA_CHAIN_TABLE = C.NFTA_CHAIN_TABLE
|
||||
NFTA_CHAIN_HANDLE = C.NFTA_CHAIN_HANDLE
|
||||
NFTA_CHAIN_NAME = C.NFTA_CHAIN_NAME
|
||||
NFTA_CHAIN_HOOK = C.NFTA_CHAIN_HOOK
|
||||
NFTA_CHAIN_POLICY = C.NFTA_CHAIN_POLICY
|
||||
NFTA_CHAIN_USE = C.NFTA_CHAIN_USE
|
||||
NFTA_CHAIN_TYPE = C.NFTA_CHAIN_TYPE
|
||||
NFTA_CHAIN_COUNTERS = C.NFTA_CHAIN_COUNTERS
|
||||
NFTA_CHAIN_PAD = C.NFTA_CHAIN_PAD
|
||||
NFTA_RULE_UNSPEC = C.NFTA_RULE_UNSPEC
|
||||
NFTA_RULE_TABLE = C.NFTA_RULE_TABLE
|
||||
NFTA_RULE_CHAIN = C.NFTA_RULE_CHAIN
|
||||
NFTA_RULE_HANDLE = C.NFTA_RULE_HANDLE
|
||||
NFTA_RULE_EXPRESSIONS = C.NFTA_RULE_EXPRESSIONS
|
||||
NFTA_RULE_COMPAT = C.NFTA_RULE_COMPAT
|
||||
NFTA_RULE_POSITION = C.NFTA_RULE_POSITION
|
||||
NFTA_RULE_USERDATA = C.NFTA_RULE_USERDATA
|
||||
NFTA_RULE_PAD = C.NFTA_RULE_PAD
|
||||
NFTA_RULE_ID = C.NFTA_RULE_ID
|
||||
NFT_RULE_COMPAT_F_INV = C.NFT_RULE_COMPAT_F_INV
|
||||
NFT_RULE_COMPAT_F_MASK = C.NFT_RULE_COMPAT_F_MASK
|
||||
NFTA_RULE_COMPAT_UNSPEC = C.NFTA_RULE_COMPAT_UNSPEC
|
||||
NFTA_RULE_COMPAT_PROTO = C.NFTA_RULE_COMPAT_PROTO
|
||||
NFTA_RULE_COMPAT_FLAGS = C.NFTA_RULE_COMPAT_FLAGS
|
||||
NFT_SET_ANONYMOUS = C.NFT_SET_ANONYMOUS
|
||||
NFT_SET_CONSTANT = C.NFT_SET_CONSTANT
|
||||
NFT_SET_INTERVAL = C.NFT_SET_INTERVAL
|
||||
NFT_SET_MAP = C.NFT_SET_MAP
|
||||
NFT_SET_TIMEOUT = C.NFT_SET_TIMEOUT
|
||||
NFT_SET_EVAL = C.NFT_SET_EVAL
|
||||
NFT_SET_OBJECT = C.NFT_SET_OBJECT
|
||||
NFT_SET_POL_PERFORMANCE = C.NFT_SET_POL_PERFORMANCE
|
||||
NFT_SET_POL_MEMORY = C.NFT_SET_POL_MEMORY
|
||||
NFTA_SET_DESC_UNSPEC = C.NFTA_SET_DESC_UNSPEC
|
||||
NFTA_SET_DESC_SIZE = C.NFTA_SET_DESC_SIZE
|
||||
NFTA_SET_UNSPEC = C.NFTA_SET_UNSPEC
|
||||
NFTA_SET_TABLE = C.NFTA_SET_TABLE
|
||||
NFTA_SET_NAME = C.NFTA_SET_NAME
|
||||
NFTA_SET_FLAGS = C.NFTA_SET_FLAGS
|
||||
NFTA_SET_KEY_TYPE = C.NFTA_SET_KEY_TYPE
|
||||
NFTA_SET_KEY_LEN = C.NFTA_SET_KEY_LEN
|
||||
NFTA_SET_DATA_TYPE = C.NFTA_SET_DATA_TYPE
|
||||
NFTA_SET_DATA_LEN = C.NFTA_SET_DATA_LEN
|
||||
NFTA_SET_POLICY = C.NFTA_SET_POLICY
|
||||
NFTA_SET_DESC = C.NFTA_SET_DESC
|
||||
NFTA_SET_ID = C.NFTA_SET_ID
|
||||
NFTA_SET_TIMEOUT = C.NFTA_SET_TIMEOUT
|
||||
NFTA_SET_GC_INTERVAL = C.NFTA_SET_GC_INTERVAL
|
||||
NFTA_SET_USERDATA = C.NFTA_SET_USERDATA
|
||||
NFTA_SET_PAD = C.NFTA_SET_PAD
|
||||
NFTA_SET_OBJ_TYPE = C.NFTA_SET_OBJ_TYPE
|
||||
NFT_SET_ELEM_INTERVAL_END = C.NFT_SET_ELEM_INTERVAL_END
|
||||
NFTA_SET_ELEM_UNSPEC = C.NFTA_SET_ELEM_UNSPEC
|
||||
NFTA_SET_ELEM_KEY = C.NFTA_SET_ELEM_KEY
|
||||
NFTA_SET_ELEM_DATA = C.NFTA_SET_ELEM_DATA
|
||||
NFTA_SET_ELEM_FLAGS = C.NFTA_SET_ELEM_FLAGS
|
||||
NFTA_SET_ELEM_TIMEOUT = C.NFTA_SET_ELEM_TIMEOUT
|
||||
NFTA_SET_ELEM_EXPIRATION = C.NFTA_SET_ELEM_EXPIRATION
|
||||
NFTA_SET_ELEM_USERDATA = C.NFTA_SET_ELEM_USERDATA
|
||||
NFTA_SET_ELEM_EXPR = C.NFTA_SET_ELEM_EXPR
|
||||
NFTA_SET_ELEM_PAD = C.NFTA_SET_ELEM_PAD
|
||||
NFTA_SET_ELEM_OBJREF = C.NFTA_SET_ELEM_OBJREF
|
||||
NFTA_SET_ELEM_LIST_UNSPEC = C.NFTA_SET_ELEM_LIST_UNSPEC
|
||||
NFTA_SET_ELEM_LIST_TABLE = C.NFTA_SET_ELEM_LIST_TABLE
|
||||
NFTA_SET_ELEM_LIST_SET = C.NFTA_SET_ELEM_LIST_SET
|
||||
NFTA_SET_ELEM_LIST_ELEMENTS = C.NFTA_SET_ELEM_LIST_ELEMENTS
|
||||
NFTA_SET_ELEM_LIST_SET_ID = C.NFTA_SET_ELEM_LIST_SET_ID
|
||||
NFT_DATA_VALUE = C.NFT_DATA_VALUE
|
||||
NFT_DATA_VERDICT = C.NFT_DATA_VERDICT
|
||||
NFTA_DATA_UNSPEC = C.NFTA_DATA_UNSPEC
|
||||
NFTA_DATA_VALUE = C.NFTA_DATA_VALUE
|
||||
NFTA_DATA_VERDICT = C.NFTA_DATA_VERDICT
|
||||
NFTA_VERDICT_UNSPEC = C.NFTA_VERDICT_UNSPEC
|
||||
NFTA_VERDICT_CODE = C.NFTA_VERDICT_CODE
|
||||
NFTA_VERDICT_CHAIN = C.NFTA_VERDICT_CHAIN
|
||||
NFTA_EXPR_UNSPEC = C.NFTA_EXPR_UNSPEC
|
||||
NFTA_EXPR_NAME = C.NFTA_EXPR_NAME
|
||||
NFTA_EXPR_DATA = C.NFTA_EXPR_DATA
|
||||
NFTA_IMMEDIATE_UNSPEC = C.NFTA_IMMEDIATE_UNSPEC
|
||||
NFTA_IMMEDIATE_DREG = C.NFTA_IMMEDIATE_DREG
|
||||
NFTA_IMMEDIATE_DATA = C.NFTA_IMMEDIATE_DATA
|
||||
NFTA_BITWISE_UNSPEC = C.NFTA_BITWISE_UNSPEC
|
||||
NFTA_BITWISE_SREG = C.NFTA_BITWISE_SREG
|
||||
NFTA_BITWISE_DREG = C.NFTA_BITWISE_DREG
|
||||
NFTA_BITWISE_LEN = C.NFTA_BITWISE_LEN
|
||||
NFTA_BITWISE_MASK = C.NFTA_BITWISE_MASK
|
||||
NFTA_BITWISE_XOR = C.NFTA_BITWISE_XOR
|
||||
NFT_BYTEORDER_NTOH = C.NFT_BYTEORDER_NTOH
|
||||
NFT_BYTEORDER_HTON = C.NFT_BYTEORDER_HTON
|
||||
NFTA_BYTEORDER_UNSPEC = C.NFTA_BYTEORDER_UNSPEC
|
||||
NFTA_BYTEORDER_SREG = C.NFTA_BYTEORDER_SREG
|
||||
NFTA_BYTEORDER_DREG = C.NFTA_BYTEORDER_DREG
|
||||
NFTA_BYTEORDER_OP = C.NFTA_BYTEORDER_OP
|
||||
NFTA_BYTEORDER_LEN = C.NFTA_BYTEORDER_LEN
|
||||
NFTA_BYTEORDER_SIZE = C.NFTA_BYTEORDER_SIZE
|
||||
NFT_CMP_EQ = C.NFT_CMP_EQ
|
||||
NFT_CMP_NEQ = C.NFT_CMP_NEQ
|
||||
NFT_CMP_LT = C.NFT_CMP_LT
|
||||
NFT_CMP_LTE = C.NFT_CMP_LTE
|
||||
NFT_CMP_GT = C.NFT_CMP_GT
|
||||
NFT_CMP_GTE = C.NFT_CMP_GTE
|
||||
NFTA_CMP_UNSPEC = C.NFTA_CMP_UNSPEC
|
||||
NFTA_CMP_SREG = C.NFTA_CMP_SREG
|
||||
NFTA_CMP_OP = C.NFTA_CMP_OP
|
||||
NFTA_CMP_DATA = C.NFTA_CMP_DATA
|
||||
NFT_RANGE_EQ = C.NFT_RANGE_EQ
|
||||
NFT_RANGE_NEQ = C.NFT_RANGE_NEQ
|
||||
NFTA_RANGE_UNSPEC = C.NFTA_RANGE_UNSPEC
|
||||
NFTA_RANGE_SREG = C.NFTA_RANGE_SREG
|
||||
NFTA_RANGE_OP = C.NFTA_RANGE_OP
|
||||
NFTA_RANGE_FROM_DATA = C.NFTA_RANGE_FROM_DATA
|
||||
NFTA_RANGE_TO_DATA = C.NFTA_RANGE_TO_DATA
|
||||
NFT_LOOKUP_F_INV = C.NFT_LOOKUP_F_INV
|
||||
NFTA_LOOKUP_UNSPEC = C.NFTA_LOOKUP_UNSPEC
|
||||
NFTA_LOOKUP_SET = C.NFTA_LOOKUP_SET
|
||||
NFTA_LOOKUP_SREG = C.NFTA_LOOKUP_SREG
|
||||
NFTA_LOOKUP_DREG = C.NFTA_LOOKUP_DREG
|
||||
NFTA_LOOKUP_SET_ID = C.NFTA_LOOKUP_SET_ID
|
||||
NFTA_LOOKUP_FLAGS = C.NFTA_LOOKUP_FLAGS
|
||||
NFT_DYNSET_OP_ADD = C.NFT_DYNSET_OP_ADD
|
||||
NFT_DYNSET_OP_UPDATE = C.NFT_DYNSET_OP_UPDATE
|
||||
NFT_DYNSET_F_INV = C.NFT_DYNSET_F_INV
|
||||
NFTA_DYNSET_UNSPEC = C.NFTA_DYNSET_UNSPEC
|
||||
NFTA_DYNSET_SET_NAME = C.NFTA_DYNSET_SET_NAME
|
||||
NFTA_DYNSET_SET_ID = C.NFTA_DYNSET_SET_ID
|
||||
NFTA_DYNSET_OP = C.NFTA_DYNSET_OP
|
||||
NFTA_DYNSET_SREG_KEY = C.NFTA_DYNSET_SREG_KEY
|
||||
NFTA_DYNSET_SREG_DATA = C.NFTA_DYNSET_SREG_DATA
|
||||
NFTA_DYNSET_TIMEOUT = C.NFTA_DYNSET_TIMEOUT
|
||||
NFTA_DYNSET_EXPR = C.NFTA_DYNSET_EXPR
|
||||
NFTA_DYNSET_PAD = C.NFTA_DYNSET_PAD
|
||||
NFTA_DYNSET_FLAGS = C.NFTA_DYNSET_FLAGS
|
||||
NFT_PAYLOAD_LL_HEADER = C.NFT_PAYLOAD_LL_HEADER
|
||||
NFT_PAYLOAD_NETWORK_HEADER = C.NFT_PAYLOAD_NETWORK_HEADER
|
||||
NFT_PAYLOAD_TRANSPORT_HEADER = C.NFT_PAYLOAD_TRANSPORT_HEADER
|
||||
NFT_PAYLOAD_CSUM_NONE = C.NFT_PAYLOAD_CSUM_NONE
|
||||
NFT_PAYLOAD_CSUM_INET = C.NFT_PAYLOAD_CSUM_INET
|
||||
NFT_PAYLOAD_L4CSUM_PSEUDOHDR = C.NFT_PAYLOAD_L4CSUM_PSEUDOHDR
|
||||
NFTA_PAYLOAD_UNSPEC = C.NFTA_PAYLOAD_UNSPEC
|
||||
NFTA_PAYLOAD_DREG = C.NFTA_PAYLOAD_DREG
|
||||
NFTA_PAYLOAD_BASE = C.NFTA_PAYLOAD_BASE
|
||||
NFTA_PAYLOAD_OFFSET = C.NFTA_PAYLOAD_OFFSET
|
||||
NFTA_PAYLOAD_LEN = C.NFTA_PAYLOAD_LEN
|
||||
NFTA_PAYLOAD_SREG = C.NFTA_PAYLOAD_SREG
|
||||
NFTA_PAYLOAD_CSUM_TYPE = C.NFTA_PAYLOAD_CSUM_TYPE
|
||||
NFTA_PAYLOAD_CSUM_OFFSET = C.NFTA_PAYLOAD_CSUM_OFFSET
|
||||
NFTA_PAYLOAD_CSUM_FLAGS = C.NFTA_PAYLOAD_CSUM_FLAGS
|
||||
NFT_EXTHDR_F_PRESENT = C.NFT_EXTHDR_F_PRESENT
|
||||
NFT_EXTHDR_OP_IPV6 = C.NFT_EXTHDR_OP_IPV6
|
||||
NFT_EXTHDR_OP_TCPOPT = C.NFT_EXTHDR_OP_TCPOPT
|
||||
NFTA_EXTHDR_UNSPEC = C.NFTA_EXTHDR_UNSPEC
|
||||
NFTA_EXTHDR_DREG = C.NFTA_EXTHDR_DREG
|
||||
NFTA_EXTHDR_TYPE = C.NFTA_EXTHDR_TYPE
|
||||
NFTA_EXTHDR_OFFSET = C.NFTA_EXTHDR_OFFSET
|
||||
NFTA_EXTHDR_LEN = C.NFTA_EXTHDR_LEN
|
||||
NFTA_EXTHDR_FLAGS = C.NFTA_EXTHDR_FLAGS
|
||||
NFTA_EXTHDR_OP = C.NFTA_EXTHDR_OP
|
||||
NFTA_EXTHDR_SREG = C.NFTA_EXTHDR_SREG
|
||||
NFT_META_LEN = C.NFT_META_LEN
|
||||
NFT_META_PROTOCOL = C.NFT_META_PROTOCOL
|
||||
NFT_META_PRIORITY = C.NFT_META_PRIORITY
|
||||
NFT_META_MARK = C.NFT_META_MARK
|
||||
NFT_META_IIF = C.NFT_META_IIF
|
||||
NFT_META_OIF = C.NFT_META_OIF
|
||||
NFT_META_IIFNAME = C.NFT_META_IIFNAME
|
||||
NFT_META_OIFNAME = C.NFT_META_OIFNAME
|
||||
NFT_META_IIFTYPE = C.NFT_META_IIFTYPE
|
||||
NFT_META_OIFTYPE = C.NFT_META_OIFTYPE
|
||||
NFT_META_SKUID = C.NFT_META_SKUID
|
||||
NFT_META_SKGID = C.NFT_META_SKGID
|
||||
NFT_META_NFTRACE = C.NFT_META_NFTRACE
|
||||
NFT_META_RTCLASSID = C.NFT_META_RTCLASSID
|
||||
NFT_META_SECMARK = C.NFT_META_SECMARK
|
||||
NFT_META_NFPROTO = C.NFT_META_NFPROTO
|
||||
NFT_META_L4PROTO = C.NFT_META_L4PROTO
|
||||
NFT_META_BRI_IIFNAME = C.NFT_META_BRI_IIFNAME
|
||||
NFT_META_BRI_OIFNAME = C.NFT_META_BRI_OIFNAME
|
||||
NFT_META_PKTTYPE = C.NFT_META_PKTTYPE
|
||||
NFT_META_CPU = C.NFT_META_CPU
|
||||
NFT_META_IIFGROUP = C.NFT_META_IIFGROUP
|
||||
NFT_META_OIFGROUP = C.NFT_META_OIFGROUP
|
||||
NFT_META_CGROUP = C.NFT_META_CGROUP
|
||||
NFT_META_PRANDOM = C.NFT_META_PRANDOM
|
||||
NFT_RT_CLASSID = C.NFT_RT_CLASSID
|
||||
NFT_RT_NEXTHOP4 = C.NFT_RT_NEXTHOP4
|
||||
NFT_RT_NEXTHOP6 = C.NFT_RT_NEXTHOP6
|
||||
NFT_RT_TCPMSS = C.NFT_RT_TCPMSS
|
||||
NFT_HASH_JENKINS = C.NFT_HASH_JENKINS
|
||||
NFT_HASH_SYM = C.NFT_HASH_SYM
|
||||
NFTA_HASH_UNSPEC = C.NFTA_HASH_UNSPEC
|
||||
NFTA_HASH_SREG = C.NFTA_HASH_SREG
|
||||
NFTA_HASH_DREG = C.NFTA_HASH_DREG
|
||||
NFTA_HASH_LEN = C.NFTA_HASH_LEN
|
||||
NFTA_HASH_MODULUS = C.NFTA_HASH_MODULUS
|
||||
NFTA_HASH_SEED = C.NFTA_HASH_SEED
|
||||
NFTA_HASH_OFFSET = C.NFTA_HASH_OFFSET
|
||||
NFTA_HASH_TYPE = C.NFTA_HASH_TYPE
|
||||
NFTA_META_UNSPEC = C.NFTA_META_UNSPEC
|
||||
NFTA_META_DREG = C.NFTA_META_DREG
|
||||
NFTA_META_KEY = C.NFTA_META_KEY
|
||||
NFTA_META_SREG = C.NFTA_META_SREG
|
||||
NFTA_RT_UNSPEC = C.NFTA_RT_UNSPEC
|
||||
NFTA_RT_DREG = C.NFTA_RT_DREG
|
||||
NFTA_RT_KEY = C.NFTA_RT_KEY
|
||||
NFT_CT_STATE = C.NFT_CT_STATE
|
||||
NFT_CT_DIRECTION = C.NFT_CT_DIRECTION
|
||||
NFT_CT_STATUS = C.NFT_CT_STATUS
|
||||
NFT_CT_MARK = C.NFT_CT_MARK
|
||||
NFT_CT_SECMARK = C.NFT_CT_SECMARK
|
||||
NFT_CT_EXPIRATION = C.NFT_CT_EXPIRATION
|
||||
NFT_CT_HELPER = C.NFT_CT_HELPER
|
||||
NFT_CT_L3PROTOCOL = C.NFT_CT_L3PROTOCOL
|
||||
NFT_CT_SRC = C.NFT_CT_SRC
|
||||
NFT_CT_DST = C.NFT_CT_DST
|
||||
NFT_CT_PROTOCOL = C.NFT_CT_PROTOCOL
|
||||
NFT_CT_PROTO_SRC = C.NFT_CT_PROTO_SRC
|
||||
NFT_CT_PROTO_DST = C.NFT_CT_PROTO_DST
|
||||
NFT_CT_LABELS = C.NFT_CT_LABELS
|
||||
NFT_CT_PKTS = C.NFT_CT_PKTS
|
||||
NFT_CT_BYTES = C.NFT_CT_BYTES
|
||||
NFT_CT_AVGPKT = C.NFT_CT_AVGPKT
|
||||
NFT_CT_ZONE = C.NFT_CT_ZONE
|
||||
NFT_CT_EVENTMASK = C.NFT_CT_EVENTMASK
|
||||
NFTA_CT_UNSPEC = C.NFTA_CT_UNSPEC
|
||||
NFTA_CT_DREG = C.NFTA_CT_DREG
|
||||
NFTA_CT_KEY = C.NFTA_CT_KEY
|
||||
NFTA_CT_DIRECTION = C.NFTA_CT_DIRECTION
|
||||
NFTA_CT_SREG = C.NFTA_CT_SREG
|
||||
NFT_LIMIT_PKTS = C.NFT_LIMIT_PKTS
|
||||
NFT_LIMIT_PKT_BYTES = C.NFT_LIMIT_PKT_BYTES
|
||||
NFT_LIMIT_F_INV = C.NFT_LIMIT_F_INV
|
||||
NFTA_LIMIT_UNSPEC = C.NFTA_LIMIT_UNSPEC
|
||||
NFTA_LIMIT_RATE = C.NFTA_LIMIT_RATE
|
||||
NFTA_LIMIT_UNIT = C.NFTA_LIMIT_UNIT
|
||||
NFTA_LIMIT_BURST = C.NFTA_LIMIT_BURST
|
||||
NFTA_LIMIT_TYPE = C.NFTA_LIMIT_TYPE
|
||||
NFTA_LIMIT_FLAGS = C.NFTA_LIMIT_FLAGS
|
||||
NFTA_LIMIT_PAD = C.NFTA_LIMIT_PAD
|
||||
NFTA_COUNTER_UNSPEC = C.NFTA_COUNTER_UNSPEC
|
||||
NFTA_COUNTER_BYTES = C.NFTA_COUNTER_BYTES
|
||||
NFTA_COUNTER_PACKETS = C.NFTA_COUNTER_PACKETS
|
||||
NFTA_COUNTER_PAD = C.NFTA_COUNTER_PAD
|
||||
NFTA_LOG_UNSPEC = C.NFTA_LOG_UNSPEC
|
||||
NFTA_LOG_GROUP = C.NFTA_LOG_GROUP
|
||||
NFTA_LOG_PREFIX = C.NFTA_LOG_PREFIX
|
||||
NFTA_LOG_SNAPLEN = C.NFTA_LOG_SNAPLEN
|
||||
NFTA_LOG_QTHRESHOLD = C.NFTA_LOG_QTHRESHOLD
|
||||
NFTA_LOG_LEVEL = C.NFTA_LOG_LEVEL
|
||||
NFTA_LOG_FLAGS = C.NFTA_LOG_FLAGS
|
||||
NFTA_QUEUE_UNSPEC = C.NFTA_QUEUE_UNSPEC
|
||||
NFTA_QUEUE_NUM = C.NFTA_QUEUE_NUM
|
||||
NFTA_QUEUE_TOTAL = C.NFTA_QUEUE_TOTAL
|
||||
NFTA_QUEUE_FLAGS = C.NFTA_QUEUE_FLAGS
|
||||
NFTA_QUEUE_SREG_QNUM = C.NFTA_QUEUE_SREG_QNUM
|
||||
NFT_QUOTA_F_INV = C.NFT_QUOTA_F_INV
|
||||
NFT_QUOTA_F_DEPLETED = C.NFT_QUOTA_F_DEPLETED
|
||||
NFTA_QUOTA_UNSPEC = C.NFTA_QUOTA_UNSPEC
|
||||
NFTA_QUOTA_BYTES = C.NFTA_QUOTA_BYTES
|
||||
NFTA_QUOTA_FLAGS = C.NFTA_QUOTA_FLAGS
|
||||
NFTA_QUOTA_PAD = C.NFTA_QUOTA_PAD
|
||||
NFTA_QUOTA_CONSUMED = C.NFTA_QUOTA_CONSUMED
|
||||
NFT_REJECT_ICMP_UNREACH = C.NFT_REJECT_ICMP_UNREACH
|
||||
NFT_REJECT_TCP_RST = C.NFT_REJECT_TCP_RST
|
||||
NFT_REJECT_ICMPX_UNREACH = C.NFT_REJECT_ICMPX_UNREACH
|
||||
NFT_REJECT_ICMPX_NO_ROUTE = C.NFT_REJECT_ICMPX_NO_ROUTE
|
||||
NFT_REJECT_ICMPX_PORT_UNREACH = C.NFT_REJECT_ICMPX_PORT_UNREACH
|
||||
NFT_REJECT_ICMPX_HOST_UNREACH = C.NFT_REJECT_ICMPX_HOST_UNREACH
|
||||
NFT_REJECT_ICMPX_ADMIN_PROHIBITED = C.NFT_REJECT_ICMPX_ADMIN_PROHIBITED
|
||||
NFTA_REJECT_UNSPEC = C.NFTA_REJECT_UNSPEC
|
||||
NFTA_REJECT_TYPE = C.NFTA_REJECT_TYPE
|
||||
NFTA_REJECT_ICMP_CODE = C.NFTA_REJECT_ICMP_CODE
|
||||
NFT_NAT_SNAT = C.NFT_NAT_SNAT
|
||||
NFT_NAT_DNAT = C.NFT_NAT_DNAT
|
||||
NFTA_NAT_UNSPEC = C.NFTA_NAT_UNSPEC
|
||||
NFTA_NAT_TYPE = C.NFTA_NAT_TYPE
|
||||
NFTA_NAT_FAMILY = C.NFTA_NAT_FAMILY
|
||||
NFTA_NAT_REG_ADDR_MIN = C.NFTA_NAT_REG_ADDR_MIN
|
||||
NFTA_NAT_REG_ADDR_MAX = C.NFTA_NAT_REG_ADDR_MAX
|
||||
NFTA_NAT_REG_PROTO_MIN = C.NFTA_NAT_REG_PROTO_MIN
|
||||
NFTA_NAT_REG_PROTO_MAX = C.NFTA_NAT_REG_PROTO_MAX
|
||||
NFTA_NAT_FLAGS = C.NFTA_NAT_FLAGS
|
||||
NFTA_MASQ_UNSPEC = C.NFTA_MASQ_UNSPEC
|
||||
NFTA_MASQ_FLAGS = C.NFTA_MASQ_FLAGS
|
||||
NFTA_MASQ_REG_PROTO_MIN = C.NFTA_MASQ_REG_PROTO_MIN
|
||||
NFTA_MASQ_REG_PROTO_MAX = C.NFTA_MASQ_REG_PROTO_MAX
|
||||
NFTA_REDIR_UNSPEC = C.NFTA_REDIR_UNSPEC
|
||||
NFTA_REDIR_REG_PROTO_MIN = C.NFTA_REDIR_REG_PROTO_MIN
|
||||
NFTA_REDIR_REG_PROTO_MAX = C.NFTA_REDIR_REG_PROTO_MAX
|
||||
NFTA_REDIR_FLAGS = C.NFTA_REDIR_FLAGS
|
||||
NFTA_DUP_UNSPEC = C.NFTA_DUP_UNSPEC
|
||||
NFTA_DUP_SREG_ADDR = C.NFTA_DUP_SREG_ADDR
|
||||
NFTA_DUP_SREG_DEV = C.NFTA_DUP_SREG_DEV
|
||||
NFTA_FWD_UNSPEC = C.NFTA_FWD_UNSPEC
|
||||
NFTA_FWD_SREG_DEV = C.NFTA_FWD_SREG_DEV
|
||||
NFTA_OBJREF_UNSPEC = C.NFTA_OBJREF_UNSPEC
|
||||
NFTA_OBJREF_IMM_TYPE = C.NFTA_OBJREF_IMM_TYPE
|
||||
NFTA_OBJREF_IMM_NAME = C.NFTA_OBJREF_IMM_NAME
|
||||
NFTA_OBJREF_SET_SREG = C.NFTA_OBJREF_SET_SREG
|
||||
NFTA_OBJREF_SET_NAME = C.NFTA_OBJREF_SET_NAME
|
||||
NFTA_OBJREF_SET_ID = C.NFTA_OBJREF_SET_ID
|
||||
NFTA_GEN_UNSPEC = C.NFTA_GEN_UNSPEC
|
||||
NFTA_GEN_ID = C.NFTA_GEN_ID
|
||||
NFTA_GEN_PROC_PID = C.NFTA_GEN_PROC_PID
|
||||
NFTA_GEN_PROC_NAME = C.NFTA_GEN_PROC_NAME
|
||||
NFTA_FIB_UNSPEC = C.NFTA_FIB_UNSPEC
|
||||
NFTA_FIB_DREG = C.NFTA_FIB_DREG
|
||||
NFTA_FIB_RESULT = C.NFTA_FIB_RESULT
|
||||
NFTA_FIB_FLAGS = C.NFTA_FIB_FLAGS
|
||||
NFT_FIB_RESULT_UNSPEC = C.NFT_FIB_RESULT_UNSPEC
|
||||
NFT_FIB_RESULT_OIF = C.NFT_FIB_RESULT_OIF
|
||||
NFT_FIB_RESULT_OIFNAME = C.NFT_FIB_RESULT_OIFNAME
|
||||
NFT_FIB_RESULT_ADDRTYPE = C.NFT_FIB_RESULT_ADDRTYPE
|
||||
NFTA_FIB_F_SADDR = C.NFTA_FIB_F_SADDR
|
||||
NFTA_FIB_F_DADDR = C.NFTA_FIB_F_DADDR
|
||||
NFTA_FIB_F_MARK = C.NFTA_FIB_F_MARK
|
||||
NFTA_FIB_F_IIF = C.NFTA_FIB_F_IIF
|
||||
NFTA_FIB_F_OIF = C.NFTA_FIB_F_OIF
|
||||
NFTA_FIB_F_PRESENT = C.NFTA_FIB_F_PRESENT
|
||||
NFTA_CT_HELPER_UNSPEC = C.NFTA_CT_HELPER_UNSPEC
|
||||
NFTA_CT_HELPER_NAME = C.NFTA_CT_HELPER_NAME
|
||||
NFTA_CT_HELPER_L3PROTO = C.NFTA_CT_HELPER_L3PROTO
|
||||
NFTA_CT_HELPER_L4PROTO = C.NFTA_CT_HELPER_L4PROTO
|
||||
NFTA_OBJ_UNSPEC = C.NFTA_OBJ_UNSPEC
|
||||
NFTA_OBJ_TABLE = C.NFTA_OBJ_TABLE
|
||||
NFTA_OBJ_NAME = C.NFTA_OBJ_NAME
|
||||
NFTA_OBJ_TYPE = C.NFTA_OBJ_TYPE
|
||||
NFTA_OBJ_DATA = C.NFTA_OBJ_DATA
|
||||
NFTA_OBJ_USE = C.NFTA_OBJ_USE
|
||||
NFTA_TRACE_UNSPEC = C.NFTA_TRACE_UNSPEC
|
||||
NFTA_TRACE_TABLE = C.NFTA_TRACE_TABLE
|
||||
NFTA_TRACE_CHAIN = C.NFTA_TRACE_CHAIN
|
||||
NFTA_TRACE_RULE_HANDLE = C.NFTA_TRACE_RULE_HANDLE
|
||||
NFTA_TRACE_TYPE = C.NFTA_TRACE_TYPE
|
||||
NFTA_TRACE_VERDICT = C.NFTA_TRACE_VERDICT
|
||||
NFTA_TRACE_ID = C.NFTA_TRACE_ID
|
||||
NFTA_TRACE_LL_HEADER = C.NFTA_TRACE_LL_HEADER
|
||||
NFTA_TRACE_NETWORK_HEADER = C.NFTA_TRACE_NETWORK_HEADER
|
||||
NFTA_TRACE_TRANSPORT_HEADER = C.NFTA_TRACE_TRANSPORT_HEADER
|
||||
NFTA_TRACE_IIF = C.NFTA_TRACE_IIF
|
||||
NFTA_TRACE_IIFTYPE = C.NFTA_TRACE_IIFTYPE
|
||||
NFTA_TRACE_OIF = C.NFTA_TRACE_OIF
|
||||
NFTA_TRACE_OIFTYPE = C.NFTA_TRACE_OIFTYPE
|
||||
NFTA_TRACE_MARK = C.NFTA_TRACE_MARK
|
||||
NFTA_TRACE_NFPROTO = C.NFTA_TRACE_NFPROTO
|
||||
NFTA_TRACE_POLICY = C.NFTA_TRACE_POLICY
|
||||
NFTA_TRACE_PAD = C.NFTA_TRACE_PAD
|
||||
NFT_TRACETYPE_UNSPEC = C.NFT_TRACETYPE_UNSPEC
|
||||
NFT_TRACETYPE_POLICY = C.NFT_TRACETYPE_POLICY
|
||||
NFT_TRACETYPE_RETURN = C.NFT_TRACETYPE_RETURN
|
||||
NFT_TRACETYPE_RULE = C.NFT_TRACETYPE_RULE
|
||||
NFTA_NG_UNSPEC = C.NFTA_NG_UNSPEC
|
||||
NFTA_NG_DREG = C.NFTA_NG_DREG
|
||||
NFTA_NG_MODULUS = C.NFTA_NG_MODULUS
|
||||
NFTA_NG_TYPE = C.NFTA_NG_TYPE
|
||||
NFTA_NG_OFFSET = C.NFTA_NG_OFFSET
|
||||
NFT_NG_INCREMENTAL = C.NFT_NG_INCREMENTAL
|
||||
NFT_NG_RANDOM = C.NFT_NG_RANDOM
|
||||
)
|
||||
|
||||
type RTCTime C.struct_rtc_time
|
||||
|
||||
type RTCWkAlrm C.struct_rtc_wkalrm
|
||||
|
||||
type RTCPLLInfo C.struct_rtc_pll_info
|
||||
|
|
9
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
9
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
|
@ -50,6 +50,7 @@ includes_Darwin='
|
|||
#include <sys/mount.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
|
@ -172,6 +173,7 @@ struct ltchars {
|
|||
#include <linux/fs.h>
|
||||
#include <linux/keyctl.h>
|
||||
#include <linux/magic.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/random.h>
|
||||
|
@ -191,6 +193,7 @@ struct ltchars {
|
|||
#include <linux/stat.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <net/route.h>
|
||||
#include <asm/termbits.h>
|
||||
|
||||
|
@ -402,7 +405,7 @@ ccflags="$@"
|
|||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
||||
$2 !~ "NLA_TYPE_MASK" &&
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
|
||||
$2 ~ /^SIOC/ ||
|
||||
$2 ~ /^TIOC/ ||
|
||||
$2 ~ /^TCGET/ ||
|
||||
|
@ -428,6 +431,7 @@ ccflags="$@"
|
|||
$2 ~ /^PERF_EVENT_IOC_/ ||
|
||||
$2 ~ /^SECCOMP_MODE_/ ||
|
||||
$2 ~ /^SPLICE_/ ||
|
||||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
||||
$2 ~ /^[A-Z0-9_]+_MAGIC2?$/ ||
|
||||
$2 ~ /^(VM|VMADDR)_/ ||
|
||||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
|
||||
|
@ -436,10 +440,11 @@ ccflags="$@"
|
|||
$2 ~ /^GENL_/ ||
|
||||
$2 ~ /^STATX_/ ||
|
||||
$2 ~ /^UTIME_/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
|
||||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
|
||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
||||
$2 ~ /^FSOPT_/ ||
|
||||
$2 ~ /^WDIOC_/ ||
|
||||
$2 ~ /^NFN/ ||
|
||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
||||
|
|
2
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
2
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
|
@ -240,7 +240,7 @@ foreach my $header (@headers) {
|
|||
|
||||
print <<EOF;
|
||||
// mksysctl_openbsd.pl
|
||||
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
|
||||
|
||||
|
|
4
vendor/golang.org/x/sys/unix/openbsd_pledge.go
generated
vendored
4
vendor/golang.org/x/sys/unix/openbsd_pledge.go
generated
vendored
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SYS_PLEDGE = 108
|
||||
_SYS_PLEDGE = 108
|
||||
)
|
||||
|
||||
// Pledge implements the pledge syscall. For more information see pledge(2).
|
||||
|
@ -30,7 +30,7 @@ func Pledge(promises string, paths []string) error {
|
|||
}
|
||||
pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
|
||||
}
|
||||
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
|
||||
_, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
|
||||
if e != 0 {
|
||||
return e
|
||||
}
|
||||
|
|
86
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
86
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
|
@ -176,6 +176,88 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func xattrPointer(dest []byte) *byte {
|
||||
// It's only when dest is set to NULL that the OS X implementations of
|
||||
// getxattr() and listxattr() return the current sizes of the named attributes.
|
||||
// An empty byte array is not sufficient. To maintain the same behaviour as the
|
||||
// linux implementation, we wrap around the system calls and pass in NULL when
|
||||
// dest is empty.
|
||||
var destp *byte
|
||||
if len(dest) > 0 {
|
||||
destp = &dest[0]
|
||||
}
|
||||
return destp
|
||||
}
|
||||
|
||||
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
|
||||
|
||||
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
|
||||
return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
|
||||
}
|
||||
|
||||
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
|
||||
return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)
|
||||
|
||||
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
// The parameters for the OS X implementation vary slightly compared to the
|
||||
// linux system call, specifically the position parameter:
|
||||
//
|
||||
// linux:
|
||||
// int setxattr(
|
||||
// const char *path,
|
||||
// const char *name,
|
||||
// const void *value,
|
||||
// size_t size,
|
||||
// int flags
|
||||
// );
|
||||
//
|
||||
// darwin:
|
||||
// int setxattr(
|
||||
// const char *path,
|
||||
// const char *name,
|
||||
// void *value,
|
||||
// size_t size,
|
||||
// u_int32_t position,
|
||||
// int options
|
||||
// );
|
||||
//
|
||||
// position specifies the offset within the extended attribute. In the
|
||||
// current implementation, only the resource fork extended attribute makes
|
||||
// use of this argument. For all others, position is reserved. We simply
|
||||
// default to setting it to zero.
|
||||
return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
|
||||
}
|
||||
|
||||
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
|
||||
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys removexattr(path string, attr string, options int) (err error)
|
||||
|
||||
func Removexattr(path string, attr string) (err error) {
|
||||
// We wrap around and explicitly zero out the options provided to the OS X
|
||||
// implementation of removexattr, we do so for interoperability with the
|
||||
// linux variant.
|
||||
return removexattr(path, attr, 0)
|
||||
}
|
||||
|
||||
func Lremovexattr(link string, attr string) (err error) {
|
||||
return removexattr(link, attr, XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
|
||||
|
||||
func Listxattr(path string, dest []byte) (sz int, err error) {
|
||||
return listxattr(path, xattrPointer(dest), len(dest), 0)
|
||||
}
|
||||
|
||||
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
_p0, err := BytePtrFromString(path)
|
||||
if err != nil {
|
||||
|
@ -447,13 +529,9 @@ func Uname(uname *Utsname) error {
|
|||
// Watchevent
|
||||
// Waitevent
|
||||
// Modwatch
|
||||
// Getxattr
|
||||
// Fgetxattr
|
||||
// Setxattr
|
||||
// Fsetxattr
|
||||
// Removexattr
|
||||
// Fremovexattr
|
||||
// Listxattr
|
||||
// Flistxattr
|
||||
// Fsctl
|
||||
// Initgroups
|
||||
|
|
19
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
Normal file
19
vendor/golang.org/x/sys/unix/syscall_darwin_test.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix_test
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Darwin, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
off := 0
|
||||
for i, b := range buf {
|
||||
if b == 0 {
|
||||
result = append(result, string(buf[off:i]))
|
||||
off = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
15
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
15
vendor/golang.org/x/sys/unix/syscall_freebsd_test.go
generated
vendored
|
@ -295,3 +295,18 @@ func TestCapRightsSetAndClear(t *testing.T) {
|
|||
t.Fatalf("Wrong rights set")
|
||||
}
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On FreeBSD, each entry consists of a single byte containing the length
|
||||
// of the attribute name, followed by the attribute name.
|
||||
// The name is _not_ NULL-terminated.
|
||||
func stringsFromByteSlice(buf []byte) []string {
|
||||
var result []string
|
||||
i := 0
|
||||
for i < len(buf) {
|
||||
next := i + 1 + int(buf[i])
|
||||
result = append(result, string(buf[i+1:next]))
|
||||
i = next
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
26
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
26
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
|
@ -148,8 +148,6 @@ func Unlink(path string) error {
|
|||
|
||||
//sys Unlinkat(dirfd int, path string, flags int) (err error)
|
||||
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
|
||||
func Utimes(path string, tv []Timeval) error {
|
||||
if tv == nil {
|
||||
err := utimensat(AT_FDCWD, path, nil, 0)
|
||||
|
@ -207,20 +205,14 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
|
|||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
|
||||
}
|
||||
|
||||
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
|
||||
|
||||
func Futimesat(dirfd int, path string, tv []Timeval) error {
|
||||
pathp, err := BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tv == nil {
|
||||
return futimesat(dirfd, pathp, nil)
|
||||
return futimesat(dirfd, path, nil)
|
||||
}
|
||||
if len(tv) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||
return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||
}
|
||||
|
||||
func Futimes(fd int, tv []Timeval) (err error) {
|
||||
|
@ -1221,12 +1213,10 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
|
|||
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||
//sys Dup(oldfd int) (fd int, err error)
|
||||
//sys Dup3(oldfd int, newfd int, flags int) (err error)
|
||||
//sysnb EpollCreate(size int) (fd int, err error)
|
||||
//sysnb EpollCreate1(flag int) (fd int, err error)
|
||||
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
|
||||
//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
|
||||
//sys Exit(code int) = SYS_EXIT_GROUP
|
||||
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
|
||||
//sys Fchdir(fd int) (err error)
|
||||
//sys Fchmod(fd int, mode uint32) (err error)
|
||||
|
@ -1306,7 +1296,6 @@ func Setgid(uid int) (err error) {
|
|||
//sysnb Uname(buf *Utsname) (err error)
|
||||
//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
|
||||
//sys Unshare(flags int) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys write(fd int, p []byte) (n int, err error)
|
||||
//sys exitThread(code int) (err error) = SYS_EXIT
|
||||
//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
|
||||
|
@ -1356,6 +1345,17 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
|
|||
return int(n), nil
|
||||
}
|
||||
|
||||
//sys faccessat(dirfd int, path string, mode uint32) (err error)
|
||||
|
||||
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
|
||||
if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
|
||||
return EINVAL
|
||||
} else if flags&(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
|
||||
return EOPNOTSUPP
|
||||
}
|
||||
return faccessat(dirfd, path, mode)
|
||||
}
|
||||
|
||||
/*
|
||||
* Unimplemented
|
||||
*/
|
||||
|
|
16
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
16
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
|
@ -10,7 +10,6 @@
|
|||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
@ -51,6 +50,8 @@ func Pipe2(p []int, flags int) (err error) {
|
|||
// 64-bit file system and 32-bit uid calls
|
||||
// (386 default is 32-bit file system and 16-bit uid).
|
||||
//sys Dup2(oldfd int, newfd int) (err error)
|
||||
//sysnb EpollCreate(size int) (fd int, err error)
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
|
||||
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
|
@ -78,12 +79,12 @@ func Pipe2(p []int, flags int) (err error) {
|
|||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
|
||||
//sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
|
||||
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||
//sys Pause() (err error)
|
||||
|
||||
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
||||
|
@ -157,10 +158,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
|||
return setrlimit(resource, &rl)
|
||||
}
|
||||
|
||||
// Underlying system call writes to newoffset via pointer.
|
||||
// Implemented in assembly to avoid allocation.
|
||||
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
|
||||
|
||||
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||
newoffset, errno := seek(fd, offset, whence)
|
||||
if errno != 0 {
|
||||
|
@ -169,11 +166,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
|||
return newoffset, nil
|
||||
}
|
||||
|
||||
// Vsyscalls on amd64.
|
||||
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
|
||||
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||
//sysnb Time(t *Time_t) (tt Time_t, err error)
|
||||
|
||||
//sys Utime(path string, buf *Utimbuf) (err error)
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
|
||||
// On x86 Linux, all the socket calls go through an extra indirection,
|
||||
// I think because the 5-register system call interface can't handle
|
||||
|
@ -206,9 +203,6 @@ const (
|
|||
_SENDMMSG = 20
|
||||
)
|
||||
|
||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||
|
||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
|
||||
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||
if e != 0 {
|
||||
|
|
5
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
5
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
|
@ -7,6 +7,7 @@
|
|||
package unix
|
||||
|
||||
//sys Dup2(oldfd int, newfd int) (err error)
|
||||
//sysnb EpollCreate(size int) (fd int, err error)
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||
|
@ -57,6 +58,7 @@ func Stat(path string, stat *Stat_t) (err error) {
|
|||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
@ -75,6 +77,8 @@ func Stat(path string, stat *Stat_t) (err error) {
|
|||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
|
||||
|
||||
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
|
||||
|
||||
func Gettimeofday(tv *Timeval) (err error) {
|
||||
errno := gettimeofday(tv)
|
||||
if errno != 0 {
|
||||
|
@ -96,6 +100,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
|
|||
}
|
||||
|
||||
//sys Utime(path string, buf *Utimbuf) (err error)
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: sec, Nsec: nsec}
|
||||
|
|
10
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
10
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
|
@ -75,6 +75,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
|||
// 64-bit file system and 32-bit uid calls
|
||||
// (16-bit uid calls are not always supported in newer kernels)
|
||||
//sys Dup2(oldfd int, newfd int) (err error)
|
||||
//sysnb EpollCreate(size int) (fd int, err error)
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
|
@ -86,6 +88,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
|||
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Pause() (err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
|
||||
|
@ -97,11 +100,10 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
|||
//sys Shutdown(fd int, how int) (err error)
|
||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
|
||||
// Vsyscalls on amd64.
|
||||
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
|
||||
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||
//sys Pause() (err error)
|
||||
|
||||
func Time(t *Time_t) (Time_t, error) {
|
||||
var tv Timeval
|
||||
|
@ -123,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error {
|
|||
return Utimes(path, tv)
|
||||
}
|
||||
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||
|
|
54
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
54
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
|
@ -6,6 +6,15 @@
|
|||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func EpollCreate(size int) (fd int, err error) {
|
||||
if size <= 0 {
|
||||
return -1, EINVAL
|
||||
}
|
||||
return EpollCreate1(0)
|
||||
}
|
||||
|
||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||
|
@ -57,6 +66,11 @@ func Lstat(path string, stat *Stat_t) (err error) {
|
|||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
|
||||
func Ustat(dev int, ubuf *Ustat_t) (err error) {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
@ -85,6 +99,18 @@ func setTimeval(sec, usec int64) Timeval {
|
|||
return Timeval{Sec: sec, Usec: usec}
|
||||
}
|
||||
|
||||
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {
|
||||
if tv == nil {
|
||||
return utimensat(dirfd, path, nil, 0)
|
||||
}
|
||||
|
||||
ts := []Timespec{
|
||||
NsecToTimespec(TimevalToNsec(tv[0])),
|
||||
NsecToTimespec(TimevalToNsec(tv[1])),
|
||||
}
|
||||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
}
|
||||
|
||||
func Time(t *Time_t) (Time_t, error) {
|
||||
var tv Timeval
|
||||
err := Gettimeofday(&tv)
|
||||
|
@ -105,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error {
|
|||
return Utimes(path, tv)
|
||||
}
|
||||
|
||||
func utimes(path string, tv *[2]Timeval) (err error) {
|
||||
if tv == nil {
|
||||
return utimensat(AT_FDCWD, path, nil, 0)
|
||||
}
|
||||
|
||||
ts := []Timespec{
|
||||
NsecToTimespec(TimevalToNsec(tv[0])),
|
||||
NsecToTimespec(TimevalToNsec(tv[1])),
|
||||
}
|
||||
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
}
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
if len(p) != 2 {
|
||||
return EINVAL
|
||||
|
@ -161,22 +199,6 @@ func Pause() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove
|
||||
// these when the deprecated syscalls that the syscall package relies on
|
||||
// are removed.
|
||||
const (
|
||||
SYS_GETPGRP = 1060
|
||||
SYS_UTIMES = 1037
|
||||
SYS_FUTIMESAT = 1066
|
||||
SYS_PAUSE = 1061
|
||||
SYS_USTAT = 1070
|
||||
SYS_UTIME = 1063
|
||||
SYS_LCHOWN = 1032
|
||||
SYS_TIME = 1062
|
||||
SYS_EPOLL_CREATE = 1042
|
||||
SYS_EPOLL_WAIT = 1069
|
||||
)
|
||||
|
||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
var ts *Timespec
|
||||
if timeout >= 0 {
|
||||
|
|
16
vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go
generated
vendored
Normal file
16
vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux,!gccgo,386
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Underlying system call writes to newoffset via pointer.
|
||||
// Implemented in assembly to avoid allocation.
|
||||
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
|
||||
|
||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
30
vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux,gccgo,386
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
|
||||
var newoffset int64
|
||||
offsetLow := uint32(offset & 0xffffffff)
|
||||
offsetHigh := uint32((offset >> 32) & 0xffffffff)
|
||||
_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
|
||||
return newoffset, err
|
||||
}
|
||||
|
||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
|
||||
fd, _, err := Syscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
|
||||
return int(fd), err
|
||||
}
|
||||
|
||||
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
|
||||
fd, _, err := RawSyscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
|
||||
return int(fd), err
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue