Bug fixes, added AmtWake to MeshCMD.

This commit is contained in:
Ylian Saint-Hilaire 2020-05-13 00:27:31 -07:00
parent f4a8981d4f
commit 04dfeebe1e
10 changed files with 584 additions and 358 deletions

Binary file not shown.

Binary file not shown.

View File

@ -114,7 +114,7 @@ function run(argv) {
//console.log('addedModules = ' + JSON.stringify(addedModules));
var actionpath = 'meshaction.txt';
if (args.actionfile != null) { actionpath = args.actionfile; }
var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTSCAN', 'AMTPOWER', 'AMTFEATURES', 'AMTNETWORK', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTACM', 'AMTDEACTIVATE', 'AMTACMDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTEVENTLOG', 'AMTPRESENCE', 'AMTWIFI'];
var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTSCAN', 'AMTPOWER', 'AMTFEATURES', 'AMTNETWORK', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTACM', 'AMTDEACTIVATE', 'AMTACMDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTEVENTLOG', 'AMTPRESENCE', 'AMTWIFI', 'AMTWAKE'];
// Load the action file
var actionfile = null;
@ -201,6 +201,7 @@ function run(argv) {
console.log(' AmtNetwork - Intel AMT network interface settings.');
console.log(' AmtScan - Search local network for Intel AMT devices.');
console.log(' AmtWifi - Intel AMT Wifi interface settings.');
console.log(' AmtWake - Intel AMT Wake Alarms.');
console.log('\r\nHelp on a specific action using:\r\n');
console.log(' meshcmd help [action]');
exit(1); return;
@ -395,7 +396,7 @@ function run(argv) {
console.log('\r\nOptional arguments:\r\n');
console.log(' --user [username] The Intel AMT login username, admin is default.');
console.log(' --tls Specifies that TLS must be used.');
console.log(' --list List of stored Wifi profile');
console.log(' --list List Wifi profiles');
console.log(' --add Add new Wifi profile');
console.log(' --name New Wifi profile name');
console.log(' --priority Priority of this profile - default 0');
@ -404,6 +405,22 @@ function run(argv) {
console.log(' --enc Wifi Encryption type (3 - TKIP, 4 - CCMP) - default 3');
console.log(' --psk Wifi password/pre-shared key');
console.log(' --del [profile-name] Delete new Wifi profile');
} else if (action == 'amtwake') {
console.log('AmtWake is used to view/set/remote Intel AMT Wake Alarms. Example usage:\r\n\r\n meshcmd amtwake --host 1.2.3.4 --user admin --pass mypassword --list');
console.log('\r\nRequired arguments:\r\n');
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
console.log(' --pass [password] The Intel AMT login password.');
console.log(' --[action] Action options are list, add, del.');
console.log('\r\nOptional arguments:\r\n');
console.log(' --user [username] The Intel AMT login username, admin is default.');
console.log(' --tls Specifies that TLS must be used.');
console.log(' --list List wake alarms profile');
console.log(' --add [alarm-name] Add new wake alarm');
console.log(' --date [yyyy-mm-dd] Alarm date in year-month-day format');
console.log(' --time (hh:mm:ss) Optional alarm time in hours:minutes:seconds format, default is 00:00:00.');
console.log(' --interval (dd-hh-mm) Optional alarm interval in days-hours-minutes format, default is alarm once.');
console.log(' --deletewhendone Indicates alarm is removed once triggered, default is to no remove.');
console.log(' --del [alarm-name] Remove a wake alarm');
} else {
actions.shift();
console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
@ -714,22 +731,24 @@ function run(argv) {
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
if (args.add != null) {
if ((args.name == null) || (typeof args.name != 'string') || args.name == '') {
console.log("Wifi profile name is required."); exit(1); return;
}
if ((args.ssid == null) || (typeof args.ssid != 'string') || args.ssid == '') {
console.log("Wifi SSID is required."); exit(1); return;
}
if ((args.psk == null) || (typeof args.psk != 'string') || args.psk == '') {
console.log("Wifi password is required."); exit(1); return;
}
if ((args.name == null) || (typeof args.name != 'string') || args.name == '') { console.log("Wifi profile name is required."); exit(1); return; }
if ((args.ssid == null) || (typeof args.ssid != 'string') || args.ssid == '') { console.log("Wifi SSID is required."); exit(1); return; }
if ((args.psk == null) || (typeof args.psk != 'string') || args.psk == '') { console.log("Wifi password is required."); exit(1); return; }
}
if (args.del !=null) {
if ((settings.name == null) || (typeof settings.name != 'string') || settings.name == '') {
console.log("Wifi profile name is required."); exit(1); return;
}
if ((settings.name == null) || (typeof settings.name != 'string') || settings.name == '') { console.log("Wifi profile name is required."); exit(1); return; }
}
performAmtWifiConfig(args);
} else if (settings.action == 'amtwake') { // Perform remote Intel AMT wake alarm operations
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
if ((args.del != null) && ((typeof args.del != 'string') || args.del == '')) { console.log("Alarm name is required (--del [name])."); exit(1); return; }
if (args.add != null) {
if (((typeof args.add != 'string') || args.add == '')) { console.log("Wake alarm name is required (--add [name])."); exit(1); return; }
if (((typeof args.date != 'string') || args.data == '')) { console.log("Wake alarm date is required (--date [yyyy-mm-dd])."); exit(1); return; }
}
performAmtWakeConfig(args);
} else if (settings.action == 'amtfeatures') { // Perform remote Intel AMT feature configuration operation
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
@ -2546,7 +2565,7 @@ function performAmtWifiConfig1(stack, name, response, status, args) {
if (args) {
if (args.list) {
console.log('List of AMT Wifi profiles:');
console.log('List of Intel AMT Wifi profiles:');
if (wifiProfiles.length==0) {
console.log('No Wifi profiles is stored.');
}
@ -2611,6 +2630,119 @@ function performAmtWifiConfig1(stack, name, response, status, args) {
}
}
//
// Intel AMT wake alarm configuration
//
function _fmtdatetime(str) {
return str.replace('T', ' ').replace('Z', '');
}
function _fmtinterval(str) {
var cl = str.replace('T', '').substring(str.indexOf('P') + 1);
cl = ' ' + cl.replace('D', " days ").replace('H', " hours ").replace('M', " minutes ");
cl = cl.replace(" 1 days ", " 1 day ").replace(" 1 hours ", " 1 hour ").replace(" 1 minutes ", " 1 minute ");
return cl.substring(0, cl.length - 1);
}
function _fmttimepad(str) {
str = '' + str;
while (str.length < 2) { str = '0' + str; }
return str;
}
function convertAmtDataStr(str) {
var timeArray = str.split('Z').join('').split('T').join('-').split(':').join('-').split('-');
return new Date(timeArray[0], timeArray[1] - 1, timeArray[2], timeArray[3], timeArray[4], timeArray[5]);
}
function prepareAlarmOccurenceTemplate(id, nm, start, interval, del) {
return '<d:AlarmTemplate xmlns:d=\"http://intel.com/wbem/wscim/1/amt-schema/1/AMT_AlarmClockService\" xmlns:s=\"http://intel.com/wbem/wscim/1/ips-schema/1/IPS_AlarmClockOccurrence\"><s:InstanceID>' + id + '</s:InstanceID><s:StartTime><p:Datetime xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">' + start + '</p:Datetime></s:StartTime><s:Interval><p:Interval xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">' + interval + '</p:Interval></s:Interval><s:DeleteOnCompletion>' + del + '</s:DeleteOnCompletion></d:AlarmTemplate>';
}
function performAmtWakeConfig(args) {
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
settings.noconsole = true; startLms(performAmtWakeConfig0, false, args);
} else {
performAmtWakeConfig0(1, args);
}
}
function performAmtWakeConfig0(state, args) {
var transport = require('amt-wsman-duk');
var wsman = require('amt-wsman');
var amt = require('amt');
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
amtstack = new amt(wsstack);
amtstack.BatchEnum(null, ['IPS_AlarmClockOccurrence'], performAmtWakeConfig1, args);
}
function performAmtWakeConfig1(stack, name, response, status, args) {
if (status == 200) {
var response = response['IPS_AlarmClockOccurrence'].responses;
if (!args) { process.exit(0); return; }
if (args.list) {
if (response.length == 0) {
console.log('No wake alarms.');
} else {
for (var i = 0; i < response.length; i++) {
var waketime = convertAmtDataStr(response[i]['StartTime']['Datetime']);
var t = waketime.toLocaleString(), tx = t.indexOf('.');
if (tx >= 0) { t = t.substring(0, tx); }
var details = response[i]['ElementName'] + ', wake on ' + t.replace(' ', ' at ');
if (response[i]['Interval'] != null) { details += ' and each' + _fmtinterval(response[i]['Interval']['Interval']); }
if (response[i]['DeleteOnCompletion'] == true) { details += ", delete when done"; }
console.log(details);
}
}
process.exit(0);
} else if (args.del) {
// Remove a wake alarm, start by looking to see if it exists
var alarmFound = false;
for (var i = 0; i < response.length; i++) { if (response[i]['ElementName'] == args.del) { alarmFound = true; } }
if (alarmFound == false) { console.log("Wake alarm " + args.del + " could not be found."); process.exit(0); return; }
// Remote the alarm
stack.Delete('IPS_AlarmClockOccurrence', { InstanceID: args.del },
function (stck, nm, resp, sts) {
if (sts == 200) { console.log("Done."); } else { console.log("Failed to delete wake alarm " + args.del + "."); }
process.exit(0);
},
0, 1);
} else if (args.add) {
// Add a wake alarm
var alarmFound = false;
for (var i = 0; i < response.length; i++) { if (response[i]['ElementName'] == args.add) { alarmFound = true; } }
if (alarmFound) { console.log("Wake alarm " + args.add + " already exists."); process.exit(0); return; }
if (typeof args.time != 'string') { args.time = '00:00:00'; }
if (typeof args.interval != 'string') { args.interval = ''; }
var alarm_name = args.add;
var x1 = args.date.split('-');
var x2 = args.time.split(':');
var t = new Date(x1[0], x1[1] - 1, x1[2], x2[0], x2[1], 0, 0); // Not sure why, but month is 0 = JAN, 11 = DEC, seconds must be 00.
var alarm_starttime = _fmttimepad(t.getFullYear()) + '-' + _fmttimepad(t.getMonth() + 1) + '-' + _fmttimepad(t.getDate()) + 'T' + _fmttimepad(t.getHours()) + ':' + _fmttimepad(t.getMinutes()) + ':' + _fmttimepad(t.getSeconds()) + 'Z';
var x = args.interval.split('-');
if (x.length != 3) { x = [0, 0, 0]; }
var alarm_interval = 'P' + x[0] + 'DT' + x[1] + 'H' + x[2] + 'M';
var alarm_doc = (args.deletewhendone != null);
var tpl = prepareAlarmOccurenceTemplate(alarm_name, alarm_name, alarm_starttime, alarm_interval, alarm_doc);
stack.wsman.ExecMethodXml(amtstack.CompleteName('AMT_AlarmClockService'), 'AddAlarm', tpl,
function (ws, resuri, response, status) {
if (status != 200) { console.log("Failed to add alarm. Status: " + status + ". Verify the alarm is for a future time."); }
else if (response.Body['ReturnValue'] != 0) { console.log("Failed to add alarm " + response.Body['ReturnValueStr'] + ". Verify the alarm is for a future time."); }
else { console.log("Done."); }
process.exit(0);
}
);
} else {
console.log("Unknown action, specify --list, --del or --add.");
process.exit(0);
}
} else {
console.log("Error, status " + status + ".");
process.exit(1);
}
}
//
// Intel AMT feature configuration action
//

View File

@ -300,14 +300,25 @@ module.exports.CreateMeshMail = function (parent) {
parent.debug('email', 'SMTP response: ' + JSON.stringify(err) + ', ' + JSON.stringify(info));
obj.sendingMail = false;
if (err == null) {
// Send the next mail
obj.pendingMails.shift();
obj.retry = 0;
sendNextMail(); // Send the next mail
sendNextMail();
} else {
obj.retry++;
parent.debug('email', 'SMTP server failed: ' + JSON.stringify(err));
console.log('SMTP server failed: ' + JSON.stringify(err));
if (obj.retry < 6) { setTimeout(sendNextMail, 60000); } // Wait and try again
parent.debug('email', 'SMTP server failed (Retry:' + obj.retry + '): ' + JSON.stringify(err));
console.log('SMTP server failed (Retry:' + obj.retry + '/3): ' + JSON.stringify(err));
// Wait and try again
if (obj.retry < 3) {
setTimeout(sendNextMail, 10000);
} else {
// Failed, send the next mail
parent.debug('email', 'SMTP server failed (Skipping): ' + JSON.stringify(err));
console.log('SMTP server failed (Skipping): ' + JSON.stringify(err));
obj.pendingMails.shift();
obj.retry = 0;
sendNextMail();
}
}
});
}

View File

@ -812,6 +812,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
break;
}
case 'email': {
if (parent.parent.mailserver == null) {
r = "No email service enabled.";
} else {
if (cmdargs['_'].length != 3) {
r = "Usage: email \"user@sample.com\" \"Subject\" \"Message\".";
} else {
parent.parent.mailserver.sendMail(cmdargs['_'][0], cmdargs['_'][1], cmdargs['_'][2]);
r = "Done.";
}
}
break;
}
case 'le': {
if (parent.parent.letsencrypt == null) {
r = "Let's Encrypt not in use.";
@ -3871,6 +3884,25 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
});
break;
}
case 'emailuser': { // Send a email message to a user
var errMsg = null, emailuser = null;
if (parent.parent.mailserver == null) { errMsg = 'Email server not enabled'; }
else if ((user.siteadmin & 2) == 0) { errMsg = 'No user management rights'; }
else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = 'Invalid userid'; }
else if (common.validateString(command.subject, 1, 1000) == false) { errMsg = 'Invalid subject message'; }
else if (common.validateString(command.msg, 1, 10000) == false) { errMsg = 'Invalid message'; }
else {
emailuser = parent.users[command.userid];
if (emailuser == null) { errMsg = 'Invalid userid'; }
else if (emailuser.email == null) { errMsg = 'No validated email address for this user'; }
else if (emailuser.emailVerified !== true) { errMsg = 'No validated email address for this user'; }
}
if (errMsg != null) { displayNotificationMessage(errMsg); break; }
parent.parent.mailserver.sendMail(emailuser.email, command.subject, command.msg);
displayNotificationMessage("Email sent.");
break;
}
case 'getClip': {
if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.5.31",
"version": "0.5.32",
"keywords": [
"Remote Management",
"Intel AMT",

File diff suppressed because one or more lines are too long

View File

@ -2332,6 +2332,10 @@ a {
background-color: gray;
}
.night #deskToolsAreaTop {
background-color: #222;
}
#deskToolsArea {
position: absolute;
top: 26px;
@ -2342,6 +2346,10 @@ a {
text-align: left;
}
.night #deskToolsArea {
background-color: #222;
}
#deskToolsHeader {
border-bottom: 1px solid darkgray;
padding: 3px;
@ -2389,6 +2397,14 @@ a {
.deskToolsBar:hover {
background-color: #EFE8B6;
}
.night .deskToolsBar {
color: #ddd;
}
.night .deskToolsBar:hover {
background-color: #444;
}
#deskarea4 {
grid-area: deskarea4;

File diff suppressed because it is too large Load Diff

View File

@ -4982,6 +4982,7 @@
if (node == null) return;
var mesh = meshes[node.meshid];
var meshrights = GetNodeRights(node);
var deviceSwitch = ((currentNode == null) || (currentNode._id != nodeid));
if (!currentNode || currentNode._id != node._id || refresh == true) {
currentNode = node;
@ -5269,9 +5270,11 @@
}
// Clear user consent status if present
p11clearConsoleMsg();
p12clearConsoleMsg();
p13clearConsoleMsg();
if (deviceSwitch) {
p11clearConsoleMsg();
p12clearConsoleMsg();
p13clearConsoleMsg();
}
// Device refresh plugin handler
if (pluginHandler != null) {
@ -10159,6 +10162,18 @@
function showSendSMSValidate() { QE('idx_dlgOkButton', Q('d2smsText').value.length > 0); }
function showSendSMSEx(b, tag) { if (Q('d2smsText').value.length > 0) { meshserver.send({ action: 'smsuser', userid: decodeURIComponent(tag), msg: Q('d2smsText').value }); } }
function showSendEmail(userid) {
if (xxdialogMode) return;
var x = '<input id=d2emailSubject style=background-color:#fcf3cf;width:100% placeholder="' + "Subject" + '"></input>';
x += '<textarea id=d2emailText maxlength=10000 style="background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:auto" onKeyUp=showSendEmailValidate()></textarea>';
setDialogMode(2, "Send Email", 3, showSendEmailEx, x, userid);
Q('d2emailSubject').focus();
showSendEmailValidate();
}
function showSendEmailValidate() { QE('idx_dlgOkButton', (Q('d2emailSubject').value.length > 0) && (Q('d2emailText').value.length > 0)); }
function showSendEmailEx(b, tag) { if (Q('d2emailText').value.length > 0) { meshserver.send({ action: 'emailuser', userid: decodeURIComponent(tag), subject: Q('d2emailSubject').value, msg: Q('d2emailText').value }); } }
function showUserAlertDialog(e, userid) {
if (xxdialogMode) return;
haltEvent(e);
@ -10916,6 +10931,7 @@
// Add action buttons
x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this user" + '" onclick=showNotes(false,"' + userid + '") />';
if (user.phone && (features & 0x02000000)) { x += '<input type=button value="' + "SMS" + '" title="' + "Send a SMS message to this user" + '" onclick=showSendSMS("' + userid + '") />'; }
if ((typeof user.email == 'string') && (user.emailVerified === true) && (features & 0x00000040)) { x += '<input type=button value="' + "Email" + '" title="' + "Send a email message to this user" + '" onclick=showSendEmail("' + userid + '") />'; }
if (!self && (activeSessions > 0)) { x += '<input type=button value="' + "Notify" + '" title="' + "Send user notification" + '" onclick=showUserAlertDialog(event,"' + userid + '") />'; }
// Setup the panel