acme: allow to separate multiple domains with spaces

This change is required to be able to set multiple domains for the same
certificate using env vars.
The change is backward compatible for general use cases but may be
backward incompatible in some edge cases, for example:

- "sftpgo.com,www.sftpgo.com" will work as before
- "sftpgo.com, www.sftpgo.com" will not work anymore

Check the logs to see if you are affected and rename the certificate and key
to fix

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-01-21 18:00:23 +01:00
parent 7b5bebc588
commit 707729ee61
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
2 changed files with 20 additions and 10 deletions

View file

@ -114,7 +114,7 @@ The configuration file contains the following sections:
<details><summary><font size=4>ACME</font></summary> <details><summary><font size=4>ACME</font></summary>
- **"acme"**, Automatic Certificate Management Environment (ACME) protocol configuration. To obtain the certificates the first time you have to configure the ACME protocol and execute the `sftpgo acme run` command. The SFTPGo service will take care of the automatic renewal of certificates for the configured domains. - **"acme"**, Automatic Certificate Management Environment (ACME) protocol configuration. To obtain the certificates the first time you have to configure the ACME protocol and execute the `sftpgo acme run` command. The SFTPGo service will take care of the automatic renewal of certificates for the configured domains.
- `domains`, list of domains for which to obtain certificates. If a single certificate is to be valid for multiple domains specify the names separated by commas, for example: `example.com,www.example.com`. An empty list means that ACME protocol is disabled. Default: empty. - `domains`, list of domains for which to obtain certificates. If a single certificate is to be valid for multiple domains specify the names separated by commas or spaces, for example: `example.com,www.example.com` or `example.com www.example.com`. An empty list means that ACME protocol is disabled. Default: empty.
- `email`, string. Email used for registration and recovery contact. Default: empty. - `email`, string. Email used for registration and recovery contact. Default: empty.
- `key_type`, string. Key type to use for private keys. Supported values: `2048` (RSA 2048), `4096` (RSA 4096), `8192` (RSA 8192), `P256` (EC 256), `P384` (EC 384). Default: `4096` - `key_type`, string. Key type to use for private keys. Supported values: `2048` (RSA 2048), `4096` (RSA 4096), `8192` (RSA 8192), `P256` (EC 256), `P384` (EC 384). Default: `4096`
- `certs_path`, string. Directory, absolute or relative to the configuration directory, to use for storing certificates and related data. - `certs_path`, string. Directory, absolute or relative to the configuration directory, to use for storing certificates and related data.

View file

@ -489,14 +489,7 @@ func (c *Configuration) tryRecoverRegistration(privateKey crypto.PrivateKey) (*r
} }
func (c *Configuration) obtainAndSaveCertificate(client *lego.Client, domain string) error { func (c *Configuration) obtainAndSaveCertificate(client *lego.Client, domain string) error {
var domains []string domains := getDomains(domain)
for _, d := range strings.Split(domain, ",") {
d = strings.TrimSpace(d)
if d != "" {
domains = append(domains, d)
}
}
acmeLog(logger.LevelInfo, "requesting certificates for domains %+v", domains) acmeLog(logger.LevelInfo, "requesting certificates for domains %+v", domains)
request := certificate.ObtainRequest{ request := certificate.ObtainRequest{
Domains: domains, Domains: domains,
@ -655,8 +648,25 @@ func isDomainValid(domain string) (string, bool) {
return domain, isValid return domain, isValid
} }
func getDomains(domain string) []string {
var domains []string
delimiter := ","
if !strings.Contains(domain, ",") && strings.Contains(domain, " ") {
delimiter = " "
}
for _, d := range strings.Split(domain, delimiter) {
d = strings.TrimSpace(d)
if d != "" {
domains = append(domains, d)
}
}
return domains
}
func sanitizedDomain(domain string) string { func sanitizedDomain(domain string) string {
return strings.NewReplacer(":", "_", "*", "_", ",", "_").Replace(domain) return strings.NewReplacer(":", "_", "*", "_", ",", "_", " ", "_").Replace(domain)
} }
func stopScheduler() { func stopScheduler() {