Last active
January 13, 2018 23:06
-
-
Save csprance/b5f4787772fa2cca79acd34ef2f2580f to your computer and use it in GitHub Desktop.
DEPRECATED - see https://github.com/csprance/node-misrcon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Name: rconUtils | |
* Created by chris on 4/26/2017. | |
* Description: Sends a command to a Miscreated server and parses the response | |
* // RCON Steps | |
* --- 1 --- | |
* // Request: challenge | |
* // Response: uptime | |
* --- 2 --- | |
* // Request: md5(uptime:password) | |
* // Response: AuthResponse | |
* --- 3 --- | |
* // Request: CommandString | |
* // Response: RCONResult | |
*/ | |
const axios = require('axios'); | |
const Promise = require('bluebird'); | |
const {parseString} = require('xml2js'); | |
const md5 = require('md5'); | |
const http = require('http'); | |
/** | |
* Sends a command via XMLRPC to a server and returns a promise response | |
* @constructor | |
* @param {Object} options object containing user credentials and command | |
* {ip:[ip], port:[port], password:[password], command: [command]} | |
* @returns{promise} response returns a promise that resolves to a String | |
*/ | |
const sendRCONCommandToServer = (options) => { | |
// return a promise so we can use .then(res=> function ); | |
return new Promise(function (resolve, reject) { | |
// the server url to send the commands to | |
const serverUrl = `http://${options.ip}:${options.port}/rpc2`; | |
// axios config | |
const config = { | |
headers: {'Content-Type': 'text/xml'}, | |
httpAgent: new http.Agent({keepAlive: true}), | |
}; | |
// create the initial challenge string to send to the server | |
const challengeString = createChallengeString(); | |
// send the initial challenge | |
// Request: challenge | |
axios.post(serverUrl, challengeString, config).then(res => { | |
// create challengeResponseRequest String | |
// Response: uptime | |
let upTime = getUpTimeFromChallengeResponse(res.data); | |
console.log(upTime); | |
let challengeResponseRequest = createChallengeResponseString(upTime, options.password); | |
// send the challenge request back to the server | |
// Request: md5(uptime:password) | |
return axios.post(serverUrl, challengeResponseRequest, config); | |
}).then(res => { | |
// handle auth error send reject so we can catch promise errors | |
// Response: AuthResponse | |
parseAuthResponse(res.data, reject); | |
// build the command to send to the server from the user | |
let commandString = createCommandString(options.command); | |
// execute axios post request | |
// Request: CommandString | |
axios.post(serverUrl, commandString, config).then(res => { | |
// resolve the string response back | |
// Response: RCONResult | |
resolve(parseCommandResponse(res.data)); | |
}); | |
// END OF THE LINE! | |
}) | |
}); | |
}; | |
function createChallengeString() { | |
return `<methodCall><methodName>challenge</methodName><params></params></methodCall>`; | |
} | |
function createChallengeResponseString(upTime, password) { | |
// by doing md5(uptime:password) | |
return `<methodCall><methodName>authenticate</methodName><params><param><value><string>${md5(`${upTime}:${password}`)}</string></value></param></params></methodCall>`; | |
} | |
function createCommandString(command) { | |
return `<methodCall><methodName>${command}</methodName><params></params></methodCall>`; | |
} | |
function getUpTimeFromChallengeResponse(str) { | |
// server response looks like | |
// <methodResponse><params><param><value><string>31268616.000000</string></value></param></params></methodResponse> | |
//get the uptime by parsing the xml | |
let uptime = ''; | |
parseString(str, (err, result) => { | |
uptime = result.methodResponse.params[0].param[0].value[0].string[0]; | |
}); | |
return uptime; | |
} | |
function parseCommandResponse(str) { | |
// server response looks like | |
//<methodResponse><params><param><value><string>{server response}</string></value></param></params></methodResponse> | |
let res = ''; | |
parseString(str, (err, result) => { | |
// parse the response | |
res = result.methodResponse.params[0].param[0].value[0].string[0]; | |
}); | |
return res; | |
} | |
const parseAuthResponse = (data, reject) => { | |
// server response looks like this | |
// <?xml version="1.0"?><methodResponse><params><param><value><string>authorized</string></value></param></params></methodResponse> | |
// stub function | |
// sometimes auth passes after a few tries it just keeps the connection open | |
// Handle auth failed here | |
let authResults = ''; | |
parseString(data, (err, result) => { | |
authResults = result.methodResponse.params[0].param[0].value[0].string[0]; | |
console.log('authResults: ', authResults); | |
// if (authResults !== 'authorized') { | |
// reject('Incorrect Password'); | |
// } | |
}); | |
return authResults; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment