@@ -8,12 +8,34 @@ import (
8
8
"os"
9
9
"os/user"
10
10
"path/filepath"
11
+ "sync"
11
12
)
12
13
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 ) {
14
+ // To avoid allocating the map if we never use ssl
15
+ var configMapOnce sync.Once
16
+ var configMapMu sync.Mutex
17
+ var configMap map [string ]* ssldata
18
+
19
+ type ssldata struct {
20
+ Conf * tls.Config
21
+ VerifyCAOnly bool
22
+ }
23
+
24
+ func getTLSConf (o values ) (* ssldata , error ) {
16
25
verifyCaOnly := false
26
+ configMapOnce .Do (func () {
27
+ configMap = make (map [string ]* ssldata )
28
+ })
29
+ // this function modifies o, so take the hash before any modifications are
30
+ // made
31
+ hash := string (o .Hash ())
32
+ // This pseudo-parameter is not recognized by the PostgreSQL server, so let's delete it after use.
33
+ configMapMu .Lock ()
34
+ conf , ok := configMap [hash ]
35
+ configMapMu .Unlock ()
36
+ if ok {
37
+ return conf , nil
38
+ }
17
39
tlsConf := tls.Config {}
18
40
switch mode := o ["sslmode" ]; mode {
19
41
// "require" is the default.
@@ -59,20 +81,34 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
59
81
return nil , err
60
82
}
61
83
62
- // This pseudo-parameter is not recognized by the PostgreSQL server, so let's delete it after use.
63
- delete (o , "sslinline" )
64
-
65
84
// Accept renegotiation requests initiated by the backend.
66
85
//
67
86
// Renegotiation was deprecated then removed from PostgreSQL 9.5, but
68
87
// the default configuration of older versions has it enabled. Redshift
69
88
// also initiates renegotiations and cannot be reconfigured.
70
89
tlsConf .Renegotiation = tls .RenegotiateFreelyAsClient
71
90
91
+ data := & ssldata {& tlsConf , verifyCaOnly }
92
+ configMapMu .Lock ()
93
+ configMap [hash ] = data
94
+ configMapMu .Unlock ()
95
+ return data , nil
96
+ }
97
+
98
+ // ssl generates a function to upgrade a net.Conn based on the "sslmode" and
99
+ // related settings. The function is nil when no upgrade should take place.
100
+ func ssl (o values ) (func (net.Conn ) (net.Conn , error ), error ) {
101
+ data , err := getTLSConf (o )
102
+ if data == nil && err == nil {
103
+ return nil , nil
104
+ }
105
+ if err != nil {
106
+ return nil , err
107
+ }
72
108
return func (conn net.Conn ) (net.Conn , error ) {
73
- client := tls .Client (conn , & tlsConf )
74
- if verifyCaOnly {
75
- err := sslVerifyCertificateAuthority (client , & tlsConf )
109
+ client := tls .Client (conn , data . Conf )
110
+ if data . VerifyCAOnly {
111
+ err := sslVerifyCertificateAuthority (client , data . Conf )
76
112
if err != nil {
77
113
return nil , err
78
114
}
@@ -86,8 +122,7 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
86
122
// in the user's home directory. The configured files must exist and have
87
123
// the correct permissions.
88
124
func sslClientCertificates (tlsConf * tls.Config , o values ) error {
89
- sslinline := o ["sslinline" ]
90
- if sslinline == "true" {
125
+ if o ["sslinline" ] == "true" {
91
126
cert , err := tls .X509KeyPair ([]byte (o ["sslcert" ]), []byte (o ["sslkey" ]))
92
127
// Clear out these params, in case they were to be sent to the PostgreSQL server by mistake
93
128
o ["sslcert" ] = ""
@@ -98,7 +133,6 @@ func sslClientCertificates(tlsConf *tls.Config, o values) error {
98
133
tlsConf .Certificates = []tls.Certificate {cert }
99
134
return nil
100
135
}
101
-
102
136
// user.Current() might fail when cross-compiling. We have to ignore the
103
137
// error and continue without home directory defaults, since we wouldn't
104
138
// know from where to load them.
@@ -168,6 +202,11 @@ func sslCertificateAuthority(tlsConf *tls.Config, o values) error {
168
202
}
169
203
}
170
204
205
+ cert , err := ioutil .ReadFile (sslrootcert )
206
+ if err != nil {
207
+ return err
208
+ }
209
+
171
210
if ! tlsConf .RootCAs .AppendCertsFromPEM (cert ) {
172
211
return fmterrorf ("couldn't parse pem in sslrootcert" )
173
212
}
0 commit comments