@@ -154,66 +154,91 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
154154}
155155
156156func 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
168188 }
169189 } else {
170- if err = mc .writePublicKeyAuthPacket (oldCipher ); err != nil {
171- return err
172- }
190+ return ErrMalformPkt
173191 }
174- }
175- }
176192
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+ }
181196 }
182197
183198 if mc .cfg == nil {
184199 return err // auth failed and retry not possible
185200 }
186201
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 ()
197213 }
198214
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 ()
209221 }
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 ()
214239 }
215- _ , err = mc .readResultOK ()
216240 }
241+
217242 return err
218243}
219244
0 commit comments