Skip to content

Commit

Permalink
cherry pick pingcap#29577 to release-5.3
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
zgcbj authored and ti-srebot committed Nov 23, 2021
1 parent 79e237d commit 131070f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 7 deletions.
23 changes: 16 additions & 7 deletions server/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ func (cc *clientConn) readOptionalSSLRequestAndHandshakeResponse(ctx context.Con

func (cc *clientConn) handleAuthPlugin(ctx context.Context, resp *handshakeResponse41) error {
if resp.Capability&mysql.ClientPluginAuth > 0 {
newAuth, err := cc.checkAuthPlugin(ctx, &resp.AuthPlugin)
newAuth, err := cc.checkAuthPlugin(ctx, resp)
if err != nil {
logutil.Logger(ctx).Warn("failed to check the user authplugin", zap.Error(err))
}
Expand Down Expand Up @@ -845,7 +845,7 @@ func (cc *clientConn) openSessionAndDoAuth(authData []byte, authPlugin string) e
}

// Check if the Authentication Plugin of the server, client and user configuration matches
func (cc *clientConn) checkAuthPlugin(ctx context.Context, authPlugin *string) ([]byte, error) {
func (cc *clientConn) checkAuthPlugin(ctx context.Context, resp *handshakeResponse41) ([]byte, error) {
// Open a context unless this was done before.
if cc.ctx == nil {
err := cc.openSession()
Expand All @@ -854,12 +854,21 @@ func (cc *clientConn) checkAuthPlugin(ctx context.Context, authPlugin *string) (
}
}

userplugin, err := cc.ctx.AuthPluginForUser(&auth.UserIdentity{Username: cc.user, Hostname: cc.peerHost})
authData := resp.Auth
hasPassword := "YES"
if len(authData) == 0 {
hasPassword = "NO"
}
host, _, err := cc.PeerHost(hasPassword)
if err != nil {
return nil, err
}
userplugin, err := cc.ctx.AuthPluginForUser(&auth.UserIdentity{Username: cc.user, Hostname: host})
if err != nil {
return nil, err
}
if userplugin == mysql.AuthSocket {
*authPlugin = mysql.AuthSocket
resp.AuthPlugin = mysql.AuthSocket
user, err := user.LookupId(fmt.Sprint(cc.socketCredUID))
if err != nil {
return nil, err
Expand All @@ -869,7 +878,7 @@ func (cc *clientConn) checkAuthPlugin(ctx context.Context, authPlugin *string) (
if len(userplugin) == 0 {
logutil.Logger(ctx).Warn("No user plugin set, assuming MySQL Native Password",
zap.String("user", cc.user), zap.String("host", cc.peerHost))
*authPlugin = mysql.AuthNativePassword
resp.AuthPlugin = mysql.AuthNativePassword
return nil, nil
}

Expand All @@ -878,12 +887,12 @@ func (cc *clientConn) checkAuthPlugin(ctx context.Context, authPlugin *string) (
// or if the authentication method send by the server doesn't match the authentication
// method send by the client (*authPlugin) then we need to switch the authentication
// method to match the one configured for that specific user.
if (cc.authPlugin != userplugin) || (cc.authPlugin != *authPlugin) {
if (cc.authPlugin != userplugin) || (cc.authPlugin != resp.AuthPlugin) {
authData, err := cc.authSwitchRequest(ctx, userplugin)
if err != nil {
return nil, err
}
*authPlugin = userplugin
resp.AuthPlugin = userplugin
return authData, nil
}

Expand Down
44 changes: 44 additions & 0 deletions server/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,3 +927,47 @@ func TestHandleAuthPlugin(t *testing.T) {
err = cc.handleAuthPlugin(ctx, &resp)
require.NoError(t, err)
}

func TestAuthPlugin2(t *testing.T) {

t.Parallel()

store, clean := testkit.CreateMockStore(t)
defer clean()

cfg := newTestConfig()
cfg.Socket = ""
cfg.Port = 0
cfg.Status.StatusPort = 0

drv := NewTiDBDriver(store)
srv, err := NewServer(cfg, drv)
require.NoError(t, err)

cc := &clientConn{
connectionID: 1,
alloc: arena.NewAllocator(1024),
chunkAlloc: chunk.NewAllocator(),
pkt: &packetIO{
bufWriter: bufio.NewWriter(bytes.NewBuffer(nil)),
},
server: srv,
user: "root",
}
ctx := context.Background()
se, _ := session.CreateSession4Test(store)
tc := &TiDBContext{
Session: se,
stmts: make(map[int]*TiDBStatement),
}
cc.ctx = tc

resp := handshakeResponse41{
Capability: mysql.ClientProtocol41 | mysql.ClientPluginAuth,
}

cc.isUnixSocket = true
_, err = cc.checkAuthPlugin(ctx, &resp)
require.NoError(t, err)

}

0 comments on commit 131070f

Please sign in to comment.