Kaynağa Gözat

Change SetTLSConfig to exported RegisterTLSConfig and add documentation

Luke Scott 12 yıl önce
ebeveyn
işleme
4974720372
3 değiştirilmiş dosya ile 55 ekleme ve 18 silme
  1. 10 1
      README.md
  2. 0 15
      tlsconfig.go
  3. 45 2
      utils.go

+ 10 - 1
README.md

@@ -19,6 +19,7 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
       * [Address](#address)
       * [Parameters](#parameters)
       * [Examples](#examples)
+    * [TLS support](#tls-support)
     * [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
     * [time.Time support](#timetime-support)
     * [Unicode support](#unicode-support)
@@ -113,7 +114,7 @@ Possible Parameters are:
   * `parseTime`: `parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
   * `strict`: Enable strict mode. MySQL warnings are treated as errors.
   * `timeout`: **Driver** side connection timeout. The value must be a string of decimal numbers, each with optional fraction and a unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*. To set a server side timeout, use the parameter [`wait_timeout`](http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout).
-  * `tls`: `true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side)
+  * `tls`: `true` enables TLS / SSL encrypted connection to the server. For other values see [TLS support](#tls-support).
 
 All other parameters are interpreted as system variables:
   * `autocommit`: *"SET autocommit=`value`"*
@@ -143,6 +144,14 @@ No Database preselected:
 user:password@/
 ```
 
+### TLS support
+For TLS support set the `tls` parameter to one of the following values:
+
+ * `true`: Server certificate is signed by a trusted authority.
+ * `skip-verify`: Server certificate is self-signed with no root authority.
+ * `custom`: Server certifiate is signed by a self-managed authority, and/or a client certificate is used. `custom` can be any value that coorisponds to a custom `tls.Config` registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
+
+
 ### `LOAD DATA LOCAL INFILE` support
 For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
 ```go

+ 0 - 15
tlsconfig.go

@@ -1,15 +0,0 @@
-package mysql
-
-import (
-	"crypto/tls"
-)
-
-type TLSConfig interface {
-	SetTLSConfig(key string, config *tls.Config)
-}
-
-var tlsConfigMap = make(map[string]*tls.Config)
-
-func (d *mysqlDriver) SetTLSConfig(key string, config *tls.Config) {
-	tlsConfigMap[key] = config
-}

+ 45 - 2
utils.go

@@ -77,6 +77,50 @@ func (nt NullTime) Value() (driver.Value, error) {
 	return nt.Time, nil
 }
 
+var tlsConfigMap map[string]*tls.Config
+
+// Registers a custom tls.Config to be used with sql.Open.
+// Use the key as a value in the DSN where tls=value.
+//
+//  rootCertPool := x509.NewCertPool()
+//  {
+//      pem, err := ioutil.ReadFile("/path/ca-cert.pem")
+//      if err != nil {
+//          log.Fatal(err)
+//      }
+//      if ok := rootCAs.AppendCertsFromPEM(pem); !ok {
+//          log.Fatal("Failed to append PEM.")
+//      }
+//  }
+//  clientCert := make([]tls.Certificate, 0, 1)
+//  {
+//      certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem")
+//      if err != nil {
+//          log.Fatal(err)
+//      }
+//      clientCert = append(clientCerts, certs)
+//  }
+//  mysql.RegisterTLSConfig("custom", tls.Config{
+//      RootCAs: rootCertPool,
+//      Certificates: clientCert,
+//  })
+//  db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
+//
+func RegisterTLSConfig(key string, config *tls.Config) {
+	if tlsConfigMap == nil {
+		tlsConfigMap = make(map[string]*tls.Config)
+	}
+	tlsConfigMap[key] = config
+}
+
+// Removes tls.Config associated with key.
+func DeregisterTLSConfig(key string) {
+	if tlsConfigMap == nil {
+		return
+	}
+	delete(tlsConfigMap, key)
+}
+
 // Logger
 var (
 	errLog *log.Logger
@@ -153,8 +197,7 @@ func parseDSN(dsn string) (cfg *config, err error) {
 					} else if strings.ToLower(value) == "skip-verify" {
 						cfg.tls = &tls.Config{InsecureSkipVerify: true}
 					} else if tlsConfig, ok := tlsConfigMap[value]; ok {
-						cfg.tls = &tls.Config{}
-						*cfg.tls = *tlsConfig
+						cfg.tls = tlsConfig
 					}
 
 				default: