Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8a4cb1d

Browse files
committedAug 14, 2020
Add support for client certificates when connecting to upstream networks
1 parent a066b7c commit 8a4cb1d

File tree

5 files changed

+50
-12
lines changed

5 files changed

+50
-12
lines changed
 

‎config.conf.example

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ gateway_name = "webircgateway"
1010
# A secret string used for generating client JWT tokens. Do not share this!
1111
secret = ""
1212

13+
# Webirc client certificate sent to servers when connecting with TLS
14+
webirc_cert = ""
15+
webirc_key = ""
16+
1317
# Send the server a quit message when the client is closed
1418
# Comment out to disable
1519
send_quit_on_client_close = "Client closed"

‎pkg/proxy/server.go

+15-10
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,24 @@ type HandshakeMeta struct {
3636
Interface string `json:"interface"`
3737
}
3838

39-
func MakeClient(conn net.Conn) *Client {
40-
return &Client{
39+
func MakeClient(conn net.Conn, webircCert *tls.Certificate) *Client {
40+
client := &Client{
4141
Client: conn,
4242
}
43+
if webircCert != nil {
44+
client.WebircCertificate = []tls.Certificate{*webircCert}
45+
}
46+
return client
4347
}
4448

4549
type Client struct {
46-
Client net.Conn
47-
Upstream net.Conn
48-
UpstreamAddr *net.TCPAddr
49-
Username string
50-
BindAddr *net.TCPAddr
51-
TLS bool
50+
Client net.Conn
51+
Upstream net.Conn
52+
UpstreamAddr *net.TCPAddr
53+
Username string
54+
BindAddr *net.TCPAddr
55+
TLS bool
56+
WebircCertificate []tls.Certificate
5257
}
5358

5459
func (c *Client) Run() {
@@ -185,7 +190,7 @@ func (c *Client) Pipe() {
185190
}
186191
}
187192

188-
func Start(laddr string) {
193+
func Start(laddr string, webircCert *tls.Certificate) {
189194
srv, err := net.Listen("tcp", laddr)
190195
if err != nil {
191196
log.Fatal(err.Error())
@@ -205,7 +210,7 @@ func Start(laddr string) {
205210
break
206211
}
207212

208-
c := MakeClient(conn)
213+
c := MakeClient(conn, webircCert)
209214
go c.Run()
210215
}
211216
}

‎pkg/webircgateway/client.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,10 @@ func (c *Client) makeUpstreamConnection() (io.ReadWriteCloser, error) {
343343
}
344344

345345
if upstreamConfig.TLS {
346-
tlsConfig := &tls.Config{InsecureSkipVerify: true}
346+
tlsConfig := &tls.Config{
347+
InsecureSkipVerify: true,
348+
Certificates: upstreamConfig.WebircCertificate,
349+
}
347350
tlsConn := tls.Client(conn, tlsConfig)
348351
err := tlsConn.Handshake()
349352
if err != nil {
@@ -697,6 +700,11 @@ func (c *Client) configureUpstream() ConfigUpstream {
697700
upstreamConfig.Throttle = c.Gateway.Config.GatewayThrottle
698701
upstreamConfig.WebircPassword = c.Gateway.findWebircPassword(c.DestHost)
699702

703+
if upstreamConfig.WebircPassword != "" && c.Gateway.Config.WebircCert != nil {
704+
upstreamConfig.WebircCertificate = []tls.Certificate{
705+
*c.Gateway.Config.WebircCert,
706+
}
707+
}
700708
return upstreamConfig
701709
}
702710

‎pkg/webircgateway/config.go

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package webircgateway
22

33
import (
4+
"crypto/tls"
45
"errors"
56
"net"
67
"os"
@@ -27,6 +28,7 @@ type ConfigUpstream struct {
2728
ServerPassword string
2829
GatewayName string
2930
Proxy *ConfigProxy
31+
WebircCertificate []tls.Certificate
3032
}
3133

3234
// ConfigServer - A web server config
@@ -77,6 +79,7 @@ type Config struct {
7779
ReCaptchaSecret string
7880
ReCaptchaKey string
7981
Secret string
82+
WebircCert *tls.Certificate
8083
Plugins []string
8184
DnsblServers []string
8285
// DnsblAction - "deny" = deny the connection. "verify" = require verification
@@ -148,6 +151,7 @@ func (c *Config) Load() error {
148151
c.ReCaptchaKey = ""
149152
c.RequiresVerification = false
150153
c.Secret = ""
154+
c.WebircCert = nil
151155
c.SendQuitOnClientClose = ""
152156
c.ClientRealname = ""
153157
c.ClientUsername = ""
@@ -172,6 +176,20 @@ func (c *Config) Load() error {
172176
}
173177

174178
c.Secret = section.Key("secret").MustString("")
179+
180+
// Load webirc client certificate
181+
webircCert := section.Key("webirc_cert").MustString("")
182+
webircKey := section.Key("webirc_key").MustString("")
183+
if webircCert != "" && webircKey != "" {
184+
certPath := c.ResolvePath(webircCert)
185+
keyPath := c.ResolvePath(webircKey)
186+
webircCert, err := tls.LoadX509KeyPair(certPath, keyPath)
187+
if err == nil {
188+
c.WebircCert = &webircCert
189+
} else {
190+
c.gateway.Log(3, "Failed to load webirc certificate, "+err.Error())
191+
}
192+
}
175193
c.SendQuitOnClientClose = section.Key("send_quit_on_client_close").MustString("Connection closed")
176194
}
177195

‎pkg/webircgateway/gateway.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ func (s *Gateway) Start() {
7878
}
7979

8080
if s.Function == "proxy" {
81-
proxy.Start(fmt.Sprintf("%s:%d", s.Config.Proxy.LocalAddr, s.Config.Proxy.Port))
81+
proxy.Start(
82+
fmt.Sprintf("%s:%d", s.Config.Proxy.LocalAddr, s.Config.Proxy.Port),
83+
s.Config.WebircCert,
84+
)
8285
}
8386
}
8487

0 commit comments

Comments
 (0)
Please sign in to comment.