3
0
mirror of https://github.com/ergochat/ergo.git synced 2025-01-12 21:22:38 +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,12 +55,15 @@ 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 {
TLS TLSListenConfig // normal TLS configuration, with a single certificate:
Proxy bool TLS TLSListenConfig
Tor bool // SNI configuration, with multiple certificates:
STSOnly bool `yaml:"sts-only"` TLSCertificates []TLSListenConfig `yaml:"tls-certificates"`
WebSocket bool Proxy bool
HideSTS bool `yaml:"hide-sts"` Tor bool
STSOnly bool `yaml:"sts-only"`
WebSocket bool
HideSTS bool `yaml:"hide-sts"`
} }
type HistoryCutoff uint type HistoryCutoff uint
@ -537,11 +540,10 @@ 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"` WebSockets struct {
WebSockets struct {
AllowedOrigins []string `yaml:"allowed-origins"` AllowedOrigins []string `yaml:"allowed-origins"`
allowedOriginRegexps []*regexp.Regexp allowedOriginRegexps []*regexp.Regexp
} }
@ -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 err != nil { if len(config.TLSCertificates) != 0 {
return nil, &CertKeyError{Err: err} // SNI configuration with multiple certificates
for _, certPairConf := range config.TLSCertificates {
cert, err := loadCertWithLeaf(certPairConf.Cert, certPairConf.Key)
if err != nil {
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 &CertKeyError{Err: err}
return 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