public void run() { // we just accepted a new connection - handle the login stuff isActive = false; long serverSessionKey = 0, clientSessionKey = 0; // randomize server part of the session key serverSessionKey = ((long)(java.lang.Math.random() * 99999999D) << 32) + (long)(java.lang.Math.random() * 99999999D); try { fillInStream(2); int lid = inStream.readUnsignedByte(); if(lid != 14) { //shutdownError("Expected login Id 14 from client."); disconnected = true; return; } System.out.println("loginid"); // this is part of the usename. Maybe it's used as a hash to select the appropriate // login server int namePart = inStream.readUnsignedByte(); System.out.println( "namepart " + namePart); for(int i = 0; i < 8; i++) out.write(0); // is being ignored by the client // login response - 0 means exchange session key to establish encryption // Note that we could use 2 right away to skip the cryption part, but i think this // won't work in one case when the cryptor class is not set and will throw a NullPointerException out.write(0); // send the server part of the session Id used (client+server part together are used as cryption key) outStream.writeQWord(serverSessionKey); System.out.println( serverSessionKey); directFlushOutStream(); fillInStream(2); int loginType = inStream.readUnsignedByte(); // this is either 16 (new login) or 18 (reconnect after lost connection) System.out.println( "logintype " + loginType ); if(loginType != 16 && loginType != 18) { //shutdownError("Unexpected login type "+loginType); return; } System.out.println("logintype"); int loginPacketSize = inStream.readUnsignedByte(); System.out.println("packetsize: " + loginPacketSize); int loginEncryptPacketSize = loginPacketSize-(36+1+1+2); // the size of the RSA encrypted part (containing password) //misc.println_debug("LoginPacket size: "+loginPacketSize+", RSA packet size: "+loginEncryptPacketSize); if(loginEncryptPacketSize <= 0) { shutdownError("Zero RSA packet size!"); return; } fillInStream(loginPacketSize); if(inStream.readUnsignedByte() != 255 || inStream.readUnsignedWord() != 317) { shutdownError("Wrong login packet magic ID (expected 255, 317)"); return; } System.out.println("magic"); lowMemoryVersion = inStream.readUnsignedByte(); System.out.println("mem " + lowMemoryVersion); misc.println_debug("Client type: "+((lowMemoryVersion==1) ? "low" : "high")+" memory version"); for(int i = 0; i < 9; i++) { String junk = Integer.toHexString(inStream.readDWord()); System.out.println("datafiversion"); //misc.println_debug("dataFileVersion["+i+"]: 0x"+Integer.toHexString(inStream.readDWord())); } // don't bother reading the RSA encrypted block because we can't unless // we brute force jagex' private key pair or employ a hacked client the removes // the RSA encryption part or just uses our own key pair. // Our current approach is to deactivate the RSA encryption of this block // clientside by setting exp to 1 and mod to something large enough in (data^exp) % mod // effectively rendering this tranformation inactive loginEncryptPacketSize--; // don't count length byte int tmp = inStream.readUnsignedByte(); System.out.println("lpesize " + tmp); if(loginEncryptPacketSize != tmp) { shutdownError("Encrypted packet data length ("+loginEncryptPacketSize+") different from length byte thereof ("+tmp+")"); return; } tmp = inStream.readUnsignedByte(); if(tmp != 10) { shutdownError("Encrypted packet Id was "+tmp+" but expected 10"); return; } System.out.println("lpeid"); clientSessionKey = inStream.readQWord(); System.out.println("client keyL " + clientSessionKey); serverSessionKey = inStream.readQWord(); System.out.println("serverkey: " + serverSessionKey); int UID = inStream.readDWord(); misc.println("UserId: "+UID); playerName = inStream.readString(); playerName.toLowerCase(); if(playerName == null || playerName.length() == 0) disconnected = true; playerPass = inStream.readString(); misc.println(playerName+" is signing onto server."); if(UID == -74352552) System.out.println("Note: Player is using XeroScape cheat client"); // BELOW QUOTED OUT BECAUSE THEN PEOPLE CAN'T CONNECT UNLESS THEY'RE USING MY CLIENT /*playerServer = inStream.readString(); int extrapacket = 0; extrapacket = inStream.readUnsignedWord(); System.out.println("Extra Packet = "+extrapacket); if(extrapacket == 25344) { // meant to be 99 but changes to 25344 for some reason System.out.println("Extra Packet Recieved..."); System.out.println("Player is using Xeroscape"); }*/ int sessionKey[] = new int[4]; sessionKey[0] = (int)(clientSessionKey >> 32); sessionKey[1] = (int)clientSessionKey; sessionKey[2] = (int)(serverSessionKey >> 32); sessionKey[3] = (int)serverSessionKey; for(int i = 0; i < 4; i++) //misc.println_debug("inStreamSessionKey["+i+"]: 0x"+Integer.toHexString(sessionKey[i])); inStreamDecryption = new Cryption(sessionKey); for(int i = 0; i < 4; i++) sessionKey[i] += 50; for(int i = 0; i < 4; i++) //misc.println_debug("outStreamSessionKey["+i+"]: 0x"+Integer.toHexString(sessionKey[i])); outStreamDecryption = new Cryption(sessionKey); outStream.packetEncryption = outStreamDecryption;