Advertisement
Guest User

Untitled

a guest
Jul 10th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.23 KB | None | 0 0
  1. package dc9.server.io;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. import java.net.Socket;
  7.  
  8. import dc9.server.io.world.WorldLoader;
  9. import dc9.server.util.ISAACCipher;
  10.  
  11. public class RS2LoginProtocol {
  12.     private InputStream in = null;
  13.     private OutputStream out = null;
  14.     private Stream inStream, outStream;
  15.     private ISAACCipher inStreamDecryption, outStreamDecryption;
  16.  
  17.     public RS2LoginProtocol(Socket s) throws IOException {
  18.         this.in = s.getInputStream();
  19.         this.out = s.getOutputStream();
  20.         this.inStream = new Stream(new byte[2042]);
  21.         this.outStream = new Stream(new byte[2042]);
  22.         login();
  23.     }
  24.  
  25.     private void login() throws IOException {
  26.         try {
  27.             fillStream(2);
  28.  
  29.             /**
  30.              * Initial login request (Login opcode)
  31.              */
  32.             int loginOpcode = inStream.readUnsignedByte();
  33.             System.out.println("Login opcode: " + loginOpcode);
  34.             loginOpcode = 0;
  35.  
  36.             /**
  37.              * Name hash
  38.              */
  39.             @SuppressWarnings("unused")
  40.             int nameHash = inStream.readUnsignedByte();
  41.  
  42.             /**
  43.              * Write 8 bytes (1 long) to client.
  44.              */
  45.             outStream.writeQWord(1);
  46.  
  47.             /**
  48.              * Write login opcode back to client
  49.              */
  50.             outStream.writeByte(loginOpcode);
  51.  
  52.             /**
  53.              * Create and write ISAAC seed half (severSessionKey)
  54.              */
  55.             long serverSessionKey = ((long) (java.lang.Math.random() * 99999999D) << 32)
  56.                     + (long) (java.lang.Math.random() * 99999999D);
  57.             outStream.writeQWord(serverSessionKey);
  58.  
  59.             /**
  60.              * Flush Stream
  61.              */
  62.             out.write(outStream.buffer, 0, outStream.currentOffset);
  63.             outStream.currentOffset = 0;
  64.             fillStream(2);
  65.  
  66.             /**
  67.              * Connection opcode
  68.              */
  69.             int opcode = inStream.readUnsignedByte();
  70.             if (opcode != 16 && opcode != 18) {
  71.                 System.out.println("Unexpected opcode: " + opcode);
  72.                 return;
  73.             }
  74.  
  75.             /**
  76.              * RSA encrypted block size
  77.              */
  78.             int RSABlockSize = inStream.readUnsignedByte();
  79.             int RSAEncryptedBlockSize = RSABlockSize - (36 + 1 + 1 + 2);
  80.             fillStream(RSABlockSize);
  81.  
  82.             /**
  83.              * Magic ID (use is unknown)
  84.              */
  85.             int magicID = inStream.readUnsignedByte();
  86.             if (magicID != 255) {
  87.                 System.out.println("Expected magid ID of 255; read " + magicID);
  88.                 return;
  89.             }
  90.  
  91.             /**
  92.              * Client version
  93.              */
  94.             int clientVersion = inStream.readUnsignedWord();
  95.             if (clientVersion != 317) {
  96.                 System.out.println("Invalid client version: " + clientVersion);
  97.                 return;
  98.             }
  99.  
  100.             /**
  101.              * Memory version
  102.              */
  103.             int memoryVersion = inStream.readUnsignedByte();
  104.             System.out.println("Client memory version: "
  105.                     + (memoryVersion == 0 ? "high" : "low"));
  106.  
  107.             /**
  108.              * Read CRC keys
  109.              */
  110.             int[] CRC_KEYS = new int[10];
  111.             for (int i = 0; i < 9; i++) {
  112.                 CRC_KEYS[i] = inStream.readDWord();
  113.             }
  114.  
  115.             /**
  116.              * Read RSA encoded block
  117.              */
  118.             RSAEncryptedBlockSize--;
  119.             int RSAEncodedBlock = inStream.readUnsignedByte();
  120.             if (RSAEncryptedBlockSize != RSAEncodedBlock) {
  121.                 System.out.println("Encrypted data lenth ("
  122.                         + RSAEncryptedBlockSize
  123.                         + ") did not equal RSA encoded block ("
  124.                         + RSAEncodedBlock + ")");
  125.                 return;
  126.             }
  127.  
  128.             /**
  129.              * RSA opcode
  130.              */
  131.             int RSAOpcode = inStream.readUnsignedByte();
  132.             if (RSAOpcode != 10) {
  133.                 System.out.println("RSA opcode was expected to be 10; read "
  134.                         + RSAOpcode);
  135.                 return;
  136.             }
  137.             System.out.println("RSA opcode: " + RSAOpcode);
  138.  
  139.             /**
  140.              * Read server & client session key
  141.              */
  142.             long clientSessionKey = inStream.readQWord();
  143.             serverSessionKey = inStream.readQWord();
  144.  
  145.             System.out.println("Client session key: " + serverSessionKey);
  146.             System.out.println("Server session key: " + serverSessionKey);
  147.  
  148.             /**
  149.              * Player username and password
  150.              */
  151.             String username = inStream.readString();
  152.             username.toLowerCase();
  153.             username.trim();
  154.             String properName = Character.toUpperCase(username.charAt(0)) + username.substring(1, username.length());
  155.             username = properName;
  156.  
  157.             String password = inStream.readString();
  158.  
  159.             System.out.println("Player username: " + username + ", password: "
  160.                     + password);
  161.  
  162.             /**
  163.              * ISAAC Seeds
  164.              */
  165.             int seed[] = new int[4];
  166.  
  167.             seed[0] = (int) (clientSessionKey >> 32);
  168.             seed[1] = (int) clientSessionKey;
  169.             seed[2] = (int) (serverSessionKey >> 32);
  170.             seed[3] = (int) serverSessionKey;
  171.  
  172.             /**
  173.              * Initialize ISAAC decryptor
  174.              */
  175.             for (int i = 0; i < 4; i++) {
  176.                 System.out.println("InStream seed[" + i + "]: 0x"
  177.                         + Integer.toHexString(seed[i]));
  178.             }
  179.             inStreamDecryption = new ISAACCipher(seed);
  180.             for (int i = 0; i < 4; i++) {
  181.                 seed[i] += 50;
  182.             }
  183.             for (int i = 0; i < 4; i++) {
  184.                 System.out.println("OutStream seed[" + i + "]: 0x"
  185.                         + Integer.toHexString(seed[i]));
  186.             }
  187.             outStreamDecryption = new ISAACCipher(seed);
  188.             outStream.packetEncryption = outStreamDecryption;
  189.  
  190.             /**
  191.              * Finalize login
  192.              */
  193.             out.write(2);
  194.             out.write(0);
  195.             out.write(0);
  196.         } catch (IOException e) {
  197.             System.err.println("An error occured during log in.");
  198.             e.printStackTrace();
  199.         }
  200.  
  201.         /**
  202.          * Initialize world loading
  203.          */
  204.         new WorldLoader(outStream, out);
  205.     }
  206.  
  207.     private void fillStream(int i) throws java.io.IOException {
  208.         inStream.currentOffset = 0;
  209.         in.read(inStream.buffer, 0, i);
  210.     }
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement