-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathChangeUserCommandCodec.java
More file actions
121 lines (108 loc) · 4.55 KB
/
Copy pathChangeUserCommandCodec.java
File metadata and controls
121 lines (108 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.mysqlclient.impl.codec;
import io.netty.buffer.ByteBuf;
import io.vertx.mysqlclient.impl.MySQLCollation;
import io.vertx.mysqlclient.impl.command.ChangeUserCommand;
import io.vertx.mysqlclient.impl.protocol.CommandType;
import io.vertx.mysqlclient.impl.util.BufferUtils;
import io.vertx.mysqlclient.impl.util.CachingSha2Authenticator;
import io.vertx.mysqlclient.impl.util.Native41Authenticator;
import io.vertx.sqlclient.impl.command.CommandResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static io.vertx.mysqlclient.impl.protocol.CapabilitiesFlag.*;
import static io.vertx.mysqlclient.impl.protocol.Packets.*;
class ChangeUserCommandCodec extends AuthenticationCommandBaseCodec<Void, ChangeUserCommand> {
ChangeUserCommandCodec(ChangeUserCommand cmd) {
super(cmd);
}
@Override
void encode(MySQLEncoder encoder) {
super.encode(encoder);
sendChangeUserCommand();
}
@Override
void decodePayload(ByteBuf payload, int payloadLength) {
int header = payload.getUnsignedByte(payload.readerIndex());
switch (header) {
case AUTH_SWITCH_REQUEST_STATUS_FLAG:
handleAuthSwitchRequest(cmd.password(), payload);
break;
case AUTH_MORE_DATA_STATUS_FLAG:
handleAuthMoreData(cmd.password().getBytes(StandardCharsets.UTF_8), payload);
break;
case OK_PACKET_HEADER:
encoder.fireCommandResponse(CommandResponse.success(null));
break;
case ERROR_PACKET_HEADER:
handleErrorPacketPayload(payload);
break;
}
}
private void handleAuthSwitchRequest(String password, ByteBuf payload) {
// Protocol::AuthSwitchRequest
payload.skipBytes(1); // status flag, always 0xFE
String pluginName = BufferUtils.readNullTerminatedString(payload, StandardCharsets.UTF_8);
authPluginData = new byte[NONCE_LENGTH];
payload.readBytes(authPluginData);
switch (pluginName) {
case "mysql_native_password":
sendBytesAsPacket(Native41Authenticator.encode(password.getBytes(StandardCharsets.UTF_8), authPluginData));
break;
case "caching_sha2_password":
sendBytesAsPacket(CachingSha2Authenticator.encode(password.getBytes(StandardCharsets.UTF_8), authPluginData));
break;
case "mysql_clear_password":
ByteBuf buffer = encoder.chctx.alloc().buffer();
BufferUtils.writeNullTerminatedString(buffer, password, StandardCharsets.UTF_8);
sendNonSplitPacket(buffer);
break;
default:
encoder.fireCommandResponse(CommandResponse.failure(new UnsupportedOperationException("Unsupported authentication method: " + pluginName)));
return;
}
}
private void sendChangeUserCommand() {
ByteBuf packet = allocateBuffer();
// encode packet header
int packetStartIdx = packet.writerIndex();
packet.writeMediumLE(0); // will set payload length later by calculation
packet.writeByte(sequenceId);
// encode packet payload
packet.writeByte(CommandType.COM_CHANGE_USER);
BufferUtils.writeNullTerminatedString(packet, cmd.username(), StandardCharsets.UTF_8);
String password = cmd.password();
if (password.isEmpty()) {
packet.writeByte(0);
} else {
packet.writeByte(password.length());
packet.writeCharSequence(password, StandardCharsets.UTF_8);
}
BufferUtils.writeNullTerminatedString(packet, cmd.database(), StandardCharsets.UTF_8);
MySQLCollation collation = cmd.collation();
int collationId = collation.collationId();
packet.writeShortLE(collationId);
if ((encoder.clientCapabilitiesFlag & CLIENT_PLUGIN_AUTH) != 0) {
BufferUtils.writeNullTerminatedString(packet, "mysql_native_password", StandardCharsets.UTF_8);
}
if ((encoder.clientCapabilitiesFlag & CLIENT_CONNECT_ATTRS) != 0) {
Map<String, String> clientConnectionAttributes = cmd.connectionAttributes();
if (clientConnectionAttributes != null) {
encodeConnectionAttributes(clientConnectionAttributes, packet);
}
}
// set payload length
int lenOfPayload = packet.writerIndex() - packetStartIdx - 4;
packet.setMediumLE(packetStartIdx, lenOfPayload);
sendPacket(packet, lenOfPayload);
}
}