#!/usr/bin/node // Get some libraries const winston = require("winston"); const random_bytes = require("random-bytes"); const bsplit = require("buffer-split"); const node_rsa = require("node-rsa"); const sqlite3 = require('sqlite3'); const btoa = require("btoa"); const atob = require("atob"); const net = require("net"); const fs = require("fs"); // Load the settings var settings = require("./settings.json"); // Create a sqlite3 database var db = new sqlite3.Database("./app.db", function(err) { // Was there an error if(err) { // Tell the user the error console.log("SQlite3 failed to start:", err); } else { // Tell the user it worked console.log("SQlite3 ready."); } }); function sqlite3_createTable(name, callback) { // Run the create table task with the callback db.run('CREATE TABLE IF NOT EXISTS '+name +'(id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT)', callback); } function sqlite3_insertData(name, data) { // Write data to the table db.run('INSERT INTO '+name+' (data) VALUES (?)', [JSON.stringify(data)]); } function sqlite3_getData(name, callback) { // Get the sqlite3 data and send it to the callback db.all('SELECT rowid AS id, data FROM '+name, callback); } function getrows_sqlite3(name, callback) { // Create the table sqlite3_createTable(name, function() { // Load the table sqlite3_getData(name, function(err, rows) { // Throw an error if there is one if(err) throw err; // Loop over the rows for(var i=0;i= 4) { // Get the number recieve_size = recieve_buffer.readUInt32BE(0); // Reset the buffer recieve_buffer = new Buffer.alloc(0); // Set the get data mode to true recieve_get = true; } } else { // Is the recieve buffer as big as the size if(recieve_buffer.length == recieve_size) { // Call the callback callback(recieve_buffer); // Reset the buffer and the size recieve_buffer = new Buffer.alloc(0); recieve_size = 0; // Set the get data mode to false recieve_get = false; } } } } function send_ordered(data) { // Convert the data into a buffer data = toBuffer(data); // Get the size of the data var size = data.length; // Turn it into a 32 bit buffer var bytes = new Buffer.alloc(4); bytes.writeUInt32BE(size, 0); // Return the buffer and the data return new Buffer.concat([bytes, data]); } function string_decrypt(key, string) { // Convert the string to a buffer var buff = toBuffer(string); // Create some new data var decrypted = new Buffer.alloc(buff.length); // Iterate over the string for(var i=0;i= key.str.length) { // Set to zero key.at.rx = 0; } } // Return the encrypted data return decrypted; } function string_encrypt(key, string) { // Convert the string to a buffer var buff = toBuffer(string); // Create some new data var encrypted = new Buffer.alloc(buff.length); // Iterate over the string for(var i=0;i 255) e -= 256; encrypted[i] = e; // Add 1 to the key counter key.at.tx += 1; // Is the key counter out of range if(key.at.tx >= key.str.length) { // Set to zero key.at.tx = 0; } } // Return the encrypted data return encrypted; } function make_encryption_key(string) { // Make a new key var key = new Object(); // Set the varibles key.str = toBuffer(string); key.at = new Object(); key.at.rx = 0; key.at.tx = 0; //console.log("make_encryption_key:", key.str); // Return the key return key; } function socket_write(socket, data) { // Send the data encrypted with JSON socket.sock.write(send_ordered(string_encrypt(socket.key, JSON.stringify(data)+"\n"))); } function socket_init(socket, ondata) { // Set the socket var sock = new Object(); sock.sock = socket; sock.new = true; console.log("Connection from "+socket.localAddress); // Wait for data sock.sock.on('data', function(data) { // Recieve data in order recieve_ordered(data, function(data) { //console.log(data); // Is the socket new if(sock.new) { // Set sock new sock.new = false; // Convert from JSON data = JSON.parse(data); // Is this the public key if(data.mode == 'pubkey') { // Load the key var key = new node_rsa(); key.importKey(data.key, 'public'); //console.log("Loaded the RSA key"); // Get some random bytes random_bytes(settings.encryption_key_size, function(error,string) { //console.log("btoa(string):",btoa(string)); // Throw an error if there is one if(error) throw error; // Make the key sock.key = make_encryption_key(string); //console.log("Created an encryption key") // Encrypt the key with RSA var key_encrypted = key.encrypt(string, 'base64'); //console.log("Encrypted the key"); // Send the key to the client sock.sock.write(send_ordered(JSON.stringify({ key: toBytes(key_encrypted), mode: "encryption_key" }))); //console.log("Sent the key to the client"); }); } } else { // Decrypt the data data = string_decrypt(sock.key, data); //console.log(data); // Parse the json data var data = JSON.parse(data); // Send the parsed data to the callback ondata(data); } }); }); // Return the socket return sock; } // Create a connections varible var connections = []; // Create a server var server = net.createServer(function(socket) { // Setup the sock varible var sock; // Initialise the socket and wait for data sock = socket_init(socket, function(data) { // Does the user want to login if(data.mode == "login" && !sock.logged_in) { // Is the user registered here if(users[data.username]) { // Is the password correct if(users[data.username].password == data.password) { // Log the user in sock.username = data.username; console.log("Logged "+sock.username+" in."); // Set logged in sock.logged_in = true; } } // Is register on fail set else if(settings.register_on_fail) { // Make a new user users[data.username] = new Object(); users[data.username].password = data.password; // Send it to sqlite3 sqlite3_insertData("users", { username: data.username, password: data.password }); // Send the status to all connections for(var i=0;i