@@ -154,66 +154,91 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
154
154
}
155
155
156
156
func handleAuthResult (mc * mysqlConn , oldCipher []byte , pluginName string ) error {
157
-
158
- // handle caching_sha2_password
159
- if pluginName == "caching_sha2_password" {
160
- auth , err := mc .readCachingSha2PasswordAuthResult ()
161
- if err != nil {
162
- return err
163
- }
164
- if auth == cachingSha2PasswordPerformFullAuthentication {
165
- if mc .cfg .tls != nil || mc .cfg .Net == "unix" {
166
- if err = mc .writeClearAuthPacket (); err != nil {
167
- return err
157
+ // Read Result Packet
158
+ cipher , err := mc .readResultOK ()
159
+ if err == nil {
160
+ // handle caching_sha2_password
161
+ // https://insidemysql.com/preparing-your-community-connector-for-mysql-8-part-2-sha256/
162
+ if pluginName == "caching_sha2_password" {
163
+ if len (cipher ) == 1 {
164
+ switch cipher [0 ] {
165
+ case cachingSha2PasswordFastAuthSuccess :
166
+ cipher , err = mc .readResultOK ()
167
+ if err == nil {
168
+ return nil // auth successful
169
+ }
170
+
171
+ case cachingSha2PasswordPerformFullAuthentication :
172
+ if mc .cfg .tls != nil || mc .cfg .Net == "unix" {
173
+ if err = mc .writeClearAuthPacket (); err != nil {
174
+ return err
175
+ }
176
+ } else {
177
+ if err = mc .writePublicKeyAuthPacket (oldCipher ); err != nil {
178
+ return err
179
+ }
180
+ }
181
+ cipher , err = mc .readResultOK ()
182
+ if err == nil {
183
+ return nil // auth successful
184
+ }
185
+
186
+ default :
187
+ return ErrMalformPkt
168
188
}
169
189
} else {
170
- if err = mc .writePublicKeyAuthPacket (oldCipher ); err != nil {
171
- return err
172
- }
190
+ return ErrMalformPkt
173
191
}
174
- }
175
- }
176
192
177
- // Read Result Packet
178
- cipher , err := mc .readResultOK ()
179
- if err == nil {
180
- return nil // auth successful
193
+ } else {
194
+ return nil // auth successful
195
+ }
181
196
}
182
197
183
198
if mc .cfg == nil {
184
199
return err // auth failed and retry not possible
185
200
}
186
201
187
- // Retry auth if configured to do so.
188
- if mc .cfg .AllowOldPasswords && err == ErrOldPassword {
189
- // Retry with old authentication method. Note: there are edge cases
190
- // where this should work but doesn't; this is currently "wontfix":
191
- // https://github.com/go-sql-driver/mysql/issues/184
192
-
193
- // If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
194
- // sent and we have to keep using the cipher sent in the init packet.
195
- if cipher == nil {
196
- cipher = oldCipher
202
+ // Retry auth if configured to do so
203
+ switch err {
204
+ case ErrCleartextPassword :
205
+ if mc .cfg .AllowCleartextPasswords {
206
+ // Retry with clear text password for
207
+ // http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
208
+ // http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
209
+ if err = mc .writeClearAuthPacket (); err != nil {
210
+ return err
211
+ }
212
+ _ , err = mc .readResultOK ()
197
213
}
198
214
199
- if err = mc .writeOldAuthPacket (cipher ); err != nil {
200
- return err
201
- }
202
- _ , err = mc .readResultOK ()
203
- } else if mc .cfg .AllowCleartextPasswords && err == ErrCleartextPassword {
204
- // Retry with clear text password for
205
- // http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
206
- // http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
207
- if err = mc .writeClearAuthPacket (); err != nil {
208
- return err
215
+ case ErrNativePassword :
216
+ if mc .cfg .AllowNativePasswords {
217
+ if err = mc .writeNativeAuthPacket (cipher ); err != nil {
218
+ return err
219
+ }
220
+ _ , err = mc .readResultOK ()
209
221
}
210
- _ , err = mc .readResultOK ()
211
- } else if mc .cfg .AllowNativePasswords && err == ErrNativePassword {
212
- if err = mc .writeNativeAuthPacket (cipher ); err != nil {
213
- return err
222
+
223
+ case ErrOldPassword :
224
+ if mc .cfg .AllowOldPasswords {
225
+ // Retry with old authentication method. Note: there are edge cases
226
+ // where this should work but doesn't; this is currently "wontfix":
227
+ // https://github.com/go-sql-driver/mysql/issues/184
228
+
229
+ // If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
230
+ // sent and we have to keep using the cipher sent in the init packet.
231
+ if cipher == nil {
232
+ cipher = oldCipher
233
+ }
234
+
235
+ if err = mc .writeOldAuthPacket (cipher ); err != nil {
236
+ return err
237
+ }
238
+ _ , err = mc .readResultOK ()
214
239
}
215
- _ , err = mc .readResultOK ()
216
240
}
241
+
217
242
return err
218
243
}
219
244
0 commit comments