1
0
Fork 0
forked from forgejo/forgejo

[Vendor] update certmagic (#15590)

* update github.com/caddyserver/certmagic v0.12.0 -> v0.13.0

* migrate
This commit is contained in:
6543 2021-04-22 22:42:33 +02:00 committed by GitHub
parent e7fc078891
commit 8ea1d32bea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
177 changed files with 4725 additions and 1984 deletions

View file

@ -37,19 +37,104 @@ func init() {
weakrand.Seed(time.Now().UnixNano())
}
// acmeClient holds state necessary for us to perform
// ACME operations for certificate management. Call
// ACMEManager.newACMEClient() to get a valid one to .
// acmeClient holds state necessary to perform ACME operations
// for certificate management with an ACME account. Call
// ACMEManager.newACMEClientWithAccount() to get a valid one.
type acmeClient struct {
mgr *ACMEManager
acmeClient *acmez.Client
account acme.Account
}
// newACMEClient creates the underlying ACME library client type.
// If useTestCA is true, am.TestCA will be used if it is set;
// otherwise, the primary CA will still be used.
func (am *ACMEManager) newACMEClient(ctx context.Context, useTestCA, interactive bool) (*acmeClient, error) {
// newACMEClientWithAccount creates an ACME client ready to use with an account, including
// loading one from storage or registering a new account with the CA if necessary. If
// useTestCA is true, am.TestCA will be used if set; otherwise, the primary CA will be used.
func (am *ACMEManager) newACMEClientWithAccount(ctx context.Context, useTestCA, interactive bool) (*acmeClient, error) {
// first, get underlying ACME client
client, err := am.newACMEClient(useTestCA)
if err != nil {
return nil, err
}
// look up or create the ACME account
var account acme.Account
if am.AccountKeyPEM != "" {
account, err = am.GetAccount(ctx, []byte(am.AccountKeyPEM))
} else {
account, err = am.getAccount(client.Directory, am.Email)
}
if err != nil {
return nil, fmt.Errorf("getting ACME account: %v", err)
}
// register account if it is new
if account.Status == "" {
if am.NewAccountFunc != nil {
account, err = am.NewAccountFunc(ctx, am, account)
if err != nil {
return nil, fmt.Errorf("account pre-registration callback: %v", err)
}
}
// agree to terms
if interactive {
if !am.Agreed {
var termsURL string
dir, err := client.GetDirectory(ctx)
if err != nil {
return nil, fmt.Errorf("getting directory: %w", err)
}
if dir.Meta != nil {
termsURL = dir.Meta.TermsOfService
}
if termsURL != "" {
am.Agreed = am.askUserAgreement(termsURL)
if !am.Agreed {
return nil, fmt.Errorf("user must agree to CA terms")
}
}
}
} else {
// can't prompt a user who isn't there; they should
// have reviewed the terms beforehand
am.Agreed = true
}
account.TermsOfServiceAgreed = am.Agreed
// associate account with external binding, if configured
if am.ExternalAccount != nil {
err := account.SetExternalAccountBinding(ctx, client.Client, *am.ExternalAccount)
if err != nil {
return nil, err
}
}
// create account
account, err = client.NewAccount(ctx, account)
if err != nil {
return nil, fmt.Errorf("registering account %v with server: %w", account.Contact, err)
}
// persist the account to storage
err = am.saveAccount(client.Directory, account)
if err != nil {
return nil, fmt.Errorf("could not save account %v: %v", account.Contact, err)
}
}
c := &acmeClient{
mgr: am,
acmeClient: client,
account: account,
}
return c, nil
}
// newACMEClient creates a new underlying ACME client using the settings in am,
// independent of any particular ACME account. If useTestCA is true, am.TestCA
// will be used if it is set; otherwise, the primary CA will be used.
func (am *ACMEManager) newACMEClient(useTestCA bool) (*acmez.Client, error) {
// ensure defaults are filled in
var caURL string
if useTestCA {
@ -78,12 +163,6 @@ func (am *ACMEManager) newACMEClient(ctx context.Context, useTestCA, interactive
return nil, fmt.Errorf("%s: insecure CA URL (HTTPS required)", caURL)
}
// look up or create the ACME account
account, err := am.getAccount(caURL, am.Email)
if err != nil {
return nil, fmt.Errorf("getting ACME account: %v", err)
}
// set up the dialers and resolver for the ACME client's HTTP client
dialer := &net.Dialer{
Timeout: 30 * time.Second,
@ -153,12 +232,12 @@ func (am *ACMEManager) newACMEClient(ctx context.Context, useTestCA, interactive
useHTTPPort = am.AltHTTPPort
}
client.ChallengeSolvers[acme.ChallengeTypeHTTP01] = distributedSolver{
acmeManager: am,
storage: am.config.Storage,
storageKeyIssuerPrefix: am.storageKeyCAPrefix(client.Directory),
solver: &httpSolver{
acmeManager: am,
address: net.JoinHostPort(am.ListenHost, strconv.Itoa(useHTTPPort)),
},
caURL: client.Directory,
}
}
@ -172,12 +251,12 @@ func (am *ACMEManager) newACMEClient(ctx context.Context, useTestCA, interactive
useTLSALPNPort = am.AltTLSALPNPort
}
client.ChallengeSolvers[acme.ChallengeTypeTLSALPN01] = distributedSolver{
acmeManager: am,
storage: am.config.Storage,
storageKeyIssuerPrefix: am.storageKeyCAPrefix(client.Directory),
solver: &tlsALPNSolver{
config: am.config,
address: net.JoinHostPort(am.ListenHost, strconv.Itoa(useTLSALPNPort)),
},
caURL: client.Directory,
}
}
} else {
@ -185,68 +264,26 @@ func (am *ACMEManager) newACMEClient(ctx context.Context, useTestCA, interactive
client.ChallengeSolvers[acme.ChallengeTypeDNS01] = am.DNS01Solver
}
// register account if it is new
if account.Status == "" {
if am.NewAccountFunc != nil {
err = am.NewAccountFunc(ctx, am, account)
if err != nil {
return nil, fmt.Errorf("account pre-registration callback: %v", err)
}
}
// agree to terms
if interactive {
if !am.Agreed {
var termsURL string
dir, err := client.GetDirectory(ctx)
if err != nil {
return nil, fmt.Errorf("getting directory: %w", err)
}
if dir.Meta != nil {
termsURL = dir.Meta.TermsOfService
}
if termsURL != "" {
am.Agreed = am.askUserAgreement(termsURL)
if !am.Agreed {
return nil, fmt.Errorf("user must agree to CA terms")
}
}
}
} else {
// can't prompt a user who isn't there; they should
// have reviewed the terms beforehand
am.Agreed = true
}
account.TermsOfServiceAgreed = am.Agreed
// associate account with external binding, if configured
if am.ExternalAccount != nil {
err := account.SetExternalAccountBinding(ctx, client.Client, *am.ExternalAccount)
if err != nil {
return nil, err
}
}
// create account
account, err = client.NewAccount(ctx, account)
if err != nil {
return nil, fmt.Errorf("registering account with server: %w", err)
}
// persist the account to storage
err = am.saveAccount(caURL, account)
if err != nil {
return nil, fmt.Errorf("could not save account: %v", err)
}
// wrap solvers in our wrapper so that we can keep track of challenge
// info: this is useful for solving challenges globally as a process;
// for example, usually there is only one process that can solve the
// HTTP and TLS-ALPN challenges, and only one server in that process
// that can bind the necessary port(s), so if a server listening on
// a different port needed a certificate, it would have to know about
// the other server listening on that port, and somehow convey its
// challenge info or share its config, but this isn't always feasible;
// what the wrapper does is it accesses a global challenge memory so
// that unrelated servers in this process can all solve each others'
// challenges without having to know about each other - Caddy's admin
// endpoint uses this functionality since it and the HTTP/TLS modules
// do not know about each other
// (doing this here in a separate loop ensures that even if we expose
// solver config to users later, we will even wrap their own solvers)
for name, solver := range client.ChallengeSolvers {
client.ChallengeSolvers[name] = solverWrapper{solver}
}
c := &acmeClient{
mgr: am,
acmeClient: client,
account: account,
}
return c, nil
return client, nil
}
func (c *acmeClient) throttle(ctx context.Context, names []string) error {
@ -325,7 +362,7 @@ var (
// RateLimitEvents is how many new events can be allowed
// in RateLimitEventsWindow.
RateLimitEvents = 10
RateLimitEvents = 20
// RateLimitEventsWindow is the size of the sliding
// window that throttles events.