Does anybody know how to add RSA to PI reloaded server?
Since it has different Login methods I am not sure what to to. I've tried myself but with no luck.
Heres my RS2LoginProtocol and RS2Decoder
Code:
package rs2.net.login;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import rs2.Connection;
import rs2.Server;
import rs2.Settings;
import rs2.game.players.Client;
import rs2.game.players.PlayerHandler;
import rs2.game.players.PlayerSave;
import rs2.net.Packet;
import rs2.net.PacketBuilder;
import rs2.util.ISAACCipher;
import rs2.util.Misc;
public class RS2LoginProtocol extends FrameDecoder {
private static final int CONNECTED = 0;
private static final int LOGGING_IN = 1;
private int state = CONNECTED;
private static final BigInteger RSA_MODULUS = new BigInteger(
"92861440003211077001102799529773785997095673360753218806148691373904108144078701477694694757584472104013507583304413787716584034022142961748466755627136754682423968618665938567538362403285069554054824462951740898779029160685451764896133633592291273582372870028623109442892015949528387875677762809416168908879");
private static final BigInteger RSA_EXPONENT = new BigInteger(
"33939760324655002935859367336568220943717787875705660162407183796620612819859272418560828593442190828195302609867565244933020085858864311194607995445882573248236038799511862582886117317731401570649229448880613479154552966323173049932387177248089686949293835183764536186039138092264631254355158392899674131569");
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer) throws Exception {
if (!channel.isConnected()) {
return null;
}
switch (state) {
case CONNECTED:
if (buffer.readableBytes() < 2)
return null;
int request = buffer.readUnsignedByte();
if (request != 14) {
System.out.println("Invalid login request: " + request);
channel.close();
return null;
}
buffer.readUnsignedByte();
channel.write(new PacketBuilder().putLong(0).put((byte) 0)
.putLong(new SecureRandom().nextLong()).toPacket());
state = LOGGING_IN;
return null;
case LOGGING_IN:
if (buffer.readableBytes() < 2) {
return null;
}
int loginType = buffer.readByte();
if (loginType != 16 && loginType != 18) {
System.out.println("Invalid login type: " + loginType);
// channel.close();
// return null;
}
// System.out.println("Login type = "+loginType);
int blockLength = buffer.readByte() & 0xff;
if (buffer.readableBytes() < blockLength) {
return null;
}
buffer.readByte();
int clientVersion = buffer.readShort();
/*
* if (clientVersion != 317) {
* System.out.println("Invalid client version: " + clientVersion);
* channel.close(); return null; }
*/
buffer.readByte();
for (int i = 0; i < 9; i++)
buffer.readInt();
buffer.readByte();
int rsaOpcode = buffer.readByte();
if (rsaOpcode != 10) {
System.out.println("Unable to decode RSA block properly!");
channel.close();
return null;
}
final long clientHalf = buffer.readLong();
final long serverHalf = buffer.readLong();
final int[] isaacSeed = { (int) (clientHalf >> 32),
(int) clientHalf, (int) (serverHalf >> 32),
(int) serverHalf };
final ISAACCipher inCipher = new ISAACCipher(isaacSeed);
for (int i = 0; i < isaacSeed.length; i++)
isaacSeed[i] += 50;
final ISAACCipher outCipher = new ISAACCipher(isaacSeed);
final int version = buffer.readInt();
final String name = Misc
.formatPlayerName(Misc.getRS2String(buffer));
final String pass = Misc.getRS2String(buffer);
channel.getPipeline().replace("decoder", "decoder",
new RS2Decoder(inCipher));
return login(channel, inCipher, outCipher, version, name, pass);
}
return null;
}
private static Client login(Channel channel, ISAACCipher inCipher,
ISAACCipher outCipher, int version, String name, String pass) {
int returnCode = 2;
if (!name.matches("[A-Za-z0-9 ]+")) {
returnCode = 4;
}
if (name.length() > 12) {
returnCode = 8;
}
Client cl = new Client(channel, -1);
cl.playerName = name;
cl.playerName2 = cl.playerName;
cl.playerPass = pass;
cl.outStream.packetEncryption = outCipher;
cl.saveCharacter = false;
cl.isActive = true;
if (Connection.isNamedBanned(cl.playerName)) {
returnCode = 4;
}
if (PlayerHandler.isPlayerOn(name)) {
returnCode = 5;
}
if (PlayerHandler.getPlayerCount() >= Settings.MAX_PLAYERS) {
returnCode = 7;
}
if (Server.UpdateServer) {
returnCode = 14;
}
if (returnCode == 2) {
int load = PlayerSave.loadGame(cl, cl.playerName, cl.playerPass);
if (load == 0)
cl.addStarter = true;
if (load == 3) {
returnCode = 3;
cl.saveFile = false;
} else {
for (int i = 0; i < cl.playerEquipment.length; i++) {
if (cl.playerEquipment[i] == 0) {
cl.playerEquipment[i] = -1;
cl.playerEquipmentN[i] = 0;
}
}
if (!Server.playerHandler.newPlayerClient(cl)) {
returnCode = 7;
cl.saveFile = false;
} else {
cl.saveFile = true;
}
}
}
if (returnCode == 2) {
cl.saveCharacter = true;
cl.packetType = -1;
cl.packetSize = 0;
final PacketBuilder bldr = new PacketBuilder();
bldr.put((byte) 2);
if (cl.playerRights == 3) {
bldr.put((byte) 2);
} else {
bldr.put((byte) cl.playerRights);
}
bldr.put((byte) 0);
channel.write(bldr.toPacket());
} else {
System.out.println("returncode:" + returnCode);
sendReturnCode(channel, returnCode);
return null;
}
synchronized (PlayerHandler.lock) {
cl.initialize();
cl.initialized = true;
}
return cl;
}
public static void sendReturnCode(final Channel channel, final int code) {
channel.write(new PacketBuilder().put((byte) code).toPacket())
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(final ChannelFuture arg0)
throws Exception {
arg0.getChannel().close();
}
});
}
}
Code:
package rs2.net.login;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import rs2.game.players.Client;
import rs2.net.Packet;
import rs2.net.Packet.Type;
import rs2.util.ISAACCipher;
public class RS2Decoder extends FrameDecoder {
private final ISAACCipher cipher;
private int opcode = -1;
private int size = -1;
public RS2Decoder(ISAACCipher cipher) {
this.cipher = cipher;
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (opcode == -1) {
if (buffer.readableBytes() >= 1) {
opcode = buffer.readByte() & 0xFF;
opcode = (opcode - cipher.getNextValue()) & 0xFF;
size = Client.PACKET_SIZES[opcode];
} else {
return null;
}
}
if (size == -1) {
if (buffer.readableBytes() >= 1) {
size = buffer.readByte() & 0xFF;
} else {
return null;
}
}
if (buffer.readableBytes() >= size) {
final byte[] data = new byte[size];
buffer.readBytes(data);
final ChannelBuffer payload = ChannelBuffers.buffer(size);
payload.writeBytes(data);
try {
return new Packet(opcode, Type.FIXED, payload);
} finally {
opcode = -1;
size = -1;
}
}
return null;
}
}