Skip to content

Commit d8ea45d

Browse files
authored
Merge pull request vitessio#2717 from alainjobart/dialog
Refactoring dialog plugin code a bit.
2 parents bada4b1 + b43b6be commit d8ea45d

File tree

4 files changed

+75
-17
lines changed

4 files changed

+75
-17
lines changed

go/mysqlconn/auth_server.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,30 @@ func scramblePassword(salt, password []byte) []byte {
125125
return scramble
126126
}
127127

128+
// Constants for the dialog plugin.
129+
const (
130+
mysqlDialogMessage = "Enter password: "
131+
132+
// Dialog plugin is similar to clear text, but can respond to multiple
133+
// prompts in a row. This is not yet implemented.
134+
// Follow questions should be prepended with a `cmd` byte:
135+
// 0x02 - ordinary question
136+
// 0x03 - last question
137+
// 0x04 - password question
138+
// 0x05 - last password
139+
mysqlDialogAskPassword = 0x04
140+
)
141+
142+
// authServerDialogSwitchData is a helper method to return the data
143+
// needed in the AuthSwitchRequest packet for the dialog plugin
144+
// to ask for a password.
145+
func authServerDialogSwitchData() []byte {
146+
result := make([]byte, len(mysqlDialogMessage)+2)
147+
result[0] = mysqlDialogAskPassword
148+
writeNullString(result, 1, mysqlDialogMessage)
149+
return result
150+
}
151+
128152
// AuthServerReadPacketString is a helper method to read a packet
129153
// as a null terminated string. It is used by the mysql_clear_password
130154
// and dialog plugins.
@@ -151,13 +175,6 @@ func AuthServerNegotiateClearOrDialog(c *Conn, method string) (string, error) {
151175
return AuthServerReadPacketString(c)
152176

153177
case MysqlDialog:
154-
// Dialog plugin is similar to clear text, but can respond to multiple
155-
// prompts in a row. This is not yet implemented.
156-
// Follow questions should be prepended with a `cmd` byte:
157-
// 0x02 - ordinary question
158-
// 0x03 - last question
159-
// 0x04 - password question
160-
// 0x05 - last password
161178
return AuthServerReadPacketString(c)
162179

163180
default:

go/mysqlconn/constants.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ const (
2222

2323
// MysqlDialog uses the dialog plugin on the client side.
2424
// It transmits data in the clear.
25-
MysqlDialog = "dialog"
26-
MysqlDialogMessage = "Enter password: "
25+
MysqlDialog = "dialog"
2726
)
2827

2928
// Capability flags.
@@ -137,8 +136,6 @@ const (
137136
// ComQuery is COM_QUERY.
138137
ComQuery = 0x03
139138

140-
AskPassword = 0x04
141-
142139
// ComPing is COM_PING.
143140
ComPing = 0x0e
144141

go/mysqlconn/server.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,11 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32) {
206206
}
207207

208208
// Switch our auth method to what the server wants.
209-
// Dialog plugin expects an AskPassword prompt
209+
// Dialog plugin expects an AskPassword prompt.
210210
var data []byte
211211
if authServerMethod == MysqlDialog {
212-
data = make([]byte, len(MysqlDialogMessage)+2)
213-
data[0] = AskPassword
214-
writeNullString(data, 1, MysqlDialogMessage)
212+
data = authServerDialogSwitchData()
215213
}
216-
217214
if err := c.writeAuthSwitchRequest(authServerMethod, data); err != nil {
218215
log.Errorf("Error write auth switch packet for client %v: %v", c.ConnectionID, err)
219216
return

go/mysqlconn/server_test.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ func TestServer(t *testing.T) {
262262
// time.Sleep(60 * time.Minute)
263263
}
264264

265-
// TestClearTextServer creates a Server that needs clear text passwords from the client.
265+
// TestClearTextServer creates a Server that needs clear text
266+
// passwords from the client.
266267
func TestClearTextServer(t *testing.T) {
267268
// If the database we're using is MariaDB, the client
268269
// is also the MariaDB client, that does support
@@ -355,6 +356,52 @@ func TestClearTextServer(t *testing.T) {
355356
}
356357
}
357358

359+
// TestDialogServer creates a Server that uses the dialog plugin on the client.
360+
func TestDialogServer(t *testing.T) {
361+
th := &testHandler{}
362+
363+
authServer := NewAuthServerStatic()
364+
authServer.Entries["user1"] = &AuthServerStaticEntry{
365+
Password: "password1",
366+
UserData: "userData1",
367+
}
368+
authServer.Method = MysqlDialog
369+
l, err := NewListener("tcp", ":0", authServer, th)
370+
if err != nil {
371+
t.Fatalf("NewListener failed: %v", err)
372+
}
373+
l.AllowClearTextWithoutTLS = true
374+
defer l.Close()
375+
go func() {
376+
l.Accept()
377+
}()
378+
379+
host := l.Addr().(*net.TCPAddr).IP.String()
380+
port := l.Addr().(*net.TCPAddr).Port
381+
382+
// Setup the right parameters.
383+
params := &sqldb.ConnParams{
384+
Host: host,
385+
Port: port,
386+
Uname: "user1",
387+
Pass: "password1",
388+
}
389+
sql := "select rows"
390+
output, ok := runMysql(t, params, sql)
391+
if strings.Contains(output, "No such file or directory") {
392+
t.Logf("skipping dialog plugin tests, as the dialog plugin cannot be loaded: %v", err)
393+
return
394+
}
395+
if !ok {
396+
t.Fatalf("mysql failed: %v", output)
397+
}
398+
if !strings.Contains(output, "nice name") ||
399+
!strings.Contains(output, "nicer name") ||
400+
!strings.Contains(output, "2 rows in set") {
401+
t.Errorf("Unexpected output for 'select rows': %v", output)
402+
}
403+
}
404+
358405
// TestTLSServer creates a Server with TLS support, then uses mysql
359406
// client to connect to it.
360407
func TestTLSServer(t *testing.T) {

0 commit comments

Comments
 (0)