Don't perform TLS handshake in connectToUpstream
This defers TLS handshake until the first read or write operation. This allows the upcoming identd server to register the connection before the TLS handshake is complete, and is necessary because some IRC servers send an ident request before that.
This commit is contained in:
parent
c1f8002428
commit
7c31c26d86
25
upstream.go
25
upstream.go
@ -98,13 +98,15 @@ func connectToUpstream(network *network) (*upstreamConn, error) {
|
|||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ircs":
|
case "ircs":
|
||||||
addr := u.Host
|
addr := u.Host
|
||||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
host, _, err := net.SplitHostPort(u.Host)
|
||||||
addr = addr + ":6697"
|
if err != nil {
|
||||||
|
host = u.Host
|
||||||
|
addr = u.Host + ":6697"
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Printf("connecting to TLS server at address %q", addr)
|
logger.Printf("connecting to TLS server at address %q", addr)
|
||||||
|
|
||||||
var tlsConfig *tls.Config
|
tlsConfig := &tls.Config{ServerName: host}
|
||||||
if network.SASL.Mechanism == "EXTERNAL" {
|
if network.SASL.Mechanism == "EXTERNAL" {
|
||||||
if network.SASL.External.CertBlob == nil {
|
if network.SASL.External.CertBlob == nil {
|
||||||
return nil, fmt.Errorf("missing certificate for authentication")
|
return nil, fmt.Errorf("missing certificate for authentication")
|
||||||
@ -116,21 +118,24 @@ func connectToUpstream(network *network) (*upstreamConn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse private key: %v", err)
|
return nil, fmt.Errorf("failed to parse private key: %v", err)
|
||||||
}
|
}
|
||||||
tlsConfig = &tls.Config{
|
tlsConfig.Certificates = []tls.Certificate{
|
||||||
Certificates: []tls.Certificate{
|
{
|
||||||
{
|
Certificate: [][]byte{network.SASL.External.CertBlob},
|
||||||
Certificate: [][]byte{network.SASL.External.CertBlob},
|
PrivateKey: key.(crypto.PrivateKey),
|
||||||
PrivateKey: key.(crypto.PrivateKey),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
logger.Printf("using TLS client certificate %x", sha256.Sum256(network.SASL.External.CertBlob))
|
logger.Printf("using TLS client certificate %x", sha256.Sum256(network.SASL.External.CertBlob))
|
||||||
}
|
}
|
||||||
|
|
||||||
netConn, err = tls.DialWithDialer(&dialer, "tcp", addr, tlsConfig)
|
netConn, err = dialer.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to dial %q: %v", addr, err)
|
return nil, fmt.Errorf("failed to dial %q: %v", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't do the TLS handshake immediately, because we need to register
|
||||||
|
// the new connection with identd ASAP. See:
|
||||||
|
// https://todo.sr.ht/~emersion/soju/69#event-41859
|
||||||
|
netConn = tls.Client(netConn, tlsConfig)
|
||||||
case "irc+insecure":
|
case "irc+insecure":
|
||||||
addr := u.Host
|
addr := u.Host
|
||||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user