Typhome

Untitled

Aug 1st, 2015
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. public void handleLogin(Player player, ByteBuffer inData) throws Exception {
  2. switch (player.getLoginStage()) {
  3. case CONNECTED:
  4. if (inData.remaining() < 2) {
  5. inData.compact();
  6. return;
  7. }
  8.  
  9. // Validate the request.
  10. int request = inData.get() & 0xff;
  11. inData.get(); // Name hash.
  12. if (request != 14) {
  13. System.err.println("Invalid login request: " + request);
  14. player.disconnect();
  15. return;
  16. }
  17.  
  18. // Write the response.
  19. StreamBuffer.OutBuffer out = StreamBuffer.newOutBuffer(17);
  20. out.writeLong(0); // First 8 bytes are ignored by the client.
  21. out.writeByte(0); // The response opcode, 0 for logging in.
  22. out.writeLong(new SecureRandom().nextLong()); // SSK.
  23. player.send(out.getBuffer());
  24.  
  25. player.setLoginStage(LoginStages.LOGGING_IN);
  26. break;
  27. case LOGGING_IN:
  28. if (inData.remaining() < 2) {
  29. inData.compact();
  30. return;
  31. }
  32.  
  33. // Validate the login type.
  34. int loginType = inData.get();
  35. if (loginType != 16 && loginType != 18) {
  36. System.err.println("Invalid login type: " + loginType);
  37. player.disconnect();
  38. return;
  39. }
  40.  
  41. // Ensure that we can read all of the login block.
  42. int blockLength = inData.get() & 0xff;
  43. int loginEncryptSize = blockLength - (36 + 1 + 1 + 2);
  44. if (inData.remaining() < blockLength) {
  45. inData.compact();
  46. return;
  47. }
  48.  
  49. // Read the login block.
  50. StreamBuffer.InBuffer in = StreamBuffer.newInBuffer(inData);
  51.  
  52. // Set the magic id
  53. player.setMagicId(in.readByte());
  54.  
  55. // Set the client version.
  56. player.setClientVersion(in.readShort());
  57.  
  58. in.readByte(); // Skip the high/low memory version.
  59.  
  60. // Skip the CRC keys.
  61. for (int i = 0; i < 9; i++) {
  62. in.readInt();
  63. }
  64. if (Constants.RSA_CHECK) {
  65. loginEncryptSize--;
  66. int reportedSize = inData.get() & 0xFF;
  67. if (reportedSize != loginEncryptSize) {
  68. System.err
  69. .println("Encrypted packet size zero or negative : "
  70. + loginEncryptSize);
  71. player.disconnect();
  72. return;
  73. }
  74. byte[] encryptionBytes = new byte[loginEncryptSize];
  75. inData.get(encryptionBytes);
  76. ByteBuffer rsaBuffer = ByteBuffer.wrap(new BigInteger(
  77. encryptionBytes).modPow(RSA_EXPONENT, RSA_MODULUS)
  78. .toByteArray());
  79. int rsaOpcode = rsaBuffer.get() & 0xFF;
  80. // Validate that the RSA block was decoded properly.
  81. if (rsaOpcode != 10) {
  82. System.err.println("Unable to decode RSA block properly!");
  83. player.disconnect();
  84. return;
  85. }
  86. long clientHalf = rsaBuffer.getLong();
  87. long serverHalf = rsaBuffer.getLong();
  88. int[] isaacSeed = { (int) (clientHalf >> 32), (int) clientHalf,
  89. (int) (serverHalf >> 32), (int) serverHalf };
  90. player.setDecryptor(new ISAACCipher(isaacSeed));
  91. for (int i = 0; i < isaacSeed.length; i++) {
  92. isaacSeed[i] += 50;
  93. }
  94. player.setEncryptor(new ISAACCipher(isaacSeed));
  95. rsaBuffer.getInt();
  96. String username = NameUtil.getRS2String(rsaBuffer).trim()
  97. .replaceAll("([\\s._\\s])\\1+", "$1");
  98. String password = NameUtil.getRS2String(rsaBuffer).trim();
  99. player.setPassword(password);
  100. player.setUsername(NameUtil.uppercaseFirstLetter(username));
  101. } else {
  102. in.readByte(); // Skip RSA block length.
  103. // Validate that the RSA block was decoded properly.
  104. int rsaOpcode = in.readByte();
  105. if (rsaOpcode != 10) {
  106. System.err.println("Unable to decode RSA block properly!");
  107. player.disconnect();
  108. return;
  109. }
  110. // Set up the ISAAC ciphers.
  111. long clientHalf = in.readLong();
  112. long serverHalf = in.readLong();
  113. int[] isaacSeed = { (int) (clientHalf >> 32), (int) clientHalf,
  114. (int) (serverHalf >> 32), (int) serverHalf };
  115. player.setDecryptor(new ISAACCipher(isaacSeed));
  116. for (int i = 0; i < isaacSeed.length; i++) {
  117. isaacSeed[i] += 50;
  118. }
  119. player.setEncryptor(new ISAACCipher(isaacSeed));
  120.  
  121. // Read the user authentication.
  122. int uid = in.readInt(); // Skip the user ID.
  123. System.out.println("uid: " + uid);
  124. player.setUid(uid);
  125. String username = in.readString().trim();
  126. String password = in.readString().toLowerCase().trim();
  127. player.setPassword(password);
  128. player.setUsername(NameUtil.uppercaseFirstLetter(username));
  129. }
  130.  
  131. player.setUsernameAsLong(NameUtil.nameToLong(player.getUsername()
  132. .toLowerCase()));
  133. player.setLoginStage(LoginStages.AWAITING_LOGIN_COMPLETE);
  134.  
  135. if (player.beginLogin()) {
  136. // Switch the player to the cycled reactor.
  137. synchronized (DedicatedReactor.getInstance()) {
  138. DedicatedReactor.getInstance().getSelector().wakeup();
  139. player.getKey().interestOps(
  140. player.getKey().interestOps()
  141. & ~SelectionKey.OP_READ);
  142. player.getSocketChannel().register(
  143. Server.getSingleton().getSelector(),
  144. SelectionKey.OP_READ, player);
  145. }
  146. }
  147. break;
  148. }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment