pokemon-showdown/verifier.js
Ben Davies d9c6fe54b2 ProcessManager: subclass to extend ProcessManager, unit tests setup (#2739)
Before, an options object containing properties and values to be used
was how decorated instances of the class would be created. This meant
the constructor could assign anything you feel like to `this`. Rather
than that, the constructor now assigns a strict set of values, and
methods are redefined in subclasses.

Basic unit tests were added to test if they could be written for after
the final refactor to fix the other memory leak here.
2016-09-09 15:51:49 -05:00

80 lines
2.0 KiB
JavaScript

/**
* Verifier process
* Pokemon Showdown - http://pokemonshowdown.com/
*
* This is just an asynchronous implementation of a verifier for a
* signed key, because Node.js's crypto functions are synchronous,
* strangely, considering how everything else is asynchronous.
*
* I wrote this one day hoping it would help with performance, but
* I don't think it had any noticeable effect.
*
* @license MIT license
*/
'use strict';
const crypto = require('crypto');
const ProcessManager = require('./process-manager');
class VerifierManager extends ProcessManager {
onMessageUpstream(message) {
// Protocol:
// success: "[id]|1"
// failure: "[id]|0"
let pipeIndex = message.indexOf('|');
let id = +message.substr(0, pipeIndex);
let result = Boolean(~~message.slice(pipeIndex + 1));
if (this.pendingTasks.has(id)) {
this.pendingTasks.get(id)(result);
this.pendingTasks.delete(id);
this.release();
}
}
onMessageDownstream(message) {
// protocol:
// "[id]|{data, sig}"
let pipeIndex = message.indexOf('|');
let id = message.substr(0, pipeIndex);
let data = JSON.parse(message.slice(pipeIndex + 1));
process.send(id + '|' + this.receive(data));
}
receive(data) {
let verifier = crypto.createVerify(Config.loginserverkeyalgo);
verifier.update(data.data);
let success = false;
try {
success = verifier.verify(Config.loginserverpublickey, data.sig, 'hex');
} catch (e) {}
return success ? 1 : 0;
}
}
exports.VerifierManager = VerifierManager;
const PM = exports.PM = new VerifierManager({
execFile: __filename,
maxProcesses: global.Config ? Config.verifierprocesses : 1,
isChatBased: false,
});
if (process.send && module === process.mainModule) {
// This is a child process!
global.Config = require('./config/config');
require('./repl').start('verifier', cmd => eval(cmd));
process.on('message', message => PM.onMessageDownstream(message));
process.on('disconnect', () => process.exit());
}
exports.verify = function (data, signature) {
return PM.send({data: data, sig: signature});
};