|
@@ -39,13 +39,9 @@ var (
|
39
|
39
|
// supportedChannelModesString acts as a cache for when we introduce users
|
40
|
40
|
supportedChannelModesString = modes.SupportedChannelModes.String()
|
41
|
41
|
|
42
|
|
- // SupportedCapabilities are the caps we advertise.
|
43
|
|
- // MaxLine, SASL and STS may be unset during server startup / rehash.
|
44
|
|
- SupportedCapabilities = caps.NewCompleteSet()
|
45
|
|
-
|
46
|
|
- // CapValues are the actual values we advertise to v3.2 clients.
|
47
|
|
- // actual values are set during server startup.
|
48
|
|
- CapValues = caps.NewValues()
|
|
42
|
+ // whitelist of caps to serve on the STS-only listener. In particular,
|
|
43
|
+ // never advertise SASL, to discourage people from sending their passwords:
|
|
44
|
+ stsOnlyCaps = caps.NewSet(caps.STS, caps.MessageTags, caps.ServerTime, caps.LabeledResponse, caps.Nope)
|
49
|
45
|
)
|
50
|
46
|
|
51
|
47
|
// ListenerWrapper wraps a listener so it can be safely reconfigured or stopped
|
|
@@ -340,6 +336,11 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
340
|
336
|
return
|
341
|
337
|
}
|
342
|
338
|
|
|
339
|
+ if c.isSTSOnly {
|
|
340
|
+ server.playRegistrationBurst(session)
|
|
341
|
+ return true
|
|
342
|
+ }
|
|
343
|
+
|
343
|
344
|
// client MUST send PASS if necessary, or authenticate with SASL if necessary,
|
344
|
345
|
// before completing the other registration commands
|
345
|
346
|
authOutcome := c.isAuthorized(server.Config())
|
|
@@ -407,6 +408,13 @@ func (server *Server) playRegistrationBurst(session *Session) {
|
407
|
408
|
//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
|
408
|
409
|
session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
|
409
|
410
|
|
|
411
|
+ if c.isSTSOnly {
|
|
412
|
+ for _, line := range server.Config().Server.STS.bannerLines {
|
|
413
|
+ c.Notice(line)
|
|
414
|
+ }
|
|
415
|
+ return
|
|
416
|
+ }
|
|
417
|
+
|
410
|
418
|
rb := NewResponseBuffer(session)
|
411
|
419
|
server.RplISupport(c, rb)
|
412
|
420
|
server.Lusers(c, rb)
|
|
@@ -623,23 +631,17 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
623
|
631
|
server.logger.Debug("server", "Regenerating HELP indexes for new languages")
|
624
|
632
|
server.helpIndexManager.GenerateIndices(config.languageManager)
|
625
|
633
|
|
626
|
|
- currentLanguageValue, _ := CapValues.Get(caps.Languages)
|
627
|
|
- newLanguageValue := config.languageManager.CapValue()
|
628
|
|
- if currentLanguageValue != newLanguageValue {
|
|
634
|
+ if oldConfig != nil && config.Server.capValues[caps.Languages] != oldConfig.Server.capValues[caps.Languages] {
|
629
|
635
|
updatedCaps.Add(caps.Languages)
|
630
|
|
- CapValues.Set(caps.Languages, newLanguageValue)
|
631
|
636
|
}
|
632
|
637
|
|
633
|
638
|
// SASL
|
634
|
639
|
authPreviouslyEnabled := oldConfig != nil && oldConfig.Accounts.AuthenticationEnabled
|
635
|
640
|
if config.Accounts.AuthenticationEnabled && (oldConfig == nil || !authPreviouslyEnabled) {
|
636
|
641
|
// enabling SASL
|
637
|
|
- SupportedCapabilities.Enable(caps.SASL)
|
638
|
|
- CapValues.Set(caps.SASL, "PLAIN,EXTERNAL")
|
639
|
642
|
addedCaps.Add(caps.SASL)
|
640
|
643
|
} else if !config.Accounts.AuthenticationEnabled && (oldConfig == nil || authPreviouslyEnabled) {
|
641
|
644
|
// disabling SASL
|
642
|
|
- SupportedCapabilities.Disable(caps.SASL)
|
643
|
645
|
removedCaps.Add(caps.SASL)
|
644
|
646
|
}
|
645
|
647
|
|
|
@@ -661,39 +663,17 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
661
|
663
|
server.channels.loadRegisteredChannels()
|
662
|
664
|
}
|
663
|
665
|
|
664
|
|
- // MaxLine
|
665
|
|
- if config.Limits.LineLen.Rest != 512 {
|
666
|
|
- SupportedCapabilities.Enable(caps.MaxLine)
|
667
|
|
- value := fmt.Sprintf("%d", config.Limits.LineLen.Rest)
|
668
|
|
- CapValues.Set(caps.MaxLine, value)
|
669
|
|
- } else {
|
670
|
|
- SupportedCapabilities.Disable(caps.MaxLine)
|
671
|
|
- }
|
672
|
|
-
|
673
|
666
|
// STS
|
674
|
667
|
stsPreviouslyEnabled := oldConfig != nil && oldConfig.Server.STS.Enabled
|
675
|
|
- stsValue := config.Server.STS.Value()
|
676
|
|
- stsDisabledByRehash := false
|
677
|
|
- stsCurrentCapValue, _ := CapValues.Get(caps.STS)
|
|
668
|
+ stsValue := config.Server.capValues[caps.STS]
|
|
669
|
+ stsCurrentCapValue := ""
|
|
670
|
+ if oldConfig != nil {
|
|
671
|
+ stsCurrentCapValue = oldConfig.Server.capValues[caps.STS]
|
|
672
|
+ }
|
678
|
673
|
server.logger.Debug("server", "STS Vals", stsCurrentCapValue, stsValue, fmt.Sprintf("server[%v] config[%v]", stsPreviouslyEnabled, config.Server.STS.Enabled))
|
679
|
|
- if config.Server.STS.Enabled {
|
680
|
|
- // enabling STS
|
681
|
|
- SupportedCapabilities.Enable(caps.STS)
|
682
|
|
- if !stsPreviouslyEnabled {
|
683
|
|
- addedCaps.Add(caps.STS)
|
684
|
|
- CapValues.Set(caps.STS, stsValue)
|
685
|
|
- } else if stsValue != stsCurrentCapValue {
|
686
|
|
- // STS policy updated
|
687
|
|
- CapValues.Set(caps.STS, stsValue)
|
688
|
|
- updatedCaps.Add(caps.STS)
|
689
|
|
- }
|
690
|
|
- } else {
|
691
|
|
- // disabling STS
|
692
|
|
- SupportedCapabilities.Disable(caps.STS)
|
693
|
|
- if stsPreviouslyEnabled {
|
694
|
|
- removedCaps.Add(caps.STS)
|
695
|
|
- stsDisabledByRehash = true
|
696
|
|
- }
|
|
674
|
+ if (config.Server.STS.Enabled != stsPreviouslyEnabled) || (stsValue != stsCurrentCapValue) {
|
|
675
|
+ // XXX: STS is always removed by CAP NEW sts=duration=0, not CAP DEL
|
|
676
|
+ addedCaps.Add(caps.STS)
|
697
|
677
|
}
|
698
|
678
|
|
699
|
679
|
// resize history buffers as needed
|
|
@@ -708,42 +688,35 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
708
|
688
|
|
709
|
689
|
// burst new and removed caps
|
710
|
690
|
var capBurstSessions []*Session
|
711
|
|
- added := make(map[caps.Version]string)
|
712
|
|
- var removed string
|
|
691
|
+ added := make(map[caps.Version][]string)
|
|
692
|
+ var removed []string
|
713
|
693
|
|
714
|
694
|
// updated caps get DEL'd and then NEW'd
|
715
|
695
|
// so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
|
716
|
|
- server.logger.Debug("server", "Updated Caps", updatedCaps.String(caps.Cap301, CapValues))
|
|
696
|
+ server.logger.Debug("server", "Updated Caps", strings.Join(updatedCaps.String(caps.Cap301, config.Server.capValues), " "))
|
717
|
697
|
addedCaps.Union(updatedCaps)
|
718
|
698
|
removedCaps.Union(updatedCaps)
|
719
|
699
|
|
720
|
700
|
if !addedCaps.Empty() || !removedCaps.Empty() {
|
721
|
701
|
capBurstSessions = server.clients.AllWithCapsNotify()
|
722
|
702
|
|
723
|
|
- added[caps.Cap301] = addedCaps.String(caps.Cap301, CapValues)
|
724
|
|
- added[caps.Cap302] = addedCaps.String(caps.Cap302, CapValues)
|
|
703
|
+ added[caps.Cap301] = addedCaps.String(caps.Cap301, config.Server.capValues)
|
|
704
|
+ added[caps.Cap302] = addedCaps.String(caps.Cap302, config.Server.capValues)
|
725
|
705
|
// removed never has values, so we leave it as Cap301
|
726
|
|
- removed = removedCaps.String(caps.Cap301, CapValues)
|
|
706
|
+ removed = removedCaps.String(caps.Cap301, config.Server.capValues)
|
727
|
707
|
}
|
728
|
708
|
|
729
|
709
|
for _, sSession := range capBurstSessions {
|
730
|
|
- if stsDisabledByRehash {
|
731
|
|
- // remove STS policy
|
732
|
|
- //TODO(dan): this is an ugly hack. we can write this better.
|
733
|
|
- stsPolicy := "sts=duration=0"
|
734
|
|
- if !addedCaps.Empty() {
|
735
|
|
- added[caps.Cap302] = added[caps.Cap302] + " " + stsPolicy
|
736
|
|
- } else {
|
737
|
|
- addedCaps.Enable(caps.STS)
|
738
|
|
- added[caps.Cap302] = stsPolicy
|
739
|
|
- }
|
740
|
|
- }
|
741
|
710
|
// DEL caps and then send NEW ones so that updated caps get removed/added correctly
|
742
|
711
|
if !removedCaps.Empty() {
|
743
|
|
- sSession.Send(nil, server.name, "CAP", sSession.client.Nick(), "DEL", removed)
|
|
712
|
+ for _, capStr := range removed {
|
|
713
|
+ sSession.Send(nil, server.name, "CAP", sSession.client.Nick(), "DEL", capStr)
|
|
714
|
+ }
|
744
|
715
|
}
|
745
|
716
|
if !addedCaps.Empty() {
|
746
|
|
- sSession.Send(nil, server.name, "CAP", sSession.client.Nick(), "NEW", added[sSession.capVersion])
|
|
717
|
+ for _, capStr := range added[sSession.capVersion] {
|
|
718
|
+ sSession.Send(nil, server.name, "CAP", sSession.client.Nick(), "NEW", capStr)
|
|
719
|
+ }
|
747
|
720
|
}
|
748
|
721
|
}
|
749
|
722
|
|
|
@@ -905,15 +878,11 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
905
|
878
|
}
|
906
|
879
|
}
|
907
|
880
|
|
|
881
|
+ publicPlaintextListener := ""
|
908
|
882
|
// create new listeners that were not previously configured
|
909
|
|
- numTlsListeners := 0
|
910
|
|
- hasStandardTlsListener := false
|
911
|
883
|
for newAddr, newConfig := range config.Server.trueListeners {
|
912
|
|
- if newConfig.TLSConfig != nil {
|
913
|
|
- numTlsListeners += 1
|
914
|
|
- if strings.HasSuffix(newAddr, ":6697") {
|
915
|
|
- hasStandardTlsListener = true
|
916
|
|
- }
|
|
884
|
+ if strings.HasPrefix(newAddr, ":") && !newConfig.IsTor && !newConfig.IsSTSOnly && newConfig.TLSConfig == nil {
|
|
885
|
+ publicPlaintextListener = newAddr
|
917
|
886
|
}
|
918
|
887
|
_, exists := server.listeners[newAddr]
|
919
|
888
|
if !exists {
|
|
@@ -929,12 +898,8 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
929
|
898
|
}
|
930
|
899
|
}
|
931
|
900
|
|
932
|
|
- if numTlsListeners == 0 {
|
933
|
|
- server.logger.Warning("server", "You are not exposing an SSL/TLS listening port. You should expose at least one port (typically 6697) to accept TLS connections")
|
934
|
|
- }
|
935
|
|
-
|
936
|
|
- if !hasStandardTlsListener {
|
937
|
|
- server.logger.Warning("server", "Port 6697 is the standard TLS port for IRC. You should (also) expose port 6697 as a TLS port to ensure clients can connect securely")
|
|
901
|
+ if publicPlaintextListener != "" {
|
|
902
|
+ server.logger.Warning("listeners", fmt.Sprintf("Your server is configured with public plaintext listener %s. Consider disabling it for improved security and privacy.", publicPlaintextListener))
|
938
|
903
|
}
|
939
|
904
|
|
940
|
905
|
return
|