Set TLS server name from Mumble address

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-13 12:53:35 -04:00
committed by Brandon McGinty
parent 883f7250f5
commit 05dc6e4e0e
2 changed files with 59 additions and 0 deletions
+31
View File
@@ -3,6 +3,7 @@ package gumble
import (
"crypto/tls"
"errors"
"fmt"
"math"
"net"
"runtime"
@@ -101,6 +102,19 @@ func Dial(config *Config) (*Client, error) {
return DialWithDialer(new(net.Dialer), config, nil)
}
// tlsServerName returns the hostname portion of a Mumble server address for
// TLS certificate verification and SNI.
func tlsServerName(address string) (string, error) {
host, _, err := net.SplitHostPort(address)
if err != nil {
return "", fmt.Errorf("gumble: derive TLS server name from %q: %w", address, err)
}
if host == "" {
return "", fmt.Errorf("gumble: derive TLS server name from %q: empty host", address)
}
return host, nil
}
// DialWithDialer connects to the Mumble server at the address given in config.
//
// The function returns after the connection has been established, the initial
@@ -120,6 +134,23 @@ func DialWithDialer(dialer *net.Dialer, config *Config, tlsConfig *tls.Config) (
if err != nil {
return nil, err
}
// tls.Client cannot infer a server name from an already-open connection.
// Clone the caller's configuration before deriving it so reconnects and
// concurrent clients do not mutate a shared configuration.
if tlsConfig == nil {
tlsConfig = &tls.Config{}
} else {
tlsConfig = tlsConfig.Clone()
}
if tlsConfig.ServerName == "" {
serverName, err := tlsServerName(config.Address)
if err != nil {
rawConn.Close()
return nil, err
}
tlsConfig.ServerName = serverName
}
conn := tls.Client(rawConn, tlsConfig)
// net.Dialer.Timeout covers only the TCP dial. Apply the same bounded
// deadline to TLS negotiation so a peer that accepts but never responds
+28
View File
@@ -0,0 +1,28 @@
package gumble
import "testing"
func TestTLSServerNameUsesAddressHost(t *testing.T) {
for _, test := range []struct {
address string
want string
}{
{"mumble.example:64738", "mumble.example"},
{"[2001:db8::1]:64738", "2001:db8::1"},
} {
got, err := tlsServerName(test.address)
if err != nil {
t.Errorf("tlsServerName(%q): %v", test.address, err)
continue
}
if got != test.want {
t.Errorf("tlsServerName(%q) = %q, want %q", test.address, got, test.want)
}
}
}
func TestTLSServerNameRejectsAddressWithoutHost(t *testing.T) {
if _, err := tlsServerName(":64738"); err == nil {
t.Fatal("tlsServerName accepted an empty host")
}
}