mirror of
https://github.com/mandatoryprogrammer/CursedChrome
synced 2026-06-08 15:39:30 +00:00
Update
This commit is contained in:
@@ -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`);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user