Skip to content

Instantly share code, notes, and snippets.

@minecrafter
Last active October 17, 2015 21:40
Show Gist options
  • Save minecrafter/3d493a432ff02fa42e2b to your computer and use it in GitHub Desktop.
Save minecrafter/3d493a432ff02fa42e2b to your computer and use it in GitHub Desktop.
Sample Votifier Protocol v2 clients
var crypto = require('crypto');
var net = require('net');
function createMessage(header, vote) {
var data = header.split(' ');
if (data.length != 3) {
throw new Error("Not a Votifier v2 protocol server");
}
vote['challenge'] = data[2].substring(0, data[2].length - 1);
var voteAsJson = JSON.stringify(vote);
var digest = crypto.createHmac('sha256', options.token);
digest.update(voteAsJson);
var sig = digest.digest('base64');
var message = JSON.stringify({payload: JSON.stringify(vote), signature: sig});
var messageBuffer = new Buffer(message.length + 4);
messageBuffer.writeUInt16BE(0x733a);
messageBuffer.writeUInt16BE(message.length, 2);
messageBuffer.write(message, 4);
return messageBuffer;
}
module.exports = exports = function vote(options, cb) {
if (!options.host || !options.port || !options.token || !options.vote) {
return cb(new Error("missing host, port, token, or vote in 'server'"));
}
var vote = options.vote;
if (!vote.username || !vote.address || !vote.timestamp || !vote.serviceName) {
return cb(new Error("missing username, address, timestamp, or serviceName in 'vote'"));
}
var socket = net.createConnection(options.port, options.host);
socket.once('data', function (buf) {
var returnError = function () {
cb(new Error('Unexpected error'));
};
socket.once('end', returnError);
socket.write(createMessage(buf.toString(), vote));
socket.once('data', function (respBuf) {
var resp = JSON.parse(respBuf.toString());
socket.removeListener('end', returnError);
socket.end();
if (resp.status == 'error') {
cb(new Error(resp.cause + ': ' + resp.errorMessage));
} else {
cb(null);
}
});
});
};
import socket
import struct
import json
import time
import base64
import argparse
import sys
import hmac
import hashlib
def send(server, vote, token, debug=False):
sock = socket.create_connection(server)
header = sock.recv(40)
vote["challenge"] = header.split(" ")[2][:-1]
res = json.dumps(vote)
signature = base64.b64encode(hmac.new(token, res, hashlib.sha256).digest())
payload = {"signature": signature, "payload": res}
res2 = json.dumps(payload)
if debug:
print("Sending: " + res2 + " (length: " + str(len(res2)) + ")")
amt = struct.pack('>H', len(res2))
magic = struct.pack('>H', 0x733A)
sock.send(magic + amt + res2)
result = sock.recv(512)
return json.loads(result)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--service-name", help="specify the service name to use when sending the vote (default: TestService)", default="TestService")
parser.add_argument("-t", "--token", help="specify the server's token", required=True)
parser.add_argument("-d", "--timestamp", help="specify the timestamp")
parser.add_argument("-u", "--username", help="specify a custom username (default: VotifierUser)", default="VotifierUser")
parser.add_argument("server", help="the backend Votifier server")
args = parser.parse_args()
server_parts = args.server.split(":")
if len(server_parts) != 2:
print "invalid server:port"
sys.exit(1)
server = (server_parts[0], int(server_parts[1]))
if args.timestamp:
timestamp = int(args.timestamp)
else:
timestamp = int(time.time()*10)
response = send(server, {'username': args.username, 'address': '127.0.0.1', 'timestamp': timestamp, 'serviceName': args.service_name}, args.token, debug=True)
print(str(response))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment