This commit is contained in:
Matthew Bryant (mandatory)
2020-04-27 04:13:21 -07:00
parent 590dc30694
commit c06a5334c0
2 changed files with 47 additions and 38 deletions
+37 -37
View File
@@ -1,7 +1,6 @@
const NodeCache = require("node-cache"); const NodeCache = require("node-cache");
const AnyProxy = require('./anyproxy'); const AnyProxy = require('./anyproxy');
const cluster = require('cluster'); const cluster = require('cluster');
const moment = require('moment');
const WebSocket = require('ws'); const WebSocket = require('ws');
const https = require('https'); const https = require('https');
const redis = require("redis"); const redis = require("redis");
@@ -18,6 +17,7 @@ const Sequelize = require('sequelize');
const Op = Sequelize.Op; const Op = Sequelize.Op;
const get_secure_random_string = require('./utils.js').get_secure_random_string; const get_secure_random_string = require('./utils.js').get_secure_random_string;
const logit = require('./utils.js').logit;
const get_api_server = require('./api-server.js').get_api_server; const get_api_server = require('./api-server.js').get_api_server;
@@ -184,7 +184,8 @@ async function get_authentication_status(inputRequestDetail) {
); );
if (!proxy_authentication || !(proxy_authentication.includes('Basic'))) { if (!proxy_authentication || !(proxy_authentication.includes('Basic'))) {
console.log(`No proxy credentials provided!`); logit(`No proxy credentials provided!`);
console.log(proxy_authentication);
return false; return false;
} }
@@ -226,7 +227,7 @@ async function get_authentication_status(inputRequestDetail) {
}); });
if (!browserproxy_record) { if (!browserproxy_record) {
console.log(`Invalid credentials for username '${username}'!`); logit(`Invalid credentials for username '${username}'!`);
return false; return false;
} }
@@ -250,12 +251,11 @@ const options = {
rule: { rule: {
async beforeSendRequest(requestDetail) { async beforeSendRequest(requestDetail) {
const remote_address = requestDetail._req.connection.remoteAddress; const remote_address = requestDetail._req.connection.remoteAddress;
const datetime = moment().format('MMMM Do YYYY, h:mm:ss a');
const auth_details = await get_authentication_status(requestDetail.requestOptions.headers); const auth_details = await get_authentication_status(requestDetail.requestOptions.headers);
if (!auth_details) { if (!auth_details) {
console.error(`[${datetime}][${remote_address}] Request denied for URL ${requestDetail.url}, no authentication information provided in proxy HTTP request!`); logit(`[${remote_address}] Request denied for URL ${requestDetail.url}, no authentication information provided in proxy HTTP request!`);
return AUTHENTICATION_REQUIRED_PROXY_RESPONSE; return AUTHENTICATION_REQUIRED_PROXY_RESPONSE;
} }
@@ -265,7 +265,7 @@ const options = {
requestDetail.requestData.length > 0 requestDetail.requestData.length > 0
) ? requestDetail.requestData.toString('base64') : false; ) ? requestDetail.requestData.toString('base64') : false;
console.log(`[${datetime}][${auth_details.id}][${auth_details.name}] Proxying request ${requestDetail._req.method} ${requestDetail.url}`); logit(`[${auth_details.id}][${auth_details.name}] Proxying request ${requestDetail._req.method} ${requestDetail.url}`);
const response = await send_request_via_browser( const response = await send_request_via_browser(
auth_details.browser_id, auth_details.browser_id,
true, true,
@@ -277,7 +277,7 @@ const options = {
// For connection errors // For connection errors
if (!response) { if (!response) {
console.error(`[${datetime}][${auth_details.id}][${auth_details.name}] A connection error occurred while requesting ${requestDetail._req.method} ${requestDetail.url}`); logit(`[${auth_details.id}][${auth_details.name}] A connection error occurred while requesting ${requestDetail._req.method} ${requestDetail.url}`);
return { return {
response: { response: {
statusCode: 503, statusCode: 503,
@@ -290,7 +290,7 @@ const options = {
}; };
} }
console.log(`[${datetime}][${auth_details.id}][${auth_details.name}] Got response ${response.status} ${requestDetail.url}`); logit(`[${auth_details.id}][${auth_details.name}] Got response ${response.status} ${requestDetail.url}`);
let encoded_body_buffer = new Buffer(response.body, 'base64'); let encoded_body_buffer = new Buffer(response.body, 'base64');
let decoded_body = encoded_body_buffer.toString('ascii'); let decoded_body = encoded_body_buffer.toString('ascii');
@@ -319,7 +319,7 @@ const options = {
}; };
async function initialize_new_browser_connection(ws) { async function initialize_new_browser_connection(ws) {
console.log(`Authenticating newly-connected browser...`); logit(`Authenticating newly-connected browser...`);
// Authenticate the newly-connected client. // Authenticate the newly-connected client.
const auth_result = await authenticate_client(ws); const auth_result = await authenticate_client(ws);
@@ -351,7 +351,7 @@ async function initialize_new_browser_connection(ws) {
This is to make the user's first use experience much easier so This is to make the user's first use experience much easier so
they can easily try out the functionality. they can easily try out the functionality.
*/ */
console.log(`Browser ID ${browser_id} is not already registered. Creating new credentials for it...`); logit(`Browser ID ${browser_id} is not already registered. Creating new credentials for it...`);
const new_username = `botuser${get_secure_random_string(8)}`; const new_username = `botuser${get_secure_random_string(8)}`;
const new_password = get_secure_random_string(18); const new_password = get_secure_random_string(18);
@@ -393,7 +393,7 @@ async function initialize() {
"host": process.env.REDIS_HOST, "host": process.env.REDIS_HOST,
}); });
redis_client.on("error", function(error) { redis_client.on("error", function(error) {
console.error(`Redis client encountered an error:`); logit(`Redis client encountered an error:`);
console.error(error); console.error(error);
}); });
subscriber = redis.createClient({ subscriber = redis.createClient({
@@ -410,12 +410,12 @@ async function initialize() {
// Called when a new redis subscription is added // Called when a new redis subscription is added
subscriber.on("subscribe", function(channel, count) { subscriber.on("subscribe", function(channel, count) {
//console.log(`New subscription created for channel ${channel}, bring total to ${count}.`); //logit(`New subscription created for channel ${channel}, bring total to ${count}.`);
}); });
// Called when a new message is written to a channel // Called when a new message is written to a channel
subscriber.on("message", function(channel, message) { subscriber.on("message", function(channel, message) {
//console.log(`Received a new message at channel '${channel}', message is '${message}'`); //logit(`Received a new message at channel '${channel}', message is '${message}'`);
// For messages being sent to the browser from the proxy // For messages being sent to the browser from the proxy
if (channel.startsWith('TOBROWSER_')) { if (channel.startsWith('TOBROWSER_')) {
@@ -434,9 +434,9 @@ async function initialize() {
message message
); );
} catch (e) { } catch (e) {
console.error(`Error parsing message received from browser:`); logit(`Error parsing message received from browser:`);
console.error(`Message: ${message}`); logit(`Message: ${message}`);
console.error(`Exception: ${e}`); logit(`Exception: ${e}`);
} }
// Check if it's an action we recognize. // Check if it's an action we recognize.
@@ -447,7 +447,7 @@ async function initialize() {
// Check if we're tracking this response // Check if we're tracking this response
if (REQUEST_TABLE.has(inbound_message.id)) { if (REQUEST_TABLE.has(inbound_message.id)) {
//console.log(`Resolving function for message ID ${inbound_message.id}...`); //logit(`Resolving function for message ID ${inbound_message.id}...`);
const resolve = REQUEST_TABLE.take(inbound_message.id); const resolve = REQUEST_TABLE.take(inbound_message.id);
resolve(inbound_message.result); resolve(inbound_message.result);
} }
@@ -460,7 +460,7 @@ async function initialize() {
}); });
wss.on('connection', async function connection(ws) { wss.on('connection', async function connection(ws) {
console.log(`A new browser has connected to us via WebSocket!`); logit(`A new browser has connected to us via WebSocket!`);
ws.isAlive = true; ws.isAlive = true;
@@ -468,7 +468,7 @@ async function initialize() {
// Only do this if there's a valid browser ID for // Only do this if there's a valid browser ID for
// the WebSocket which has died. // the WebSocket which has died.
if (ws.browser_id) { if (ws.browser_id) {
console.log(`WebSocket browser ${ws.browser_id} has disconnected.`); logit(`WebSocket browser ${ws.browser_id} has disconnected.`);
// Unsubscribe from the browser topic since we can no longer send // Unsubscribe from the browser topic since we can no longer send
// any messages to the browser anymore // any messages to the browser anymore
@@ -483,7 +483,7 @@ async function initialize() {
browserproxy_record.is_online = false; browserproxy_record.is_online = false;
await browserproxy_record.save(); await browserproxy_record.save();
} else { } else {
console.log(`Unauthenticated WebSocket has disconnected from us.`); logit(`Unauthenticated WebSocket has disconnected from us.`);
} }
}); });
@@ -495,9 +495,9 @@ async function initialize() {
message message
); );
} catch (e) { } catch (e) {
console.error(`Error parsing message received from browser:`); logit(`Error parsing message received from browser:`);
console.error(`Message: ${message}`); logit(`Message: ${message}`);
console.error(`Exception: ${e}`); logit(`Exception: ${e}`);
} }
// As a special case, if this is the result // As a special case, if this is the result
@@ -505,7 +505,7 @@ async function initialize() {
if (inbound_message.origin_action === 'AUTH') { if (inbound_message.origin_action === 'AUTH') {
// Check if we're tracking this response // Check if we're tracking this response
if (REQUEST_TABLE.has(inbound_message.id)) { if (REQUEST_TABLE.has(inbound_message.id)) {
//console.log(`Resolving function for message ID ${inbound_message.id}...`) //logit(`Resolving function for message ID ${inbound_message.id}...`)
const resolve = REQUEST_TABLE.take(inbound_message.id); const resolve = REQUEST_TABLE.take(inbound_message.id);
resolve(inbound_message.result); resolve(inbound_message.result);
} }
@@ -517,8 +517,8 @@ async function initialize() {
// websocket connection. // websocket connection.
publisher.publish(`TOPROXY_${ws.browser_id}`, message); publisher.publish(`TOPROXY_${ws.browser_id}`, message);
} else { } else {
console.error(`Wat, this shouldn't happen? Orphaned message:`); logit(`Wat, this shouldn't happen? Orphaned message (somebody might be probing you!):`);
console.error(message); logit(message);
} }
}); });
@@ -526,32 +526,32 @@ async function initialize() {
}); });
wss.on('ready', () => { wss.on('ready', () => {
console.log(`CursedChrome WebSocket server is now running on port ${WS_PORT}.`) logit(`CursedChrome WebSocket server is now running on port ${WS_PORT}.`)
}); });
proxyServer = new AnyProxy.ProxyServer(options); proxyServer = new AnyProxy.ProxyServer(options);
proxyServer.on('ready', () => { proxyServer.on('ready', () => {
console.log(`CursedChrome HTTP Proxy server is now running on port ${PROXY_PORT}.`) logit(`CursedChrome HTTP Proxy server is now running on port ${PROXY_PORT}.`)
}); });
proxyServer.on('error', (e) => { proxyServer.on('error', (e) => {
console.error(`CursedChrome HTTP Proxy server encountered an unexpected error:`); logit(`CursedChrome HTTP Proxy server encountered an unexpected error:`);
console.error(e); console.error(e);
}); });
console.log(`Starting the WebSocket server...`); logit(`Starting the WebSocket server...`);
console.log(`Starting the HTTP proxy server...`) logit(`Starting the HTTP proxy server...`)
proxyServer.start(); proxyServer.start();
console.log(`Starting API server...`); logit(`Starting API server...`);
// Start the API server // Start the API server
const api_server = await get_api_server(); const api_server = await get_api_server();
api_server.listen(API_SERVER_PORT, () => { api_server.listen(API_SERVER_PORT, () => {
console.log(`CursedChrome API server is now listening on port ${API_SERVER_PORT}`); logit(`CursedChrome API server is now listening on port ${API_SERVER_PORT}`);
}); });
} }
@@ -559,9 +559,9 @@ async function initialize() {
// If we're the master process spin up workers // If we're the master process spin up workers
// If we're the worker processes, get to work! // If we're the worker processes, get to work!
if (cluster.isMaster) { if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`); logit(`Master ${process.pid} is running`);
console.log(`Initializing the database connection...`); logit(`Initializing the database connection...`);
await database_init(); await database_init();
// Fork workers. // Fork workers.
@@ -570,12 +570,12 @@ async function initialize() {
} }
cluster.on('exit', (worker, code, signal) => { cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`); logit(`worker ${worker.process.pid} died`);
}); });
} else { } else {
// Start worker // Start worker
initialize(); initialize();
console.log(`Worker ${process.pid} started`); logit(`Worker ${process.pid} started`);
} }
})(); })();
+10 -1
View File
@@ -1,5 +1,6 @@
const crypto = require('crypto'); const crypto = require('crypto');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const moment = require('moment');
function copy(input_data) { function copy(input_data) {
return JSON.parse(JSON.stringify(input_data)); return JSON.parse(JSON.stringify(input_data));
@@ -24,8 +25,16 @@ async function get_hashed_password(password) {
); );
} }
function logit(input_string) {
const datetime = moment().format('MMMM Do YYYY, h:mm:ss a');
// Add spacer unless it starts with a `[`
const spacer = input_string.startsWith('[') ? '' : ' ';
console.log(`[${datetime}]${spacer}${input_string.trim()}`);
}
module.exports = { module.exports = {
copy: copy, copy: copy,
get_secure_random_string: get_secure_random_string, get_secure_random_string: get_secure_random_string,
get_hashed_password: get_hashed_password get_hashed_password: get_hashed_password,
logit: logit
}; };