@@ -3,17 +3,36 @@ package pq
3
3
import (
4
4
"crypto/tls"
5
5
"crypto/x509"
6
+ "fmt"
6
7
"io/ioutil"
7
8
"net"
8
9
"os"
9
10
"os/user"
10
11
"path/filepath"
12
+ "sync"
11
13
)
12
14
13
- // ssl generates a function to upgrade a net.Conn based on the "sslmode" and
14
- // related settings. The function is nil when no upgrade should take place.
15
- func ssl (o values ) (func (net.Conn ) (net.Conn , error ), error ) {
15
+ // To avoid allocating the map if we never use ssl
16
+ var configMapOnce sync.Once
17
+ var configMapMu sync.Mutex
18
+ var configMap map [string ]* ssldata
19
+
20
+ type ssldata struct {
21
+ Conf * tls.Config
22
+ VerifyCAOnly bool
23
+ }
24
+
25
+ func getTLSConf (o values ) (* ssldata , error ) {
16
26
verifyCaOnly := false
27
+ configMapOnce .Do (func () {
28
+ configMap = make (map [string ]* ssldata )
29
+ })
30
+ configMapMu .Lock ()
31
+ conf , ok := configMap [string (o .Hash ())]
32
+ configMapMu .Unlock ()
33
+ if ok {
34
+ return conf , nil
35
+ }
17
36
tlsConf := tls.Config {}
18
37
switch mode := o ["sslmode" ]; mode {
19
38
// "require" is the default.
@@ -59,20 +78,35 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
59
78
return nil , err
60
79
}
61
80
62
- // This pseudo-parameter is not recognized by the PostgreSQL server, so let's delete it after use.
63
- delete (o , "sslinline" )
64
-
65
81
// Accept renegotiation requests initiated by the backend.
66
82
//
67
83
// Renegotiation was deprecated then removed from PostgreSQL 9.5, but
68
84
// the default configuration of older versions has it enabled. Redshift
69
85
// also initiates renegotiations and cannot be reconfigured.
70
86
tlsConf .Renegotiation = tls .RenegotiateFreelyAsClient
71
87
88
+ data := & ssldata {& tlsConf , verifyCaOnly }
89
+ configMapMu .Lock ()
90
+ configMap [string (o .Hash ())] = data
91
+ fmt .Printf ("o: %#v\n " , string (o .Hash ()))
92
+ configMapMu .Unlock ()
93
+ return data , nil
94
+ }
95
+
96
+ // ssl generates a function to upgrade a net.Conn based on the "sslmode" and
97
+ // related settings. The function is nil when no upgrade should take place.
98
+ func ssl (o values ) (func (net.Conn ) (net.Conn , error ), error ) {
99
+ data , err := getTLSConf (o )
100
+ if data == nil && err == nil {
101
+ return nil , nil
102
+ }
103
+ if err != nil {
104
+ return nil , err
105
+ }
72
106
return func (conn net.Conn ) (net.Conn , error ) {
73
- client := tls .Client (conn , & tlsConf )
74
- if verifyCaOnly {
75
- err := sslVerifyCertificateAuthority (client , & tlsConf )
107
+ client := tls .Client (conn , data . Conf )
108
+ if data . VerifyCAOnly {
109
+ err := sslVerifyCertificateAuthority (client , data . Conf )
76
110
if err != nil {
77
111
return nil , err
78
112
}
@@ -86,19 +120,6 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
86
120
// in the user's home directory. The configured files must exist and have
87
121
// the correct permissions.
88
122
func sslClientCertificates (tlsConf * tls.Config , o values ) error {
89
- sslinline := o ["sslinline" ]
90
- if sslinline == "true" {
91
- cert , err := tls .X509KeyPair ([]byte (o ["sslcert" ]), []byte (o ["sslkey" ]))
92
- // Clear out these params, in case they were to be sent to the PostgreSQL server by mistake
93
- o ["sslcert" ] = ""
94
- o ["sslkey" ] = ""
95
- if err != nil {
96
- return err
97
- }
98
- tlsConf .Certificates = []tls.Certificate {cert }
99
- return nil
100
- }
101
-
102
123
// user.Current() might fail when cross-compiling. We have to ignore the
103
124
// error and continue without home directory defaults, since we wouldn't
104
125
// know from where to load them.
@@ -153,19 +174,9 @@ func sslCertificateAuthority(tlsConf *tls.Config, o values) error {
153
174
if sslrootcert := o ["sslrootcert" ]; len (sslrootcert ) > 0 {
154
175
tlsConf .RootCAs = x509 .NewCertPool ()
155
176
156
- sslinline := o ["sslinline" ]
157
-
158
- var cert []byte
159
- if sslinline == "true" {
160
- // // Clear out this param, in case it were to be sent to the PostgreSQL server by mistake
161
- o ["sslrootcert" ] = ""
162
- cert = []byte (sslrootcert )
163
- } else {
164
- var err error
165
- cert , err = ioutil .ReadFile (sslrootcert )
166
- if err != nil {
167
- return err
168
- }
177
+ cert , err := ioutil .ReadFile (sslrootcert )
178
+ if err != nil {
179
+ return err
169
180
}
170
181
171
182
if ! tlsConf .RootCAs .AppendCertsFromPEM (cert ) {
0 commit comments