Inter-user messaging fixes.

Ylian Saint-Hilaire committed Sep 10, 2021 at 21:17 UTC a80af24779e7c74a1c9bb0fd1a6dfd594105fe20
2 files changed +119 -2
meshbot.js new
+117
@@ -0,0 +1,117 @@
1 +#!/usr/bin/env node
2 +
3 +// Make sure we have the dependency modules
4 +try { require('minimist'); } catch (ex) { console.log('Missing module "minimist", type "npm install minimist" to install it.'); return; }
5 +try { require('ws'); } catch (ex) { console.log('Missing module "ws", type "npm install ws" to install it.'); return; }
6 +
7 +var settings = {};
8 +const crypto = require('crypto');
9 +const args = require('minimist')(process.argv.slice(2));
10 +const path = require('path');
11 +if (args.proxy != null) { try { require('https-proxy-agent'); } catch (ex) { console.log('Missing module "https-proxy-agent", type "npm install https-proxy-agent" to install it.'); return; } }
12 +
13 +if (args['_'].length == 0) {
14 + console.log("MeshBot is a bot that connects to MeshCentral and perform various tasks.");
15 + console.log("Information at: https://meshcentral.com");
16 + console.log("No action specified, use MeshBot like this:\r\n\r\n meshbot [action] [arguments]\r\n");
17 + console.log("Supported actions:");
18 + console.log(" run - Run the bot.");
19 + console.log("\r\nSupported login arguments:");
20 + console.log(" --url [wss://server] - Server url, wss://localhost:443 is default.");
21 + console.log(" - Use wss://localhost:443?key=xxx if login key is required.");
22 + console.log(" --loginuser [username] - Login username, admin is default.");
23 + console.log(" --loginpass [password] - Login password.");
24 + console.log(" --token [number] - 2nd factor authentication token.");
25 + console.log(" --loginkey [key] - Server login key.");
26 + console.log(" --nocertcheck - Ignore server certificate warning.");
27 + console.log(" --proxy [http://proxy:123] - Specify an HTTP proxy.");
28 + return;
29 +} else {
30 + settings.cmd = args['_'][0].toLowerCase();
31 + if (settings.cmd != 'run') { console.log("Invalid command. \"run\" command will start the bot."); return; } else { serverConnect(); }
32 +}
33 +
34 +function serverConnect() {
35 + const WebSocket = require('ws'), options = {}
36 +
37 + // URL setup
38 + var url = 'wss://localhost/control.ashx';
39 + if (args.url) {
40 + url = args.url;
41 + if (url.length < 5) { console.log("Invalid url."); process.exit(); return; }
42 + if ((url.startsWith('wss://') == false) && (url.startsWith('ws://') == false)) { console.log("Invalid url."); process.exit(); return; }
43 + var i = url.indexOf('?key='), loginKey = null;
44 + if (i >= 0) { loginKey = url.substring(i + 5); url = url.substring(0, i); }
45 + if (url.endsWith('/') == false) { url += '/'; }
46 + url += 'control.ashx';
47 + if (loginKey != null) { url += '?key=' + loginKey; }
48 + }
49 +
50 + // Certificate checking
51 + if (args.nocertcheck) { options.rejectUnauthorized = false; }
52 +
53 + // Setup the HTTP proxy if needed
54 + if (args.proxy != null) {
55 + const HttpsProxyAgent = require('https-proxy-agent');
56 + options.agent = new HttpsProxyAgent(require('url').parse(args.proxy));
57 + }
58 +
59 + // Authentication setup
60 + if (args.loginkey != null) { url += '?auth=' + args.loginkey; } // Cookie authentication
61 + else if (args.loginpass != null) { // Password authentication
62 + var username = 'admin';
63 + if (args.loginuser != null) { username = args.loginuser; }
64 + var token = '';
65 + if (args.token != null) { token = ',' + Buffer.from('' + args.token).toString('base64'); }
66 + options.headers = { 'x-meshauth': Buffer.from('' + username).toString('base64') + ',' + Buffer.from('' + args.loginpass).toString('base64') + token }
67 + }
68 +
69 + // Connect to the server
70 + const ws = new WebSocket(url, options);
71 + console.log('MeshBot, press CTRl-C to stop.');
72 + console.log('Connecting to ' + url);
73 + ws.on('open', function open() {
74 + //console.log('Connected.');
75 + switch (settings.cmd) {
76 + // ws.send(JSON.stringify({ action: 'users', responseid: 'meshctrl' })); // Ask for list of users
77 + // ws.send(JSON.stringify({ action: 'meshes' })); // Ask for list of device groups
78 + // ws.send(JSON.stringify({ action: 'nodes', responseid: 'meshctrl' })); // Ask for list of devices
79 + }
80 + });
81 + ws.on('close', function () {
82 + console.log('Reconnecting in 10 seconds...');
83 + setTimeout(serverConnect, 10000);
84 + });
85 + ws.on('error', function (err) {
86 + if (err.code == 'ENOTFOUND') { console.log('Unable to resolve ' + url); }
87 + else if (err.code == 'ECONNREFUSED') { console.log('Unable to connect to ' + url); }
88 + else { console.log(err); }
89 + });
90 + ws.on('message', function incoming(rawdata) {
91 + var data = null;
92 + try { data = JSON.parse(rawdata); } catch (ex) { }
93 + if (data == null) { console.log('Unable to parse data: ' + rawdata); }
94 +
95 + //console.log("Got command: " + data.action);
96 +
97 + switch (data.action) {
98 + case 'serverinfo': { console.log('Connected to server: ' + data.serverinfo.name); break; }
99 + case 'userinfo': {
100 + console.log('Connected at user: ' + data.userinfo.name);
101 + if ((args.targetuser != null) || (args.targetsession != null)) {
102 + console.log('Sending interuser message...');
103 + ws.send(JSON.stringify({ action: 'interuser', userid: args.targetuser, sessionid: args.targetsession, data: 'Hello!!!' })); // Send a hello message
104 + }
105 + break;
106 + }
107 + case 'interuser': {
108 + console.log('Got InterUser Message', data);
109 + if ((args.targetuser == null) && (args.targetsession == null) && (typeof data.data == 'string')) { // For testing, echo back the original message.
110 + console.log('Sending interuser echo...');
111 + ws.send(JSON.stringify({ action: 'interuser', sessionid: data.sessionid, data: 'ECHO: ' + data.data }));
112 + }
113 + break;
114 + }
115 + }
116 + });
117 +}
meshuser.js
+2 -2
@@ -622,8 +622,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
622 }
623 case 'interuser':
624 {
625 - // Sends data between users only if allowed.
626 - if (command.data == null) return;
625 + // Sends data between users only if allowed. Only a user in the "interUserMessaging": [] list, in the settings section of the config.json can receive and send inter-user messages from and to all users.
626 + if ((parent.parent.config.settings.interusermessaging == null) || (parent.parent.config.settings.interusermessaging == false) || (command.data == null)) return;
627 if (typeof command.sessionid == 'string') { var userSessionId = command.sessionid.split('/'); if (userSessionId.length != 4) return; command.userid = userSessionId[0] + '/' + userSessionId[1] + '/' + userSessionId[2]; }
628 if (common.validateString(command.userid, 0, 2014) == false) return;
629 var userSplit = command.userid.split('/');