meshbot.js 6.0 KB

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