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