提交 4508c12e 编写于 作者: T tristaZero

new function: proxy authority.

上级 ccd2e0b3
......@@ -78,6 +78,7 @@
<os-maven-plugin.version>1.5.0.Final</os-maven-plugin.version>
<coveralls-maven-plugin.version>4.1.0</coveralls-maven-plugin.version>
<docker-maven-plugin.version>0.4.14</docker-maven-plugin.version>
<commons-codec.version>1.10</commons-codec.version>
<javadocExecutable>${java.home}/../bin/javadoc</javadocExecutable>
</properties>
......@@ -315,6 +316,11 @@
<version>${opentracing.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
......
/*
* Copyright 2016-2018 shardingsphere.io.
* <p>
* 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.
* </p>
*/
package io.shardingsphere.core.rule;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Yam proxy authority.
*
* @author panjuan
*/
@NoArgsConstructor
@Getter
@Setter
public final class ProxyAuthority {
private String username;
private String password;
}
......@@ -20,8 +20,9 @@ package io.shardingsphere.core.yaml.proxy;
import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration;
import io.shardingsphere.core.rule.MasterSlaveRule;
import io.shardingsphere.core.rule.ShardingRule;
import io.shardingsphere.core.rule.ProxyAuthority;
import io.shardingsphere.core.yaml.masterslave.YamlMasterSlaveRuleConfiguration;
import io.shardingsphere.core.yaml.sharding.DataSourceParameter;
import io.shardingsphere.core.rule.DataSourceParameter;
import io.shardingsphere.core.yaml.sharding.YamlShardingRuleConfiguration;
import lombok.Getter;
import lombok.Setter;
......@@ -47,7 +48,7 @@ import java.util.Map;
*/
@Getter
@Setter
public class YamlProxyConfiguration {
public final class YamlProxyConfiguration {
private Map<String, DataSourceParameter> dataSources = new HashMap<>();
......@@ -55,6 +56,8 @@ public class YamlProxyConfiguration {
private YamlShardingRuleConfiguration shardingRule = new YamlShardingRuleConfiguration();
private ProxyAuthority proxyAuthority = new ProxyAuthority();
/**
* Unmarshal yaml sharding configuration from yaml file.
*
......
......@@ -64,6 +64,10 @@
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
<build>
......
......@@ -26,9 +26,10 @@ import io.shardingsphere.core.constant.ShardingPropertiesConstant;
import io.shardingsphere.core.exception.ShardingException;
import io.shardingsphere.core.metadata.ShardingMetaData;
import io.shardingsphere.core.rule.MasterSlaveRule;
import io.shardingsphere.core.rule.ProxyAuthority;
import io.shardingsphere.core.rule.ShardingRule;
import io.shardingsphere.core.yaml.proxy.YamlProxyConfiguration;
import io.shardingsphere.core.yaml.sharding.DataSourceParameter;
import io.shardingsphere.core.rule.DataSourceParameter;
import io.shardingsphere.proxy.metadata.ProxyShardingMetaData;
import lombok.Getter;
......@@ -71,6 +72,8 @@ public final class RuleRegistry {
private final boolean showSQL;
private final ProxyAuthority proxyAuthority;
private RuleRegistry() {
YamlProxyConfiguration yamlProxyConfiguration;
try {
......@@ -94,7 +97,7 @@ public final class RuleRegistry {
if (!isOnlyMasterSlave) {
shardingMetaData.init(shardingRule);
}
proxyAuthority = yamlProxyConfiguration.getProxyAuthority();
}
private DataSource getDataSource(final DataSourceParameter dataSourceParameter) {
......
......@@ -26,38 +26,45 @@ import io.shardingsphere.proxy.transport.mysql.constant.StatusFlag;
import io.shardingsphere.proxy.transport.mysql.packet.MySQLPacketPayload;
import io.shardingsphere.proxy.transport.mysql.packet.command.CommandPacket;
import io.shardingsphere.proxy.transport.mysql.packet.command.CommandPacketFactory;
import io.shardingsphere.proxy.transport.mysql.packet.generic.ErrPacket;
import io.shardingsphere.proxy.transport.mysql.packet.generic.OKPacket;
import io.shardingsphere.proxy.transport.mysql.packet.handshake.AuthPluginData;
import io.shardingsphere.proxy.transport.mysql.packet.handshake.ConnectionIdGenerator;
import io.shardingsphere.proxy.transport.mysql.packet.handshake.HandshakePacket;
import io.shardingsphere.proxy.transport.mysql.packet.handshake.HandshakeResponse41Packet;
import lombok.RequiredArgsConstructor;
import io.shardingsphere.proxy.transport.mysql.packet.handshake.ProxyAuthorityHandler;
/**
* MySQL frontend handler.
*
* @author zhangliang
* @author panjuan
*/
@RequiredArgsConstructor
public final class MySQLFrontendHandler extends FrontendHandler {
private final EventLoopGroup eventLoopGroup;
private AuthPluginData authPluginData;
private final ProxyAuthorityHandler proxyAuthorityHandler;
public MySQLFrontendHandler(final EventLoopGroup eventLoopGroup) {
this.eventLoopGroup = eventLoopGroup;
proxyAuthorityHandler = new ProxyAuthorityHandler();
}
@Override
protected void handshake(final ChannelHandlerContext context) {
authPluginData = new AuthPluginData();
context.writeAndFlush(new HandshakePacket(ConnectionIdGenerator.getInstance().nextId(), authPluginData));
context.writeAndFlush(new HandshakePacket(ConnectionIdGenerator.getInstance().nextId(), proxyAuthorityHandler.getAuthPluginData()));
}
@Override
protected void auth(final ChannelHandlerContext context, final ByteBuf message) {
MySQLPacketPayload mysqlPacketPayload = new MySQLPacketPayload(message);
try {
// TODO use authPluginData to auth
HandshakeResponse41Packet response41 = new HandshakeResponse41Packet(mysqlPacketPayload);
context.writeAndFlush(new OKPacket(response41.getSequenceId() + 1, 0L, 0L, StatusFlag.SERVER_STATUS_AUTOCOMMIT.getValue(), 0, ""));
if (proxyAuthorityHandler.isLegalForProxyLogin(response41.getUsername(), response41.getAuthResponse())) {
context.writeAndFlush(new OKPacket(response41.getSequenceId() + 1, 0L, 0L, StatusFlag.SERVER_STATUS_AUTOCOMMIT.getValue(), 0, ""));
} else {
context.writeAndFlush(new ErrPacket(response41.getSequenceId() + 1, 1045, "", "", "Access denied because of invalid username and password for Sharding Proxy."));
}
} finally {
mysqlPacketPayload.getByteBuf().release();
}
......
......@@ -222,6 +222,18 @@ public final class MySQLPacketPayload {
return new String(result);
}
/**
* Read fixed length string from byte buffers.
*
* @return fixed length bytes
*/
public byte[] readStringLenencByBytes() {
int length = (int) readIntLenenc();
byte[] result = new byte[length];
byteBuf.readBytes(result);
return result;
}
/**
* Write fixed length string to byte buffers.
* @see <a href="https://dev.mysql.com/doc/internals/en/string.html#packet-Protocol::FixedLengthString">FixedLengthString</a>
......
......@@ -56,7 +56,7 @@ public final class HandshakeResponse41Packet extends MySQLPacket {
private void readAuthResponse(final MySQLPacketPayload mysqlPacketPayload) {
if (0 != (capabilityFlags & CapabilityFlag.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA.getValue())) {
authResponse = mysqlPacketPayload.readStringLenenc().getBytes();
authResponse = mysqlPacketPayload.readStringLenencByBytes();
} else if (0 != (capabilityFlags & CapabilityFlag.CLIENT_SECURE_CONNECTION.getValue())) {
int length = mysqlPacketPayload.readInt1();
authResponse = mysqlPacketPayload.readStringFix(length).getBytes();
......
/*
* Copyright 2016-2018 shardingsphere.io.
* <p>
* 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.
* </p>
*/
package io.shardingsphere.proxy.transport.mysql.packet.handshake;
import io.shardingsphere.proxy.config.RuleRegistry;
import lombok.Getter;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.Arrays;
/**
* Check authority of user.
*
* @author panjuan
*/
@Getter
public class ProxyAuthorityHandler {
private final AuthPluginData authPluginData;
public ProxyAuthorityHandler() {
authPluginData = new AuthPluginData();
}
/**
* Judege whether it is legal to login into Proxy.
*
* @param username connection username.
* @param authResponse connection auth response.
* @return legal or illegal.
*/
public boolean isLegalForProxyLogin(final String username, final byte[] authResponse) {
byte[] configAuthResponse = getAuthCipherBytes(RuleRegistry.getInstance().getProxyAuthority().getPassword());
String configUsername = RuleRegistry.getInstance().getProxyAuthority().getUsername();
return configUsername.equals(username) && Arrays.equals(configAuthResponse, authResponse);
}
private byte[] getAuthCipherBytes(final String password) {
byte[] sha1Password = DigestUtils.sha1(password);
byte[] doubleSha1Password = DigestUtils.sha1(sha1Password);
byte[] concatBytes = new byte[authPluginData.getAuthPluginData().length + doubleSha1Password.length];
System.arraycopy(authPluginData.getAuthPluginData(), 0, concatBytes, 0, authPluginData.getAuthPluginData().length);
System.arraycopy(doubleSha1Password, 0, concatBytes, authPluginData.getAuthPluginData().length, doubleSha1Password.length);
byte[] sha1ConcatBytes = DigestUtils.sha1(concatBytes);
return xor(sha1Password, sha1ConcatBytes);
}
private byte[] xor(final byte[] input, final byte[] secret) {
final byte[] result = new byte[input.length];
for (int i = 0; i < input.length; ++i) {
result[i] = (byte) (input[i] ^ secret[i]);
}
return result;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册