Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.91 KB | None | 0 0
  1.  
  2.  
  3. /**
  4. *
  5. * @author Stuart Murphy
  6. *
  7. */
  8. public class LoginDecoder extends FrameDecoder {
  9.  
  10. /**
  11. * Client version
  12. */
  13. public static final int CLIENT_VERSION = 10;
  14.  
  15. /**
  16. * Connected login state
  17. */
  18. private static final int CONNECTED = 0;
  19. /**
  20. * Logging in login state
  21. */
  22. private static final int LOGGING_IN = 1;
  23.  
  24. /**
  25. * Current login state
  26. */
  27. private int state = CONNECTED;
  28.  
  29. @Override
  30. protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer in) throws Exception {
  31. if (!channel.isConnected()) {
  32. return null;
  33. }
  34. switch (state) {
  35. case CONNECTED:
  36. if (in.readableBytes() < 2) {
  37. return null;
  38. }
  39.  
  40. // Validate the request
  41. int request = in.readUnsignedByte();
  42.  
  43. if (request == 5) {
  44. sendReturnCode(channel, Utility.LOGIN_RESPONSE_COULD_NOT_COMPLETE_LOGIN);// system
  45. // ban
  46. return null;
  47. }
  48.  
  49. if (request != 14) {
  50. System.out.println("Invalidsss login request: " + request);
  51. channel.close();
  52. return null;
  53. }
  54.  
  55. // Name hash
  56. in.readUnsignedByte();
  57.  
  58. // Write the response.
  59. StreamBuffer.OutBuffer out = StreamBuffer.newOutBuffer(17);
  60. out.writeLong(0); // First 8 bytes are ignored by the client.
  61. out.writeByte(0); // The response opcode, 0 for logging in.
  62. out.writeLong((new SecureRandom().nextLong() / 2) + (new SecureRandom().nextLong() / 2)); // SSK.
  63. channel.write(out.getBuffer());
  64.  
  65. state = LOGGING_IN;
  66. break;
  67. case LOGGING_IN:
  68. if (in.readableBytes() < 2) {
  69. return null;
  70. }
  71.  
  72. // Validate the login type
  73. int loginType = in.readUnsignedByte();
  74. if (loginType != 16 && loginType != 18) {
  75. System.out.println("Invalid login type: " + loginType);
  76. channel.close();
  77. return null;
  78. }
  79.  
  80. // Make sure we have the complete login block
  81. int blockLength = in.readUnsignedByte();
  82. int loginEncryptSize = blockLength - (36 + 1 + 1 + 2);
  83. if (loginEncryptSize <= 0) {
  84. System.out.println("Encrypted packet size zero or negative: " + loginEncryptSize);
  85. channel.close();
  86. return null;
  87. }
  88.  
  89. in.readUnsignedByte(); // Magic id
  90.  
  91. // Validate the client version
  92. int clientVersion = in.readUnsignedShort();
  93. int currentVersion = 217 + CLIENT_VERSION;
  94. if (clientVersion != currentVersion) {
  95. System.out.println("Invalid client version, Received: " + clientVersion + " Expected: " + currentVersion);
  96. StreamBuffer.OutBuffer resp = StreamBuffer.newOutBuffer(3);
  97. resp.writeByte(Utility.LOGIN_RESPONSE_UPDATED);
  98. resp.writeByte(0);
  99. resp.writeByte(0);
  100. channel.write(resp.getBuffer());
  101. channel.close();
  102. return null;
  103. }
  104.  
  105. // High/low memory
  106. in.readByte();
  107.  
  108. // Skip the CRC keys.
  109. for (int i = 0; i < 9; i++) {
  110. in.readInt();
  111. }
  112.  
  113. // Skip RSA block length.
  114. in.readByte();
  115.  
  116. // Validate that the RSA block was decoded properly.
  117. int rsaOpcode = in.readByte();
  118. if (rsaOpcode != 100) {
  119. System.err.println("Unable to decode RSA block properly!");
  120. channel.close();
  121. return null;
  122. }
  123.  
  124. // Set up the ISAAC ciphers.
  125. long clientHalf = in.readLong();
  126. long serverHalf = in.readLong();
  127. int[] isaacSeed = { (int) (clientHalf >> 32), (int) clientHalf, (int) (serverHalf >> 32), (int) serverHalf };
  128. ISAACCipher inCipher = new ISAACCipher(isaacSeed);
  129. for (int i = 0; i < isaacSeed.length; i++) {
  130. isaacSeed[i] += 50;
  131. }
  132. ISAACCipher outCipher = new ISAACCipher(isaacSeed);
  133.  
  134. int version = in.readInt();
  135.  
  136. String uid = Utility.getRS2String(in);
  137.  
  138. String username = Utility.getRS2String(in).trim();
  139. String password = Utility.getRS2String(in);
  140.  
  141. return login(channel, inCipher, outCipher, version, username, password, uid);
  142. }
  143. return null;
  144. }
  145.  
  146. /**
  147. * Login
  148. *
  149. * @param channel
  150. * @param inCipher
  151. * @param outCipher
  152. * @param version
  153. * @param name
  154. * @param pass
  155. * @param uid
  156. * @return
  157. */
  158. private static Client login(Channel channel, ISAACCipher inCipher, ISAACCipher outCipher, int version, String name, String pass, String uid) {
  159.  
  160. // Validate name
  161. if (!name.matches("[A-Za-z0-9 ]+") || name.length() > 12 || name.length() <= 0) {
  162. sendReturnCode(channel, Utility.LOGIN_RESPONSE_INVALID_CREDENTIALS);
  163. return null;
  164. }
  165. String hostName = ((InetSocketAddress) channel.getRemoteAddress()).getAddress().getHostName();
  166.  
  167. if (HostBlacklist.isBlocked(hostName))
  168. sendReturnCode(channel, Utility.LOGIN_RESPONSE_INVALID_CREDENTIALS);
  169.  
  170. if (Constants.STAFF_ONLY) {
  171. boolean isStaff = false;
  172. for (String usernames : Constants.STAFF_MEMBERS) {
  173. if (name.equalsIgnoreCase(usernames)) {
  174. isStaff = true;
  175. }
  176. }
  177. if (!isStaff) {
  178. sendReturnCode(channel, Utility.LOGIN_RESPONSE_INVALID_USERNAME);
  179. return null;
  180. }
  181. }
  182.  
  183. for (String retard : Constants.BAD_USERNAMES) {
  184. if (name.toLowerCase().contains(retard.toLowerCase())) {
  185. sendReturnCode(channel, Utility.LOGIN_RESPONSE_INVALID_USERNAME);
  186. return null;
  187. }
  188. }
  189.  
  190. if (World.worldUpdating) {
  191. sendReturnCode(channel, Utility.LOGIN_RESPONSE_SERVER_BEING_UPDATED);
  192. return null;
  193. }
  194.  
  195. name = name.trim();
  196.  
  197. channel.getPipeline().remove("decoder");
  198. channel.getPipeline().addFirst("decoder", new Decoder(inCipher));
  199.  
  200. Client client = new Client(channel);
  201. client.getPlayer().setUid(uid);
  202. client.getPlayer().setUsername(name);
  203. client.getPlayer().setDisplay(name);
  204. client.getPlayer().setPassword(pass);
  205. client.setEnteredPassword(pass);
  206. client.setEncryptor(outCipher);
  207. return client;
  208. }
  209.  
  210. /**
  211. * Send return code
  212. *
  213. * @param channel
  214. * @param code
  215. */
  216. public static void sendReturnCode(Channel channel, int code) {
  217. // Write the response.
  218. StreamBuffer.OutBuffer out = StreamBuffer.newOutBuffer(1);
  219. out.writeByte(code); // First 8 bytes are ignored by the client.
  220.  
  221. channel.write(out.getBuffer()).addListener(new ChannelFutureListener() {
  222. @Override
  223. public void operationComplete(final ChannelFuture arg0) throws Exception {
  224. arg0.getChannel().close();
  225. }
  226. });
  227. }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement