diff --git a/pkg/proxy/backend/authenticator.go b/pkg/proxy/backend/authenticator.go index c4ea467f..a64be0c7 100644 --- a/pkg/proxy/backend/authenticator.go +++ b/pkg/proxy/backend/authenticator.go @@ -50,6 +50,7 @@ type Authenticator struct { serverAddr string user string attrs []byte // no need to parse + salt []byte capability uint32 // client capability collation uint8 proxyProtocol bool @@ -104,7 +105,7 @@ func (auth *Authenticator) handshakeFirstTime(logger *zap.Logger, clientIO *pnet proxyCapability ^= pnet.ClientSSL } - if err := clientIO.WriteInitialHandshake(proxyCapability.Uint32(), make([]byte, 20), mysql.AuthNativePassword); err != nil { + if err := clientIO.WriteInitialHandshake(proxyCapability.Uint32(), auth.salt, mysql.AuthNativePassword); err != nil { return err } pkt, isSSL, err := clientIO.ReadSSLRequestOrHandshakeResp() diff --git a/pkg/proxy/backend/backend_conn_mgr.go b/pkg/proxy/backend/backend_conn_mgr.go index 107130f2..61bda683 100644 --- a/pkg/proxy/backend/backend_conn_mgr.go +++ b/pkg/proxy/backend/backend_conn_mgr.go @@ -90,11 +90,16 @@ type BackendConnManager struct { // NewBackendConnManager creates a BackendConnManager. func NewBackendConnManager(logger *zap.Logger, nsmgr *namespace.NamespaceManager, connectionID uint64, proxyProtocol, requireBackendTLS bool) *BackendConnManager { mgr := &BackendConnManager{ - logger: logger, - connectionID: connectionID, - cmdProcessor: NewCmdProcessor(), - nsmgr: nsmgr, - authenticator: &Authenticator{supportedServerCapabilities: supportedServerCapabilities, proxyProtocol: proxyProtocol, requireBackendTLS: requireBackendTLS}, + logger: logger, + connectionID: connectionID, + cmdProcessor: NewCmdProcessor(), + nsmgr: nsmgr, + authenticator: &Authenticator{ + supportedServerCapabilities: supportedServerCapabilities, + proxyProtocol: proxyProtocol, + requireBackendTLS: requireBackendTLS, + salt: GenerateSalt(20), + }, signalReceived: make(chan struct{}, 1), redirectResCh: make(chan *redirectResult, 1), } diff --git a/pkg/proxy/backend/util.go b/pkg/proxy/backend/util.go new file mode 100644 index 00000000..2529667e --- /dev/null +++ b/pkg/proxy/backend/util.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package backend + +import _ "unsafe" + +//go:linkname Uint32N runtime.fastrandn +func Uint32N(a uint64) uint64 + +// Buf generates a random string using ASCII characters but avoid separator character. +// Ref https://github.com/mysql/mysql-server/blob/5.7/mysys_ssl/crypt_genhash_impl.cc#L435. +func GenerateSalt(size int) []byte { + buf := make([]byte, size) + for i := range buf { + buf[i] = byte(Uint32N(127)) + for buf[i] == 0 || buf[i] == byte('$') { + buf[i] = byte(Uint32N(127)) + } + } + return buf +}