Advertisement
Guest User

Rs2LoginProtocolDecoder

a guest
Aug 21st, 2014
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.13 KB | None | 0 0
  1. package server.net;
  2.  
  3. import org.apache.mina.common.ByteBuffer;
  4. import org.apache.mina.common.IoFuture;
  5. import org.apache.mina.common.IoFutureListener;
  6. import org.apache.mina.common.IoSession;
  7. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
  8. import org.apache.mina.filter.codec.ProtocolCodecFilter;
  9. import org.apache.mina.filter.codec.ProtocolDecoderOutput;
  10.  
  11. import java.math.BigInteger;
  12. import java.net.InetSocketAddress;
  13.  
  14. import server.Constants;
  15. import server.Connection;
  16. import server.Server;
  17. import server.game.players.Client;
  18. import server.game.players.PlayerHandler;
  19. import server.game.players.PlayerSave;
  20. import server.util.HostBlacklist;
  21. import server.util.ISAACRandomGen;
  22.  
  23. /**
  24. * Login protocol decoder.
  25. *
  26. * @author Graham
  27. * @author Ryan / Lmctruck30 <- login Protocol fixes
  28. *
  29. */
  30. public class RS2LoginProtocolDecoder extends CumulativeProtocolDecoder {
  31.  
  32. private static final BigInteger RSA_MODULUS = new BigInteger("91553247461173033466542043374346300088148707506479543786501537350363031301992107112953015516557748875487935404852620239974482067336878286174236183516364787082711186740254168914127361643305190640280157664988536979163450791820893999053469529344247707567448479470137716627440246788713008490213212272520901741443");
  33. private static final BigInteger RSA_EXPONENT = new BigInteger("33280025241734061313051117678670856264399753710527826596057587687835856000539511539311834363046145710983857746766009612538140077973762171163294453513440619295457626227183742315140865830778841533445402605660729039310637444146319289077374748018792349647460850308384280105990607337322160553135806205784213241305");
  34.  
  35.  
  36. /**
  37. * Parses the data in the provided byte buffer and writes it to
  38. * <code>out</code> as a <code>Packet</code>.
  39. *
  40. * @param session
  41. * The IoSession the data was read from
  42. * @param in
  43. * The buffer
  44. * @param out
  45. * The decoder output stream to which to write the
  46. * <code>Packet</code>
  47. * @return Whether enough data was available to create a packet
  48. */
  49. @Override
  50. public boolean doDecode(IoSession session, ByteBuffer in,
  51. ProtocolDecoderOutput out) {
  52. synchronized (session) {
  53. Object loginStageObj = session.getAttribute("LOGIN_STAGE");
  54. int loginStage = 0;
  55. if (loginStageObj != null) {
  56. loginStage = (Integer) loginStageObj;
  57. }
  58. // Logger.log("recv login packet, stage: "+loginStage);
  59. switch (loginStage) {
  60. case 0:
  61. if (2 <= in.remaining()) {
  62. int protocol = in.get() & 0xff;
  63. @SuppressWarnings("unused")
  64. int nameHash = in.get() & 0xff;
  65. if (protocol == 14) {
  66. long serverSessionKey = ((long) (java.lang.Math
  67. .random() * 99999999D) << 32)
  68. + (long) (java.lang.Math.random() * 99999999D);
  69. StaticPacketBuilder s1Response = new StaticPacketBuilder();
  70. s1Response
  71. .setBare(true)
  72. .addBytes(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 })
  73. .addByte((byte) 0).addLong(serverSessionKey);
  74. session.setAttribute("SERVER_SESSION_KEY",
  75. serverSessionKey);
  76. session.write(s1Response.toPacket());
  77. session.setAttribute("LOGIN_STAGE", 1);
  78. }
  79. return true;
  80. } else {
  81. in.rewind();
  82. return false;
  83. }
  84. case 1:
  85. @SuppressWarnings("unused")
  86. int loginType = -1,
  87. loginPacketSize = -1,
  88. loginEncryptPacketSize = -1;
  89. if (2 <= in.remaining()) {
  90. loginType = in.get() & 0xff; // should be 16 or 18
  91. loginPacketSize = in.get() & 0xff;
  92. loginEncryptPacketSize = loginPacketSize - (36 + 1 + 1 + 2);
  93. if (loginPacketSize <= 0 || loginEncryptPacketSize <= 0) {
  94. System.out.println("Zero or negative login size.");
  95. session.close();
  96. return false;
  97. }
  98. } else {
  99. in.rewind();
  100. return false;
  101. }
  102. if (loginPacketSize <= in.remaining()) {
  103. int magic = in.get() & 0xff;
  104. int version = in.getUnsignedShort();
  105. if (magic != 255) {
  106. // System.out.println("Wrong magic id.");
  107. session.close();
  108. return false;
  109. }
  110. if (version != 1) {
  111. // Dont Add Anything
  112. }
  113. @SuppressWarnings("unused")
  114. int lowMem = in.get() & 0xff;
  115. for (int i = 0; i < 9; i++) {
  116. in.getInt();
  117. }
  118. loginEncryptPacketSize--;
  119. if(loginEncryptPacketSize != (in.get() & 0xff)) {
  120. System.out.println("Encrypted size mismatch.");
  121. session.close();
  122. return false;
  123. }
  124. byte[] encryptionBytes = new byte[loginEncryptPacketSize];
  125. in.get(encryptionBytes);
  126. ByteBuffer rsaBuffer = ByteBuffer.wrap(new BigInteger(encryptionBytes) .modPow(RSA_EXPONENT, RSA_MODULUS).toByteArray());
  127. if((rsaBuffer.get() & 0xff) != 10) {
  128. System.out.println("Encrypted id != 10.");
  129. session.close();
  130. return false;
  131. }
  132. long clientSessionKey = rsaBuffer.getLong();
  133. long serverSessionKey = rsaBuffer.getLong();
  134. int uid = rsaBuffer.getInt();
  135. if(uid != 275802413) {
  136. session.close();
  137. return false;
  138. }
  139.  
  140. String name = readRS2String(rsaBuffer);
  141. String pass = readRS2String(rsaBuffer);
  142. int sessionKey[] = new int[4];
  143. sessionKey[0] = (int) (clientSessionKey >> 32);
  144. sessionKey[1] = (int) clientSessionKey;
  145. sessionKey[2] = (int) (serverSessionKey >> 32);
  146. sessionKey[3] = (int) serverSessionKey;
  147. ISAACRandomGen inC = new ISAACRandomGen(sessionKey);
  148. for (int i = 0; i < 4; i++)
  149. sessionKey[i] += 50;
  150. ISAACRandomGen outC = new ISAACRandomGen(sessionKey);
  151. load(session, uid, name, pass, inC, outC, version);
  152. session.getFilterChain().remove("protocolFilter");
  153. session.getFilterChain().addLast("protocolFilter", new ProtocolCodecFilter(new GameCodecFactory(inC)));
  154. return true;
  155. } else {
  156. in.rewind();
  157. return false;
  158. }
  159. }
  160. }
  161. return false;
  162. }
  163.  
  164. private synchronized void load(final IoSession session, final int uid, String name, String pass, final ISAACRandomGen inC, ISAACRandomGen outC, int version) {
  165. session.setAttribute("opcode", -1);
  166. session.setAttribute("size", -1);
  167. int loginDelay = 1;
  168. int returnCode = 2;
  169.  
  170. name = name.trim();
  171. name = name.toLowerCase();
  172. //pass = pass.toLowerCase();
  173. String hostName = ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostName();
  174.  
  175. if (HostBlacklist.isBlocked(hostName)) {
  176. returnCode = 11;
  177. }
  178.  
  179. if (!name.matches("[A-Za-z0-9 ]+")) {
  180. returnCode = 4;
  181. }
  182.  
  183. if (name.length() > 12) {
  184. returnCode = 8;
  185. }
  186.  
  187. Client cl = new Client(session, -1);
  188. cl.playerName = name;
  189. cl.playerName2 = cl.playerName;
  190. cl.playerPass = pass;
  191. cl.setInStreamDecryption(inC);
  192. cl.setOutStreamDecryption(outC);
  193. cl.outStream.packetEncryption = outC;
  194.  
  195. cl.saveCharacter = false;
  196.  
  197. char first = name.charAt(0);
  198. cl.properName = Character.toUpperCase(first) + name.substring(1, name.length());
  199.  
  200. if (Connection.isNamedBanned(cl.playerName)) {
  201. returnCode = 4;
  202. }
  203.  
  204. if (PlayerHandler.isPlayerOn(name)) {
  205. returnCode = 5;
  206. }
  207.  
  208. if (PlayerHandler.playerCount >= Constants.MAX_PLAYERS) {
  209. returnCode = 7;
  210. }
  211.  
  212. if (Server.UpdateServer) {
  213. returnCode = 14;
  214. }
  215.  
  216. if (returnCode == 2) {
  217. int load = PlayerSave.loadGame(cl, cl.playerName, cl.playerPass);
  218. if (load == 0)
  219. cl.addStarter = true;
  220. if (load == 3) {
  221. returnCode = 3;
  222. cl.saveFile = false;
  223. } else {
  224. for (int i = 0; i < cl.playerEquipment.length; i++) {
  225. if (cl.playerEquipment[i] == 0) {
  226. cl.playerEquipment[i] = -1;
  227. cl.playerEquipmentN[i] = 0;
  228. }
  229. }
  230. if (!Server.playerHandler.newPlayerClient(cl)) {
  231. returnCode = 7;
  232. cl.saveFile = false;
  233. } else {
  234. cl.saveFile = true;
  235. }
  236. }
  237. }
  238.  
  239. cl.packetType = -1;
  240. cl.packetSize = 0;
  241.  
  242. StaticPacketBuilder bldr = new StaticPacketBuilder();
  243. bldr.setBare(true);
  244. bldr.addByte((byte) returnCode);
  245. if (returnCode == 2) {
  246. cl.saveCharacter = true;
  247. if (cl.playerRights == 3) {
  248. bldr.addByte((byte) 2);
  249. } else {
  250. bldr.addByte((byte) cl.playerRights);
  251. }
  252. } else if (returnCode == 21) {
  253. bldr.addByte((byte) loginDelay);
  254. } else {
  255. bldr.addByte((byte) 0);
  256. }
  257. cl.isActive = true;
  258. bldr.addByte((byte) 0);
  259. Packet pkt = bldr.toPacket();
  260. session.setAttachment(cl);
  261. session.write(pkt).addListener(new IoFutureListener() {
  262. @Override
  263. public void operationComplete(IoFuture arg0) {
  264. session.getFilterChain().remove("protocolFilter");
  265. session.getFilterChain().addFirst("protocolFilter",
  266. new ProtocolCodecFilter(new GameCodecFactory(inC)));
  267. }
  268. });
  269. }
  270.  
  271. private synchronized String readRS2String(ByteBuffer in) {
  272. StringBuilder sb = new StringBuilder();
  273. byte b;
  274. while ((b = in.get()) != 10) {
  275. sb.append((char) b);
  276. }
  277. return sb.toString();
  278. }
  279.  
  280. /**
  281. * Releases the buffer used by the given session.
  282. *
  283. * @param session
  284. * The session for which to release the buffer
  285. * @throws Exception
  286. * if failed to dispose all resources
  287. */
  288. @Override
  289. public void dispose(IoSession session) throws Exception {
  290. super.dispose(session);
  291. }
  292.  
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement