use of com.alibaba.otter.canal.protocol.AdminPacket.ClientAuth in project canal by alibaba.
the class ClientAuthenticationHandler method messageReceived.
public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception {
ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
final Packet packet = Packet.parseFrom(buffer.readBytes(buffer.readableBytes()).array());
switch(packet.getVersion()) {
case SUPPORTED_VERSION:
default:
final ClientAuth clientAuth = ClientAuth.parseFrom(packet.getBody());
if (seed == null) {
byte[] errorBytes = AdminNettyUtils.errorPacket(300, MessageFormatter.format("auth failed for seed is null", clientAuth.getUsername()).getMessage());
AdminNettyUtils.write(ctx.getChannel(), errorBytes);
}
if (!canalAdmin.auth(clientAuth.getUsername(), clientAuth.getPassword().toStringUtf8(), seed)) {
byte[] errorBytes = AdminNettyUtils.errorPacket(300, MessageFormatter.format("auth failed for user:{}", clientAuth.getUsername()).getMessage());
AdminNettyUtils.write(ctx.getChannel(), errorBytes);
}
byte[] ackBytes = AdminNettyUtils.ackPacket();
AdminNettyUtils.write(ctx.getChannel(), ackBytes, future -> {
logger.info("remove unused channel handlers after authentication is done successfully.");
ctx.getPipeline().remove(HandshakeInitializationHandler.class.getName());
ctx.getPipeline().remove(ClientAuthenticationHandler.class.getName());
int readTimeout = defaultSubscriptorDisconnectIdleTimeout;
int writeTimeout = defaultSubscriptorDisconnectIdleTimeout;
if (clientAuth.getNetReadTimeout() > 0) {
readTimeout = clientAuth.getNetReadTimeout();
}
if (clientAuth.getNetWriteTimeout() > 0) {
writeTimeout = clientAuth.getNetWriteTimeout();
}
// fix bug: soTimeout parameter's unit from connector is
// millseconds.
IdleStateHandler idleStateHandler = new IdleStateHandler(NettyUtils.hashedWheelTimer, readTimeout, writeTimeout, 0, TimeUnit.MILLISECONDS);
ctx.getPipeline().addBefore(SessionHandler.class.getName(), IdleStateHandler.class.getName(), idleStateHandler);
IdleStateAwareChannelHandler idleStateAwareChannelHandler = new IdleStateAwareChannelHandler() {
public void channelIdle(ChannelHandlerContext ctx1, IdleStateEvent e1) throws Exception {
logger.warn("channel:{} idle timeout exceeds, close channel to save server resources...", ctx1.getChannel());
ctx1.getChannel().close();
}
};
ctx.getPipeline().addBefore(SessionHandler.class.getName(), IdleStateAwareChannelHandler.class.getName(), idleStateAwareChannelHandler);
});
break;
}
}
use of com.alibaba.otter.canal.protocol.AdminPacket.ClientAuth in project canal by alibaba.
the class SimpleAdminConnector method connect.
@Override
public void connect() throws ServiceException {
try {
if (connected) {
return;
}
channel = SocketChannel.open();
channel.socket().setSoTimeout(soTimeout);
channel.connect(address);
readableChannel = Channels.newChannel(channel.socket().getInputStream());
writableChannel = Channels.newChannel(channel.socket().getOutputStream());
Packet p = Packet.parseFrom(readNextPacket());
if (p.getVersion() != 1) {
throw new CanalClientException("unsupported version at this client.");
}
if (p.getType() != PacketType.HANDSHAKE) {
throw new CanalClientException("expect handshake but found other type.");
}
Handshake handshake = Handshake.parseFrom(p.getBody());
// seed for auth
ByteString seed = handshake.getSeeds();
String newPasswd = passwd;
if (passwd != null) {
// encode passwd
newPasswd = SecurityUtil.byte2HexStr(SecurityUtil.scramble411(passwd.getBytes(), seed.toByteArray()));
}
ClientAuth ca = ClientAuth.newBuilder().setUsername(user != null ? user : "").setPassword(ByteString.copyFromUtf8(newPasswd != null ? newPasswd : "")).setNetReadTimeout(idleTimeout).setNetWriteTimeout(idleTimeout).build();
writeWithHeader(Packet.newBuilder().setType(PacketType.CLIENTAUTHENTICATION).setBody(ca.toByteString()).build().toByteArray());
//
Packet ack = Packet.parseFrom(readNextPacket());
if (ack.getType() != PacketType.ACK) {
throw new CanalClientException("unexpected packet type when ack is expected");
}
Ack ackBody = Ack.parseFrom(ack.getBody());
if (ackBody.getCode() > 0) {
throw new ServiceException("something goes wrong when doing authentication: " + ackBody.getMessage());
}
connected = true;
} catch (IOException | NoSuchAlgorithmException e) {
throw new ServiceException(e);
}
}
Aggregations