|
@@ -41,6 +41,12 @@ type TLSListenConfig struct {
|
41
|
41
|
Key string
|
42
|
42
|
}
|
43
|
43
|
|
|
44
|
+// This is the YAML-deserializable type of the value of the `Server.Listeners` map
|
|
45
|
+type listenerConfigBlock struct {
|
|
46
|
+ TLS TLSListenConfig
|
|
47
|
+ Tor bool
|
|
48
|
+}
|
|
49
|
+
|
44
|
50
|
// listenerConfig is the config governing a particular listener (bound address),
|
45
|
51
|
// in particular whether it has TLS or Tor (or both) enabled.
|
46
|
52
|
type listenerConfig struct {
|
|
@@ -252,8 +258,8 @@ type FakelagConfig struct {
|
252
|
258
|
}
|
253
|
259
|
|
254
|
260
|
type TorListenersConfig struct {
|
255
|
|
- Listeners []string
|
256
|
|
- RequireSasl bool `yaml:"require-sasl"`
|
|
261
|
+ Listeners []string // legacy only
|
|
262
|
+ RequireSasl bool `yaml:"require-sasl"`
|
257
|
263
|
Vhost string
|
258
|
264
|
MaxConnections int `yaml:"max-connections"`
|
259
|
265
|
ThrottleDuration time.Duration `yaml:"throttle-duration"`
|
|
@@ -267,15 +273,19 @@ type Config struct {
|
267
|
273
|
}
|
268
|
274
|
|
269
|
275
|
Server struct {
|
270
|
|
- Password string
|
271
|
|
- passwordBytes []byte
|
272
|
|
- Name string
|
273
|
|
- nameCasefolded string
|
274
|
|
- Listen []string
|
275
|
|
- UnixBindMode os.FileMode `yaml:"unix-bind-mode"`
|
276
|
|
- TLSListeners map[string]TLSListenConfig `yaml:"tls-listeners"`
|
277
|
|
- TorListeners TorListenersConfig `yaml:"tor-listeners"`
|
278
|
|
- listeners map[string]listenerConfig
|
|
276
|
+ Password string
|
|
277
|
+ passwordBytes []byte
|
|
278
|
+ Name string
|
|
279
|
+ nameCasefolded string
|
|
280
|
+ // Listeners is the new style for configuring listeners:
|
|
281
|
+ Listeners map[string]listenerConfigBlock
|
|
282
|
+ UnixBindMode os.FileMode `yaml:"unix-bind-mode"`
|
|
283
|
+ TorListeners TorListenersConfig `yaml:"tor-listeners"`
|
|
284
|
+ // Listen and TLSListeners are the legacy style:
|
|
285
|
+ Listen []string
|
|
286
|
+ TLSListeners map[string]TLSListenConfig `yaml:"tls-listeners"`
|
|
287
|
+ // either way, the result is this:
|
|
288
|
+ trueListeners map[string]listenerConfig
|
279
|
289
|
STS STSConfig
|
280
|
290
|
CheckIdent bool `yaml:"check-ident"`
|
281
|
291
|
MOTD string
|
|
@@ -481,37 +491,63 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
|
481
|
491
|
return operators, nil
|
482
|
492
|
}
|
483
|
493
|
|
484
|
|
-// prepareListeners populates Config.Server.listeners
|
485
|
|
-func (conf *Config) prepareListeners() (err error) {
|
486
|
|
- torListeners := make(map[string]bool, len(conf.Server.TorListeners.Listeners))
|
487
|
|
- for _, addr := range conf.Server.TorListeners.Listeners {
|
488
|
|
- torListeners[addr] = true
|
|
494
|
+func loadTlsConfig(config TLSListenConfig) (tlsConfig *tls.Config, err error) {
|
|
495
|
+ cert, err := tls.LoadX509KeyPair(config.Cert, config.Key)
|
|
496
|
+ if err != nil {
|
|
497
|
+ return nil, ErrInvalidCertKeyPair
|
489
|
498
|
}
|
|
499
|
+ result := tls.Config{
|
|
500
|
+ Certificates: []tls.Certificate{cert},
|
|
501
|
+ ClientAuth: tls.RequestClientCert,
|
|
502
|
+ }
|
|
503
|
+ return &result, nil
|
|
504
|
+}
|
490
|
505
|
|
491
|
|
- conf.Server.listeners = make(map[string]listenerConfig, len(conf.Server.Listen))
|
492
|
|
-
|
493
|
|
- for _, addr := range conf.Server.Listen {
|
494
|
|
- var lconf listenerConfig
|
495
|
|
- lconf.IsTor = torListeners[addr]
|
496
|
|
- tlsListenConf, ok := conf.Server.TLSListeners[addr]
|
497
|
|
- if ok {
|
498
|
|
- cert, err := tls.LoadX509KeyPair(tlsListenConf.Cert, tlsListenConf.Key)
|
499
|
|
- if err != nil {
|
500
|
|
- return ErrInvalidCertKeyPair
|
|
506
|
+// prepareListeners populates Config.Server.trueListeners
|
|
507
|
+func (conf *Config) prepareListeners() (err error) {
|
|
508
|
+ listeners := make(map[string]listenerConfig)
|
|
509
|
+ if 0 < len(conf.Server.Listeners) {
|
|
510
|
+ for addr, block := range conf.Server.Listeners {
|
|
511
|
+ var lconf listenerConfig
|
|
512
|
+ lconf.IsTor = block.Tor
|
|
513
|
+ if block.TLS.Cert != "" {
|
|
514
|
+ tlsConfig, err := loadTlsConfig(block.TLS)
|
|
515
|
+ if err != nil {
|
|
516
|
+ return err
|
|
517
|
+ }
|
|
518
|
+ lconf.TLSConfig = tlsConfig
|
501
|
519
|
}
|
502
|
|
- tlsConfig := tls.Config{
|
503
|
|
- Certificates: []tls.Certificate{cert},
|
504
|
|
- ClientAuth: tls.RequestClientCert,
|
|
520
|
+ listeners[addr] = lconf
|
|
521
|
+ }
|
|
522
|
+ } else if 0 < len(conf.Server.Listen) {
|
|
523
|
+ log.Printf("WARNING: configuring listeners via the legacy `server.listen` config option")
|
|
524
|
+ log.Printf("This will be removed in a later release: you should update to use `server.listeners`")
|
|
525
|
+ torListeners := make(map[string]bool, len(conf.Server.TorListeners.Listeners))
|
|
526
|
+ for _, addr := range conf.Server.TorListeners.Listeners {
|
|
527
|
+ torListeners[addr] = true
|
|
528
|
+ }
|
|
529
|
+ for _, addr := range conf.Server.Listen {
|
|
530
|
+ var lconf listenerConfig
|
|
531
|
+ lconf.IsTor = torListeners[addr]
|
|
532
|
+ tlsListenConf, ok := conf.Server.TLSListeners[addr]
|
|
533
|
+ if ok {
|
|
534
|
+ tlsConfig, err := loadTlsConfig(tlsListenConf)
|
|
535
|
+ if err != nil {
|
|
536
|
+ return err
|
|
537
|
+ }
|
|
538
|
+ lconf.TLSConfig = tlsConfig
|
505
|
539
|
}
|
506
|
|
- lconf.TLSConfig = &tlsConfig
|
|
540
|
+ listeners[addr] = lconf
|
507
|
541
|
}
|
508
|
|
- conf.Server.listeners[addr] = lconf
|
|
542
|
+ } else {
|
|
543
|
+ return fmt.Errorf("No listeners were configured")
|
509
|
544
|
}
|
|
545
|
+ conf.Server.trueListeners = listeners
|
510
|
546
|
return nil
|
511
|
547
|
}
|
512
|
548
|
|
513
|
|
-// LoadConfig loads the given YAML configuration file.
|
514
|
|
-func LoadConfig(filename string) (config *Config, err error) {
|
|
549
|
+// LoadRawConfig loads the config without doing any consistency checks or postprocessing
|
|
550
|
+func LoadRawConfig(filename string) (config *Config, err error) {
|
515
|
551
|
data, err := ioutil.ReadFile(filename)
|
516
|
552
|
if err != nil {
|
517
|
553
|
return nil, err
|
|
@@ -521,6 +557,15 @@ func LoadConfig(filename string) (config *Config, err error) {
|
521
|
557
|
if err != nil {
|
522
|
558
|
return nil, err
|
523
|
559
|
}
|
|
560
|
+ return
|
|
561
|
+}
|
|
562
|
+
|
|
563
|
+// LoadConfig loads the given YAML configuration file.
|
|
564
|
+func LoadConfig(filename string) (config *Config, err error) {
|
|
565
|
+ config, err = LoadRawConfig(filename)
|
|
566
|
+ if err != nil {
|
|
567
|
+ return nil, err
|
|
568
|
+ }
|
524
|
569
|
|
525
|
570
|
config.Filename = filename
|
526
|
571
|
|
|
@@ -536,9 +581,6 @@ func LoadConfig(filename string) (config *Config, err error) {
|
536
|
581
|
if config.Datastore.Path == "" {
|
537
|
582
|
return nil, ErrDatastorePathMissing
|
538
|
583
|
}
|
539
|
|
- if len(config.Server.Listen) == 0 {
|
540
|
|
- return nil, ErrNoListenersDefined
|
541
|
|
- }
|
542
|
584
|
//dan: automagically fix identlen until a few releases in the future (from now, 0.12.0), being a newly-introduced limit
|
543
|
585
|
if config.Limits.IdentLen < 1 {
|
544
|
586
|
config.Limits.IdentLen = 20
|