mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2025-05-08 20:30:28 -04:00
Added server encryption and online mode
This commit is contained in:
parent
0eb72c2046
commit
ebc6af6a7e
2 changed files with 71 additions and 5 deletions
|
@ -3,7 +3,6 @@ var mc = require('../');
|
|||
var yellow = '§e';
|
||||
|
||||
var options = {
|
||||
'online-mode': false,
|
||||
motd: 'Vox Industries',
|
||||
'max-players': 127,
|
||||
port: 25565,
|
||||
|
|
75
index.js
75
index.js
|
@ -30,13 +30,16 @@ function createServer(options) {
|
|||
var checkTimeoutInterval = options.checkTimeoutInterval || 4 * 1000;
|
||||
var motd = options.motd || "A Minecraft server";
|
||||
var onlineMode = options['online-mode'] == null ? true : options['online-mode'];
|
||||
assert.ok(! onlineMode, "online mode for servers is not yet supported");
|
||||
var encryptionEnabled = options['enable-encryption'] == null ? true : options['enable-encryption'];
|
||||
|
||||
var serverKey = ursa.generatePrivateKey(1024);
|
||||
|
||||
var server = new Server(options);
|
||||
server.maxPlayers = maxPlayers;
|
||||
server.on("connection", function(client) {
|
||||
client.once(0xfe, onPing);
|
||||
client.on(0x02, onHandshake);
|
||||
client.once(0x02, onHandshake);
|
||||
client.once(0xFC, onEncryptionKeyResponse);
|
||||
client.on('end', onEnd);
|
||||
|
||||
var keepAlive = false;
|
||||
|
@ -46,6 +49,8 @@ function createServer(options) {
|
|||
var keepAliveTimer = null;
|
||||
var loginKickTimer = setTimeout(kickForNotLoggingIn, kickTimeout);
|
||||
|
||||
var hash;
|
||||
|
||||
function kickForNotLoggingIn() {
|
||||
client.end('LoginTimeout');
|
||||
}
|
||||
|
@ -95,9 +100,71 @@ function createServer(options) {
|
|||
}
|
||||
|
||||
function onHandshake(packet) {
|
||||
assert.ok(! onlineMode);
|
||||
loggedIn = true;
|
||||
client.username = packet.username;
|
||||
if (onlineMode) {
|
||||
serverId = crypto.randomBytes(4).toString('hex');
|
||||
} else {
|
||||
serverId = '-';
|
||||
}
|
||||
if (encryptionEnabled) {
|
||||
client.verifyToken = crypto.randomBytes(4);
|
||||
var publicKeyStrArr = serverKey.toPublicPem("utf8").split("\n");
|
||||
var publicKeyStr = "";
|
||||
for (i=1;i<publicKeyStrArr.length - 2;i++) {
|
||||
publicKeyStr += publicKeyStrArr[i]
|
||||
}
|
||||
client.publicKey = new Buffer(publicKeyStr,'base64');
|
||||
hash = crypto.createHash("sha1");
|
||||
hash.update(serverId);
|
||||
client.write(0xFD, {
|
||||
serverId: serverId,
|
||||
publicKey: client.publicKey,
|
||||
verifyToken: client.verifyToken
|
||||
});
|
||||
} else {
|
||||
logInClient();
|
||||
}
|
||||
}
|
||||
|
||||
function onEncryptionKeyResponse(packet) {
|
||||
var success = client.verifyToken.toString("hex") === serverKey.decrypt(packet.verifyToken, undefined, undefined, ursa.RSA_PKCS1_PADDING).toString("hex");
|
||||
if (success) {
|
||||
var sharedSecret = serverKey.decrypt(packet.sharedSecret, undefined, undefined, ursa.RSA_PKCS1_PADDING);
|
||||
client.cipher = crypto.createCipheriv('aes-128-cfb8', sharedSecret, sharedSecret);
|
||||
client.decipher = crypto.createDecipheriv('aes-128-cfb8', sharedSecret, sharedSecret);
|
||||
hash.update(sharedSecret);
|
||||
hash.update(client.publicKey);
|
||||
var digest = mcHexDigest(hash);
|
||||
if (onlineMode) {
|
||||
var request = superagent.get("http://session.minecraft.net/game/checkserver.jsp");
|
||||
request.query({
|
||||
user: client.username,
|
||||
serverId: digest
|
||||
});
|
||||
request.end(function (err,resp){
|
||||
if (err) {
|
||||
client.end('Error :', err);
|
||||
return;
|
||||
}
|
||||
if (resp.text !== "YES") {
|
||||
client.end('FailedToVerifyUsername');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
client.write(0xFC, {
|
||||
sharedSecret: new Buffer(0),
|
||||
verifyToken: new Buffer(0)
|
||||
});
|
||||
client.encryptionEnabled = true;
|
||||
loginClient();
|
||||
} else {
|
||||
client.end('DidNotEncryptVerifyTokenProperly');
|
||||
}
|
||||
}
|
||||
|
||||
function loginClient() {
|
||||
loggedIn = true;
|
||||
startKeepAlive();
|
||||
|
||||
clearTimeout(loginKickTimer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue