Skip to content

Commit a962bc8

Browse files
committed
Allow multiple custom TLS configs in driver
Stored in a map using the address (hostname:port) as the key. Initial work at addressing review feedback. Possibly/probably there is mutex and locking stuff we want to do. Maybe overkill though? Using the address vs the full DSN makes sense to me as the key. It's a little cleaner and I can't see a situation where a slight difference in the DSN (i.e. different database) would require a different certificate or TLS config. This is actually pretty neat as we just use `&ssl=custom` and it looks up the TLS Config (that people will have to pre-register/store) based on the address in the DSN.
1 parent 43aa9b9 commit a962bc8

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

driver/driver.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
sqldriver "database/sql/driver"
99
"fmt"
1010
"io"
11+
"net/url"
1112
"strings"
1213

1314
"github.com/go-mysql-org/go-mysql/client"
@@ -16,7 +17,8 @@ import (
1617
"github.com/siddontang/go/hack"
1718
)
1819

19-
var customTLSConfig *tls.Config
20+
// Map of dsn address (makes more sense than full dsn?) to tls Config
21+
var customTLSConfigMap = make(map[string]*tls.Config)
2022

2123
type driver struct {
2224
}
@@ -84,9 +86,10 @@ func (d driver) Open(dsn string) (sqldriver.Conn, error) {
8486
case "custom":
8587
// I was too concerned about mimicking what go-sql-driver/mysql does which will
8688
// allow any name for a custom tls profile and maps the query parameter value to
87-
// that TLSConfig variable... there is no need to be that clever. We can just
88-
// insist `"custom"` (string) == `custom` (TLSConfig)
89-
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) { c.SetTLSConfig(customTLSConfig) })
89+
// that TLSConfig variable... there is no need to be that clever.
90+
// Instead of doing that, let's store required custom TLSConfigs in a map that
91+
// uses the DSN address as the key
92+
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) { c.SetTLSConfig(customTLSConfigMap[addr]) })
9093
default:
9194
return nil, errors.Errorf("Supported options are ssl=true or ssl=custom")
9295
}
@@ -275,8 +278,19 @@ func init() {
275278
sql.Register("mysql", driver{})
276279
}
277280

278-
func SetCustomTLSConfig(caPem []byte, certPem []byte, keyPem []byte, insecureSkipVerify bool, serverName string) {
281+
func SetCustomTLSConfig(dsn string, caPem []byte, certPem []byte, keyPem []byte, insecureSkipVerify bool, serverName string) {
282+
// Extract addr from dsn
283+
// We can hopefully extend the use of url.Parse if we switch the DSN style
284+
parsed, err := url.Parse(dsn)
285+
if err != nil {
286+
errors.Errorf("Unable to parse DSN. Need to extract address to use as key for storing custom TLS config")
287+
}
288+
addr := parsed.Host
289+
290+
// I thought about using serverName instead of addr below, but decided against that as
291+
// having multiple CA certs for one hostname is likely when you have services running on
292+
// different ports.
293+
279294
// Basic pass-through function so we can just import the driver
280-
// For now there is a single shared "custom" config. I.e. any program can only have one "custom" config
281-
customTLSConfig = client.NewClientTLSConfig(caPem, certPem, keyPem, insecureSkipVerify, serverName)
295+
customTLSConfigMap[addr] = client.NewClientTLSConfig(caPem, certPem, keyPem, insecureSkipVerify, serverName)
282296
}

0 commit comments

Comments
 (0)