Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

irc.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package main
  2. import (
  3. "crypto/tls"
  4. "fmt"
  5. "github.com/spf13/viper"
  6. "github.com/thoj/go-ircevent"
  7. "strings"
  8. "time"
  9. )
  10. func (i *IRCCat) connectIRC(debug bool) error {
  11. viper.SetDefault("irc.user", viper.GetString("irc.nick"))
  12. irccon := irc.IRC(viper.GetString("irc.nick"), viper.GetString("irc.user"))
  13. irccon.RealName = viper.GetString("irc.realname")
  14. i.irc = irccon
  15. irccon.Debug = debug
  16. irccon.Timeout = time.Second * 15
  17. irccon.RequestCaps = []string{"away-notify", "account-notify", "draft/message-tags-0.2"}
  18. irccon.UseTLS = viper.GetBool("irc.tls")
  19. if viper.IsSet("irc.sasl_pass") && viper.GetString("irc.sasl_pass") != "" {
  20. if viper.IsSet("irc.sasl_login") && viper.GetString("irc.sasl_login") != "" {
  21. irccon.SASLLogin = viper.GetString("irc.sasl_login")
  22. } else {
  23. irccon.SASLLogin = viper.GetString("irc.nick")
  24. }
  25. irccon.SASLPassword = viper.GetString("irc.sasl_pass")
  26. irccon.UseSASL = true
  27. }
  28. if viper.GetBool("irc.sasl_external") {
  29. irccon.SASLMech = "EXTERNAL"
  30. irccon.UseSASL = true
  31. }
  32. if viper.GetBool("irc.tls_skip_verify") {
  33. irccon.TLSConfig = &tls.Config{InsecureSkipVerify: true}
  34. } else {
  35. server_parts := strings.Split(viper.GetString("irc.server"), ":")
  36. irccon.TLSConfig = &tls.Config{ServerName: server_parts[0]}
  37. }
  38. if err := addClientCert(irccon); err != nil {
  39. return err
  40. }
  41. irccon.Password = viper.GetString("irc.server_pass")
  42. if err := irccon.Connect(viper.GetString("irc.server")); err != nil {
  43. return err
  44. }
  45. irccon.AddCallback("001", i.handleWelcome)
  46. irccon.AddCallback("PRIVMSG", func(event *irc.Event) {
  47. msg := event.Message()
  48. if (msg[0] == '?' || msg[0] == '!') && len(msg) > 1 {
  49. go i.handleCommand(event)
  50. }
  51. })
  52. irccon.AddCallback("353", i.handleNames)
  53. irccon.AddCallback("JOIN", i.handleJoin)
  54. irccon.AddCallback("PART", i.handlePart)
  55. irccon.AddCallback("QUIT", i.handleQuit)
  56. irccon.AddCallback("KILL", i.handleQuit)
  57. irccon.AddCallback("NICK", i.handleNick)
  58. return nil
  59. }
  60. func (i *IRCCat) handleWelcome(e *irc.Event) {
  61. log.Infof("Negotiated IRCv3 capabilities: %v", i.irc.AcknowledgedCaps)
  62. if viper.IsSet("irc.identify_pass") && viper.GetString("irc.identify_pass") != "" {
  63. i.irc.SendRawf("NICKSERV IDENTIFY %s", viper.GetString("irc.identify_pass"))
  64. }
  65. log.Infof("Connected, joining channels...")
  66. for _, channel := range viper.GetStringSlice("irc.channels") {
  67. key_var := fmt.Sprintf("irc.keys.%s", channel)
  68. if strings.ContainsAny(channel, " \t") {
  69. log.Errorf("Channel name '%s' contains whitespace. Set a channel key by setting the config variable irc.keys.#channel",
  70. channel)
  71. continue
  72. }
  73. if viper.IsSet(key_var) {
  74. i.irc.Join(channel + " " + viper.GetString(key_var))
  75. } else {
  76. i.irc.Join(channel)
  77. }
  78. i.channels.Add(channel)
  79. }
  80. }
  81. func addClientCert(irccon *irc.Connection) error {
  82. certFile := viper.GetString("irc.tls_client_cert") // "" when unset
  83. if certFile == "" {
  84. return nil
  85. }
  86. keyFile := certFile
  87. if k := viper.GetString("irc.tls_client_key"); k != "" {
  88. keyFile = k
  89. }
  90. cert, err := tls.LoadX509KeyPair(certFile, keyFile)
  91. if err != nil {
  92. return err
  93. }
  94. existing := irccon.TLSConfig.Certificates
  95. irccon.TLSConfig.Certificates = append(existing, cert)
  96. return nil
  97. }