Guest User

Untitled

a guest
Jan 12th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.51 KB | None | 0 0
  1. /**
  2. * Logger instance.
  3. */
  4. private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
  5.  
  6. /**
  7. * Opcode stage.
  8. */
  9. public static final int STATE_OPCODE = 0;
  10.  
  11. /**
  12. * Login stage.
  13. */
  14. public static final int STATE_LOGIN = 1;
  15.  
  16. /**
  17. * Precrypted stage.
  18. */
  19. public static final int STATE_PRECRYPTED = 2;
  20.  
  21. /**
  22. * Crypted stage.
  23. */
  24. public static final int STATE_CRYPTED = 3;
  25.  
  26. /**
  27. * Update stage.
  28. */
  29. public static final int STATE_CRC = 4;
  30.  
  31. /**
  32. * Server stage.
  33. */
  34. public static final int STATE_UPDATE = 5;
  35.  
  36. /**
  37. * Game opcode.
  38. */
  39. public static final int OPCODE_GAME = 14;
  40.  
  41. /**
  42. * CRCUpdate opcode.
  43. */
  44. public static final int OPCODE_CRC_UPDATE = 15;
  45.  
  46. /**
  47. * Secure random number generator.
  48. */
  49. private static final SecureRandom RANDOM = new SecureRandom();
  50.  
  51. @Override
  52. protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
  53. synchronized (session) {
  54. int state = (Integer) session.getAttribute("state", STATE_OPCODE);
  55. switch (state) {
  56. case STATE_OPCODE :
  57. if (in.remaining() >= 2) {
  58. /*
  59. * Here we read the first opcode which indicates the
  60. * type of connection.
  61. *
  62. * 14 = game 15 = update
  63. *
  64. * Updating is disabled in the vast majority of 317
  65. * clients.
  66. */
  67. int opcode = in.get() & 0xFF;
  68. @SuppressWarnings("unused")
  69. int hash = in.get() & 0xFF;
  70. switch (opcode) {
  71. case OPCODE_GAME :
  72. long serverKey = RANDOM.nextLong();
  73. session.write(new PacketBuilder().put((byte) 0).putLong(serverKey).toPacket());
  74. session.setAttribute("state", STATE_PRECRYPTED);
  75. session.setAttribute("serverKey", serverKey);
  76. return true;
  77. case OPCODE_CRC_UPDATE :
  78. session.setAttribute("state", STATE_CRC);
  79. return true;
  80. default :
  81. logger.info("Invalid opcode : " + opcode);
  82. session.close(false);
  83. break;
  84. }
  85. } else {
  86. in.rewind();
  87. return false;
  88. }
  89. break;
  90. /*
  91. * case STATE_LOGIN: if(in.remaining() >= 1) { /* The name hash
  92. * is a simple hash of the name which is suspected to be used to
  93. * select the appropriate login server.
  94. *//*
  95. * @SuppressWarnings("unused") int nameHash = in.get() &
  96. * 0xFF;
  97. *
  98. * /* We generated the server session key using a
  99. * SecureRandom class for security.
  100. *//*
  101. * long serverKey = RANDOM.nextLong();
  102. *
  103. * /* The initial response is just 0s which the client
  104. * is set to ignore (probably some sort of
  105. * modification).
  106. *//*
  107. * session.write(new
  108. * PacketBuilder().put(INITIAL_RESPONSE).put((byte)
  109. * 0).putLong(serverKey).toPacket());
  110. * session.setAttribute("state", STATE_PRECRYPTED);
  111. * session.setAttribute("serverKey", serverKey);
  112. * return true; } break;
  113. */
  114. case STATE_PRECRYPTED :
  115. if (3 <= in.remaining()) {
  116. /*
  117. * We read the type of login.
  118. *
  119. * 16 = normal 18 = reconnection
  120. */
  121. int loginOpcode = in.get() & 0xFF;
  122. if ((loginOpcode != 16) && (loginOpcode != 18)) {
  123. logger.info("Invalid login opcode : " + loginOpcode);
  124. session.close(false);
  125. in.rewind();
  126. return false;
  127. }
  128. /*
  129. * We read the size of the login packet.
  130. */
  131. int loginSize = in.get() & 0xFF;
  132.  
  133. session.setAttribute("state", STATE_CRYPTED);
  134. session.setAttribute("size", loginSize);
  135. return true;
  136. }
  137. break;
  138. case STATE_CRYPTED :
  139. int size = (Integer) session.getAttribute("size");
  140. // int encryptSize = (Integer)
  141. // session.getAttribute("encryptSize");
  142. if (in.remaining() >= size) {
  143.  
  144. /*
  145. * We now read a short which is the client version and
  146. * check if it equals 317.
  147. */
  148. int version = in.getInt();
  149. if (version != Server.VERSION) {
  150. logger.info("Incorrect version : " + version);
  151. session.close(false);
  152. in.rewind();
  153. return false;
  154. }
  155.  
  156. /*
  157. * No idea what those two does..
  158. */
  159. in.get();
  160. in.get();
  161.  
  162. /*
  163. * The following byte indicates if we are using a low
  164. * memory version.
  165. */
  166. // boolean lowMemoryVersion = (in.get() & 0xFF) == 1;
  167. // logger.info("Login request with lowMemoryVersion : "+lowMemoryVersion);
  168.  
  169. /*
  170. * We know read the cache indices.
  171. */
  172. for (int i = 0; i < 16; i++) {
  173. in.getInt();
  174. }
  175.  
  176. /*
  177. * We now read the encrypted block opcode (although in
  178. * most 317 clients and this server the RSA is disabled)
  179. * and check it is equal to 10.
  180. */
  181. int blockOpcode = in.get() & 0xFF;
  182. if (blockOpcode != 10) {
  183. logger.info("Invalid login block opcode : " + blockOpcode);
  184. session.close(false);
  185. in.rewind();
  186. return false;
  187. }
  188.  
  189. /*
  190. * We read the client's session key.
  191. */
  192. // long clientKey = in.getLong();
  193.  
  194. /*
  195. * And verify it has the correct server session key.
  196. *//*
  197. * long serverKey = (Long)
  198. * session.getAttribute("serverKey"); long
  199. * reportedServerKey = in.getLong();
  200. * if(reportedServerKey != serverKey) {
  201. * logger.info("Server key mismatch (expected : " +
  202. * serverKey + ", reported : " + reportedServerKey +
  203. * ")"); session.close(false); in.rewind(); return
  204. * false; }
  205. */
  206.  
  207. int[] sessionKey = new int[4];
  208. for (int i = 0; i < sessionKey.length; i++) {
  209. sessionKey[i] = in.getInt();
  210. }
  211.  
  212. /*
  213. * The UID, found in random.dat in newer clients and
  214. * uid.dat in older clients is a way of identifying a
  215. * computer.
  216. *
  217. * However, some clients send a hardcoded or random UID,
  218. * making it useless in the private server scene.
  219. */
  220. @SuppressWarnings("unused")
  221. int uid = in.getInt();
  222.  
  223.  
  224. /*
  225. * We read and format the name and passwords.
  226. */
  227. String name = NameUtils.formatName(NameUtils.longToName(in.getLong()));
  228. if (name.length() > 12) {
  229. in.rewind();
  230. return false;
  231. }
  232. String pass = IoBufferUtils.getRS2String(in);
  233. if (pass.length() > 20) {
  234. in.rewind();
  235. return false;
  236. }
  237. logger.info("Login request : username=" + name + " password=" + pass);
  238.  
  239. /*
  240. * And setup the ISAAC cipher which is used to encrypt
  241. * and decrypt opcodes.
  242. *
  243. * However, without RSA, this is rendered useless
  244. * anyway.
  245. */
  246.  
  247. session.removeAttribute("state");
  248. session.removeAttribute("serverKey");
  249. session.removeAttribute("size");
  250. session.removeAttribute("encryptSize");
  251.  
  252. ISAACCipher inCipher = new ISAACCipher(sessionKey);
  253. for (int i = 0; i < 4; i++) {
  254. sessionKey[i] += 50;
  255. }
  256. ISAACCipher outCipher = new ISAACCipher(sessionKey);
  257.  
  258. /*
  259. * Now, the login has completed, and we do the
  260. * appropriate things to fire off the chain of events
  261. * which will load and check the saved games etc.
  262. */
  263. session.getFilterChain().remove("protocol");
  264. session.getFilterChain().addFirst("protocol", new ProtocolCodecFilter(RS2CodecFactory.GAME));
  265.  
  266. PlayerDetails pd = new PlayerDetails(session, name, pass, inCipher, outCipher);
  267. World.getWorld().load(pd);
  268. }
  269. break;
  270. case STATE_CRC :
  271. if (in.remaining() >= 3) {
  272. in.get();
  273. int version = in.getShort();
  274. if (version != Server.VERSION) {
  275. logger.info("Incorrect version : " + version);
  276. session.write(new PacketBuilder().put((byte) 6).toPacket());
  277. session.close(false);
  278. in.rewind();
  279. return false;
  280. }
  281. session.write(new PacketBuilder().put((byte) 0).toPacket());
  282. session.setAttribute("state", STATE_UPDATE);
  283. return true;
  284. }
  285. in.rewind();
  286. return false;
  287. case STATE_UPDATE :
  288. if (8 <= in.remaining()) {
  289. for (int i = 0; i < 8; i++) {
  290. in.get();
  291. }
  292. PacketBuilder ukeys = new PacketBuilder();
  293. for (int key : Constants.UPDATE_KEYS) {
  294. ukeys.put((byte) key);
  295. }
  296. session.write(ukeys.toPacket());
  297. session.close(false);
  298. return true;
  299. }
  300. break;
  301. }
  302. in.rewind();
  303. return false;
  304. }
  305. }
  306.  
  307. }
Add Comment
Please, Sign In to add comment