Advertisement
Guest User

Untitled

a guest
Sep 25th, 2016
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.16 KB | None | 0 0
  1. package com.asteria.net.login;
  2.  
  3. import io.netty.buffer.ByteBuf;
  4. import io.netty.buffer.Unpooled;
  5. import io.netty.channel.ChannelHandlerContext;
  6. import io.netty.handler.codec.ByteToMessageDecoder;
  7.  
  8. import java.math.BigInteger;
  9. import java.util.List;
  10.  
  11. import com.asteria.net.ISAACCipher;
  12. import com.asteria.net.NetworkConstants;
  13. import com.asteria.net.message.LoginDetailsMessage;
  14. import com.asteria.net.message.MessageBuilder;
  15.  
  16. /**
  17. * The {@link ByteToMessageDecoder} implementation that will manage the
  18. * post-handshake section of the login protocol.
  19. *
  20. * @author lare96 <http://github.com/lare96>
  21. */
  22. public final class PostLoginHandshakeHandler extends ByteToMessageDecoder {
  23.  
  24. @Override
  25. protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  26.  
  27. // Read the login type, validate it.
  28. if (in.readableBytes() < 2)
  29. return;
  30.  
  31. int type = in.readByte();
  32. if (type != 16 && type != 18)
  33. throw new Exception("Invalid login type [" + type + "]");
  34.  
  35. // Decode the block length, validate RSA block size.
  36. int blockLength = in.readUnsignedByte();
  37. int loginEncryptPacketSize = blockLength - (36 + 1 + 1 + 2);
  38. if (loginEncryptPacketSize <= 0)
  39. throw new Exception("Invalid RSA packet size [" + loginEncryptPacketSize + "]");
  40. if (in.readableBytes() < blockLength)
  41. return;
  42.  
  43. // Read the client version, validate it.
  44. in.readByte();
  45. int version = in.readShort();
  46. if (version != 317)
  47. throw new Exception("Invalid client version [" + version + "]");
  48.  
  49. // Read and ignore the data for CRC keys.
  50. in.readByte();
  51. for (int i = 0; i < 9; i++)
  52. in.readInt();
  53.  
  54. // Either decode RSA, or proceed normally depending on the network
  55. // settings.
  56. loginEncryptPacketSize--;
  57. in.readByte();
  58. String username = null;
  59. String password = null;
  60. ISAACCipher encryptor = null;
  61. ISAACCipher decryptor = null;
  62. if (NetworkConstants.DECODE_RSA) {
  63. byte[] encryptionBytes = new byte[loginEncryptPacketSize];
  64. in.readBytes(encryptionBytes);
  65. ByteBuf rsaBuffer = Unpooled.wrappedBuffer(new BigInteger(encryptionBytes).modPow(NetworkConstants.RSA_EXPONENT,
  66. NetworkConstants.RSA_MODULUS).toByteArray());
  67. int rsaOpcode = rsaBuffer.readByte();
  68. if (rsaOpcode != 10)
  69. throw new Exception("Invalid RSA opcode [" + rsaOpcode + "]");
  70. long clientHalf = rsaBuffer.readLong();
  71. long serverHalf = rsaBuffer.readLong();
  72. int[] isaacSeed = { (int) (clientHalf >> 32), (int) clientHalf, (int) (serverHalf >> 32), (int) serverHalf };
  73. decryptor = new ISAACCipher(isaacSeed);
  74. for (int i = 0; i < isaacSeed.length; i++)
  75. isaacSeed[i] += 50;
  76. encryptor = new ISAACCipher(isaacSeed);
  77. rsaBuffer.readInt();
  78. MessageBuilder db = MessageBuilder.create(rsaBuffer);
  79. username = db.getString();
  80. password = db.getString();
  81. } else {
  82. in.readByte();
  83. long clientHalf = in.readLong();
  84. long serverHalf = in.readLong();
  85. int[] isaacSeed = { (int) (clientHalf >> 32), (int) clientHalf, (int) (serverHalf >> 32), (int) serverHalf };
  86. decryptor = new ISAACCipher(isaacSeed);
  87. for (int i = 0; i < isaacSeed.length; i++)
  88. isaacSeed[i] += 50;
  89. encryptor = new ISAACCipher(isaacSeed);
  90. in.readInt();
  91. MessageBuilder db = MessageBuilder.create(in);
  92. username = db.getString().toLowerCase().replaceAll("_", " ").trim();
  93. password = db.getString().toLowerCase();
  94. }
  95.  
  96. // Finally, we've decoded all the data we need for the final response of
  97. // the login protocol. Here we send it as an upstream Netty message to
  98. // be handled in the PlayerIO class.
  99. out.add(new LoginDetailsMessage(ctx, username, password, encryptor, decryptor));
  100. }
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement