3
0
mirror of https://github.com/ergochat/ergo.git synced 2025-01-03 08:32:43 +01:00

support SNI

This commit is contained in:
Shivaram Lingamneni 2021-04-07 22:49:33 -04:00
parent f9c1a00b91
commit aecb28a616

View File

@ -55,7 +55,10 @@ type TLSListenConfig struct {
// This is the YAML-deserializable type of the value of the `Server.Listeners` map // This is the YAML-deserializable type of the value of the `Server.Listeners` map
type listenerConfigBlock struct { type listenerConfigBlock struct {
// normal TLS configuration, with a single certificate:
TLS TLSListenConfig TLS TLSListenConfig
// SNI configuration, with multiple certificates:
TLSCertificates []TLSListenConfig `yaml:"tls-certificates"`
Proxy bool Proxy bool
Tor bool Tor bool
STSOnly bool `yaml:"sts-only"` STSOnly bool `yaml:"sts-only"`
@ -537,7 +540,6 @@ type Config struct {
passwordBytes []byte passwordBytes []byte
Name string Name string
nameCasefolded string nameCasefolded string
// Listeners is the new style for configuring listeners:
Listeners map[string]listenerConfigBlock Listeners map[string]listenerConfigBlock
UnixBindMode os.FileMode `yaml:"unix-bind-mode"` UnixBindMode os.FileMode `yaml:"unix-bind-mode"`
TorListeners TorListenersConfig `yaml:"tor-listeners"` TorListeners TorListenersConfig `yaml:"tor-listeners"`
@ -846,13 +848,30 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
return operators, nil return operators, nil
} }
func loadTlsConfig(config TLSListenConfig, webSocket bool) (tlsConfig *tls.Config, err error) { func loadTlsConfig(config listenerConfigBlock) (tlsConfig *tls.Config, err error) {
cert, err := loadCertWithLeaf(config.Cert, config.Key) var certificates []tls.Certificate
if len(config.TLSCertificates) != 0 {
// SNI configuration with multiple certificates
for _, certPairConf := range config.TLSCertificates {
cert, err := loadCertWithLeaf(certPairConf.Cert, certPairConf.Key)
if err != nil { if err != nil {
return nil, &CertKeyError{Err: err} return nil, err
}
certificates = append(certificates, cert)
}
} else if config.TLS.Cert != "" {
// normal configuration with one certificate
cert, err := loadCertWithLeaf(config.TLS.Cert, config.TLS.Key)
if err != nil {
return nil, err
}
certificates = append(certificates, cert)
} else {
// plaintext!
return nil, nil
} }
clientAuth := tls.RequestClientCert clientAuth := tls.RequestClientCert
if webSocket { if config.WebSocket {
// if Chrome receives a server request for a client certificate // if Chrome receives a server request for a client certificate
// on a websocket connection, it will immediately disconnect: // on a websocket connection, it will immediately disconnect:
// https://bugs.chromium.org/p/chromium/issues/detail?id=329884 // https://bugs.chromium.org/p/chromium/issues/detail?id=329884
@ -860,7 +879,7 @@ func loadTlsConfig(config TLSListenConfig, webSocket bool) (tlsConfig *tls.Confi
clientAuth = tls.NoClientCert clientAuth = tls.NoClientCert
} }
result := tls.Config{ result := tls.Config{
Certificates: []tls.Certificate{cert}, Certificates: certificates,
ClientAuth: clientAuth, ClientAuth: clientAuth,
} }
return &result, nil return &result, nil
@ -895,12 +914,9 @@ func (conf *Config) prepareListeners() (err error) {
if lconf.STSOnly && !conf.Server.STS.Enabled { if lconf.STSOnly && !conf.Server.STS.Enabled {
return fmt.Errorf("%s is configured as a STS-only listener, but STS is disabled", addr) return fmt.Errorf("%s is configured as a STS-only listener, but STS is disabled", addr)
} }
if block.TLS.Cert != "" { lconf.TLSConfig, err = loadTlsConfig(block)
tlsConfig, err := loadTlsConfig(block.TLS, block.WebSocket)
if err != nil { if err != nil {
return err return &CertKeyError{Err: err}
}
lconf.TLSConfig = tlsConfig
} }
lconf.RequireProxy = block.TLS.Proxy || block.Proxy lconf.RequireProxy = block.TLS.Proxy || block.Proxy
lconf.WebSocket = block.WebSocket lconf.WebSocket = block.WebSocket