From c3644c8d3b4fa87e0a001d8c419edbfbd67ceb5b Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 5 Feb 2022 21:12:03 +0100 Subject: [PATCH] Add support for client certificate (irc) (#1710) Supports https://libera.chat/guides/certfp.html --- bridge/irc/irc.go | 32 +++++++++++++++++++++++++++++++- matterbridge.toml.sample | 7 +++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go index 260f66df..4b7b144b 100644 --- a/bridge/irc/irc.go +++ b/bridge/irc/irc.go @@ -2,6 +2,7 @@ package birc import ( "crypto/tls" + "errors" "fmt" "hash/crc32" "io/ioutil" @@ -72,6 +73,10 @@ func (b *Birc) Command(msg *config.Message) string { } func (b *Birc) Connect() error { + if b.GetBool("UseSASL") && b.GetString("TLSClientCertificate") != "" { + return errors.New("you can't enable SASL and TLSClientCertificate at the same time") + } + b.Local = make(chan config.Message, b.MessageQueue+10) b.Log.Infof("Connecting %s", b.GetString("Server")) @@ -300,6 +305,11 @@ func (b *Birc) getClient() (*girc.Client, error) { b.Log.Debugf("setting pingdelay to %s", pingDelay) + tlsConfig, err := b.getTLSConfig() + if err != nil { + return nil, err + } + i := girc.New(girc.Config{ Server: server, ServerPass: b.GetString("Password"), @@ -309,7 +319,7 @@ func (b *Birc) getClient() (*girc.Client, error) { Name: realName, SSL: b.GetBool("UseTLS"), Bind: b.GetString("Bind"), - TLSConfig: &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec + TLSConfig: tlsConfig, PingDelay: pingDelay, // skip gIRC internal rate limiting, since we have our own throttling AllowFlood: true, @@ -381,3 +391,23 @@ func (b *Birc) storeNames(client *girc.Client, event girc.Event) { func (b *Birc) formatnicks(nicks []string) string { return strings.Join(nicks, ", ") + " currently on IRC" } + +func (b *Birc) getTLSConfig() (*tls.Config, error) { + server, _, _ := net.SplitHostPort(b.GetString("server")) + + tlsConfig := &tls.Config{ + InsecureSkipVerify: b.GetBool("skiptlsverify"), //nolint:gosec + ServerName: server, + } + + if filename := b.GetString("TLSClientCertificate"); filename != "" { + cert, err := tls.LoadX509KeyPair(filename, filename) + if err != nil { + return nil, err + } + + tlsConfig.Certificates = []tls.Certificate{cert} + } + + return tlsConfig, nil +} diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample index fd341ff8..8bc0f6c1 100644 --- a/matterbridge.toml.sample +++ b/matterbridge.toml.sample @@ -24,6 +24,13 @@ Password="" #OPTIONAL (default false) UseTLS=false +#Use client certificate - see CertFP https://libera.chat/guides/certfp.html +#Specify filename which contains private key and cert +#OPTIONAL (default "") +# +#TLSClientCertificate="cert.pem" +TLSClientCertificate="" + #Enable SASL (PLAIN) authentication. (libera requires this from eg AWS hosts) #It uses NickServNick and NickServPassword as login and password #OPTIONAL (default false)