Advertisement
Guest User

Untitled

a guest
Jun 1st, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.63 KB | None | 0 0
  1. @Override
  2. protected Object decode(ChannelHandlerContext ctx, Channel channel,
  3. ChannelBuffer buffer) throws Exception {
  4. switch (state) {
  5. /*
  6. * The login handshake
  7. */
  8. case LOGIN_HANDSHAKE:
  9. if (buffer.readableBytes() >= 1) {
  10. /*
  11. * The name hash is a simple hash of the name which is suspected
  12. * to be used to select the appropriate login server.
  13. */
  14. @SuppressWarnings("unused")
  15. int nameHash = buffer.readByte() & 0xFF;
  16.  
  17. /*
  18. * We generated the server session key using a SecureRandom
  19. * class for security.
  20. */
  21. serverKey = RANDOM.nextLong();
  22.  
  23. /*
  24. * The initial response is just 0s which the client is set to
  25. * ignore (probably some sort of modification).
  26. */
  27. ChannelBuffer resp = ChannelBuffers.buffer(9);
  28. /*
  29. * This is the return code (just like the login return code 2
  30. * allows the session to login) This allows session keys to be
  31. * exchanged
  32. *
  33. * Warning, If this is skipped it makes a null pointer exception
  34. * and no ISAAC cipher is used
  35. */
  36. resp.writeByte(0);
  37. /*
  38. * This is sent so the ISAAC server and client side both use
  39. * that key.
  40. */
  41. resp.writeLong(serverKey);
  42. /*
  43. * We now write the data to the client
  44. */
  45. channel.write(resp);
  46. /*
  47. * Changes the state for the next part of the login
  48. */
  49. setLoginState(LoginState.LOGIN_HEADER);
  50. }
  51. break;
  52.  
  53. /*
  54. * The login header
  55. */
  56. case LOGIN_HEADER:
  57. if (buffer.readableBytes() >= 3) {
  58. /*
  59. * We read the type of login.
  60. *
  61. * 16 = normal 18 = reconnection
  62. */
  63. int loginOpcode = buffer.readByte() & 0xff;
  64. if (loginOpcode != 16 && loginOpcode != 18) {
  65. channel.close();
  66. }
  67. /*
  68. * We read the size of the login packet.
  69. */
  70. loginSize = buffer.readShort() & 0xFFFF;
  71. setLoginState(LoginState.LOGIN_PAYLOAD);
  72. }
  73. break;
  74.  
  75. /**
  76. * The login payload
  77. */
  78. case LOGIN_PAYLOAD:
  79. if (buffer.readableBytes() >= loginSize) {
  80.  
  81. /*
  82. * Reads the client version as an Integer data type.
  83. */
  84. int version = buffer.readInt();
  85. if (version != CLIENT_VERSION) {
  86. channel.close();
  87. }
  88. /*
  89. * Maybe a flag?
  90. */
  91. buffer.readByte();
  92.  
  93. /*
  94. * checks if the client is on low memory Most likely to tell the
  95. * server not to play sounds and such
  96. */
  97. boolean isLowMemory = (buffer.readByte() & 0xff) == 1 ? true
  98. : false;
  99. /*
  100. * checks if the client is HD
  101. */
  102. boolean isHD = (buffer.readByte() & 0xff) == 1 ? true : false;
  103. /*
  104. * There are different view points in HD
  105. *
  106. * 0 = Stand Detail
  107. * 1 = Fixed HD
  108. * 2 = Resizable HD Screen
  109. * 4 = Fixed Fullscreen
  110. */
  111. byte hdType = (byte) (buffer.readByte() & 0xff);
  112. /*
  113. * We now check what detail the client is and set it
  114. */
  115. GraphicDetail details = GraphicDetail.NORMAL;
  116. /*
  117. * The different hd types
  118. */
  119. switch (hdType) {
  120. case 0:
  121. /*
  122. * The standard detail.
  123. */
  124. details = GraphicDetail.NORMAL;
  125. break;
  126. case 1:
  127. /*
  128. * The fixed HD detail.
  129. */
  130. details = GraphicDetail.HD_FIXED;
  131. break;
  132. case 2:
  133. /*
  134. * The HD resizable detail.
  135. */
  136. details = GraphicDetail.HD_RESIZABLE;
  137. break;
  138. case 3:
  139. /*
  140. * The HD full screen detail.
  141. */
  142. details = GraphicDetail.HD_FULLSCREEN;
  143. break;
  144. }
  145. /*
  146. * We read the clientWidth, this is probably used to define something server side and to check
  147. * if the client doesn't exceed to a certain size client crashes when its resized to a certain smaller size
  148. * but it is probably also used to stop some types of Anti Cheating from the mouse click.
  149. */
  150. short clientWidth = (short) (buffer.readShort() & 0xffff);
  151. /*
  152. * We read the clientHeight, this is probably used to define something server side and to check
  153. * if the client doesn't exceed to a certain height size since the client crashes when its resized to a certain smaller size
  154. * but it is probably also used to stop some types of Anti Cheating from the mouse click.
  155. */
  156. short clientHeight = (short) (buffer.readShort() & 0xffff);
  157. /*
  158. * Maybe a flag?
  159. */
  160. buffer.readByte();
  161. /*
  162. * The client settings array
  163. */
  164. byte[] clientSettings = new byte[24];
  165. /*
  166. * In client sends as a 24 byte array of write bytes this is
  167. * probably some client setting sent on the players login.
  168. */
  169. for (int i = 0; i < 24; i++) {
  170. clientSettings[i] = buffer.readByte();
  171. }
  172. /*
  173. * A key from the client/loader
  174. * This key is just the "Settings" parameter from the loader, this is most likely used
  175. * to check if it matches the official setting key else it will report it back to jagex
  176. * and they will know you're using 3rd parter software.
  177. */
  178. ChannelBufferUtils.getRS2String(buffer);
  179. /*
  180. * maybe the random.dat value
  181. */
  182. buffer.readInt();
  183. /*
  184. * Not sure
  185. */
  186. buffer.readInt();
  187. /*
  188. * Not sure
  189. */
  190. buffer.readShort();
  191. /*
  192. * The cache index's CRC values (probably used to check the
  193. * local Cache CRC values are the same as the official Runescape
  194. * one)
  195. */
  196. for (int i = 0; i < 28; i++) {
  197. buffer.readInt();
  198. }
  199. /*
  200. * The amount of bytes
  201. */
  202. int rsaPayloadSize = buffer.readByte() & 0xFF;
  203. /*
  204. * The rsaPayload
  205. */
  206. byte[] rsaPayload = new byte[rsaPayloadSize];
  207. /*
  208. * The main buffer reads the bytes
  209. */
  210. buffer.readBytes(rsaPayload);
  211. /*
  212. * The encrypted buffer for RSA
  213. */
  214. ChannelBuffer rsaBuffer = ChannelBuffers
  215. .wrappedBuffer(new BigInteger(rsaPayload).modPow(
  216. RSA_PRIVATE, RSA_MODULE).toByteArray());
  217. /*
  218. * We now read the encrypted block opcode (although in most clients
  219. * and this server the RSA is disabled) and check it is equal to 10.
  220. */
  221. int blockOpcode = rsaBuffer.readByte() & 0xFF;
  222. if (blockOpcode != 10) {
  223. logger.info("Invalid login block opcode : " + blockOpcode);
  224. channel.close();
  225. }
  226.  
  227. /*
  228. * We read the clients session key.
  229. */
  230. long clientKey = rsaBuffer.readLong();
  231.  
  232. /*
  233. * We verify it has the correct server session key.
  234. */
  235. long reportedServerKey = rsaBuffer.readLong();
  236. if (reportedServerKey != serverKey) {
  237. logger.info("Server key mismatch (expected : " + serverKey
  238. + ", reported : " + reportedServerKey + ")");
  239. channel.close();
  240. }
  241.  
  242. String username = StringUtils.longToName(rsaBuffer.readLong());
  243. String password = ChannelBufferUtils.getRS2String(rsaBuffer);
  244. logger.info("Login request : username=" + username
  245. + " password=" + password);
  246.  
  247. /*
  248. * And setup the ISAAC cipher which is used to encrypt and
  249. * decrypt opcodes.
  250. */
  251. int[] sessionKey = new int[4];
  252. sessionKey[0] = (int) (clientKey >> 32);
  253. sessionKey[1] = (int) clientKey;
  254. sessionKey[2] = (int) (serverKey >> 32);
  255. sessionKey[3] = (int) serverKey;
  256.  
  257. ISAACCipher in = new ISAACCipher(sessionKey);
  258. for (int i = 0; i < sessionKey.length; i++) {
  259. sessionKey[i] += 50;
  260. }
  261. ISAACCipher out = new ISAACCipher(sessionKey);
  262. /*
  263. * We now return a new <code>PlayerDetails</code> which will
  264. * fire to the ChannelHandler.
  265. */
  266. return new PlayerDetails(username, password, isHD, details,
  267. clientWidth, clientHeight, isLowMemory, in, out, clientSettings);
  268. }
  269. }
  270. return null;
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement