Skip to content

Commit

Permalink
Add support for client certificates when connecting to upstream networks
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsOnlyBinary committed Aug 14, 2020
1 parent a066b7c commit f7a0382
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 12 deletions.
4 changes: 4 additions & 0 deletions config.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ gateway_name = "webircgateway"
# A secret string used for generating client JWT tokens. Do not share this!
secret = ""

# Webirc client certificate sent to servers when connecting with TLS
webirc_cert = ""
webirc_key = ""

# Send the server a quit message when the client is closed
# Comment out to disable
send_quit_on_client_close = "Client closed"
Expand Down
25 changes: 15 additions & 10 deletions pkg/proxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,24 @@ type HandshakeMeta struct {
Interface string `json:"interface"`
}

func MakeClient(conn net.Conn) *Client {
return &Client{
func MakeClient(conn net.Conn, webircCert *tls.Certificate) *Client {
client := &Client{
Client: conn,
}
if webircCert != nil {
client.WebircCertificate = []tls.Certificate{*webircCert}
}
return client
}

type Client struct {
Client net.Conn
Upstream net.Conn
UpstreamAddr *net.TCPAddr
Username string
BindAddr *net.TCPAddr
TLS bool
Client net.Conn
Upstream net.Conn
UpstreamAddr *net.TCPAddr
Username string
BindAddr *net.TCPAddr
TLS bool
WebircCertificate []tls.Certificate
}

func (c *Client) Run() {
Expand Down Expand Up @@ -185,7 +190,7 @@ func (c *Client) Pipe() {
}
}

func Start(laddr string) {
func Start(laddr string, webircCert *tls.Certificate) {
srv, err := net.Listen("tcp", laddr)
if err != nil {
log.Fatal(err.Error())
Expand All @@ -205,7 +210,7 @@ func Start(laddr string) {
break
}

c := MakeClient(conn)
c := MakeClient(conn, webircCert)
go c.Run()
}
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/webircgateway/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,10 @@ func (c *Client) makeUpstreamConnection() (io.ReadWriteCloser, error) {
}

if upstreamConfig.TLS {
tlsConfig := &tls.Config{InsecureSkipVerify: true}
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
Certificates: upstreamConfig.WebircCertificate,
}
tlsConn := tls.Client(conn, tlsConfig)
err := tlsConn.Handshake()
if err != nil {
Expand Down Expand Up @@ -697,6 +700,11 @@ func (c *Client) configureUpstream() ConfigUpstream {
upstreamConfig.Throttle = c.Gateway.Config.GatewayThrottle
upstreamConfig.WebircPassword = c.Gateway.findWebircPassword(c.DestHost)

if c.Gateway.Config.WebircCert != nil {
upstreamConfig.WebircCertificate = []tls.Certificate{
*c.Gateway.Config.WebircCert,
}
}
return upstreamConfig
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/webircgateway/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package webircgateway

import (
"crypto/tls"
"errors"
"net"
"os"
Expand All @@ -27,6 +28,7 @@ type ConfigUpstream struct {
ServerPassword string
GatewayName string
Proxy *ConfigProxy
WebircCertificate []tls.Certificate
}

// ConfigServer - A web server config
Expand Down Expand Up @@ -77,6 +79,7 @@ type Config struct {
ReCaptchaSecret string
ReCaptchaKey string
Secret string
WebircCert *tls.Certificate
Plugins []string
DnsblServers []string
// DnsblAction - "deny" = deny the connection. "verify" = require verification
Expand Down Expand Up @@ -148,6 +151,7 @@ func (c *Config) Load() error {
c.ReCaptchaKey = ""
c.RequiresVerification = false
c.Secret = ""
c.WebircCert = nil
c.SendQuitOnClientClose = ""
c.ClientRealname = ""
c.ClientUsername = ""
Expand All @@ -172,6 +176,20 @@ func (c *Config) Load() error {
}

c.Secret = section.Key("secret").MustString("")

// Load webirc client certificate
webircCert := section.Key("webirc_cert").MustString("")
webircKey := section.Key("webirc_key").MustString("")
if webircCert != "" && webircKey != "" {
certPath := c.ResolvePath(webircCert)
keyPath := c.ResolvePath(webircKey)
webircCert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err == nil {
c.WebircCert = &webircCert
} else {
c.gateway.Log(3, "Failed to load webirc certificate, "+err.Error())
}
}
c.SendQuitOnClientClose = section.Key("send_quit_on_client_close").MustString("Connection closed")
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/webircgateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ func (s *Gateway) Start() {
}

if s.Function == "proxy" {
proxy.Start(fmt.Sprintf("%s:%d", s.Config.Proxy.LocalAddr, s.Config.Proxy.Port))
proxy.Start(
fmt.Sprintf("%s:%d", s.Config.Proxy.LocalAddr, s.Config.Proxy.Port),
s.Config.WebircCert,
)
}
}

Expand Down

0 comments on commit f7a0382

Please sign in to comment.